4545from copy import copy
4646from io import StringIO
4747from os .path import abspath , dirname , join
48- from typing import Generator
48+ from typing import Generator , Optional
4949from unittest import mock
5050from unittest .mock import patch
5151
@@ -724,61 +724,131 @@ def test_sys_path() -> Generator[None, None, None]:
724724 finally :
725725 sys .path = original_path
726726
727+ @contextlib .contextmanager
728+ def test_environ_pythonpath (
729+ new_pythonpath : Optional [str ],
730+ ) -> Generator [None , None , None ]:
731+ original_pythonpath = os .environ .get ("PYTHONPATH" )
732+ if new_pythonpath :
733+ os .environ ["PYTHONPATH" ] = new_pythonpath
734+ elif new_pythonpath is None and original_pythonpath is not None :
735+ # If new_pythonpath is None, make sure to delete PYTHONPATH if present
736+ del os .environ ["PYTHONPATH" ]
737+ try :
738+ yield
739+ finally :
740+ if original_pythonpath :
741+ os .environ ["PYTHONPATH" ] = original_pythonpath
742+ elif new_pythonpath is not None :
743+ # Only delete PYTHONPATH if new_pythonpath wasn't None
744+ del os .environ ["PYTHONPATH" ]
745+
727746 with test_sys_path (), patch ("os.getcwd" ) as mock_getcwd :
728747 cwd = "/tmp/pytest-of-root/pytest-0/test_do_not_import_files_from_0"
729748 mock_getcwd .return_value = cwd
730-
731- paths = [
732- cwd ,
733- cwd ,
749+ default_paths = [
734750 "/usr/local/lib/python39.zip" ,
735751 "/usr/local/lib/python3.9" ,
736752 "/usr/local/lib/python3.9/lib-dynload" ,
737753 "/usr/local/lib/python3.9/site-packages" ,
738754 ]
755+
756+ paths = [
757+ cwd ,
758+ * default_paths ,
759+ ]
739760 sys .path = copy (paths )
740- modify_sys_path ()
741- assert sys .path == paths [2 :]
761+ with test_environ_pythonpath (None ):
762+ modify_sys_path ()
763+ assert sys .path == paths [1 :]
764+
765+ paths = [
766+ cwd ,
767+ cwd ,
768+ * default_paths ,
769+ ]
770+ sys .path = copy (paths )
771+ with test_environ_pythonpath ("." ):
772+ modify_sys_path ()
773+ assert sys .path == paths [1 :]
742774
743775 paths = [
744776 cwd ,
745777 "/custom_pythonpath" ,
778+ * default_paths ,
779+ ]
780+ sys .path = copy (paths )
781+ with test_environ_pythonpath ("/custom_pythonpath" ):
782+ modify_sys_path ()
783+ assert sys .path == paths [1 :]
784+
785+ paths = [
746786 cwd ,
747- "/usr/local/lib/python39.zip" ,
748- "/usr/local/lib/python3.9" ,
749- "/usr/local/lib/python3.9/lib-dynload" ,
750- "/usr/local/lib/python3.9/site-packages" ,
787+ "/custom_pythonpath" ,
788+ cwd ,
789+ * default_paths ,
751790 ]
752791 sys .path = copy (paths )
753- modify_sys_path ()
792+ with test_environ_pythonpath ("/custom_pythonpath:" ):
793+ modify_sys_path ()
754794 assert sys .path == [paths [1 ]] + paths [3 :]
755795
756796 paths = [
757797 "" ,
758798 cwd ,
759799 "/custom_pythonpath" ,
760- "/usr/local/lib/python39.zip" ,
761- "/usr/local/lib/python3.9" ,
762- "/usr/local/lib/python3.9/lib-dynload" ,
763- "/usr/local/lib/python3.9/site-packages" ,
800+ * default_paths ,
764801 ]
765802 sys .path = copy (paths )
766- modify_sys_path ()
803+ with test_environ_pythonpath (":/custom_pythonpath" ):
804+ modify_sys_path ()
767805 assert sys .path == paths [2 :]
768806
769807 paths = [
770- "" ,
771808 cwd ,
772- "/usr/local/lib/python39.zip" ,
773- "/usr/local/lib/python3.9" ,
774- "/usr/local/lib/python3.9/lib-dynload" ,
775- "/usr/local/lib/python3.9/site-packages" ,
776809 cwd ,
810+ "/custom_pythonpath" ,
811+ * default_paths ,
777812 ]
778813 sys .path = copy (paths )
779- modify_sys_path ()
814+ with test_environ_pythonpath (":/custom_pythonpath:" ):
815+ modify_sys_path ()
780816 assert sys .path == paths [2 :]
781817
818+ paths = [
819+ cwd ,
820+ cwd ,
821+ * default_paths ,
822+ ]
823+ sys .path = copy (paths )
824+ with test_environ_pythonpath (":." ):
825+ modify_sys_path ()
826+ assert sys .path == paths [1 :]
827+ sys .path = copy (paths )
828+ with test_environ_pythonpath (f":{ cwd } " ):
829+ modify_sys_path ()
830+ assert sys .path == paths [1 :]
831+
832+ sys .path = copy (paths )
833+ with test_environ_pythonpath (".:" ):
834+ modify_sys_path ()
835+ assert sys .path == paths [1 :]
836+ sys .path = copy (paths )
837+ with test_environ_pythonpath (f"{ cwd } :" ):
838+ modify_sys_path ()
839+ assert sys .path == paths [1 :]
840+
841+ paths = [
842+ "" ,
843+ cwd ,
844+ * default_paths ,
845+ cwd ,
846+ ]
847+ sys .path = copy (paths )
848+ with test_environ_pythonpath (cwd ):
849+ modify_sys_path ()
850+ assert sys .path == paths [1 :]
851+
782852 @staticmethod
783853 def test_do_not_import_files_from_local_directory (tmpdir ):
784854 p_astroid = tmpdir / "astroid.py"
@@ -838,7 +908,7 @@ def test_do_not_import_files_from_local_directory_with_pythonpath(tmpdir):
838908 # https://github.com/PyCQA/pylint/issues/3636
839909 with tmpdir .as_cwd ():
840910 orig_pythonpath = os .environ .get ("PYTHONPATH" )
841- os .environ ["PYTHONPATH" ] = os . environ . get ( "PYTHONPATH" , "" ) + " :"
911+ os .environ ["PYTHONPATH" ] = f" { ( orig_pythonpath or '' ). strip ( ':' ) } :"
842912 subprocess .check_output (
843913 [
844914 sys .executable ,
@@ -849,8 +919,39 @@ def test_do_not_import_files_from_local_directory_with_pythonpath(tmpdir):
849919 ],
850920 cwd = str (tmpdir ),
851921 )
852- if orig_pythonpath is not None :
922+ if orig_pythonpath :
923+ os .environ ["PYTHONPATH" ] = orig_pythonpath
924+ else :
925+ del os .environ ["PYTHONPATH" ]
926+
927+ @staticmethod
928+ def test_import_plugin_from_local_directory_if_pythonpath_cwd (tmpdir ):
929+ p_plugin = tmpdir / "plugin.py"
930+ p_plugin .write ("# Some plugin content" )
931+
932+ with tmpdir .as_cwd ():
933+ orig_pythonpath = os .environ .get ("PYTHONPATH" )
934+ os .environ ["PYTHONPATH" ] = "."
935+ process = subprocess .run (
936+ [
937+ sys .executable ,
938+ "-m" ,
939+ "pylint" ,
940+ "--load-plugins" ,
941+ "plugin" ,
942+ ],
943+ cwd = str (tmpdir ),
944+ stderr = subprocess .PIPE ,
945+ check = False ,
946+ )
947+ assert (
948+ "AttributeError: module 'plugin' has no attribute 'register'"
949+ in process .stderr .decode ()
950+ )
951+ if orig_pythonpath :
853952 os .environ ["PYTHONPATH" ] = orig_pythonpath
953+ else :
954+ del os .environ ["PYTHONPATH" ]
854955
855956 def test_allow_import_of_files_found_in_modules_during_parallel_check (self , tmpdir ):
856957 test_directory = tmpdir / "test_directory"
0 commit comments