tests for pathfinder find none checkfound none def testfailureself test none returned upon not finding a suitable loader module test module with util importstate self assertisnoneself findmodule def testsyspathself test that sys path is used when path is none implicitly tests that sys pathimportercache is used module test module path test path importer util mockspecmodule with util importstatepathimportercachepath importer pathpath found self findmodule self checkfoundfound importer def testpathself test that path is used when set implicitly tests that sys pathimportercache is used module test module path test path importer util mockspecmodule with util importstatepathimportercachepath importer found self findmodule path self checkfoundfound importer def testemptylistself an empty list should not count as asking for sys path module module path test path importer util mockspecmodule with util importstatepathimportercachepath importer pathpath self assertisnoneself find module def testpathhooksself test that sys pathhooks is used test that sys pathimportercache is set module test module path test path importer util mockspecmodule hook util mockpathhookpath importerimporter with util importstatepathhookshook found self findmodule path self checkfoundfound importer self assertinpath sys pathimportercache self assertissys pathimportercachepath importer def testemptypathhooksself test that if sys pathhooks is empty a warning is raised sys pathimportercache gets none set and pathfinder returns none pathentry boguspath with util importstatepathimportercache pathhooks pathpathentry with warnings catchwarningsrecordtrue as w warnings simplefilter always importwarning warnings simplefilter ignore deprecationwarning self assertisnoneself find os self assertisnonesys pathimportercachepathentry self assertequallenw 1 self asserttrueissubclassw1 category importwarning def testpathimportercacheemptystringself the empty string should create a finder using the cwd path module test module importer util mockspecmodule hook util mockpathhookos getcwd importerimporter with util importstatepathpath pathhookshook found self findmodule self checkfoundfound importer self assertinos getcwd sys pathimportercache def testnoneonsyspathself putting none in sys path0 caused an import regression from python 3 2 http bugs python orgissue16514 newpath sys path newpath insert0 none newpathimportercache sys pathimportercache copy newpathimportercache popnone none newpathhooks zipimport zipimporter self machinery filefinder pathhook self importlib bootstrapexternal getsupportedfileloaders missing object email sys modules pop email missing try with util importstatemetapathsys metapath pathnewpath pathimportercachenewpathimportercache pathhooksnewpathhooks module self importlib importmodule email self assertisinstancemodule moduletype finally if email is not missing sys modules email email def testfinderwithfindspecself class testfinder spec none def findspecself fullname targetnone return self spec path testing path with util importstatepathimportercachepath testfinder self assertisnone self machinery pathfinder findspec whatever path successfinder testfinder successfinder spec self machinery modulespec whatever loader with util importstatepathimportercachepath successfinder got self machinery pathfinder findspec whatever path self assertequalgot successfinder spec def testdeletedcwdself issue 22834 olddir os getcwd self addcleanupos chdir olddir newdir tempfile mkdtemp try os chdirnewdir try os rmdirnewdir except oserror einval on solaris ebusy on aix enotempty on windows self skiptestplatform does not allow the deletion of the cwd except os chdirolddir os rmdirnewdir raise with util importstatepath do not want filenotfounderror raised self assertisnoneself machinery pathfinder findspec whatever def testinvalidatecachesfindersself finders with an invalidatecaches method have it called class fakefinder def initself self called false def invalidatecachesself self called true key os path abspath findertoinvalidate cache leavealone object key fakefinder with util importstatepathimportercachecache self machinery pathfinder invalidatecaches self asserttruecachekey called def testinvalidatecachesclearoutnoneself clear out none in sys pathimportercache when invalidating caches cache clearout none with util importstatepathimportercachecache self machinery pathfinder invalidatecaches self assertequallencache 0 def testinvalidatecachesclearoutrelativepathself class fakefinder def invalidatecachesself pass cache relativepath fakefinder with util importstatepathimportercachecache self machinery pathfinder invalidatecaches self assertequalcache class findmoduletestsfindertests def findself args kwargs spec self machinery pathfinder findspecargs kwargs return none if spec is none else spec loader def checkfoundself found importer self assertisfound importer frozenfindmoduletests sourcefindmoduletests util testbothfindmoduletests importlibimportlib machinerymachinery class findspectestsfindertests def findself args kwargs return self machinery pathfinder findspecargs kwargs def checkfoundself found importer self assertisfound loader importer frozenfindspectests sourcefindspectests util testbothfindspectests importlibimportlib machinerymachinery class pathentryfindertests def testfinderwithfailingfindspecself class finder pathlocation testfinderwithfindspec def initself path if path self pathlocation raise importerror staticmethod def findspecfullname targetnone return none with util importstatepathfinder pathlocationsys path pathhooksfinder with warnings catchwarnings warnings simplefilterignore importwarning self machinery pathfinder findspec importlib frozenpeftests sourcepeftests util testbothpathentryfindertests machinerymachinery if name main unittest main tests for pathfinder test none returned upon not finding a suitable loader test that sys path is used when path is none implicitly tests that sys path_importer_cache is used test that path is used when set implicitly tests that sys path_importer_cache is used an empty list should not count as asking for sys path test that sys path_hooks is used test that sys path_importer_cache is set test that if sys path_hooks is empty a warning is raised sys path_importer_cache gets none set and pathfinder returns none the empty string should create a finder using the cwd putting none in sys path 0 caused an import regression from python 3 2 http bugs python org issue16514 issue 22834 einval on solaris ebusy on aix enotempty on windows do not want filenotfounderror raised finders with an invalidate_caches method have it called clear out none in sys path_importer_cache when invalidating caches
from test.test_importlib import util

importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery')

import os
import sys
import tempfile
from types import ModuleType
import unittest
import warnings
import zipimport


class FinderTests:

    

    find = None
    check_found = None

    def test_failure(self):
        
        module = '<test module>'
        with util.import_state():
            self.assertIsNone(self.find(module))

    def test_sys_path(self):
        
        
        module = '<test module>'
        path = '<test path>'
        importer = util.mock_spec(module)
        with util.import_state(path_importer_cache={path: importer},
                               path=[path]):
            found = self.find(module)
            self.check_found(found, importer)

    def test_path(self):
        
        
        module = '<test module>'
        path = '<test path>'
        importer = util.mock_spec(module)
        with util.import_state(path_importer_cache={path: importer}):
            found = self.find(module, [path])
            self.check_found(found, importer)

    def test_empty_list(self):
        
        module = 'module'
        path = '<test path>'
        importer = util.mock_spec(module)
        with util.import_state(path_importer_cache={path: importer},
                               path=[path]):
            self.assertIsNone(self.find('module', []))

    def test_path_hooks(self):
        
        
        module = '<test module>'
        path = '<test path>'
        importer = util.mock_spec(module)
        hook = util.mock_path_hook(path, importer=importer)
        with util.import_state(path_hooks=[hook]):
            found = self.find(module, [path])
            self.check_found(found, importer)
            self.assertIn(path, sys.path_importer_cache)
            self.assertIs(sys.path_importer_cache[path], importer)

    def test_empty_path_hooks(self):
        
        
        path_entry = 'bogus_path'
        with util.import_state(path_importer_cache={}, path_hooks=[],
                               path=[path_entry]):
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter('always', ImportWarning)
                warnings.simplefilter('ignore', DeprecationWarning)
                self.assertIsNone(self.find('os'))
                self.assertIsNone(sys.path_importer_cache[path_entry])
                self.assertEqual(len(w), 1)
                self.assertTrue(issubclass(w[-1].category, ImportWarning))

    def test_path_importer_cache_empty_string(self):
        
        path = ''
        module = '<test module>'
        importer = util.mock_spec(module)
        hook = util.mock_path_hook(os.getcwd(), importer=importer)
        with util.import_state(path=[path], path_hooks=[hook]):
            found = self.find(module)
            self.check_found(found, importer)
            self.assertIn(os.getcwd(), sys.path_importer_cache)

    def test_None_on_sys_path(self):
        
        
        new_path = sys.path[:]
        new_path.insert(0, None)
        new_path_importer_cache = sys.path_importer_cache.copy()
        new_path_importer_cache.pop(None, None)
        new_path_hooks = [zipimport.zipimporter,
                          self.machinery.FileFinder.path_hook(
                              *self.importlib._bootstrap_external._get_supported_file_loaders())]
        missing = object()
        email = sys.modules.pop('email', missing)
        try:
            with util.import_state(meta_path=sys.meta_path[:],
                                   path=new_path,
                                   path_importer_cache=new_path_importer_cache,
                                   path_hooks=new_path_hooks):
                module = self.importlib.import_module('email')
                self.assertIsInstance(module, ModuleType)
        finally:
            if email is not missing:
                sys.modules['email'] = email

    def test_finder_with_find_spec(self):
        class TestFinder:
            spec = None
            def find_spec(self, fullname, target=None):
                return self.spec
        path = 'testing path'
        with util.import_state(path_importer_cache={path: TestFinder()}):
            self.assertIsNone(
                    self.machinery.PathFinder.find_spec('whatever', [path]))
        success_finder = TestFinder()
        success_finder.spec = self.machinery.ModuleSpec('whatever', __loader__)
        with util.import_state(path_importer_cache={path: success_finder}):
            got = self.machinery.PathFinder.find_spec('whatever', [path])
        self.assertEqual(got, success_finder.spec)

    def test_deleted_cwd(self):
        
        old_dir = os.getcwd()
        self.addCleanup(os.chdir, old_dir)
        new_dir = tempfile.mkdtemp()
        try:
            os.chdir(new_dir)
            try:
                os.rmdir(new_dir)
            except OSError:
                
                self.skipTest("platform does not allow "
                              "the deletion of the cwd")
        except:
            os.chdir(old_dir)
            os.rmdir(new_dir)
            raise

        with util.import_state(path=['']):
            
            self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))

    def test_invalidate_caches_finders(self):
        
        class FakeFinder:
            def __init__(self):
                self.called = False

            def invalidate_caches(self):
                self.called = True

        key = os.path.abspath('finder_to_invalidate')
        cache = {'leave_alone': object(), key: FakeFinder()}
        with util.import_state(path_importer_cache=cache):
            self.machinery.PathFinder.invalidate_caches()
        self.assertTrue(cache[key].called)

    def test_invalidate_caches_clear_out_None(self):
        
        cache = {'clear_out': None}
        with util.import_state(path_importer_cache=cache):
            self.machinery.PathFinder.invalidate_caches()
        self.assertEqual(len(cache), 0)

    def test_invalidate_caches_clear_out_relative_path(self):
        class FakeFinder:
            def invalidate_caches(self):
                pass

        cache = {'relative_path': FakeFinder()}
        with util.import_state(path_importer_cache=cache):
            self.machinery.PathFinder.invalidate_caches()
        self.assertEqual(cache, {})


