test extensionfileloader def setupself if not self machinery extensionsuffixes raise unittest skiptestrequires dynamic loading support if util extensions name in sys builtinmodulenames raise unittest skiptest futil extensions name is a builtin module self loader self machinery extensionfileloaderutil extensions name util extensions filepath def loadmoduleself fullname with warnings catchwarnings warnings simplefilterignore deprecationwarning return self loader loadmodulefullname def testequalityself other self machinery extensionfileloaderutil extensions name util extensions filepath self assertequalself loader other def testinequalityself other self machinery extensionfileloader util extensions name util extensions filepath self assertnotequalself loader other def testloadmoduleapiself test the default argument for loadmodule with warnings catchwarnings warnings simplefilterignore deprecationwarning self loader loadmodule self loader loadmodulenone with self assertraisesimporterror self loadmodule xxx def testmoduleself with util uncacheutil extensions name module self loadmoduleutil extensions name for attr value in name util extensions name file util extensions filepath package self assertequalgetattrmodule attr value self assertinutil extensions name sys modules self assertisinstancemodule loader self machinery extensionfileloader no extension module as init available for testing testpackage none no extension module in a package available for testing testlackingparent none no easy way to trigger a failure after a successful import teststateafterfailure none def testunloadableself name asdfjkl with self assertraisesimporterror as cm self loadmodulename self assertequalcm exception name name def testmodulereuseself with util uncacheutil extensions name module1 self loadmoduleutil extensions name module2 self loadmoduleutil extensions name self assertismodule1 module2 def testispackageself self assertfalseself loader ispackageutil extensions name for suffix in self machinery extensionsuffixes path os path join some path pkg init suffix loader self machinery extensionfileloader pkg path self asserttrueloader ispackage pkg frozenloadertests sourceloadertests util testbothloadertests machinerymachinery class singlephaseextensionmoduletestsabc loadertests test loading extension modules without multiphase initialization def setupself if not self machinery extensionsuffixes raise unittest skiptestrequires dynamic loading support self name testsinglephase if self name in sys builtinmodulenames raise unittest skiptest fself name is a builtin module finder self machinery filefindernone self spec importlib util findspecself name assert self spec self loader self machinery extensionfileloader self name self spec origin def loadmoduleself with warnings catchwarnings warnings simplefilterignore deprecationwarning return self loader loadmoduleself name def loadmodulebynameself fullname load a module from the test extension by name origin self spec origin loader self machinery extensionfileloaderfullname origin spec importlib util specfromloaderfullname loader module importlib util modulefromspecspec loader execmodulemodule return module def testmoduleself test loading an extension module with util uncacheself name module self loadmodule for attr value in name self name file self spec origin package self assertequalgetattrmodule attr value with self assertraisesattributeerror module path self assertismodule sys modulesself name self assertisinstancemodule loader self machinery extensionfileloader no extension module as init available for testing testpackage none no extension module in a package available for testing testlackingparent none no easy way to trigger a failure after a successful import teststateafterfailure none def testunloadableself name asdfjkl with self assertraisesimporterror as cm self loadmodulebynamename self assertequalcm exception name name def testunloadablenonasciiself test behavior with nonexistent module with nonascii name name foxf3 with self assertraisesimporterror as cm self loadmodulebynamename self assertequalcm exception name name it may make sense to add the equivalent to the following multiphaseextensionmoduletests tests testnonmodule testnonmodulewithmethods testbadmodules testnonascii frozensinglephaseextensionmoduletests sourcesinglephaseextensionmoduletests util testbothsinglephaseextensionmoduletests machinerymachinery class multiphaseextensionmoduletestsabc loadertests test loading extension modules with multiphase initialization pep 489 def setupself if not self machinery extensionsuffixes raise unittest skiptestrequires dynamic loading support self name testmultiphase if self name in sys builtinmodulenames raise unittest skiptest fself name is a builtin module finder self machinery filefindernone self spec importlib util findspecself name assert self spec self loader self machinery extensionfileloader self name self spec origin def loadmoduleself load the module from the test extension with warnings catchwarnings warnings simplefilterignore deprecationwarning return self loader loadmoduleself name def loadmodulebynameself fullname load a module from the test extension by name origin self spec origin loader self machinery extensionfileloaderfullname origin spec importlib util specfromloaderfullname loader module importlib util modulefromspecspec loader execmodulemodule return module no extension module as init available for testing testpackage none no extension module in a package available for testing testlackingparent none handling failure on reload is the up to the module teststateafterfailure none def testmoduleself test loading an extension module with util uncacheself name module self loadmodule for attr value in name self name file self spec origin package self assertequalgetattrmodule attr value with self assertraisesattributeerror module path self assertismodule sys modulesself name self assertisinstancemodule loader self machinery extensionfileloader def testfunctionalityself test basic functionality of stuff defined in an extension module with util uncacheself name module self loadmodule self assertisinstancemodule types moduletype ex module example self assertequalex demo abcd abcd self assertequalex demo none with self assertraisesattributeerror ex abc ex abc 0 self assertequalex abc 0 self assertequalmodule foo9 9 18 self assertisinstancemodule str str self assertequalmodule str1 23 123 with self assertraisesmodule error raise module error self assertequalmodule intconst 1969 self assertequalmodule strconst something different def testreloadself test that reload didn t reset the module s attributes with util uncacheself name module self loadmodule exclass module example importlib reloadmodule self assertisexclass module example def testtryregistrationself assert that the pystatefind add removemodule c api doesn t work with util uncacheself name module self loadmodule with self subtest pystatefindmodule self assertequalmodule callstateregistrationfunc0 none with self subtest pystateaddmodule with self assertraisessystemerror module callstateregistrationfunc1 with self subtest pystateremovemodule with self assertraisessystemerror module callstateregistrationfunc2 def testloadsubmoduleself test loading a simulated submodule module self loadmodulebyname pkg self name self assertisinstancemodule types moduletype self assertequalmodule name pkg self name self assertequalmodule strconst something different def testloadshortnameself test loading module with a onecharacter name module self loadmodulebyname x self assertisinstancemodule types moduletype self assertequalmodule name x self assertequalmodule strconst something different self assertnotin x sys modules def testloadtwiceself test that 2 loads result in 2 module objects module1 self loadmodulebynameself name module2 self loadmodulebynameself name self assertisnotmodule1 module2 def testunloadableself test nonexistent module name asdfjkl with self assertraisesimporterror as cm self loadmodulebynamename self assertequalcm exception name name def testunloadablenonasciiself test behavior with nonexistent module with nonascii name name foxf3 with self assertraisesimporterror as cm self loadmodulebynamename self assertequalcm exception name name def testnonmoduleself test returning a nonmodule object from create works name self name nonmodule mod self loadmodulebynamename self assertnotequaltypemod typeunittest self assertequalmod three 3 issue 27782 def testnonmodulewithmethodsself test creating a nonmodule object with methods defined name self name nonmodulewithmethods mod self loadmodulebynamename self assertnotequaltypemod typeunittest self assertequalmod three 3 self assertequalmod bar10 1 9 def testnullslotsself test that null slots aren t a problem name self name nullslots module self loadmodulebynamename self assertisinstancemodule types moduletype self assertequalmodule name name def testbadmodulesself test systemerror is raised for misbehaving extensions for namebase in badslotlarge badslotnegative createintwithstate negativesize exportnull exportuninitialized exportraise exportunreportedexception createnull createraise createunreportedexception nonmodulewithexecslots execerr execraise execunreportedexception multiplecreateslots multiplemultipleinterpretersslots with self subtestnamebase name self name namebase with self assertraisessystemerror as cm self loadmodulebynamename if there is an unreported exception it should be chained with the systemerror if unreportedexception in namebase self assertisnotnonecm exception cause def testnonasciiself test that modules with nonascii names can be loaded punycode behaves slightly differently in someascii and noascii cases so test both cases self name zkouu0161kanau010dtenxed czech uff3fu30a4u30f3u30ddu30fcu30c8u30c6u30b9u30c8 japanese for name lang in cases with self subtestname module self loadmodulebynamename self assertequalmodule name name self assertequalmodule doc module named in s lang frozenmultiphaseextensionmoduletests sourcemultiphaseextensionmoduletests util testbothmultiphaseextensionmoduletests machinerymachinery if name main unittest main test extensionfileloader test the default argument for load_module no extension module as __init__ available for testing no extension module in a package available for testing no easy way to trigger a failure after a successful import test loading extension modules without multi phase initialization load a module from the test extension by name test loading an extension module no extension module as __init__ available for testing no extension module in a package available for testing no easy way to trigger a failure after a successful import test behavior with nonexistent module with non ascii name it may make sense to add the equivalent to the following multiphaseextensionmoduletests tests test_nonmodule test_nonmodule_with_methods test_bad_modules test_nonascii test loading extension modules with multi phase initialization pep 489 load the module from the test extension load a module from the test extension by name no extension module as __init__ available for testing no extension module in a package available for testing handling failure on reload is the up to the module test loading an extension module test basic functionality of stuff defined in an extension module test that reload didn t re set the module s attributes assert that the pystate_ find add remove module c api doesn t work test loading a simulated submodule test loading module with a one character name test that 2 loads result in 2 module objects test nonexistent module test behavior with nonexistent module with non ascii name test returning a non module object from create works issue 27782 test creating a non module object with methods defined test that null slots aren t a problem test systemerror is raised for misbehaving extensions if there is an unreported exception it should be chained with the systemerror test that modules with non ascii names can be loaded punycode behaves slightly differently in some ascii and no ascii cases so test both
from test.test_importlib import abc, util

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

