Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions Lib/test/test_lazy_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,59 @@ def test_from_import_with_module_getattr(self):
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_from_import_with_module_getattr_raising(self):
"""Lazy from import should respect module-level __getattr__."""
code = textwrap.dedent("""
lazy from test.test_lazy_import.data.module_with_getattr import raising_attr

try:
raising_attr
except ValueError as exc:
assert str(exc) == 'from_getattr', exc
else:
assert False, f'ValueError is not raised: {raising_attr}'
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_from_import_with_module_getattr_missing(self):
"""Lazy from import should respect module-level __getattr__."""
for attr in ("missing_attr", "import_error_attr"):
with self.subTest(attr=attr):
code = textwrap.dedent(f"""
lazy from test.test_lazy_import.data.module_with_getattr import {attr}

try:
{attr}
except ImportError as exc:
assert '{attr}' in str(exc), exc
assert exc.__cause__ is not None
else:
assert False, ('ImportError is not raised', {attr})
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_from_import_with_module_getattr_warning(self):
"""Lazy from import should respect module-level __getattr__."""
code = textwrap.dedent("""
import warnings

with warnings.catch_warnings(record=True) as log:
lazy from test.test_lazy_import.data.module_with_getattr import warning_attr

assert log == []

with warnings.catch_warnings(record=True) as log:
warning_attr
assert warning_attr == 'from_warning_attr', warning_attr
assert len(log) == 1, log
assert isinstance(log[0].message, UserWarning), log
assert str(log[0].message) == 'from_getattr', log
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_from_import_with_imported_module_getattr(self):
"""Lazy from import should not shadow an imported module's __getattr__."""
Expand Down Expand Up @@ -458,6 +511,59 @@ def test_lazy_import_pkg_cross_import(self):
self.assertEqual(type(g["x"]), int)
self.assertEqual(type(g["b"]), types.LazyImportType)

@support.requires_subprocess()
def test_package_from_import_with_module_getattr_raising(self):
"""Lazy from import should respect a package's __getattr__."""
code = textwrap.dedent("""
lazy from test.test_lazy_import.data.pkg import raising_attr

try:
raising_attr
except ValueError as exc:
assert str(exc) == 'from_getattr', exc
else:
assert False, f'ValueError is not raised: {raising_attr}'
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_package_from_import_with_module_getattr_missing(self):
"""Lazy from import should respect package's __getattr__."""
for attr in ("missing_attr", "import_error_attr"):
with self.subTest(attr=attr):
code = textwrap.dedent(f"""
lazy from test.test_lazy_import.data.pkg import {attr}

try:
{attr}
except ImportError as exc:
assert '{attr}' in str(exc), exc
assert exc.__cause__ is not None
else:
assert False, ('ImportError is not raised', {attr})
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_from_import_with_module_getattr_warning(self):
"""Lazy from import should respect package's __getattr__."""
code = textwrap.dedent("""
import warnings

with warnings.catch_warnings(record=True) as log:
lazy from test.test_lazy_import.data.pkg import warning_attr

assert log == []

with warnings.catch_warnings(record=True) as log:
warning_attr
assert warning_attr == 'from_warning_attr', warning_attr
assert len(log) == 1, log
assert isinstance(log[0].message, UserWarning), log
assert str(log[0].message) == 'from_getattr', log
""")
assert_python_ok("-c", code)

@support.requires_subprocess()
def test_package_from_import_with_module_getattr(self):
"""Lazy from import should respect a package's __getattr__."""
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_lazy_import/data/module_with_getattr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
def __getattr__(name):
if name == "dynamic_attr":
return "from_getattr"
elif name == "raising_attr":
raise ValueError("from_getattr")
elif name == "import_error_attr":
raise ImportError(name)
elif name == "warning_attr":
import warnings
warnings.warn("from_getattr", category=UserWarning)
return "from_warning_attr"
raise AttributeError(name)
8 changes: 8 additions & 0 deletions Lib/test/test_lazy_import/data/pkg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
def __getattr__(name):
if name == "dynamic_attr":
return "from_getattr"
elif name == "raising_attr":
raise ValueError("from_getattr")
elif name == "import_error_attr":
raise ImportError(name)
elif name == "warning_attr":
import warnings
warnings.warn("from_getattr", category=UserWarning)
return "from_warning_attr"
raise AttributeError(name)
Loading