Skip to content

Commit 2554992

Browse files
authored
PEP 810: Add rejected idea for object transformation approach (#4676)
1 parent 09815f2 commit 2554992

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

peps/pep-0810.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,55 @@ Past decisions that violated this principle of keeping core abstractions clean
17351735
have caused significant pain in the CPython ecosystem, making optimization
17361736
difficult and introducing subtle bugs.
17371737

1738+
Transforming lazy objects via ``__class__`` mutation
1739+
----------------------------------------------------
1740+
1741+
An alternative implementation approach was proposed where lazy import objects
1742+
would be transformed into their final form by mutating their internal state,
1743+
rather than replacing the object entirely. Under this approach, a lazy object
1744+
would be transformed in-place after the actual import completes.
1745+
1746+
This approach was rejected for several reasons:
1747+
1748+
1. This technique could potentially work for module objects, but breaks down
1749+
completely for arbitrary objects imported via ``from`` statements. When a
1750+
user writes ``lazy from foo import bar``, the object ``bar`` could be any
1751+
Python object (a function, class, constant, etc.), not just a module. Any
1752+
transformation approach would require that the lazy proxy object have
1753+
compatible memory layout and other considerations with the target object,
1754+
which is impossible to know before loading the module. This creates a
1755+
fundamental asymmetry where ``lazy import x`` and ``lazy from x import y``
1756+
would require completely different implementation strategies, with the latter
1757+
still needing the proxy replacement mechanism.
1758+
1759+
2. Even for module objects, the approach has fundamental limitations. Some
1760+
implementations substitute custom classes in ``sys.modules`` that inherit
1761+
from or replace the standard module type. These custom module classes can
1762+
have different memory layouts and sizes than ``PyModuleObject``. The
1763+
transformation approach cannot work with such generic custom module
1764+
implementations, creating fragility and maintenance burden across the
1765+
ecosystem.
1766+
1767+
3. While the transformation approach might appear simpler in some respects, this
1768+
is somewhat subjective. It introduces a bifurcated implementation: one path
1769+
for modules and a completely different path for non-module objects. Whether
1770+
this is simpler than a unified proxy mechanism depends on perspective and
1771+
implementation details.
1772+
1773+
4. Any code holding a reference to the object before transformation will see a
1774+
different type after transformation. This can break code that checks object
1775+
types or relies on type stability, particularly C extensions that cache type
1776+
pointers or use ``PyObject_TypeCheck``. The transformation also requires
1777+
careful coordination between the lazy import machinery and the type system to
1778+
ensure that the object remains valid throughout the transformation process.
1779+
The current proxy-based design avoids these issues by maintaining clear
1780+
boundaries between the lazy proxy and the actual imported object.
1781+
1782+
The current design, which uses object replacement through the ``LazyImportType``
1783+
proxy pattern, provides a consistent mechanism that works uniformly for both
1784+
``import`` and ``from ... import`` statements while maintaining cleaner
1785+
separation between the lazy import machinery and Python's core object model.
1786+
17381787
Making ``lazy`` imports find the module without loading it
17391788
----------------------------------------------------------
17401789

0 commit comments

Comments
 (0)