micropython/tests/basics/import_star_nonmodule.py
Damien George 570744d06c py/runtime: Make import-all support non-modules via __dict__/__all__.
Prior to this fix, `mp_import_all()` assumed that its argument was exactly
a native module instance.  That would lead to a crash if something else was
passed in, eg a user class via a custom `__import__` implementation or by
writing to `sys.modules`.

MicroPython already supports injecting non-module objects into the import
machinery, so it makes sense to round out that implementation by supporting
`from x import *` where `x` is a non-module object.

Fixes issue #18639.

Signed-off-by: Damien George <damien@micropython.org>
2026-02-05 00:24:14 +11:00

66 lines
1.1 KiB
Python

# Test "from x import *" where x is something other than a module.
import sys
try:
next(iter([]), 42)
except TypeError:
# Two-argument version of next() not supported. We are probably not at
# MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES which is needed for "import *".
print("SKIP")
raise SystemExit
print("== test with a class as a module ==")
class M:
x = "a1"
def __init__(self):
self.x = "a2"
sys.modules["mod"] = M
from mod import *
print(x)
sys.modules["mod"] = M()
from mod import *
print(x)
print("== test with a class as a module that overrides __all__ ==")
class M:
__all__ = ("y",)
x = "b1"
y = "b2"
def __init__(self):
self.__all__ = ("x",)
self.x = "b3"
self.y = "b4"
sys.modules["mod"] = M
x = None
from mod import *
print(x, y)
sys.modules["mod"] = M()
from mod import *
print(x, y)
print("== test with objects that don't have a __dict__ ==")
sys.modules["mod"] = 1
try:
from mod import *
# MicroPython raises AttributeError, CPython raises ImportError.
except (AttributeError, ImportError):
print("ImportError")