Skip to content

Dotted lazy import reification bypasses full-name __import__ hook #152297

Description

@Kuhai9801

Bug report

Bug description:

A dotted lazy import appears to reify by importing only the top-level package name, rather than calling __import__ with the full dotted module name.

import builtins
import os
import sys
import tempfile
import types

real_import = builtins.__import__
calls = []

with tempfile.TemporaryDirectory() as tmpdir:
    os.mkdir(os.path.join(tmpdir, "hookpkg"))
    open(os.path.join(tmpdir, "hookpkg", "__init__.py"), "w").close()
    with open(os.path.join(tmpdir, "hookpkg", "sub.py"), "w") as f:
        f.write("VALUE = 'real-submodule'\n")

    sys.path.insert(0, tmpdir)

    def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
        if name == "hookpkg.sub":
            calls.append((name, globals.get("__name__"), tuple(fromlist or ())))
            package = real_import("hookpkg", globals, locals, (), level)
            module = types.ModuleType("hookpkg.sub")
            module.VALUE = "hooked-submodule"
            package.sub = module
            sys.modules["hookpkg.sub"] = module
            return package
        return real_import(name, globals, locals, fromlist, level)

    builtins.__import__ = custom_import
    try:
        lazy import hookpkg.sub
        print(hookpkg.sub.VALUE)
        print(calls)
    finally:
        builtins.__import__ = real_import
        sys.path.remove(tmpdir)

Expected:

hooked-submodule
[('hookpkg.sub', '__main__', ())]

Actual on current main:

real-submodule
[]

I confirmed this across tier1, tier2, and tier2 without uop optimization:
https://github.com/Kuhai9801/cpython/actions/runs/28242426554

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions