From c58ecf45c39ab5bf80f19832c580f0154015f582 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 6 May 2018 12:58:48 -0400 Subject: [PATCH 1/4] Fix module names for custom components --- homeassistant/loader.py | 16 ++++++++++++---- tests/test_loader.py | 9 +++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/homeassistant/loader.py b/homeassistant/loader.py index 322870952f207a..149c8ffb46421c 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -73,13 +73,15 @@ def get_component(hass, comp_or_platform): # Try custom component module = _load_module(hass.config.path(PATH_CUSTOM_COMPONENTS), - comp_or_platform) + PATH_CUSTOM_COMPONENTS, comp_or_platform) if module is None: try: module = importlib.import_module( '{}.{}'.format(PACKAGE_COMPONENTS, comp_or_platform)) + _LOGGER.debug('Loaded %s (built-in)', comp_or_platform) except ImportError: + _LOGGER.warning('Unable to find %s', comp_or_platform) module = None cache = hass.data.get(DATA_KEY) @@ -102,18 +104,20 @@ def _find_spec(path, name): return None -def _load_module(path, name): +def _load_module(path, base_module, name): """Load a module based on a folder and a name.""" + mod_name = "{}.{}".format(base_module, name) spec = _find_spec([path], name) # Special handling if loading platforms and the folder is a namespace # (namespace is a folder without __init__.py) if spec is None and '.' in name: - parent_spec = _find_spec([path], name.split('.')[0]) + mod_parent_name = name.split('.')[0] + parent_spec = _find_spec([path], mod_parent_name) if (parent_spec is None or parent_spec.submodule_search_locations is None): return None - spec = _find_spec(parent_spec.submodule_search_locations, name) + spec = _find_spec(parent_spec.submodule_search_locations, mod_name) # Not found if spec is None: @@ -123,8 +127,12 @@ def _load_module(path, name): if spec.loader is None: return None + _LOGGER.debug('Loaded %s (%s)', name, base_module) + module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) + # A hack, I know. Don't currently know how to work around it. + module.__name__ = "{}.{}".format(base_module, name) return module diff --git a/tests/test_loader.py b/tests/test_loader.py index 646526e94ea64a..3ed7428d01d616 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -30,8 +30,7 @@ def test_set_component(self): comp = object() loader.set_component(self.hass, 'switch.test_set', comp) - self.assertEqual(comp, - loader.get_component(self.hass, 'switch.test_set')) + assert loader.get_component(self.hass, 'switch.test_set') is comp def test_get_component(self): """Test if get_component works.""" @@ -106,3 +105,9 @@ def discovery_callback(service, discovered): yield from hass.async_block_till_done() assert result == ['hello'] + + +async def test_custom_component_name(hass): + """Test the name attribte of custom components.""" + comp = loader.get_component(hass, 'test_standalone') + assert comp.__name__ == 'custom_components.test_standalone' From 08b774ba527d715c91e32c1a2262fcd817d5c264 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 6 May 2018 20:17:26 -0400 Subject: [PATCH 2/4] Also set __package__ correctly --- homeassistant/loader.py | 5 +++++ tests/test_loader.py | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/homeassistant/loader.py b/homeassistant/loader.py index 149c8ffb46421c..e285ac586209ac 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -133,6 +133,11 @@ def _load_module(path, base_module, name): spec.loader.exec_module(module) # A hack, I know. Don't currently know how to work around it. module.__name__ = "{}.{}".format(base_module, name) + if module.__package__: + module.__package__ = "{}.{}".format(base_module, module.__package__) + else: + module.__package__ = base_module + return module diff --git a/tests/test_loader.py b/tests/test_loader.py index 3ed7428d01d616..e8a79c6501f33d 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -111,3 +111,12 @@ async def test_custom_component_name(hass): """Test the name attribte of custom components.""" comp = loader.get_component(hass, 'test_standalone') assert comp.__name__ == 'custom_components.test_standalone' + assert comp.__package__ == 'custom_components' + + comp = loader.get_component(hass, 'test_package') + assert comp.__name__ == 'custom_components.test_package' + assert comp.__package__ == 'custom_components.test_package' + + comp = loader.get_component(hass, 'light.test') + assert comp.__name__ == 'custom_components.light.test' + assert comp.__package__ == 'custom_components.light' From c9a57fca271c5ff66283e0990d8e3f76f80da6fd Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 6 May 2018 20:35:21 -0400 Subject: [PATCH 3/4] bla --- homeassistant/loader.py | 11 +++++++---- .../custom_components/test_package/__init__.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/homeassistant/loader.py b/homeassistant/loader.py index e285ac586209ac..027838dfd3dabd 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -132,11 +132,14 @@ def _load_module(path, base_module, name): module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # A hack, I know. Don't currently know how to work around it. - module.__name__ = "{}.{}".format(base_module, name) - if module.__package__: - module.__package__ = "{}.{}".format(base_module, module.__package__) - else: + print(name, module.__name__, module.__package__) + if not module.__name__.startswith(base_module): + module.__name__ = "{}.{}".format(base_module, name) + + if not module.__package__: module.__package__ = base_module + elif not module.__package__.startswith(base_module): + module.__package__ = "{}.{}".format(base_module, name) return module diff --git a/tests/testing_config/custom_components/test_package/__init__.py b/tests/testing_config/custom_components/test_package/__init__.py index 528f056948b675..ee669c6c9b59fc 100644 --- a/tests/testing_config/custom_components/test_package/__init__.py +++ b/tests/testing_config/custom_components/test_package/__init__.py @@ -2,6 +2,6 @@ DOMAIN = 'test_package' -def setup(hass, config): +async def async_setup(hass, config): """Mock a successful setup.""" return True From c5c452bd6e1c0238eb84dd643a022f0d3b644ae6 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 6 May 2018 20:54:41 -0400 Subject: [PATCH 4/4] Remove print --- homeassistant/loader.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/loader.py b/homeassistant/loader.py index 027838dfd3dabd..b6dabb1d88397b 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -132,7 +132,6 @@ def _load_module(path, base_module, name): module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # A hack, I know. Don't currently know how to work around it. - print(name, module.__name__, module.__package__) if not module.__name__.startswith(base_module): module.__name__ = "{}.{}".format(base_module, name)