Implications of Brénainn Woodsend's observation
Implications of Brénainn Woodsend's observation
Posted Apr 8, 2026 16:31 UTC (Wed) by zahlman (guest, #175387)Parent article: Disabling Python's lazy imports from the command line
Anyway, the primary cause of import-related performance issues, as I see it, is the tendency of libraries to recursively import the entire package (e.g. `from . import x, y, z`, or even `from .x import *` etc., in the top-level `__init__.py`) for "convenience" when most clients will only use a small fraction of the library. The next thing you know, `pip install` (*with no specified package*, such that an error message will be printed) adds over 500 entries to `sys.modules`, including almost 100 from Requests and its dependencies, *even though it didn't actually access the Internet*.[0]
Aside from which, developers like to move in lock-step with the CPython release cadence, so in practical terms they don't have access to this feature until the 3.19 release anyway. In the mean time, the habit of manual import deferral will just get more ingrained, because it generally works fine. I don't think that "the imports aren't all at the top of the file" is a big problem; one can add e.g `deferred : Optional[ModuleType] = None` at the top in place of the import. There's also already support for lazy-loading modules in the standard library, although it's neither easy to use nor quite as thorough as the proposed implementation[1].
If a Python 4 were politically feasible, we could address this sort of thing. We could make lazy importing behaviour the default. We could even apply such logic to sub-module imports.[2]
[0] The Requests imports are deferred manually, although apparently not quite as far as they could be. Arguably that's an argument in favour of the feature in general.
[1] See e.g. https://news.ycombinator.com/item?id=45467489 where I showed how to "install" lazy-loading behaviour as the default for all subsequent imports.
[2] Since 3.7, though, you can simulate this with module-level `__getattr__` as per https://peps.python.org/pep-0562/ . But that boilerplate needs to be repeated in every `__init__.py`.
