(root)/
Python-3.11.7/
Lib/
test/
test_importlib/
import_/
test_path.py
       1  from test.test_importlib import util
       2  
       3  importlib = util.import_importlib('importlib')
       4  machinery = util.import_importlib('importlib.machinery')
       5  
       6  import os
       7  import sys
       8  import tempfile
       9  from types import ModuleType
      10  import unittest
      11  import warnings
      12  import zipimport
      13  
      14  
      15  class ESC[4;38;5;81mFinderTests:
      16  
      17      """Tests for PathFinder."""
      18  
      19      find = None
      20      check_found = None
      21  
      22      def test_failure(self):
      23          # Test None returned upon not finding a suitable loader.
      24          module = '<test module>'
      25          with util.import_state():
      26              self.assertIsNone(self.find(module))
      27  
      28      def test_sys_path(self):
      29          # Test that sys.path is used when 'path' is None.
      30          # Implicitly tests that sys.path_importer_cache is used.
      31          module = '<test module>'
      32          path = '<test path>'
      33          importer = util.mock_spec(module)
      34          with util.import_state(path_importer_cache={path: importer},
      35                                 path=[path]):
      36              found = self.find(module)
      37              self.check_found(found, importer)
      38  
      39      def test_path(self):
      40          # Test that 'path' is used when set.
      41          # Implicitly tests that sys.path_importer_cache is used.
      42          module = '<test module>'
      43          path = '<test path>'
      44          importer = util.mock_spec(module)
      45          with util.import_state(path_importer_cache={path: importer}):
      46              found = self.find(module, [path])
      47              self.check_found(found, importer)
      48  
      49      def test_empty_list(self):
      50          # An empty list should not count as asking for sys.path.
      51          module = 'module'
      52          path = '<test path>'
      53          importer = util.mock_spec(module)
      54          with util.import_state(path_importer_cache={path: importer},
      55                                 path=[path]):
      56              self.assertIsNone(self.find('module', []))
      57  
      58      def test_path_hooks(self):
      59          # Test that sys.path_hooks is used.
      60          # Test that sys.path_importer_cache is set.
      61          module = '<test module>'
      62          path = '<test path>'
      63          importer = util.mock_spec(module)
      64          hook = util.mock_path_hook(path, importer=importer)
      65          with util.import_state(path_hooks=[hook]):
      66              found = self.find(module, [path])
      67              self.check_found(found, importer)
      68              self.assertIn(path, sys.path_importer_cache)
      69              self.assertIs(sys.path_importer_cache[path], importer)
      70  
      71      def test_empty_path_hooks(self):
      72          # Test that if sys.path_hooks is empty a warning is raised,
      73          # sys.path_importer_cache gets None set, and PathFinder returns None.
      74          path_entry = 'bogus_path'
      75          with util.import_state(path_importer_cache={}, path_hooks=[],
      76                                 path=[path_entry]):
      77              with warnings.catch_warnings(record=True) as w:
      78                  warnings.simplefilter('always', ImportWarning)
      79                  warnings.simplefilter('ignore', DeprecationWarning)
      80                  self.assertIsNone(self.find('os'))
      81                  self.assertIsNone(sys.path_importer_cache[path_entry])
      82                  self.assertEqual(len(w), 1)
      83                  self.assertTrue(issubclass(w[-1].category, ImportWarning))
      84  
      85      def test_path_importer_cache_empty_string(self):
      86          # The empty string should create a finder using the cwd.
      87          path = ''
      88          module = '<test module>'
      89          importer = util.mock_spec(module)
      90          hook = util.mock_path_hook(os.getcwd(), importer=importer)
      91          with util.import_state(path=[path], path_hooks=[hook]):
      92              found = self.find(module)
      93              self.check_found(found, importer)
      94              self.assertIn(os.getcwd(), sys.path_importer_cache)
      95  
      96      def test_None_on_sys_path(self):
      97          # Putting None in sys.path[0] caused an import regression from Python
      98          # 3.2: http://bugs.python.org/issue16514
      99          new_path = sys.path[:]
     100          new_path.insert(0, None)
     101          new_path_importer_cache = sys.path_importer_cache.copy()
     102          new_path_importer_cache.pop(None, None)
     103          new_path_hooks = [zipimport.zipimporter,
     104                            self.machinery.FileFinder.path_hook(
     105                                *self.importlib._bootstrap_external._get_supported_file_loaders())]
     106          missing = object()
     107          email = sys.modules.pop('email', missing)
     108          try:
     109              with util.import_state(meta_path=sys.meta_path[:],
     110                                     path=new_path,
     111                                     path_importer_cache=new_path_importer_cache,
     112                                     path_hooks=new_path_hooks):
     113                  module = self.importlib.import_module('email')
     114                  self.assertIsInstance(module, ModuleType)
     115          finally:
     116              if email is not missing:
     117                  sys.modules['email'] = email
     118  
     119      def test_finder_with_find_module(self):
     120          class ESC[4;38;5;81mTestFinder:
     121              def find_module(self, fullname):
     122                  return self.to_return
     123          failing_finder = TestFinder()
     124          failing_finder.to_return = None
     125          path = 'testing path'
     126          with util.import_state(path_importer_cache={path: failing_finder}):
     127              with warnings.catch_warnings():
     128                  warnings.simplefilter("ignore", ImportWarning)
     129                  self.assertIsNone(
     130                      self.machinery.PathFinder.find_spec('whatever', [path]))
     131          success_finder = TestFinder()
     132          success_finder.to_return = __loader__
     133          with util.import_state(path_importer_cache={path: success_finder}):
     134              with warnings.catch_warnings():
     135                  warnings.simplefilter("ignore", ImportWarning)
     136                  spec = self.machinery.PathFinder.find_spec('whatever', [path])
     137          self.assertEqual(spec.loader, __loader__)
     138  
     139      def test_finder_with_find_loader(self):
     140          class ESC[4;38;5;81mTestFinder:
     141              loader = None
     142              portions = []
     143              def find_loader(self, fullname):
     144                  return self.loader, self.portions
     145          path = 'testing path'
     146          with util.import_state(path_importer_cache={path: TestFinder()}):
     147              with warnings.catch_warnings():
     148                  warnings.simplefilter("ignore", ImportWarning)
     149                  self.assertIsNone(
     150                      self.machinery.PathFinder.find_spec('whatever', [path]))
     151          success_finder = TestFinder()
     152          success_finder.loader = __loader__
     153          with util.import_state(path_importer_cache={path: success_finder}):
     154              with warnings.catch_warnings():
     155                  warnings.simplefilter("ignore", ImportWarning)
     156                  spec = self.machinery.PathFinder.find_spec('whatever', [path])
     157          self.assertEqual(spec.loader, __loader__)
     158  
     159      def test_finder_with_find_spec(self):
     160          class ESC[4;38;5;81mTestFinder:
     161              spec = None
     162              def find_spec(self, fullname, target=None):
     163                  return self.spec
     164          path = 'testing path'
     165          with util.import_state(path_importer_cache={path: TestFinder()}):
     166              self.assertIsNone(
     167                      self.machinery.PathFinder.find_spec('whatever', [path]))
     168          success_finder = TestFinder()
     169          success_finder.spec = self.machinery.ModuleSpec('whatever', __loader__)
     170          with util.import_state(path_importer_cache={path: success_finder}):
     171              got = self.machinery.PathFinder.find_spec('whatever', [path])
     172          self.assertEqual(got, success_finder.spec)
     173  
     174      def test_deleted_cwd(self):
     175          # Issue #22834
     176          old_dir = os.getcwd()
     177          self.addCleanup(os.chdir, old_dir)
     178          new_dir = tempfile.mkdtemp()
     179          try:
     180              os.chdir(new_dir)
     181              try:
     182                  os.rmdir(new_dir)
     183              except OSError:
     184                  # EINVAL on Solaris, EBUSY on AIX, ENOTEMPTY on Windows
     185                  self.skipTest("platform does not allow "
     186                                "the deletion of the cwd")
     187          except:
     188              os.chdir(old_dir)
     189              os.rmdir(new_dir)
     190              raise
     191  
     192          with util.import_state(path=['']):
     193              # Do not want FileNotFoundError raised.
     194              self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
     195  
     196      def test_invalidate_caches_finders(self):
     197          # Finders with an invalidate_caches() method have it called.
     198          class ESC[4;38;5;81mFakeFinder:
     199              def __init__(self):
     200                  self.called = False
     201  
     202              def invalidate_caches(self):
     203                  self.called = True
     204  
     205          key = os.path.abspath('finder_to_invalidate')
     206          cache = {'leave_alone': object(), key: FakeFinder()}
     207          with util.import_state(path_importer_cache=cache):
     208              self.machinery.PathFinder.invalidate_caches()
     209          self.assertTrue(cache[key].called)
     210  
     211      def test_invalidate_caches_clear_out_None(self):
     212          # Clear out None in sys.path_importer_cache() when invalidating caches.
     213          cache = {'clear_out': None}
     214          with util.import_state(path_importer_cache=cache):
     215              self.machinery.PathFinder.invalidate_caches()
     216          self.assertEqual(len(cache), 0)
     217  
     218      def test_invalidate_caches_clear_out_relative_path(self):
     219          class ESC[4;38;5;81mFakeFinder:
     220              def invalidate_caches(self):
     221                  pass
     222  
     223          cache = {'relative_path': FakeFinder()}
     224          with util.import_state(path_importer_cache=cache):
     225              self.machinery.PathFinder.invalidate_caches()
     226          self.assertEqual(cache, {})
     227  
     228  
     229  class ESC[4;38;5;81mFindModuleTests(ESC[4;38;5;149mFinderTests):
     230      def find(self, *args, **kwargs):
     231          with warnings.catch_warnings():
     232              warnings.simplefilter("ignore", DeprecationWarning)
     233              return self.machinery.PathFinder.find_module(*args, **kwargs)
     234      def check_found(self, found, importer):
     235          self.assertIs(found, importer)
     236  
     237  
     238  (Frozen_FindModuleTests,
     239   Source_FindModuleTests
     240  ) = util.test_both(FindModuleTests, importlib=importlib, machinery=machinery)
     241  
     242  
     243  class ESC[4;38;5;81mFindSpecTests(ESC[4;38;5;149mFinderTests):
     244      def find(self, *args, **kwargs):
     245          return self.machinery.PathFinder.find_spec(*args, **kwargs)
     246      def check_found(self, found, importer):
     247          self.assertIs(found.loader, importer)
     248  
     249  
     250  (Frozen_FindSpecTests,
     251   Source_FindSpecTests
     252   ) = util.test_both(FindSpecTests, importlib=importlib, machinery=machinery)
     253  
     254  
     255  class ESC[4;38;5;81mPathEntryFinderTests:
     256  
     257      def test_finder_with_failing_find_spec(self):
     258          # PathEntryFinder with find_module() defined should work.
     259          # Issue #20763.
     260          class ESC[4;38;5;81mFinder:
     261              path_location = 'test_finder_with_find_module'
     262              def __init__(self, path):
     263                  if path != self.path_location:
     264                      raise ImportError
     265  
     266              @staticmethod
     267              def find_module(fullname):
     268                  return None
     269  
     270  
     271          with util.import_state(path=[Finder.path_location]+sys.path[:],
     272                                 path_hooks=[Finder]):
     273              with warnings.catch_warnings():
     274                  warnings.simplefilter("ignore", ImportWarning)
     275                  self.machinery.PathFinder.find_spec('importlib')
     276  
     277      def test_finder_with_failing_find_module(self):
     278          # PathEntryFinder with find_module() defined should work.
     279          # Issue #20763.
     280          class ESC[4;38;5;81mFinder:
     281              path_location = 'test_finder_with_find_module'
     282              def __init__(self, path):
     283                  if path != self.path_location:
     284                      raise ImportError
     285  
     286              @staticmethod
     287              def find_module(fullname):
     288                  return None
     289  
     290  
     291          with util.import_state(path=[Finder.path_location]+sys.path[:],
     292                                 path_hooks=[Finder]):
     293              with warnings.catch_warnings():
     294                  warnings.simplefilter("ignore", ImportWarning)
     295                  warnings.simplefilter("ignore", DeprecationWarning)
     296                  self.machinery.PathFinder.find_module('importlib')
     297  
     298  
     299  (Frozen_PEFTests,
     300   Source_PEFTests
     301   ) = util.test_both(PathEntryFinderTests, machinery=machinery)
     302  
     303  
     304  if __name__ == '__main__':
     305      unittest.main()