Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Lazy submodule imports hide exceptions raised while loading the submodule #153236

Description

@pablogsal

Bug report

Bug description:

Accessing a pending lazy submodule through the parent module can hide the real
exception raised while importing the submodule.

Reproducer:

mkdir -p lel/lol
printf 'print("LEL")\n' > lel/__init__.py
printf '1/0\n' > lel/lol/__init__.py
./python -c 'lazy import lel.lol; lel.lol'

Actual output:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
    lazy import lel.lol; lel.lol
                         ^^^^^^^
AttributeError: module 'lel' has no attribute 'lol'
LEL

The eager import is much easier to debug:

./python -c 'import lel.lol; lel.lol'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import lel.lol; lel.lol
    ^^^^^^^^^^^^^^
  File "/tmp/lazy-issue-repro/lel/lol/__init__.py", line 1, in <module>
    1/0
    ~^~
ZeroDivisionError: division by zero
LEL

I would expect the lazy import path to propagate the exception raised while
executing lel.lol, probably with the lazy-import reification chain, instead
of turning it into a missing attribute on lel.

Unless I am missing something, this is coming from
Objects/moduleobject.c:try_load_lazy_submodule(). It calls
_PyImport_TryLoadLazySubmodule(), and if that returns NULL, it clears the
active exception:

PyObject *result = _PyImport_TryLoadLazySubmodule(mod_name, name);
Py_DECREF(mod_name);
if (result == NULL) {
    PyErr_Clear();
    return NULL;
}

But _PyImport_TryLoadLazySubmodule() calls PyImport_ImportModuleLevelObject(),
so NULL can mean that the pending submodule exists but failed while importing,
not only that the attribute should fall through to normal AttributeError
handling.

This seems related to gh-150052 / gh-150744, but it looks different from
gh-151208: there is no parent attribute shadowing here, the child module itself
raises during import.

CPython versions tested on:

CPython main branch

Tested on a local 3.16.0a0 main-derived build at 8b59df84c0d, containing
5a2d2736a655d993934adee1bbb568067d53f6f4.

Operating systems tested on:

Linux

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions