@@ -549,6 +549,26 @@ def test_import_standard_library(self):
549
549
assert "json" in sys .modules
550
550
assert result == '{"key": "value"}'
551
551
552
+ def test_cached_module_import (self ):
553
+ """Test that _import_module returns the cached module if it exists"""
554
+ # Remove the module from sys.modules if it's already imported
555
+ if "json" in sys .modules :
556
+ del sys .modules ["json" ]
557
+
558
+ # Lazy import the module
559
+ json = lazy_import ("json" )
560
+
561
+ # Access an attribute to trigger the import
562
+ json .dumps
563
+
564
+ # The module should now be cached
565
+ # We need to access the private _import_module method directly
566
+ # to test the cached path
567
+ module = json ._import_module ()
568
+
569
+ # Verify that the cached module was returned
570
+ assert module is json ._module
571
+
552
572
def test_import_already_imported_module (self ):
553
573
"""Test lazy importing of an already imported module"""
554
574
# Make sure the module is imported
@@ -618,6 +638,17 @@ def test_import_nonexistent_module(self):
618
638
619
639
assert "Failed to lazily import nonexistent_module_xyz" in str (excinfo .value )
620
640
641
+ def test_call_nonexistent_module (self ):
642
+ """Test calling a nonexistent module"""
643
+ # Lazy import a nonexistent module
644
+ nonexistent = lazy_import ("nonexistent_module_xyz" )
645
+
646
+ # Calling the nonexistent module should raise ImportError
647
+ with pytest .raises (ImportError ) as excinfo :
648
+ nonexistent ()
649
+
650
+ assert "Failed to lazily import nonexistent_module_xyz" in str (excinfo .value )
651
+
621
652
def test_import_nonexistent_attribute (self ):
622
653
"""Test lazy importing of a nonexistent attribute"""
623
654
# Lazy import a nonexistent attribute
@@ -631,6 +662,19 @@ def test_import_nonexistent_attribute(self):
631
662
excinfo .value
632
663
)
633
664
665
+ def test_getattr_on_nonexistent_attribute_path (self ):
666
+ """Test accessing an attribute on a nonexistent attribute path"""
667
+ # Lazy import a nonexistent attribute path
668
+ nonexistent_attr = lazy_import ("math.nonexistent_attribute" )
669
+
670
+ # Accessing an attribute on the nonexistent attribute should raise AttributeError
671
+ with pytest .raises (AttributeError ) as excinfo :
672
+ nonexistent_attr .some_attribute
673
+
674
+ assert "module 'math' has no attribute 'nonexistent_attribute'" in str (
675
+ excinfo .value
676
+ )
677
+
634
678
def test_import_noncallable (self ):
635
679
"""Test calling a non-callable lazy imported object"""
636
680
# Lazy import a non-callable attribute
@@ -654,3 +698,62 @@ def test_attribute_error(self):
654
698
assert "module 'math' has no attribute 'nonexistent_attribute'" in str (
655
699
excinfo .value
656
700
)
701
+
702
+ def test_attribute_error_after_import (self ):
703
+ """Test accessing a nonexistent attribute on a module after it's been imported"""
704
+ # Create a simple module with a known attribute
705
+ import types
706
+
707
+ test_module = types .ModuleType ("test_module" )
708
+ test_module .existing_attr = "exists"
709
+
710
+ # Add it to sys.modules so lazy_import can find it
711
+ sys .modules ["test_module" ] = test_module
712
+
713
+ try :
714
+ # Lazy import the module
715
+ lazy_mod = lazy_import ("test_module" )
716
+
717
+ # Access the existing attribute to trigger the import
718
+ assert lazy_mod .existing_attr == "exists"
719
+
720
+ # Now access a nonexistent attribute
721
+ with pytest .raises (AttributeError ) as excinfo :
722
+ lazy_mod .nonexistent_attribute
723
+
724
+ assert (
725
+ "module 'test_module' has no attribute 'nonexistent_attribute'"
726
+ in str (excinfo .value )
727
+ )
728
+ finally :
729
+ # Clean up
730
+ if "test_module" in sys .modules :
731
+ del sys .modules ["test_module" ]
732
+
733
+ def test_attribute_error_with_direct_module_access (self ):
734
+ """Test accessing a nonexistent attribute by directly setting the _module attribute"""
735
+ # Get the lazy_import function
736
+ from redisvl .utils .utils import lazy_import
737
+
738
+ # Create a lazy import for a module that doesn't exist yet
739
+ lazy_mod = lazy_import ("test_direct_module" )
740
+
741
+ # Create a simple object with no __getattr__ method
742
+ class SimpleObject :
743
+ pass
744
+
745
+ obj = SimpleObject ()
746
+
747
+ # Directly set the _module attribute to our simple object
748
+ # This bypasses the normal import mechanism
749
+ lazy_mod ._module = obj
750
+
751
+ # Now access a nonexistent attribute
752
+ # This should go through our LazyModule.__getattr__ and hit line 332
753
+ with pytest .raises (AttributeError ) as excinfo :
754
+ lazy_mod .nonexistent_attribute
755
+
756
+ assert (
757
+ "module 'test_direct_module' has no attribute 'nonexistent_attribute'"
758
+ in str (excinfo .value )
759
+ )
0 commit comments