import os.path
import sys
import types
import unittest
import warnings
import importlib.util
import importlib


class LoaderTests:

    

    def setUp(self):
        if not self.machinery.EXTENSION_SUFFIXES:
            raise unittest.SkipTest("Requires dynamic loading support.")
        if util.EXTENSIONS.name in sys.builtin_module_names:
            raise unittest.SkipTest(
                f"{util.EXTENSIONS.name} is a builtin module"
            )
        self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
                                                         util.EXTENSIONS.file_path)

    def load_module(self, fullname):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            return self.loader.load_module(fullname)

    def test_equality(self):
        other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
                                                   util.EXTENSIONS.file_path)
        self.assertEqual(self.loader, other)

    def test_inequality(self):
        other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name,
                                                   util.EXTENSIONS.file_path)
        self.assertNotEqual(self.loader, other)

    def test_load_module_API(self):
        
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            self.loader.load_module()
            self.loader.load_module(None)
            with self.assertRaises(ImportError):
                self.load_module('XXX')

    def test_module(self):
        with util.uncache(util.EXTENSIONS.name):
            module = self.load_module(util.EXTENSIONS.name)
            for attr, value in [('__name__', util.EXTENSIONS.name),
                                ('__file__', util.EXTENSIONS.file_path),
                                ('__package__', '')]:
                self.assertEqual(getattr(module, attr), value)
            self.assertIn(util.EXTENSIONS.name, sys.modules)
            self.assertIsInstance(module.__loader__,
                                  self.machinery.ExtensionFileLoader)

    
    test_package = None

    
    test_lacking_parent = None

    
    test_state_after_failure = None

    def test_unloadable(self):
        name = 'asdfjkl;'
        with self.assertRaises(ImportError) as cm:
            self.load_module(name)
        self.assertEqual(cm.exception.name, name)

    def test_module_reuse(self):
        with util.uncache(util.EXTENSIONS.name):
            module1 = self.load_module(util.EXTENSIONS.name)
            module2 = self.load_module(util.EXTENSIONS.name)
            self.assertIs(module1, module2)

    def test_is_package(self):
        self.assertFalse(self.loader.is_package(util.EXTENSIONS.name))
        for suffix in self.machinery.EXTENSION_SUFFIXES:
            path = os.path.join('some', 'path', 'pkg', '__init__' + suffix)
            loader = self.machinery.ExtensionFileLoader('pkg', path)
            self.assertTrue(loader.is_package('pkg'))


(Frozen_LoaderTests,
 Source_LoaderTests
 ) = util.test_both(LoaderTests, machinery=machinery)


class SinglePhaseExtensionModuleTests(abc.LoaderTests):
    

    def setUp(self):
        if not self.machinery.EXTENSION_SUFFIXES:
            raise unittest.SkipTest("Requires dynamic loading support.")
        self.name = '_testsinglephase'
        if self.name in sys.builtin_module_names:
            raise unittest.SkipTest(
                f"{self.name} is a builtin module"
            )
        finder = self.machinery.FileFinder(None)
        self.spec = importlib.util.find_spec(self.name)
        assert self.spec
        self.loader = self.machinery.ExtensionFileLoader(
            self.name, self.spec.origin)

    def load_module(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            return self.loader.load_module(self.name)

    def load_module_by_name(self, fullname):
        
        origin = self.spec.origin
        loader = self.machinery.ExtensionFileLoader(fullname, origin)
        spec = importlib.util.spec_from_loader(fullname, loader)
        module = importlib.util.module_from_spec(spec)
        loader.exec_module(module)
        return module

    def test_module(self):
        
        with util.uncache(self.name):
            module = self.load_module()
            for attr, value in [('__name__', self.name),
                                ('__file__', self.spec.origin),
                                ('__package__', '')]:
                self.assertEqual(getattr(module, attr), value)
            with self.assertRaises(AttributeError):
                module.__path__
            self.assertIs(module, sys.modules[self.name])
            self.assertIsInstance(module.__loader__,
                                  self.machinery.ExtensionFileLoader)

    
    test_package = None

    
    test_lacking_parent = None

    
    test_state_after_failure = None

    def test_unloadable(self):
        name = 'asdfjkl;'
        with self.assertRaises(ImportError) as cm:
            self.load_module_by_name(name)
        self.assertEqual(cm.exception.name, name)

    def test_unloadable_nonascii(self):
        
        name = 'fo\xf3'
        with self.assertRaises(ImportError) as cm:
            self.load_module_by_name(name)
        self.assertEqual(cm.exception.name, name)

    
    
    
    
    
    
    


(Frozen_SinglePhaseExtensionModuleTests,
 Source_SinglePhaseExtensionModuleTests
 ) = util.test_both(SinglePhaseExtensionModuleTests, machinery=machinery)


class MultiPhaseExtensionModuleTests(abc.LoaderTests):
    

    def setUp(self):
        if not self.machinery.EXTENSION_SUFFIXES:
            raise unittest.SkipTest("Requires dynamic loading support.")
        self.name = '_testmultiphase'
        if self.name in sys.builtin_module_names:
            raise unittest.SkipTest(
                f"{self.name} is a builtin module"
            )
        finder = self.machinery.FileFinder(None)
        self.spec = importlib.util.find_spec(self.name)
        assert self.spec
        self.loader = self.machinery.ExtensionFileLoader(
            self.name, self.spec.origin)

    def load_module(self):
        
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            return self.loader.load_module(self.name)

    def load_module_by_name(self, fullname):
        
        origin = self.spec.origin
        loader = self.machinery.ExtensionFileLoader(fullname, origin)
        spec = importlib.util.spec_from_loader(fullname, loader)
        module = importlib.util.module_from_spec(spec)
        loader.exec_module(module)
        return module

    
    test_package = None

    
    test_lacking_parent = None

    
    test_state_after_failure = None

    def test_module(self):
        
        with util.uncache(self.name):
            module = self.load_module()
            for attr, value in [('__name__', self.name),
                                ('__file__', self.spec.origin),
                                ('__package__', '')]:
                self.assertEqual(getattr(module, attr), value)
            with self.assertRaises(AttributeError):
                module.__path__
            self.assertIs(module, sys.modules[self.name])
            self.assertIsInstance(module.__loader__,
                                  self.machinery.ExtensionFileLoader)

    def test_functionality(self):
        
        with util.uncache(self.name):
            module = self.load_module()
            self.assertIsInstance(module, types.ModuleType)
            ex = module.Example()
            self.assertEqual(ex.demo('abcd'), 'abcd')
            self.assertEqual(ex.demo(), None)
            with self.assertRaises(AttributeError):
                ex.abc
            ex.abc = 0
            self.assertEqual(ex.abc, 0)
            self.assertEqual(module.foo(9, 9), 18)
            self.assertIsInstance(module.Str(), str)
            self.assertEqual(module.Str(1) + '23', '123')
            with self.assertRaises(module.error):
                raise module.error()
            self.assertEqual(module.int_const, 1969)
            self.assertEqual(module.str_const, 'something different')

    def test_reload(self):
        
        with util.uncache(self.name):
            module = self.load_module()
            ex_class = module.Example
            importlib.reload(module)
            self.assertIs(ex_class, module.Example)

    def test_try_registration(self):
        
        with util.uncache(self.name):
            module = self.load_module()
            with self.subTest('PyState_FindModule'):
                self.assertEqual(module.call_state_registration_func(0), None)
            with self.subTest('PyState_AddModule'):
                with self.assertRaises(SystemError):
                    module.call_state_registration_func(1)
            with self.subTest('PyState_RemoveModule'):
                with self.assertRaises(SystemError):
                    module.call_state_registration_func(2)

    def test_load_submodule(self):
        
        module = self.load_module_by_name('pkg.' + self.name)
        self.assertIsInstance(module, types.ModuleType)
        self.assertEqual(module.__name__, 'pkg.' + self.name)
        self.assertEqual(module.str_const, 'something different')

    def test_load_short_name(self):
        
        module = self.load_module_by_name('x')
        self.assertIsInstance(module, types.ModuleType)
        self.assertEqual(module.__name__, 'x')
        self.assertEqual(module.str_const, 'something different')
        self.assertNotIn('x', sys.modules)

    def test_load_twice(self):
        
        module1 = self.load_module_by_name(self.name)
        module2 = self.load_module_by_name(self.name)
        self.assertIsNot(module1, module2)

    def test_unloadable(self):
        
        name = 'asdfjkl;'
        with self.assertRaises(ImportError) as cm:
            self.load_module_by_name(name)
        self.assertEqual(cm.exception.name, name)

    def test_unloadable_nonascii(self):
        
        name = 'fo\xf3'
        with self.assertRaises(ImportError) as cm:
            self.load_module_by_name(name)
        self.assertEqual(cm.exception.name, name)

    def test_nonmodule(self):
        
        name = self.name + '_nonmodule'
        mod = self.load_module_by_name(name)
        self.assertNotEqual(type(mod), type(unittest))
        self.assertEqual(mod.three, 3)

    
    def test_nonmodule_with_methods(self):
        
        name = self.name + '_nonmodule_with_methods'
        mod = self.load_module_by_name(name)
        self.assertNotEqual(type(mod), type(unittest))
        self.assertEqual(mod.three, 3)
        self.assertEqual(mod.bar(10, 1), 9)

    def test_null_slots(self):
        
        name = self.name + '_null_slots'
        module = self.load_module_by_name(name)
        self.assertIsInstance(module, types.ModuleType)
        self.assertEqual(module.__name__, name)

    def test_bad_modules(self):
        
        for name_base in [
                'bad_slot_large',
                'bad_slot_negative',
                'create_int_with_state',
                'negative_size',
                'export_null',
                'export_uninitialized',
                'export_raise',
                'export_unreported_exception',
                'create_null',
                'create_raise',
                'create_unreported_exception',
                'nonmodule_with_exec_slots',
                'exec_err',
                'exec_raise',
                'exec_unreported_exception',
                'multiple_create_slots',
                'multiple_multiple_interpreters_slots',
                ]:
            with self.subTest(name_base):
                name = self.name + '_' + name_base
                with self.assertRaises(SystemError) as cm:
                    self.load_module_by_name(name)

                
                
                if "unreported_exception" in name_base:
                    self.assertIsNotNone(cm.exception.__cause__)

    def test_nonascii(self):
        
        
        
        cases = [
            (self.name + '_zkou\u0161ka_na\u010dten\xed', 'Czech'),
            ('\uff3f\u30a4\u30f3\u30dd\u30fc\u30c8\u30c6\u30b9\u30c8',
             'Japanese'),
            ]
        for name, lang in cases:
            with self.subTest(name):
                module = self.load_module_by_name(name)
                self.assertEqual(module.__name__, name)
                self.assertEqual(module.__doc__, "Module named in %s" % lang)


(Frozen_MultiPhaseExtensionModuleTests,
 Source_MultiPhaseExtensionModuleTests
 ) = util.test_both(MultiPhaseExtensionModuleTests, machinery=machinery)


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