1111import os
1212import sys
1313import types
14+ import warnings
1415
1516__all__ = ["attach" , "load" , "attach_stub" ]
1617
@@ -121,34 +122,44 @@ def load(fullname, error_on_import=False):
121122 We often see the following pattern::
122123
123124 def myfunc():
124- from numpy import linalg as la
125- la .norm(...)
125+ import numpy as np
126+ np .norm(...)
126127 ....
127128
128- This is to prevent a module, in this case `numpy`, from being
129- imported at function definition time, since that can be slow.
129+ Putting the import inside the function prevents, in this case,
130+ `numpy`, from being imported at function definition time.
131+ That saves time if `myfunc` ends up not being called.
130132
131- This function provides a proxy module that, upon access, imports
133+ This `load` function returns a proxy module that, upon access, imports
132134 the actual module. So the idiom equivalent to the above example is::
133135
134- la = lazy.load("numpy.linalg ")
136+ np = lazy.load("numpy")
135137
136138 def myfunc():
137- la .norm(...)
139+ np .norm(...)
138140 ....
139141
140142 The initial import time is fast because the actual import is delayed
141143 until the first attribute is requested. The overall import time may
142144 decrease as well for users that don't make use of large portions
143- of the library.
145+ of your library.
146+
147+ Warning
148+ -------
149+ While lazily loading *sub*packages technically works, it causes the
150+ package (that contains the subpackage) to be eagerly loaded even
151+ if the package is already lazily loaded.
152+ So, you probably shouldn't use subpackages with this `load` feature.
153+ Instead you should encourage the package maintainers to use the
154+ `lazy_loader.attach` to make their subpackages load lazily.
144155
145156 Parameters
146157 ----------
147158 fullname : str
148159 The full name of the module or submodule to import. For example::
149160
150161 sp = lazy.load('scipy') # import scipy as sp
151- spla = lazy.load('scipy.linalg') # import scipy.linalg as spla
162+
152163 error_on_import : bool
153164 Whether to postpone raising import errors until the module is accessed.
154165 If set to `True`, import errors are raised as soon as `load` is called.
@@ -165,6 +176,14 @@ def myfunc():
165176 except KeyError :
166177 pass
167178
179+ if "." in fullname :
180+ msg = (
181+ "subpackages can technically be lazily loaded, but it causes the "
182+ "package to be eagerly loaded even if it is already lazily loaded."
183+ "So, you probably shouldn't use subpackages with this lazy feature."
184+ )
185+ warnings .warn (msg , RuntimeWarning )
186+
168187 spec = importlib .util .find_spec (fullname )
169188 if spec is None :
170189 if error_on_import :
0 commit comments