Doc updates

This commit is contained in:
Pablo Galindo Salgado 2025-12-06 18:33:55 +00:00
parent 2f7d223e2c
commit 0985e2af5e
3 changed files with 65 additions and 7 deletions

View file

@ -457,6 +457,7 @@ Some names are only reserved under specific contexts. These are known as
- ``match``, ``case``, and ``_``, when used in the :keyword:`match` statement.
- ``type``, when used in the :keyword:`type` statement.
- ``lazy``, when used before an :keyword:`import` statement.
These syntactically act as keywords in their specific contexts,
but this distinction is done at the parser level, not when tokenizing.
@ -468,6 +469,9 @@ identifier names.
.. versionchanged:: 3.12
``type`` is now a soft keyword.
.. versionchanged:: next
``lazy`` is now a soft keyword.
.. index::
single: _, identifiers
single: __, identifiers

View file

@ -748,14 +748,15 @@ The :keyword:`!import` statement
pair: name; binding
pair: keyword; from
pair: keyword; as
pair: keyword; lazy
pair: exception; ImportError
single: , (comma); import statement
.. productionlist:: python-grammar
import_stmt: "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])*
: | "from" `relative_module` "import" `identifier` ["as" `identifier`]
import_stmt: ["lazy"] "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])*
: | ["lazy"] "from" `relative_module` "import" `identifier` ["as" `identifier`]
: ("," `identifier` ["as" `identifier`])*
: | "from" `relative_module` "import" "(" `identifier` ["as" `identifier`]
: | ["lazy"] "from" `relative_module` "import" "(" `identifier` ["as" `identifier`]
: ("," `identifier` ["as" `identifier`])* [","] ")"
: | "from" `relative_module` "import" "*"
module: (`identifier` ".")* `identifier`
@ -870,6 +871,57 @@ determine dynamically the modules to be loaded.
.. audit-event:: import module,filename,sys.path,sys.meta_path,sys.path_hooks import
.. _lazy-imports:
Lazy imports
------------
.. index::
pair: lazy; import
single: lazy import
When an import statement is preceded by the :keyword:`lazy<lazy import>` keyword,
the import becomes *lazy*: the module is not loaded immediately at the import
statement. Instead, a lazy proxy object is created and bound to the name. The
actual module is loaded on first use of that name.
.. keyword:: lazy import
The ``lazy`` keyword marks an import as lazy. It is a :ref:`soft keyword
<soft-keywords>` that only has special meaning when it appears immediately
before an :keyword:`import` or :keyword:`from` statement.
Lazy imports are only permitted at module scope. Using ``lazy`` inside a
function, class body, or :keyword:`try`/:keyword:`except`/:keyword:`finally`
block raises a :exc:`SyntaxError`. Star imports cannot be lazy (``lazy from
module import *`` is a syntax error), and :ref:`future statements <future>`
cannot be lazy.
When using ``lazy from ... import``, each imported name is bound to a lazy
proxy object. The first access to any of these names triggers loading of the
entire module and resolves only that specific name to its actual value. Other
names remain as lazy proxies until they are accessed.
Example::
lazy import json
print('json' in sys.modules) # False - module not loaded yet
# First use triggers loading
result = json.dumps({"hello": "world"})
print('json' in sys.modules) # True - now loaded
If an error occurs during module loading (such as :exc:`ImportError` or
:exc:`SyntaxError`), it is raised at the point where the lazy import is first
used, not at the import statement itself.
See :pep:`810` for the full specification of lazy imports.
.. versionadded:: next
.. _future:
Future statements

View file

@ -139,15 +139,17 @@ runtime.
For more selective control, :func:`sys.set_lazy_imports_filter` accepts a callable
that determines whether a specific module should be loaded lazily. The filter
receives the fully-qualified module name and returns a boolean. This allows
patterns like making only your own application's modules lazy while keeping
third-party dependencies eager:
receives three arguments: the importing module's name (or ``None``), the imported
module's name, and the fromlist (or ``None`` for regular imports). It should
return ``True`` to allow the import to be lazy, or ``False`` to force eager loading.
This allows patterns like making only your own application's modules lazy while
keeping third-party dependencies eager:
.. code-block:: python
import sys
sys.set_lazy_imports_filter(lambda name: name.startswith("myapp."))
sys.set_lazy_imports_filter(lambda importing, imported, fromlist: imported.startswith("myapp."))
sys.set_lazy_imports("all")
import myapp.slow_module # lazy (matches filter)