diff --git a/homeassistant/loader.py b/homeassistant/loader.py index 322870952f2..b6dabb1d883 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,19 @@ 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. + 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/test_loader.py b/tests/test_loader.py index 646526e94ea..e8a79c6501f 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -30,8 +30,7 @@ class TestLoader(unittest.TestCase): 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,18 @@ def test_helpers_wrapper(hass): 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' + 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' diff --git a/tests/testing_config/custom_components/test_package/__init__.py b/tests/testing_config/custom_components/test_package/__init__.py index 528f056948b..ee669c6c9b5 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