@@ -676,52 +676,35 @@ def test_lazy_modules_tracks_lazy_imports(self):
676676
677677@support .requires_subprocess ()
678678class ErrorHandlingTests (LazyImportTestCase ):
679- """Tests for error handling during lazy import reification.
679+ """Tests for error handling during lazy import reification."""
680680
681- PEP 810: Errors during reification should show exception chaining with
682- both the lazy import definition location and the access location.
683- """
684-
685- def test_import_error_shows_chained_traceback (self ):
681+ def test_missing_lazy_submodule_raises_attribute_error (self ):
686682 """Accessing a nonexistent lazy submodule via parent attr raises AttributeError."""
687683 code = textwrap .dedent ("""
688- import sys
689684 lazy import test.test_lazy_import.data.nonexistent_module
690685
691686 try:
692- x = test.test_lazy_import.data.nonexistent_module
693- except AttributeError as e:
694- print("OK")
687+ _ = test.test_lazy_import.data.nonexistent_module
688+ except AttributeError:
689+ pass
690+ else:
691+ raise AssertionError("AttributeError was not raised")
695692 """ )
696- result = subprocess .run (
697- [sys .executable , "-c" , code ],
698- capture_output = True ,
699- text = True
700- )
701- self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
702- self .assertIn ("OK" , result .stdout )
693+ assert_python_ok ("-c" , code )
703694
704- def test_attribute_error_on_from_import_shows_chained_traceback (self ):
695+ def test_missing_lazy_from_import_shows_chained_traceback (self ):
705696 """Accessing missing attribute from lazy from-import should chain errors."""
706- # Tests 'lazy from module import nonexistent' behavior
707697 code = textwrap .dedent ("""
708- import sys
709698 lazy from test.test_lazy_import.data.basic2 import nonexistent_name
710699
711700 try:
712- x = nonexistent_name
701+ _ = nonexistent_name
713702 except ImportError as e:
714- # PEP 810: Enhanced error reporting through exception chaining
715703 assert e.__cause__ is not None, "Expected chained exception"
716- print("OK")
704+ else:
705+ raise AssertionError("ImportError was not raised")
717706 """ )
718- result = subprocess .run (
719- [sys .executable , "-c" , code ],
720- capture_output = True ,
721- text = True
722- )
723- self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
724- self .assertIn ("OK" , result .stdout )
707+ assert_python_ok ("-c" , code )
725708
726709 def test_reification_retries_on_failure (self ):
727710 """Failed reification should allow retry on subsequent access.
@@ -731,53 +714,74 @@ def test_reification_retries_on_failure(self):
731714 """
732715 code = textwrap .dedent ("""
733716 import sys
734- import types
735717
736718 lazy import test.test_lazy_import.data.broken_module
737719
738- # First access - should fail
739720 try:
740- x = test.test_lazy_import.data.broken_module
741- except AttributeError:
742- pass
721+ _ = test.test_lazy_import.data.broken_module
722+ except ValueError as exc:
723+ assert str(exc) == "This module always fails to import", exc
724+ else:
725+ raise AssertionError("ValueError was not raised")
726+
727+ assert "test.test_lazy_import.data.broken_module" not in sys.modules
743728
744- # The lazy object should still be a lazy proxy (not reified)
745- g = globals()
746- lazy_obj = g['test']
747- # The root 'test' binding should still allow retry
748- # Second access - should also fail (retry the import)
749729 try:
750- x = test.test_lazy_import.data.broken_module
751- except AttributeError:
752- print("OK - retry worked")
730+ _ = test.test_lazy_import.data.broken_module
731+ except ValueError as exc:
732+ assert str(exc) == "This module always fails to import", exc
733+ else:
734+ raise AssertionError("ValueError was not raised")
753735 """ )
754- result = subprocess .run (
755- [sys .executable , "-c" , code ],
756- capture_output = True ,
757- text = True
758- )
759- self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
760- self .assertIn ("OK" , result .stdout )
736+ assert_python_ok ("-c" , code )
761737
762- def test_error_during_module_execution_propagates (self ):
763- """Errors in module code during reification should propagate correctly."""
738+ def test_module_not_found_during_module_execution_propagates (self ):
739+ code = textwrap .dedent ("""
740+ lazy import test.test_lazy_import.data.missing_dependency
741+
742+ try:
743+ _ = test.test_lazy_import.data.missing_dependency
744+ except ModuleNotFoundError as exc:
745+ assert exc.name == "missing_dependency_for_lazy_import_test", exc.name
746+ assert str(exc) == "No module named 'missing_dependency_for_lazy_import_test'", exc
747+ else:
748+ raise AssertionError("ModuleNotFoundError was not raised")
749+ """ )
750+ assert_python_ok ("-c" , code )
751+
752+ def test_self_named_module_not_found_during_module_execution_propagates (self ):
753+ code = textwrap .dedent ("""
754+ lazy import test.test_lazy_import.data.self_named_module_not_found
755+
756+ try:
757+ _ = test.test_lazy_import.data.self_named_module_not_found
758+ except ModuleNotFoundError as exc:
759+ assert exc.name == "test.test_lazy_import.data.self_named_module_not_found", exc.name
760+ assert str(exc) == "boom", exc
761+ else:
762+ raise AssertionError("ModuleNotFoundError was not raised")
763+ """ )
764+ assert_python_ok ("-c" , code )
765+
766+ def test_none_in_sys_modules_during_submodule_resolution_propagates (self ):
764767 code = textwrap .dedent ("""
765768 import sys
766- lazy import test.test_lazy_import.data.broken_module
769+
770+ sys.modules["test.test_lazy_import.data.blocked_module"] = None
771+ lazy import test.test_lazy_import.data.blocked_module
767772
768773 try:
769- _ = test.test_lazy_import.data.broken_module
770- print("FAIL - should have raised")
771- except AttributeError:
772- print("OK")
774+ _ = test.test_lazy_import.data.blocked_module
775+ except ModuleNotFoundError as exc:
776+ assert exc.name == "test.test_lazy_import.data.blocked_module", exc.name
777+ assert str(exc) == (
778+ "import of test.test_lazy_import.data.blocked_module "
779+ "halted; None in sys.modules"
780+ ), exc
781+ else:
782+ raise AssertionError("ModuleNotFoundError was not raised")
773783 """ )
774- result = subprocess .run (
775- [sys .executable , "-c" , code ],
776- capture_output = True ,
777- text = True
778- )
779- self .assertEqual (result .returncode , 0 , f"stdout: { result .stdout } , stderr: { result .stderr } " )
780- self .assertIn ("OK" , result .stdout )
784+ assert_python_ok ("-c" , code )
781785
782786 def test_circular_lazy_import_does_not_crash_for_gh_144727 (self ):
783787 with tempfile .TemporaryDirectory () as tmpdir :
0 commit comments