diff --git a/peps/pep-0810.rst b/peps/pep-0810.rst index e67b5d19d5c..3e9c78e4ad0 100644 --- a/peps/pep-0810.rst +++ b/peps/pep-0810.rst @@ -961,7 +961,7 @@ The overhead is minimal: the slow path away. - Small one-time cost to create the proxy object. - Reification (first use) has the same cost as a regular import. -- No ongoing performance penalty unlike ``importlib.util.LazyLoader``. +- No ongoing performance penalty. Benchmarking with the `pyperformance suite`_ shows the implementation is performance neutral when lazy imports are not used. @@ -1048,7 +1048,6 @@ Why not use ``importlib.util.LazyLoader`` instead? ``LazyLoader`` has significant limitations: - Requires verbose setup code for each lazy import. -- Has ongoing performance overhead on every attribute access. - Doesn't work well with ``from ... import`` statements. - Less clear and standard than dedicated syntax. @@ -1283,6 +1282,13 @@ any eager import. print('json' in sys.modules) # True +Does ``lazy from __future__ import feature`` work? +-------------------------------------------------- + +No, future imports can't be lazy because they're parser/compiler directives. +It's technically possible for the runtime behavior to be lazy but there's no +real value in it. + Why you chose ``lazy`` as the keyword name? ------------------------------------------- @@ -1319,6 +1325,14 @@ imports. The most compelling alternates were ``defer`` and ``delay``. Rejected Ideas ============== +Making the new behavior the default +----------------------------------- + +Changing ``import`` to be lazy by default is outside of the scope of this PEP. +From the discussion on :pep:`690` it is clear that this is a fairly +contentious idea, although perhaps once we have wide-spread use of lazy +imports this can be reconsidered. + Modification of the dict object ------------------------------- @@ -1346,6 +1360,24 @@ Past decisions that violated this principle of keeping core abstractions clean have caused significant pain in the CPython ecosystem, making optimization difficult and introducing subtle bugs. +Making ``lazy`` imports find the module without loading it +---------------------------------------------------------- + +The Python ``import`` machinery separates out finding a module and loading +it, and the lazy import implementation could technically defer only the +loading part. However: + + - Finding the module does not guarantee the import will succeed, nor even + that it will not raise ImportError. + - Finding modules in packages requires that those packages are loaded, so + it would only help with lazy loading one level of a package hierarchy. + - Since "finding" attributes in modules *requires* loading them, this would + create a hard to explain difference between + ``from package import module`` and ``from module import function``. + - A significant part of the performance win is skipping the finding part + (which may involve filesystem searches and consulting multiple importers + and meta-importers). + Placing the ``lazy`` keyword in the middle of from imports ---------------------------------------------------------- @@ -1364,6 +1396,37 @@ this approach provided less clarity. For example, if multiple modules are imported in a single statement, it is unclear if the lazy binding applies to all of the imported objects or just a subset of the items. +Adding an explicit ``eager`` keyword +------------------------------------ + +Since we're not changing the default behavior, and we don't want to +encourage use of the global flags, it's too early to consider adding +superfluous syntax for the common, default case. It would create too much +confusion about what the default is, or when the ``eager`` keyword would be +necessary, or whether it affects lazy imports *in* the explicitly eagerly +imported module. + +Using a context manager instead of a new soft keyword +----------------------------------------------------- + +A backward compatible syntax, for example in the form of a context manager, +has been proposed: + +.. code-block:: python + + with lazy_imports(...): + import json + +This would replace the need for :data:`!__lazy_modules__`, and allow +libraries to use one of the existing lazy imports implementations in older +Python versions. However, adding magic ``with`` statements with that kind of +effect would be a signficant change to Python and ``with`` statements in +general, and it would not be easy to combine with the implementation for +lazy imports in this proposal. Adding standard library support for existing +lazy importers *without* changes to the implementation amounts to the status +quo, and does not solve the performance and usability issues with those +existing solutions. + Returning a proxy dict from ``globals()`` ------------------------------------------