Skip to content

Commit d3be9ca

Browse files
authored
PEP 810: Address discuss comments (#4628)
Address discuss comments.
1 parent 8ac5c8d commit d3be9ca

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

peps/pep-0810.rst

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ The overhead is minimal:
961961
the slow path away.
962962
- Small one-time cost to create the proxy object.
963963
- Reification (first use) has the same cost as a regular import.
964-
- No ongoing performance penalty unlike ``importlib.util.LazyLoader``.
964+
- No ongoing performance penalty.
965965

966966
Benchmarking with the `pyperformance suite`_ shows the implementation is
967967
performance neutral when lazy imports are not used.
@@ -1048,7 +1048,6 @@ Why not use ``importlib.util.LazyLoader`` instead?
10481048
``LazyLoader`` has significant limitations:
10491049

10501050
- Requires verbose setup code for each lazy import.
1051-
- Has ongoing performance overhead on every attribute access.
10521051
- Doesn't work well with ``from ... import`` statements.
10531052
- Less clear and standard than dedicated syntax.
10541053

@@ -1283,6 +1282,13 @@ any eager import.
12831282
12841283
print('json' in sys.modules) # True
12851284
1285+
Does ``lazy from __future__ import feature`` work?
1286+
--------------------------------------------------
1287+
1288+
No, future imports can't be lazy because they're parser/compiler directives.
1289+
It's technically possible for the runtime behavior to be lazy but there's no
1290+
real value in it.
1291+
12861292
Why you chose ``lazy`` as the keyword name?
12871293
-------------------------------------------
12881294

@@ -1319,6 +1325,14 @@ imports. The most compelling alternates were ``defer`` and ``delay``.
13191325
Rejected Ideas
13201326
==============
13211327

1328+
Making the new behavior the default
1329+
-----------------------------------
1330+
1331+
Changing ``import`` to be lazy by default is outside of the scope of this PEP.
1332+
From the discussion on :pep:`690` it is clear that this is a fairly
1333+
contentious idea, although perhaps once we have wide-spread use of lazy
1334+
imports this can be reconsidered.
1335+
13221336
Modification of the dict object
13231337
-------------------------------
13241338

@@ -1346,6 +1360,24 @@ Past decisions that violated this principle of keeping core abstractions clean
13461360
have caused significant pain in the CPython ecosystem, making optimization
13471361
difficult and introducing subtle bugs.
13481362

1363+
Making ``lazy`` imports find the module without loading it
1364+
----------------------------------------------------------
1365+
1366+
The Python ``import`` machinery separates out finding a module and loading
1367+
it, and the lazy import implementation could technically defer only the
1368+
loading part. However:
1369+
1370+
- Finding the module does not guarantee the import will succeed, nor even
1371+
that it will not raise ImportError.
1372+
- Finding modules in packages requires that those packages are loaded, so
1373+
it would only help with lazy loading one level of a package hierarchy.
1374+
- Since "finding" attributes in modules *requires* loading them, this would
1375+
create a hard to explain difference between
1376+
``from package import module`` and ``from module import function``.
1377+
- A significant part of the performance win is skipping the finding part
1378+
(which may involve filesystem searches and consulting multiple importers
1379+
and meta-importers).
1380+
13491381
Placing the ``lazy`` keyword in the middle of from imports
13501382
----------------------------------------------------------
13511383

@@ -1364,6 +1396,37 @@ this approach provided less clarity. For example, if multiple modules are
13641396
imported in a single statement, it is unclear if the lazy binding applies to
13651397
all of the imported objects or just a subset of the items.
13661398

1399+
Adding an explicit ``eager`` keyword
1400+
------------------------------------
1401+
1402+
Since we're not changing the default behavior, and we don't want to
1403+
encourage use of the global flags, it's too early to consider adding
1404+
superfluous syntax for the common, default case. It would create too much
1405+
confusion about what the default is, or when the ``eager`` keyword would be
1406+
necessary, or whether it affects lazy imports *in* the explicitly eagerly
1407+
imported module.
1408+
1409+
Using a context manager instead of a new soft keyword
1410+
-----------------------------------------------------
1411+
1412+
A backward compatible syntax, for example in the form of a context manager,
1413+
has been proposed:
1414+
1415+
.. code-block:: python
1416+
1417+
with lazy_imports(...):
1418+
import json
1419+
1420+
This would replace the need for :data:`!__lazy_modules__`, and allow
1421+
libraries to use one of the existing lazy imports implementations in older
1422+
Python versions. However, adding magic ``with`` statements with that kind of
1423+
effect would be a signficant change to Python and ``with`` statements in
1424+
general, and it would not be easy to combine with the implementation for
1425+
lazy imports in this proposal. Adding standard library support for existing
1426+
lazy importers *without* changes to the implementation amounts to the status
1427+
quo, and does not solve the performance and usability issues with those
1428+
existing solutions.
1429+
13671430
Returning a proxy dict from ``globals()``
13681431
------------------------------------------
13691432

0 commit comments

Comments
 (0)