Fix module names for custom components (#14317)
* Fix module names for custom components * Also set __package__ correctly * bla * Remove printpull/14325/head
parent
107769ab81
commit
34727be5ac
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
DOMAIN = 'test_package'
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
async def async_setup(hass, config):
|
||||
"""Mock a successful setup."""
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue