Skip to content

Lazy imports may leave phantom unresolvable attributes in module #150052

@DinoV

Description

@DinoV

Bug description:

@pablogsal brought this up at the sprints today. When doing "from .. import .." we track the "from" values to publish when on the module when it finally gets imported. We have no way to distinguish whether the values actually exist, if they're values within the package we're importing from, or if they're subpackages. When the module is imported we publish these values as LazyImportObjects on the module. Because we don't know if they exist or if they're subpackages they all get published as long as they don't already exist in the module potentially leaving some cruft around.

Initially this feels like it's "by design". But there's a few alternatives we should consider:

  1. Remove the LazyImportObject from the module if the value is attempted to be resolved but doesn't exist
  2. Switch to instead of publishing the value update _Py_module_getattro_impl to return these values. This is maybe more in the spirit of the changes we've made to push things into the module object in general. We'd publish nothing into the module but it would magically become available if we resolve it and then presumably we'd publish it into the module.
>>> lazy from json import noway
>>> import json
>>> dir(json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__doc__', '__file__', '__getattr__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'noway', 'scanner']
>>> json.noway
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 1319, in _find_and_load_unlocked
ImportError: deferred import of 'json.noway' raised an exception during resolution

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    json.noway
ImportError: cannot import name 'noway' from 'json' (/home/dinoviehland/cpython_upstream/Lib/json/__init__.py)
>>> dir(json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__doc__', '__file__', '__getattr__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'noway', 'scanner']
>>>```

### CPython versions tested on:

3.15

### Operating systems tested on:

Linux

<!-- gh-linked-prs -->
### Linked PRs
* gh-150054
* gh-150055
<!-- /gh-linked-prs -->

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions