From 0c66e997d7b9b15998d3752b883c45d1654f0caa Mon Sep 17 00:00:00 2001 From: Manuel Nuno Melo Date: Mon, 22 Jan 2018 02:14:37 +0000 Subject: [PATCH] Fixed a serious bug when lazy-loading a submodule of a fully-loaded base. Closes #2 Bumped version to 0.2.2 --- CHANGELOG | 2 ++ lazy_import/VERSION | 2 +- lazy_import/__init__.py | 2 +- lazy_import/test_lazy.py | 17 ++++++++++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3ff79cb..c434b34 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +22/01/2018 v0.2.2 + - fixed a serious bug when lazy-loading a submodule of a fully-loaded base. 17/01/2018 v0.2.1 - annoying release to fix install notice on PyPi (because README.rst was incorrect). diff --git a/lazy_import/VERSION b/lazy_import/VERSION index 0c62199..ee1372d 100644 --- a/lazy_import/VERSION +++ b/lazy_import/VERSION @@ -1 +1 @@ -0.2.1 +0.2.2 diff --git a/lazy_import/__init__.py b/lazy_import/__init__.py index 03eaa39..a0b3737 100644 --- a/lazy_import/__init__.py +++ b/lazy_import/__init__.py @@ -348,7 +348,7 @@ def __repr__(self): # ModuleSpec(modname, None)) if fullsubmodname: submod = sys.modules[fullsubmodname] - super(LazyModule, mod).__setattr__(submodname, submod) + ModuleType.__setattr__(mod, submodname, submod) _LazyModule._lazy_import_submodules[submodname] = submod fullsubmodname = modname modname, _, submodname = modname.rpartition('.') diff --git a/lazy_import/test_lazy.py b/lazy_import/test_lazy.py index 7ab2cf6..d801ac1 100644 --- a/lazy_import/test_lazy.py +++ b/lazy_import/test_lazy.py @@ -66,7 +66,8 @@ class _TestLazyModule(lazy_import.LazyModule): pass _GENERATED_NAMES = [] -# Modules not usually loaded on startup +# Modules not usually loaded on startup. Must include at least one with +# submodule NAMES_EXISTING = ("sched", "distutils.core") LEVELS = ("leaf", "base") @@ -243,3 +244,17 @@ def test_callable_missing(modname, errors, cnames, fn): _check_callable_missing(lazy, msg=expected_err) +@pytest.mark.parametrize("modname", + [modname for modname in NAMES_EXISTING if '.' in modname]) +def test_load_lazysub_on_fullmodule(modname, lazy_opts): + level, modclass, errors = lazy_opts + base = modname.split('.')[0] + # A fully loaded base... + importlib.import_module(base) + # and a lazy sub... + mod = lazy_import.lazy_module(modname, error_strings=errors, + lazy_mod_class=modclass, level=level) + if level == 'base': + assert not isinstance(mod, modclass) + else: + assert isinstance(mod, modclass)