@@ -961,7 +961,7 @@ The overhead is minimal:
961
961
the slow path away.
962
962
- Small one-time cost to create the proxy object.
963
963
- 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.
965
965
966
966
Benchmarking with the `pyperformance suite `_ shows the implementation is
967
967
performance neutral when lazy imports are not used.
@@ -1048,7 +1048,6 @@ Why not use ``importlib.util.LazyLoader`` instead?
1048
1048
``LazyLoader `` has significant limitations:
1049
1049
1050
1050
- Requires verbose setup code for each lazy import.
1051
- - Has ongoing performance overhead on every attribute access.
1052
1051
- Doesn't work well with ``from ... import `` statements.
1053
1052
- Less clear and standard than dedicated syntax.
1054
1053
@@ -1283,6 +1282,13 @@ any eager import.
1283
1282
1284
1283
print (' json' in sys.modules) # True
1285
1284
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
+
1286
1292
Why you chose ``lazy `` as the keyword name?
1287
1293
-------------------------------------------
1288
1294
@@ -1319,6 +1325,14 @@ imports. The most compelling alternates were ``defer`` and ``delay``.
1319
1325
Rejected Ideas
1320
1326
==============
1321
1327
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
+
1322
1336
Modification of the dict object
1323
1337
-------------------------------
1324
1338
@@ -1346,6 +1360,24 @@ Past decisions that violated this principle of keeping core abstractions clean
1346
1360
have caused significant pain in the CPython ecosystem, making optimization
1347
1361
difficult and introducing subtle bugs.
1348
1362
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
+
1349
1381
Placing the ``lazy `` keyword in the middle of from imports
1350
1382
----------------------------------------------------------
1351
1383
@@ -1364,6 +1396,37 @@ this approach provided less clarity. For example, if multiple modules are
1364
1396
imported in a single statement, it is unclear if the lazy binding applies to
1365
1397
all of the imported objects or just a subset of the items.
1366
1398
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
+
1367
1430
Returning a proxy dict from ``globals() ``
1368
1431
------------------------------------------
1369
1432
0 commit comments