class FindModuleTests(FinderTests):
    def find(self, *args, **kwargs):
        spec = self.machinery.PathFinder.find_spec(*args, **kwargs)
        return None if spec is None else spec.loader

    def check_found(self, found, importer):
        self.assertIs(found, importer)


(Frozen_FindModuleTests,
 Source_FindModuleTests
) = util.test_both(FindModuleTests, importlib=importlib, machinery=machinery)


class FindSpecTests(FinderTests):
    def find(self, *args, **kwargs):
        return self.machinery.PathFinder.find_spec(*args, **kwargs)
    def check_found(self, found, importer):
        self.assertIs(found.loader, importer)


(Frozen_FindSpecTests,
 Source_FindSpecTests
 ) = util.test_both(FindSpecTests, importlib=importlib, machinery=machinery)


class PathEntryFinderTests:

    def test_finder_with_failing_find_spec(self):
        class Finder:
            path_location = 'test_finder_with_find_spec'
            def __init__(self, path):
                if path != self.path_location:
                    raise ImportError

            @staticmethod
            def find_spec(fullname, target=None):
                return None


        with util.import_state(path=[Finder.path_location]+sys.path[:],
                               path_hooks=[Finder]):
            with warnings.catch_warnings():
                warnings.simplefilter("ignore", ImportWarning)
                self.machinery.PathFinder.find_spec('importlib')


(Frozen_PEFTests,
 Source_PEFTests
 ) = util.test_both(PathEntryFinderTests, machinery=machinery)


if __name__ == '__main__':
    unittest.main()