44
55
66def lazy_import (
7- * imports : str ,
7+ * bare_imports : str ,
88 aliases : collections .abc .Mapping [str , str ] | None = None ,
99 sub_import : collections .abc .Mapping [str , str ] | None = None ,
1010 ** kw_sub_import : str ,
@@ -30,18 +30,25 @@ def lazy_import(
3030 sub_import={'submodule2':'package'}
3131 )
3232
33- :param imports : Any number of module names to import.
33+ :param bare_imports : Any number of module names to import.
3434 :param aliases: A mapping of alias names to module names.
3535 :param sub_import: A mapping of module names to package names.
3636 :param kw_sub_import: Keyword arguments of module names to package names.
3737 :return: A function that returns the imported modules.
3838 """
39- imports = set (imports )
4039 if aliases is None :
4140 aliases = {}
4241 if sub_import is None :
4342 sub_import = {}
44- sub_import = sub_import | kw_sub_import
43+
44+ imports = {name for name in bare_imports if len (name .split ('.' )) == 1 }
45+ top_level_import = collections .defaultdict (list )
46+ for import_path in bare_imports :
47+ root , * path = (import_path .split ('.' ))
48+ if path :
49+ top_level_import [root ].append (import_path )
50+
51+ sub_import .update (kw_sub_import )
4552
4653 import functools
4754 import importlib
@@ -50,11 +57,6 @@ def lazy_import(
5057 def getattr_ (name : str ) -> ModuleType :
5158 name = aliases .get (name , name )
5259
53- if name not in imports and name not in sub_import :
54- raise AttributeError (
55- f'Module has no attribute { name !r} '
56- ) from None
57-
5860 if name in imports :
5961 try :
6062 return importlib .import_module (name )
@@ -63,10 +65,23 @@ def getattr_(name: str) -> ModuleType:
6365 f'Module has no attribute { name !r} '
6466 ) from e
6567
66- try :
67- return importlib .import_module (f'.{ name } ' ,
68- sub_import [name ])
69- except ModuleNotFoundError as e :
70- raise AttributeError (f'Module has no attribute { name !r} ' ) from e
68+ if name in sub_import :
69+ try :
70+ return importlib .import_module (f'.{ name } ' , sub_import [name ])
71+ except ModuleNotFoundError as e :
72+ raise AttributeError (
73+ f'Module has no attribute { name !r} ' ) from e
74+
75+ if name in top_level_import :
76+ try :
77+ module = importlib .__import__ (top_level_import [name ].pop ())
78+ for import_path_ in top_level_import [name ]:
79+ module = importlib .__import__ (import_path_ )
80+ return module
81+ except ModuleNotFoundError as e :
82+ raise AttributeError (
83+ f'Module has no attribute { name !r} ' ) from e
84+
85+ raise AttributeError (f'Module has no attribute { name !r} ' )
7186
7287 return getattr_
0 commit comments