mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 13:52:28 +00:00
python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
parent
75fc601ff5
commit
0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions
5
third_party/python/Lib/test/test_importlib/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
94
third_party/python/Lib/test/test_importlib/abc.py
vendored
Normal file
94
third_party/python/Lib/test/test_importlib/abc.py
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
import abc
|
||||
import unittest
|
||||
|
||||
|
||||
class FinderTests(metaclass=abc.ABCMeta):
|
||||
|
||||
"""Basic tests for a finder to pass."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_module(self):
|
||||
# Test importing a top-level module.
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_package(self):
|
||||
# Test importing a package.
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_module_in_package(self):
|
||||
# Test importing a module contained within a package.
|
||||
# A value for 'path' should be used if for a meta_path finder.
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_package_in_package(self):
|
||||
# Test importing a subpackage.
|
||||
# A value for 'path' should be used if for a meta_path finder.
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_package_over_module(self):
|
||||
# Test that packages are chosen over modules.
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_failure(self):
|
||||
# Test trying to find a module that cannot be handled.
|
||||
pass
|
||||
|
||||
|
||||
class LoaderTests(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_module(self):
|
||||
"""A module should load without issue.
|
||||
|
||||
After the loader returns the module should be in sys.modules.
|
||||
|
||||
Attributes to verify:
|
||||
|
||||
* __file__
|
||||
* __loader__
|
||||
* __name__
|
||||
* No __path__
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_package(self):
|
||||
"""Loading a package should work.
|
||||
|
||||
After the loader returns the module should be in sys.modules.
|
||||
|
||||
Attributes to verify:
|
||||
|
||||
* __name__
|
||||
* __file__
|
||||
* __package__
|
||||
* __path__
|
||||
* __loader__
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_lacking_parent(self):
|
||||
"""A loader should not be dependent on it's parent package being
|
||||
imported."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_state_after_failure(self):
|
||||
"""If a module is already in sys.modules and a reload fails
|
||||
(e.g. a SyntaxError), the module should be in the state it was before
|
||||
the reload began."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_unloadable(self):
|
||||
"""Test ImportError is raised when the loader is asked to load a module
|
||||
it can't."""
|
||||
pass
|
5
third_party/python/Lib/test/test_importlib/builtin/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/builtin/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/builtin/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/builtin/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
90
third_party/python/Lib/test/test_importlib/builtin/test_finder.py
vendored
Normal file
90
third_party/python/Lib/test/test_importlib/builtin/test_finder.py
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
|
||||
class FindSpecTests(abc.FinderTests):
|
||||
|
||||
"""Test find_spec() for built-in modules."""
|
||||
|
||||
def test_module(self):
|
||||
# Common case.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
found = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name)
|
||||
self.assertTrue(found)
|
||||
self.assertEqual(found.origin, 'built-in')
|
||||
|
||||
# Built-in modules cannot be a package.
|
||||
test_package = None
|
||||
|
||||
# Built-in modules cannot be in a package.
|
||||
test_module_in_package = None
|
||||
|
||||
# Built-in modules cannot be a package.
|
||||
test_package_in_package = None
|
||||
|
||||
# Built-in modules cannot be a package.
|
||||
test_package_over_module = None
|
||||
|
||||
def test_failure(self):
|
||||
name = 'importlib'
|
||||
assert name not in sys.builtin_module_names
|
||||
spec = self.machinery.BuiltinImporter.find_spec(name)
|
||||
self.assertIsNone(spec)
|
||||
|
||||
def test_ignore_path(self):
|
||||
# The value for 'path' should always trigger a failed import.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
spec = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name,
|
||||
['pkg'])
|
||||
self.assertIsNone(spec)
|
||||
|
||||
|
||||
(Frozen_FindSpecTests,
|
||||
Source_FindSpecTests
|
||||
) = util.test_both(FindSpecTests, machinery=machinery)
|
||||
|
||||
|
||||
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
|
||||
class FinderTests(abc.FinderTests):
|
||||
|
||||
"""Test find_module() for built-in modules."""
|
||||
|
||||
def test_module(self):
|
||||
# Common case.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name)
|
||||
self.assertTrue(found)
|
||||
self.assertTrue(hasattr(found, 'load_module'))
|
||||
|
||||
# Built-in modules cannot be a package.
|
||||
test_package = test_package_in_package = test_package_over_module = None
|
||||
|
||||
# Built-in modules cannot be in a package.
|
||||
test_module_in_package = None
|
||||
|
||||
def test_failure(self):
|
||||
assert 'importlib' not in sys.builtin_module_names
|
||||
loader = self.machinery.BuiltinImporter.find_module('importlib')
|
||||
self.assertIsNone(loader)
|
||||
|
||||
def test_ignore_path(self):
|
||||
# The value for 'path' should always trigger a failed import.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
loader = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name,
|
||||
['pkg'])
|
||||
self.assertIsNone(loader)
|
||||
|
||||
|
||||
(Frozen_FinderTests,
|
||||
Source_FinderTests
|
||||
) = util.test_both(FinderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
108
third_party/python/Lib/test/test_importlib/builtin/test_loader.py
vendored
Normal file
108
third_party/python/Lib/test/test_importlib/builtin/test_loader.py
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
|
||||
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
|
||||
class LoaderTests(abc.LoaderTests):
|
||||
|
||||
"""Test load_module() for built-in modules."""
|
||||
|
||||
def setUp(self):
|
||||
self.verification = {'__name__': 'errno', '__package__': '',
|
||||
'__loader__': self.machinery.BuiltinImporter}
|
||||
|
||||
def verify(self, module):
|
||||
"""Verify that the module matches against what it should have."""
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
for attr, value in self.verification.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
self.assertIn(module.__name__, sys.modules)
|
||||
|
||||
def load_module(self, name):
|
||||
return self.machinery.BuiltinImporter.load_module(name)
|
||||
|
||||
def test_module(self):
|
||||
# Common case.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
module = self.load_module(util.BUILTINS.good_name)
|
||||
self.verify(module)
|
||||
|
||||
# Built-in modules cannot be a package.
|
||||
test_package = test_lacking_parent = None
|
||||
|
||||
# No way to force an import failure.
|
||||
test_state_after_failure = None
|
||||
|
||||
def test_module_reuse(self):
|
||||
# Test that the same module is used in a reload.
|
||||
with util.uncache(util.BUILTINS.good_name):
|
||||
module1 = self.load_module(util.BUILTINS.good_name)
|
||||
module2 = self.load_module(util.BUILTINS.good_name)
|
||||
self.assertIs(module1, module2)
|
||||
|
||||
def test_unloadable(self):
|
||||
name = 'dssdsdfff'
|
||||
assert name not in sys.builtin_module_names
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.load_module(name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
|
||||
def test_already_imported(self):
|
||||
# Using the name of a module already imported but not a built-in should
|
||||
# still fail.
|
||||
module_name = 'builtin_reload_test'
|
||||
assert module_name not in sys.builtin_module_names
|
||||
with util.uncache(module_name):
|
||||
module = types.ModuleType(module_name)
|
||||
sys.modules[module_name] = module
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.load_module(module_name)
|
||||
self.assertEqual(cm.exception.name, module_name)
|
||||
|
||||
|
||||
(Frozen_LoaderTests,
|
||||
Source_LoaderTests
|
||||
) = util.test_both(LoaderTests, machinery=machinery)
|
||||
|
||||
|
||||
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
|
||||
class InspectLoaderTests:
|
||||
|
||||
"""Tests for InspectLoader methods for BuiltinImporter."""
|
||||
|
||||
def test_get_code(self):
|
||||
# There is no code object.
|
||||
result = self.machinery.BuiltinImporter.get_code(util.BUILTINS.good_name)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_get_source(self):
|
||||
# There is no source.
|
||||
result = self.machinery.BuiltinImporter.get_source(util.BUILTINS.good_name)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_is_package(self):
|
||||
# Cannot be a package.
|
||||
result = self.machinery.BuiltinImporter.is_package(util.BUILTINS.good_name)
|
||||
self.assertFalse(result)
|
||||
|
||||
@unittest.skipIf(util.BUILTINS.bad_name is None, 'all modules are built in')
|
||||
def test_not_builtin(self):
|
||||
# Modules not built-in should raise ImportError.
|
||||
for meth_name in ('get_code', 'get_source', 'is_package'):
|
||||
method = getattr(self.machinery.BuiltinImporter, meth_name)
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
method(util.BUILTINS.bad_name)
|
||||
|
||||
|
||||
(Frozen_InspectLoaderTests,
|
||||
Source_InspectLoaderTests
|
||||
) = util.test_both(InspectLoaderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
5
third_party/python/Lib/test/test_importlib/extension/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/extension/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/extension/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/extension/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
46
third_party/python/Lib/test/test_importlib/extension/test_case_sensitivity.py
vendored
Normal file
46
third_party/python/Lib/test/test_importlib/extension/test_case_sensitivity.py
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
from importlib import _bootstrap_external
|
||||
from test import support
|
||||
import unittest
|
||||
|
||||
from .. import util
|
||||
|
||||
importlib = util.import_importlib('importlib')
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
|
||||
@unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available')
|
||||
@util.case_insensitive_tests
|
||||
class ExtensionModuleCaseSensitivityTest(util.CASEOKTestBase):
|
||||
|
||||
def find_module(self):
|
||||
good_name = util.EXTENSIONS.name
|
||||
bad_name = good_name.upper()
|
||||
assert good_name != bad_name
|
||||
finder = self.machinery.FileFinder(util.EXTENSIONS.path,
|
||||
(self.machinery.ExtensionFileLoader,
|
||||
self.machinery.EXTENSION_SUFFIXES))
|
||||
return finder.find_module(bad_name)
|
||||
|
||||
def test_case_sensitive(self):
|
||||
with support.EnvironmentVarGuard() as env:
|
||||
env.unset('PYTHONCASEOK')
|
||||
self.caseok_env_changed(should_exist=False)
|
||||
loader = self.find_module()
|
||||
self.assertIsNone(loader)
|
||||
|
||||
def test_case_insensitivity(self):
|
||||
with support.EnvironmentVarGuard() as env:
|
||||
env.set('PYTHONCASEOK', '1')
|
||||
self.caseok_env_changed(should_exist=True)
|
||||
loader = self.find_module()
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
|
||||
(Frozen_ExtensionCaseSensitivity,
|
||||
Source_ExtensionCaseSensitivity
|
||||
) = util.test_both(ExtensionModuleCaseSensitivityTest, importlib=importlib,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
44
third_party/python/Lib/test/test_importlib/extension/test_finder.py
vendored
Normal file
44
third_party/python/Lib/test/test_importlib/extension/test_finder.py
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class FinderTests(abc.FinderTests):
|
||||
|
||||
"""Test the finder for extension modules."""
|
||||
|
||||
def find_module(self, fullname):
|
||||
importer = self.machinery.FileFinder(util.EXTENSIONS.path,
|
||||
(self.machinery.ExtensionFileLoader,
|
||||
self.machinery.EXTENSION_SUFFIXES))
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
return importer.find_module(fullname)
|
||||
|
||||
def test_module(self):
|
||||
self.assertTrue(self.find_module(util.EXTENSIONS.name))
|
||||
|
||||
# No extension module as an __init__ available for testing.
|
||||
test_package = test_package_in_package = None
|
||||
|
||||
# No extension module in a package available for testing.
|
||||
test_module_in_package = None
|
||||
|
||||
# Extension modules cannot be an __init__ for a package.
|
||||
test_package_over_module = None
|
||||
|
||||
def test_failure(self):
|
||||
self.assertIsNone(self.find_module('asdfjkl;'))
|
||||
|
||||
|
||||
(Frozen_FinderTests,
|
||||
Source_FinderTests
|
||||
) = util.test_both(FinderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
300
third_party/python/Lib/test/test_importlib/extension/test_loader.py
vendored
Normal file
300
third_party/python/Lib/test/test_importlib/extension/test_loader.py
vendored
Normal file
|
@ -0,0 +1,300 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
import importlib.util
|
||||
import importlib
|
||||
from test.support.script_helper import assert_python_failure
|
||||
|
||||
class LoaderTests(abc.LoaderTests):
|
||||
|
||||
"""Test load_module() for extension modules."""
|
||||
|
||||
def setUp(self):
|
||||
self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
|
||||
util.EXTENSIONS.file_path)
|
||||
|
||||
def load_module(self, fullname):
|
||||
return self.loader.load_module(fullname)
|
||||
|
||||
def test_load_module_API(self):
|
||||
# Test the default argument for load_module().
|
||||
self.loader.load_module()
|
||||
self.loader.load_module(None)
|
||||
with self.assertRaises(ImportError):
|
||||
self.load_module('XXX')
|
||||
|
||||
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_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)
|
||||
|
||||
# No extension module as __init__ available for testing.
|
||||
test_package = None
|
||||
|
||||
# No extension module in a package available for testing.
|
||||
test_lacking_parent = None
|
||||
|
||||
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)
|
||||
|
||||
# No easy way to trigger a failure after a successful import.
|
||||
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_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 MultiPhaseExtensionModuleTests(abc.LoaderTests):
|
||||
"""Test loading extension modules with multi-phase initialization (PEP 489)
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.name = '_testmultiphase'
|
||||
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)
|
||||
|
||||
# No extension module as __init__ available for testing.
|
||||
test_package = None
|
||||
|
||||
# No extension module in a package available for testing.
|
||||
test_lacking_parent = None
|
||||
|
||||
# Handling failure on reload is the up to the module.
|
||||
test_state_after_failure = None
|
||||
|
||||
def test_module(self):
|
||||
'''Test loading an extension module'''
|
||||
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):
|
||||
'''Test basic functionality of stuff defined in an extension module'''
|
||||
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):
|
||||
'''Test that reload didn't re-set the module's attributes'''
|
||||
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):
|
||||
'''Assert that the PyState_{Find,Add,Remove}Module C API doesn't work'''
|
||||
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 load_module(self):
|
||||
'''Load the module from the test extension'''
|
||||
return self.loader.load_module(self.name)
|
||||
|
||||
def load_module_by_name(self, fullname):
|
||||
'''Load a module from the test extension by name'''
|
||||
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_load_submodule(self):
|
||||
'''Test loading a simulated submodule'''
|
||||
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):
|
||||
'''Test loading module with a one-character name'''
|
||||
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):
|
||||
'''Test that 2 loads result in 2 module objects'''
|
||||
module1 = self.load_module_by_name(self.name)
|
||||
module2 = self.load_module_by_name(self.name)
|
||||
self.assertIsNot(module1, module2)
|
||||
|
||||
def test_unloadable(self):
|
||||
'''Test nonexistent module'''
|
||||
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):
|
||||
'''Test behavior with nonexistent module with non-ASCII name'''
|
||||
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):
|
||||
'''Test returning a non-module object from create works'''
|
||||
name = self.name + '_nonmodule'
|
||||
mod = self.load_module_by_name(name)
|
||||
self.assertNotEqual(type(mod), type(unittest))
|
||||
self.assertEqual(mod.three, 3)
|
||||
|
||||
# issue 27782
|
||||
def test_nonmodule_with_methods(self):
|
||||
'''Test creating a non-module object with methods defined'''
|
||||
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):
|
||||
'''Test that NULL slots aren't a problem'''
|
||||
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):
|
||||
'''Test SystemError is raised for misbehaving extensions'''
|
||||
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',
|
||||
]:
|
||||
with self.subTest(name_base):
|
||||
name = self.name + '_' + name_base
|
||||
with self.assertRaises(SystemError):
|
||||
self.load_module_by_name(name)
|
||||
|
||||
def test_nonascii(self):
|
||||
'''Test that modules with non-ASCII names can be loaded'''
|
||||
# punycode behaves slightly differently in some-ASCII and no-ASCII
|
||||
# cases, so test both
|
||||
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)
|
||||
|
||||
@unittest.skipIf(not hasattr(sys, 'gettotalrefcount'),
|
||||
'--with-pydebug has to be enabled for this test')
|
||||
def test_bad_traverse(self):
|
||||
''' Issue #32374: Test that traverse fails when accessing per-module
|
||||
state before Py_mod_exec was executed.
|
||||
(Multiphase initialization modules only)
|
||||
'''
|
||||
script = """if True:
|
||||
try:
|
||||
from test import support
|
||||
import importlib.util as util
|
||||
spec = util.find_spec('_testmultiphase')
|
||||
spec.name = '_testmultiphase_with_bad_traverse'
|
||||
|
||||
with support.SuppressCrashReport():
|
||||
m = spec.loader.create_module(spec)
|
||||
except:
|
||||
# Prevent Python-level exceptions from
|
||||
# ending the process with non-zero status
|
||||
# (We are testing for a crash in C-code)
|
||||
pass"""
|
||||
assert_python_failure("-c", script)
|
||||
|
||||
|
||||
(Frozen_MultiPhaseExtensionModuleTests,
|
||||
Source_MultiPhaseExtensionModuleTests
|
||||
) = util.test_both(MultiPhaseExtensionModuleTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
31
third_party/python/Lib/test/test_importlib/extension/test_path_hook.py
vendored
Normal file
31
third_party/python/Lib/test/test_importlib/extension/test_path_hook.py
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class PathHookTests:
|
||||
|
||||
"""Test the path hook for extension modules."""
|
||||
# XXX Should it only succeed for pre-existing directories?
|
||||
# XXX Should it only work for directories containing an extension module?
|
||||
|
||||
def hook(self, entry):
|
||||
return self.machinery.FileFinder.path_hook(
|
||||
(self.machinery.ExtensionFileLoader,
|
||||
self.machinery.EXTENSION_SUFFIXES))(entry)
|
||||
|
||||
def test_success(self):
|
||||
# Path hook should handle a directory where a known extension module
|
||||
# exists.
|
||||
self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module'))
|
||||
|
||||
|
||||
(Frozen_PathHooksTests,
|
||||
Source_PathHooksTests
|
||||
) = util.test_both(PathHookTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
5
third_party/python/Lib/test/test_importlib/frozen/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/frozen/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/frozen/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/frozen/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
84
third_party/python/Lib/test/test_importlib/frozen/test_finder.py
vendored
Normal file
84
third_party/python/Lib/test/test_importlib/frozen/test_finder.py
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class FindSpecTests(abc.FinderTests):
|
||||
|
||||
"""Test finding frozen modules."""
|
||||
|
||||
def find(self, name, path=None):
|
||||
finder = self.machinery.FrozenImporter
|
||||
return finder.find_spec(name, path)
|
||||
|
||||
def test_module(self):
|
||||
name = '__hello__'
|
||||
spec = self.find(name)
|
||||
self.assertEqual(spec.origin, 'frozen')
|
||||
|
||||
def test_package(self):
|
||||
spec = self.find('__phello__')
|
||||
self.assertIsNotNone(spec)
|
||||
|
||||
def test_module_in_package(self):
|
||||
spec = self.find('__phello__.spam', ['__phello__'])
|
||||
self.assertIsNotNone(spec)
|
||||
|
||||
# No frozen package within another package to test with.
|
||||
test_package_in_package = None
|
||||
|
||||
# No easy way to test.
|
||||
test_package_over_module = None
|
||||
|
||||
def test_failure(self):
|
||||
spec = self.find('<not real>')
|
||||
self.assertIsNone(spec)
|
||||
|
||||
|
||||
(Frozen_FindSpecTests,
|
||||
Source_FindSpecTests
|
||||
) = util.test_both(FindSpecTests, machinery=machinery)
|
||||
|
||||
|
||||
class FinderTests(abc.FinderTests):
|
||||
|
||||
"""Test finding frozen modules."""
|
||||
|
||||
def find(self, name, path=None):
|
||||
finder = self.machinery.FrozenImporter
|
||||
return finder.find_module(name, path)
|
||||
|
||||
def test_module(self):
|
||||
name = '__hello__'
|
||||
loader = self.find(name)
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
def test_package(self):
|
||||
loader = self.find('__phello__')
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
def test_module_in_package(self):
|
||||
loader = self.find('__phello__.spam', ['__phello__'])
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
# No frozen package within another package to test with.
|
||||
test_package_in_package = None
|
||||
|
||||
# No easy way to test.
|
||||
test_package_over_module = None
|
||||
|
||||
def test_failure(self):
|
||||
loader = self.find('<not real>')
|
||||
self.assertIsNone(loader)
|
||||
|
||||
|
||||
(Frozen_FinderTests,
|
||||
Source_FinderTests
|
||||
) = util.test_both(FinderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
225
third_party/python/Lib/test/test_importlib/frozen/test_loader.py
vendored
Normal file
225
third_party/python/Lib/test/test_importlib/frozen/test_loader.py
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
from test.support import captured_stdout
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class ExecModuleTests(abc.LoaderTests):
|
||||
|
||||
def exec_module(self, name):
|
||||
with util.uncache(name), captured_stdout() as stdout:
|
||||
spec = self.machinery.ModuleSpec(
|
||||
name, self.machinery.FrozenImporter, origin='frozen',
|
||||
is_package=self.machinery.FrozenImporter.is_package(name))
|
||||
module = types.ModuleType(name)
|
||||
module.__spec__ = spec
|
||||
assert not hasattr(module, 'initialized')
|
||||
self.machinery.FrozenImporter.exec_module(module)
|
||||
self.assertTrue(module.initialized)
|
||||
self.assertTrue(hasattr(module, '__spec__'))
|
||||
self.assertEqual(module.__spec__.origin, 'frozen')
|
||||
return module, stdout.getvalue()
|
||||
|
||||
def test_module(self):
|
||||
name = '__hello__'
|
||||
module, output = self.exec_module(name)
|
||||
check = {'__name__': name}
|
||||
for attr, value in check.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
self.assertEqual(output, 'Hello world!\n')
|
||||
self.assertTrue(hasattr(module, '__spec__'))
|
||||
|
||||
def test_package(self):
|
||||
name = '__phello__'
|
||||
module, output = self.exec_module(name)
|
||||
check = {'__name__': name}
|
||||
for attr, value in check.items():
|
||||
attr_value = getattr(module, attr)
|
||||
self.assertEqual(attr_value, value,
|
||||
'for {name}.{attr}, {given!r} != {expected!r}'.format(
|
||||
name=name, attr=attr, given=attr_value,
|
||||
expected=value))
|
||||
self.assertEqual(output, 'Hello world!\n')
|
||||
|
||||
def test_lacking_parent(self):
|
||||
name = '__phello__.spam'
|
||||
with util.uncache('__phello__'):
|
||||
module, output = self.exec_module(name)
|
||||
check = {'__name__': name}
|
||||
for attr, value in check.items():
|
||||
attr_value = getattr(module, attr)
|
||||
self.assertEqual(attr_value, value,
|
||||
'for {name}.{attr}, {given} != {expected!r}'.format(
|
||||
name=name, attr=attr, given=attr_value,
|
||||
expected=value))
|
||||
self.assertEqual(output, 'Hello world!\n')
|
||||
|
||||
def test_module_repr(self):
|
||||
name = '__hello__'
|
||||
module, output = self.exec_module(name)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
repr_str = self.machinery.FrozenImporter.module_repr(module)
|
||||
self.assertEqual(repr_str,
|
||||
"<module '__hello__' (frozen)>")
|
||||
|
||||
def test_module_repr_indirect(self):
|
||||
name = '__hello__'
|
||||
module, output = self.exec_module(name)
|
||||
self.assertEqual(repr(module),
|
||||
"<module '__hello__' (frozen)>")
|
||||
|
||||
# No way to trigger an error in a frozen module.
|
||||
test_state_after_failure = None
|
||||
|
||||
def test_unloadable(self):
|
||||
assert self.machinery.FrozenImporter.find_module('_not_real') is None
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.exec_module('_not_real')
|
||||
self.assertEqual(cm.exception.name, '_not_real')
|
||||
|
||||
|
||||
(Frozen_ExecModuleTests,
|
||||
Source_ExecModuleTests
|
||||
) = util.test_both(ExecModuleTests, machinery=machinery)
|
||||
|
||||
|
||||
class LoaderTests(abc.LoaderTests):
|
||||
|
||||
def test_module(self):
|
||||
with util.uncache('__hello__'), captured_stdout() as stdout:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.machinery.FrozenImporter.load_module('__hello__')
|
||||
check = {'__name__': '__hello__',
|
||||
'__package__': '',
|
||||
'__loader__': self.machinery.FrozenImporter,
|
||||
}
|
||||
for attr, value in check.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
|
||||
self.assertFalse(hasattr(module, '__file__'))
|
||||
|
||||
def test_package(self):
|
||||
with util.uncache('__phello__'), captured_stdout() as stdout:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.machinery.FrozenImporter.load_module('__phello__')
|
||||
check = {'__name__': '__phello__',
|
||||
'__package__': '__phello__',
|
||||
'__path__': [],
|
||||
'__loader__': self.machinery.FrozenImporter,
|
||||
}
|
||||
for attr, value in check.items():
|
||||
attr_value = getattr(module, attr)
|
||||
self.assertEqual(attr_value, value,
|
||||
"for __phello__.%s, %r != %r" %
|
||||
(attr, attr_value, value))
|
||||
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
|
||||
self.assertFalse(hasattr(module, '__file__'))
|
||||
|
||||
def test_lacking_parent(self):
|
||||
with util.uncache('__phello__', '__phello__.spam'), \
|
||||
captured_stdout() as stdout:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.machinery.FrozenImporter.load_module('__phello__.spam')
|
||||
check = {'__name__': '__phello__.spam',
|
||||
'__package__': '__phello__',
|
||||
'__loader__': self.machinery.FrozenImporter,
|
||||
}
|
||||
for attr, value in check.items():
|
||||
attr_value = getattr(module, attr)
|
||||
self.assertEqual(attr_value, value,
|
||||
"for __phello__.spam.%s, %r != %r" %
|
||||
(attr, attr_value, value))
|
||||
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
|
||||
self.assertFalse(hasattr(module, '__file__'))
|
||||
|
||||
def test_module_reuse(self):
|
||||
with util.uncache('__hello__'), captured_stdout() as stdout:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module1 = self.machinery.FrozenImporter.load_module('__hello__')
|
||||
module2 = self.machinery.FrozenImporter.load_module('__hello__')
|
||||
self.assertIs(module1, module2)
|
||||
self.assertEqual(stdout.getvalue(),
|
||||
'Hello world!\nHello world!\n')
|
||||
|
||||
def test_module_repr(self):
|
||||
with util.uncache('__hello__'), captured_stdout():
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.machinery.FrozenImporter.load_module('__hello__')
|
||||
repr_str = self.machinery.FrozenImporter.module_repr(module)
|
||||
self.assertEqual(repr_str,
|
||||
"<module '__hello__' (frozen)>")
|
||||
|
||||
def test_module_repr_indirect(self):
|
||||
with util.uncache('__hello__'), captured_stdout():
|
||||
module = self.machinery.FrozenImporter.load_module('__hello__')
|
||||
self.assertEqual(repr(module),
|
||||
"<module '__hello__' (frozen)>")
|
||||
|
||||
# No way to trigger an error in a frozen module.
|
||||
test_state_after_failure = None
|
||||
|
||||
def test_unloadable(self):
|
||||
assert self.machinery.FrozenImporter.find_module('_not_real') is None
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.machinery.FrozenImporter.load_module('_not_real')
|
||||
self.assertEqual(cm.exception.name, '_not_real')
|
||||
|
||||
|
||||
(Frozen_LoaderTests,
|
||||
Source_LoaderTests
|
||||
) = util.test_both(LoaderTests, machinery=machinery)
|
||||
|
||||
|
||||
class InspectLoaderTests:
|
||||
|
||||
"""Tests for the InspectLoader methods for FrozenImporter."""
|
||||
|
||||
def test_get_code(self):
|
||||
# Make sure that the code object is good.
|
||||
name = '__hello__'
|
||||
with captured_stdout() as stdout:
|
||||
code = self.machinery.FrozenImporter.get_code(name)
|
||||
mod = types.ModuleType(name)
|
||||
exec(code, mod.__dict__)
|
||||
self.assertTrue(hasattr(mod, 'initialized'))
|
||||
self.assertEqual(stdout.getvalue(), 'Hello world!\n')
|
||||
|
||||
def test_get_source(self):
|
||||
# Should always return None.
|
||||
result = self.machinery.FrozenImporter.get_source('__hello__')
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_is_package(self):
|
||||
# Should be able to tell what is a package.
|
||||
test_for = (('__hello__', False), ('__phello__', True),
|
||||
('__phello__.spam', False))
|
||||
for name, is_package in test_for:
|
||||
result = self.machinery.FrozenImporter.is_package(name)
|
||||
self.assertEqual(bool(result), is_package)
|
||||
|
||||
def test_failure(self):
|
||||
# Raise ImportError for modules that are not frozen.
|
||||
for meth_name in ('get_code', 'get_source', 'is_package'):
|
||||
method = getattr(self.machinery.FrozenImporter, meth_name)
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
method('importlib')
|
||||
self.assertEqual(cm.exception.name, 'importlib')
|
||||
|
||||
(Frozen_ILTests,
|
||||
Source_ILTests
|
||||
) = util.test_both(InspectLoaderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
5
third_party/python/Lib/test/test_importlib/import_/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/import_/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/import_/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/import_/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
75
third_party/python/Lib/test/test_importlib/import_/test___loader__.py
vendored
Normal file
75
third_party/python/Lib/test/test_importlib/import_/test___loader__.py
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
from importlib import machinery
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
|
||||
from .. import util
|
||||
|
||||
|
||||
class SpecLoaderMock:
|
||||
|
||||
def find_spec(self, fullname, path=None, target=None):
|
||||
return machinery.ModuleSpec(fullname, self)
|
||||
|
||||
def create_module(self, spec):
|
||||
return None
|
||||
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
|
||||
|
||||
class SpecLoaderAttributeTests:
|
||||
|
||||
def test___loader__(self):
|
||||
loader = SpecLoaderMock()
|
||||
with util.uncache('blah'), util.import_state(meta_path=[loader]):
|
||||
module = self.__import__('blah')
|
||||
self.assertEqual(loader, module.__loader__)
|
||||
|
||||
|
||||
(Frozen_SpecTests,
|
||||
Source_SpecTests
|
||||
) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__)
|
||||
|
||||
|
||||
class LoaderMock:
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
return self
|
||||
|
||||
def load_module(self, fullname):
|
||||
sys.modules[fullname] = self.module
|
||||
return self.module
|
||||
|
||||
|
||||
class LoaderAttributeTests:
|
||||
|
||||
def test___loader___missing(self):
|
||||
module = types.ModuleType('blah')
|
||||
try:
|
||||
del module.__loader__
|
||||
except AttributeError:
|
||||
pass
|
||||
loader = LoaderMock()
|
||||
loader.module = module
|
||||
with util.uncache('blah'), util.import_state(meta_path=[loader]):
|
||||
module = self.__import__('blah')
|
||||
self.assertEqual(loader, module.__loader__)
|
||||
|
||||
def test___loader___is_None(self):
|
||||
module = types.ModuleType('blah')
|
||||
module.__loader__ = None
|
||||
loader = LoaderMock()
|
||||
loader.module = module
|
||||
with util.uncache('blah'), util.import_state(meta_path=[loader]):
|
||||
returned_module = self.__import__('blah')
|
||||
self.assertEqual(loader, module.__loader__)
|
||||
|
||||
|
||||
(Frozen_Tests,
|
||||
Source_Tests
|
||||
) = util.test_both(LoaderAttributeTests, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
163
third_party/python/Lib/test/test_importlib/import_/test___package__.py
vendored
Normal file
163
third_party/python/Lib/test/test_importlib/import_/test___package__.py
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
"""PEP 366 ("Main module explicit relative imports") specifies the
|
||||
semantics for the __package__ attribute on modules. This attribute is
|
||||
used, when available, to detect which package a module belongs to (instead
|
||||
of using the typical __path__/__name__ test).
|
||||
|
||||
"""
|
||||
import unittest
|
||||
import warnings
|
||||
from .. import util
|
||||
|
||||
|
||||
class Using__package__:
|
||||
|
||||
"""Use of __package__ supercedes the use of __name__/__path__ to calculate
|
||||
what package a module belongs to. The basic algorithm is [__package__]::
|
||||
|
||||
def resolve_name(name, package, level):
|
||||
level -= 1
|
||||
base = package.rsplit('.', level)[0]
|
||||
return '{0}.{1}'.format(base, name)
|
||||
|
||||
But since there is no guarantee that __package__ has been set (or not been
|
||||
set to None [None]), there has to be a way to calculate the attribute's value
|
||||
[__name__]::
|
||||
|
||||
def calc_package(caller_name, has___path__):
|
||||
if has__path__:
|
||||
return caller_name
|
||||
else:
|
||||
return caller_name.rsplit('.', 1)[0]
|
||||
|
||||
Then the normal algorithm for relative name imports can proceed as if
|
||||
__package__ had been set.
|
||||
|
||||
"""
|
||||
|
||||
def import_module(self, globals_):
|
||||
with self.mock_modules('pkg.__init__', 'pkg.fake') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__('pkg.fake')
|
||||
module = self.__import__('',
|
||||
globals=globals_,
|
||||
fromlist=['attr'], level=2)
|
||||
return module
|
||||
|
||||
def test_using___package__(self):
|
||||
# [__package__]
|
||||
module = self.import_module({'__package__': 'pkg.fake'})
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
||||
def test_using___name__(self):
|
||||
# [__name__]
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
module = self.import_module({'__name__': 'pkg.fake',
|
||||
'__path__': []})
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
||||
def test_warn_when_using___name__(self):
|
||||
with self.assertWarns(ImportWarning):
|
||||
self.import_module({'__name__': 'pkg.fake', '__path__': []})
|
||||
|
||||
def test_None_as___package__(self):
|
||||
# [None]
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
module = self.import_module({
|
||||
'__name__': 'pkg.fake', '__path__': [], '__package__': None })
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
||||
def test_spec_fallback(self):
|
||||
# If __package__ isn't defined, fall back on __spec__.parent.
|
||||
module = self.import_module({'__spec__': FakeSpec('pkg.fake')})
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
||||
def test_warn_when_package_and_spec_disagree(self):
|
||||
# Raise an ImportWarning if __package__ != __spec__.parent.
|
||||
with self.assertWarns(ImportWarning):
|
||||
self.import_module({'__package__': 'pkg.fake',
|
||||
'__spec__': FakeSpec('pkg.fakefake')})
|
||||
|
||||
def test_bad__package__(self):
|
||||
globals = {'__package__': '<not real>'}
|
||||
with self.assertRaises(ModuleNotFoundError):
|
||||
self.__import__('', globals, {}, ['relimport'], 1)
|
||||
|
||||
def test_bunk__package__(self):
|
||||
globals = {'__package__': 42}
|
||||
with self.assertRaises(TypeError):
|
||||
self.__import__('', globals, {}, ['relimport'], 1)
|
||||
|
||||
|
||||
class FakeSpec:
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
|
||||
class Using__package__PEP302(Using__package__):
|
||||
mock_modules = util.mock_modules
|
||||
|
||||
|
||||
(Frozen_UsingPackagePEP302,
|
||||
Source_UsingPackagePEP302
|
||||
) = util.test_both(Using__package__PEP302, __import__=util.__import__)
|
||||
|
||||
|
||||
class Using__package__PEP451(Using__package__):
|
||||
mock_modules = util.mock_spec
|
||||
|
||||
|
||||
(Frozen_UsingPackagePEP451,
|
||||
Source_UsingPackagePEP451
|
||||
) = util.test_both(Using__package__PEP451, __import__=util.__import__)
|
||||
|
||||
|
||||
class Setting__package__:
|
||||
|
||||
"""Because __package__ is a new feature, it is not always set by a loader.
|
||||
Import will set it as needed to help with the transition to relying on
|
||||
__package__.
|
||||
|
||||
For a top-level module, __package__ is set to None [top-level]. For a
|
||||
package __name__ is used for __package__ [package]. For submodules the
|
||||
value is __name__.rsplit('.', 1)[0] [submodule].
|
||||
|
||||
"""
|
||||
|
||||
__import__ = util.__import__['Source']
|
||||
|
||||
# [top-level]
|
||||
def test_top_level(self):
|
||||
with self.mock_modules('top_level') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['top_level'].__package__
|
||||
module = self.__import__('top_level')
|
||||
self.assertEqual(module.__package__, '')
|
||||
|
||||
# [package]
|
||||
def test_package(self):
|
||||
with self.mock_modules('pkg.__init__') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['pkg'].__package__
|
||||
module = self.__import__('pkg')
|
||||
self.assertEqual(module.__package__, 'pkg')
|
||||
|
||||
# [submodule]
|
||||
def test_submodule(self):
|
||||
with self.mock_modules('pkg.__init__', 'pkg.mod') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['pkg.mod'].__package__
|
||||
pkg = self.__import__('pkg.mod')
|
||||
module = getattr(pkg, 'mod')
|
||||
self.assertEqual(module.__package__, 'pkg')
|
||||
|
||||
class Setting__package__PEP302(Setting__package__, unittest.TestCase):
|
||||
mock_modules = util.mock_modules
|
||||
|
||||
class Setting__package__PEP451(Setting__package__, unittest.TestCase):
|
||||
mock_modules = util.mock_spec
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
119
third_party/python/Lib/test/test_importlib/import_/test_api.py
vendored
Normal file
119
third_party/python/Lib/test/test_importlib/import_/test_api.py
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
from .. import util
|
||||
|
||||
from importlib import machinery
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
|
||||
PKG_NAME = 'fine'
|
||||
SUBMOD_NAME = 'fine.bogus'
|
||||
|
||||
|
||||
class BadSpecFinderLoader:
|
||||
@classmethod
|
||||
def find_spec(cls, fullname, path=None, target=None):
|
||||
if fullname == SUBMOD_NAME:
|
||||
spec = machinery.ModuleSpec(fullname, cls)
|
||||
return spec
|
||||
|
||||
@staticmethod
|
||||
def create_module(spec):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def exec_module(module):
|
||||
if module.__name__ == SUBMOD_NAME:
|
||||
raise ImportError('I cannot be loaded!')
|
||||
|
||||
|
||||
class BadLoaderFinder:
|
||||
@classmethod
|
||||
def find_module(cls, fullname, path):
|
||||
if fullname == SUBMOD_NAME:
|
||||
return cls
|
||||
|
||||
@classmethod
|
||||
def load_module(cls, fullname):
|
||||
if fullname == SUBMOD_NAME:
|
||||
raise ImportError('I cannot be loaded!')
|
||||
|
||||
|
||||
class APITest:
|
||||
|
||||
"""Test API-specific details for __import__ (e.g. raising the right
|
||||
exception when passing in an int for the module name)."""
|
||||
|
||||
def test_raises_ModuleNotFoundError(self):
|
||||
with self.assertRaises(ModuleNotFoundError):
|
||||
util.import_importlib('some module that does not exist')
|
||||
|
||||
def test_name_requires_rparition(self):
|
||||
# Raise TypeError if a non-string is passed in for the module name.
|
||||
with self.assertRaises(TypeError):
|
||||
self.__import__(42)
|
||||
|
||||
def test_negative_level(self):
|
||||
# Raise ValueError when a negative level is specified.
|
||||
# PEP 328 did away with sys.module None entries and the ambiguity of
|
||||
# absolute/relative imports.
|
||||
with self.assertRaises(ValueError):
|
||||
self.__import__('os', globals(), level=-1)
|
||||
|
||||
def test_nonexistent_fromlist_entry(self):
|
||||
# If something in fromlist doesn't exist, that's okay.
|
||||
# issue15715
|
||||
mod = types.ModuleType(PKG_NAME)
|
||||
mod.__path__ = ['XXX']
|
||||
with util.import_state(meta_path=[self.bad_finder_loader]):
|
||||
with util.uncache(PKG_NAME):
|
||||
sys.modules[PKG_NAME] = mod
|
||||
self.__import__(PKG_NAME, fromlist=['not here'])
|
||||
|
||||
def test_fromlist_load_error_propagates(self):
|
||||
# If something in fromlist triggers an exception not related to not
|
||||
# existing, let that exception propagate.
|
||||
# issue15316
|
||||
mod = types.ModuleType(PKG_NAME)
|
||||
mod.__path__ = ['XXX']
|
||||
with util.import_state(meta_path=[self.bad_finder_loader]):
|
||||
with util.uncache(PKG_NAME):
|
||||
sys.modules[PKG_NAME] = mod
|
||||
with self.assertRaises(ImportError):
|
||||
self.__import__(PKG_NAME,
|
||||
fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
|
||||
|
||||
def test_blocked_fromlist(self):
|
||||
# If fromlist entry is None, let a ModuleNotFoundError propagate.
|
||||
# issue31642
|
||||
mod = types.ModuleType(PKG_NAME)
|
||||
mod.__path__ = []
|
||||
with util.import_state(meta_path=[self.bad_finder_loader]):
|
||||
with util.uncache(PKG_NAME, SUBMOD_NAME):
|
||||
sys.modules[PKG_NAME] = mod
|
||||
sys.modules[SUBMOD_NAME] = None
|
||||
with self.assertRaises(ModuleNotFoundError) as cm:
|
||||
self.__import__(PKG_NAME,
|
||||
fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
|
||||
self.assertEqual(cm.exception.name, SUBMOD_NAME)
|
||||
|
||||
|
||||
class OldAPITests(APITest):
|
||||
bad_finder_loader = BadLoaderFinder
|
||||
|
||||
|
||||
(Frozen_OldAPITests,
|
||||
Source_OldAPITests
|
||||
) = util.test_both(OldAPITests, __import__=util.__import__)
|
||||
|
||||
|
||||
class SpecAPITests(APITest):
|
||||
bad_finder_loader = BadSpecFinderLoader
|
||||
|
||||
|
||||
(Frozen_SpecAPITests,
|
||||
Source_SpecAPITests
|
||||
) = util.test_both(SpecAPITests, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
93
third_party/python/Lib/test/test_importlib/import_/test_caching.py
vendored
Normal file
93
third_party/python/Lib/test/test_importlib/import_/test_caching.py
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
"""Test that sys.modules is used properly by import."""
|
||||
from .. import util
|
||||
import sys
|
||||
from types import MethodType
|
||||
import unittest
|
||||
|
||||
|
||||
class UseCache:
|
||||
|
||||
"""When it comes to sys.modules, import prefers it over anything else.
|
||||
|
||||
Once a name has been resolved, sys.modules is checked to see if it contains
|
||||
the module desired. If so, then it is returned [use cache]. If it is not
|
||||
found, then the proper steps are taken to perform the import, but
|
||||
sys.modules is still used to return the imported module (e.g., not what a
|
||||
loader returns) [from cache on return]. This also applies to imports of
|
||||
things contained within a package and thus get assigned as an attribute
|
||||
[from cache to attribute] or pulled in thanks to a fromlist import
|
||||
[from cache for fromlist]. But if sys.modules contains None then
|
||||
ImportError is raised [None in cache].
|
||||
|
||||
"""
|
||||
|
||||
def test_using_cache(self):
|
||||
# [use cache]
|
||||
module_to_use = "some module found!"
|
||||
with util.uncache('some_module'):
|
||||
sys.modules['some_module'] = module_to_use
|
||||
module = self.__import__('some_module')
|
||||
self.assertEqual(id(module_to_use), id(module))
|
||||
|
||||
def test_None_in_cache(self):
|
||||
#[None in cache]
|
||||
name = 'using_None'
|
||||
with util.uncache(name):
|
||||
sys.modules[name] = None
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.__import__(name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
|
||||
|
||||
(Frozen_UseCache,
|
||||
Source_UseCache
|
||||
) = util.test_both(UseCache, __import__=util.__import__)
|
||||
|
||||
|
||||
class ImportlibUseCache(UseCache, unittest.TestCase):
|
||||
|
||||
# Pertinent only to PEP 302; exec_module() doesn't return a module.
|
||||
|
||||
__import__ = util.__import__['Source']
|
||||
|
||||
def create_mock(self, *names, return_=None):
|
||||
mock = util.mock_modules(*names)
|
||||
original_load = mock.load_module
|
||||
def load_module(self, fullname):
|
||||
original_load(fullname)
|
||||
return return_
|
||||
mock.load_module = MethodType(load_module, mock)
|
||||
return mock
|
||||
|
||||
# __import__ inconsistent between loaders and built-in import when it comes
|
||||
# to when to use the module in sys.modules and when not to.
|
||||
def test_using_cache_after_loader(self):
|
||||
# [from cache on return]
|
||||
with self.create_mock('module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
module = self.__import__('module')
|
||||
self.assertEqual(id(module), id(sys.modules['module']))
|
||||
|
||||
# See test_using_cache_after_loader() for reasoning.
|
||||
def test_using_cache_for_assigning_to_attribute(self):
|
||||
# [from cache to attribute]
|
||||
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg.module')
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(id(module.module),
|
||||
id(sys.modules['pkg.module']))
|
||||
|
||||
# See test_using_cache_after_loader() for reasoning.
|
||||
def test_using_cache_for_fromlist(self):
|
||||
# [from cache for fromlist]
|
||||
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg', fromlist=['module'])
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(id(module.module),
|
||||
id(sys.modules['pkg.module']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
175
third_party/python/Lib/test/test_importlib/import_/test_fromlist.py
vendored
Normal file
175
third_party/python/Lib/test/test_importlib/import_/test_fromlist.py
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
"""Test that the semantics relating to the 'fromlist' argument are correct."""
|
||||
from .. import util
|
||||
import warnings
|
||||
import unittest
|
||||
|
||||
|
||||
class ReturnValue:
|
||||
|
||||
"""The use of fromlist influences what import returns.
|
||||
|
||||
If direct ``import ...`` statement is used, the root module or package is
|
||||
returned [import return]. But if fromlist is set, then the specified module
|
||||
is actually returned (whether it is a relative import or not)
|
||||
[from return].
|
||||
|
||||
"""
|
||||
|
||||
def test_return_from_import(self):
|
||||
# [import return]
|
||||
with util.mock_spec('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg.module')
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
||||
def test_return_from_from_import(self):
|
||||
# [from return]
|
||||
with util.mock_modules('pkg.__init__', 'pkg.module')as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg.module', fromlist=['attr'])
|
||||
self.assertEqual(module.__name__, 'pkg.module')
|
||||
|
||||
|
||||
(Frozen_ReturnValue,
|
||||
Source_ReturnValue
|
||||
) = util.test_both(ReturnValue, __import__=util.__import__)
|
||||
|
||||
|
||||
class HandlingFromlist:
|
||||
|
||||
"""Using fromlist triggers different actions based on what is being asked
|
||||
of it.
|
||||
|
||||
If fromlist specifies an object on a module, nothing special happens
|
||||
[object case]. This is even true if the object does not exist [bad object].
|
||||
|
||||
If a package is being imported, then what is listed in fromlist may be
|
||||
treated as a module to be imported [module]. And this extends to what is
|
||||
contained in __all__ when '*' is imported [using *]. And '*' does not need
|
||||
to be the only name in the fromlist [using * with others].
|
||||
|
||||
"""
|
||||
|
||||
def test_object(self):
|
||||
# [object case]
|
||||
with util.mock_modules('module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('module', fromlist=['attr'])
|
||||
self.assertEqual(module.__name__, 'module')
|
||||
|
||||
def test_nonexistent_object(self):
|
||||
# [bad object]
|
||||
with util.mock_modules('module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('module', fromlist=['non_existent'])
|
||||
self.assertEqual(module.__name__, 'module')
|
||||
self.assertFalse(hasattr(module, 'non_existent'))
|
||||
|
||||
def test_module_from_package(self):
|
||||
# [module]
|
||||
with util.mock_modules('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg', fromlist=['module'])
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(module.module.__name__, 'pkg.module')
|
||||
|
||||
def test_nonexistent_from_package(self):
|
||||
with util.mock_modules('pkg.__init__') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg', fromlist=['non_existent'])
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertFalse(hasattr(module, 'non_existent'))
|
||||
|
||||
def test_module_from_package_triggers_ModuleNotFoundError(self):
|
||||
# If a submodule causes an ModuleNotFoundError because it tries
|
||||
# to import a module which doesn't exist, that should let the
|
||||
# ModuleNotFoundError propagate.
|
||||
def module_code():
|
||||
import i_do_not_exist
|
||||
with util.mock_modules('pkg.__init__', 'pkg.mod',
|
||||
module_code={'pkg.mod': module_code}) as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
with self.assertRaises(ModuleNotFoundError) as exc:
|
||||
self.__import__('pkg', fromlist=['mod'])
|
||||
self.assertEqual('i_do_not_exist', exc.exception.name)
|
||||
|
||||
def test_empty_string(self):
|
||||
with util.mock_modules('pkg.__init__', 'pkg.mod') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg.mod', fromlist=[''])
|
||||
self.assertEqual(module.__name__, 'pkg.mod')
|
||||
|
||||
def basic_star_test(self, fromlist=['*']):
|
||||
# [using *]
|
||||
with util.mock_modules('pkg.__init__', 'pkg.module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
mock['pkg'].__all__ = ['module']
|
||||
module = self.__import__('pkg', fromlist=fromlist)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(module.module.__name__, 'pkg.module')
|
||||
|
||||
def test_using_star(self):
|
||||
# [using *]
|
||||
self.basic_star_test()
|
||||
|
||||
def test_fromlist_as_tuple(self):
|
||||
self.basic_star_test(('*',))
|
||||
|
||||
def test_star_with_others(self):
|
||||
# [using * with others]
|
||||
context = util.mock_modules('pkg.__init__', 'pkg.module1', 'pkg.module2')
|
||||
with context as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
mock['pkg'].__all__ = ['module1']
|
||||
module = self.__import__('pkg', fromlist=['module2', '*'])
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'module1'))
|
||||
self.assertTrue(hasattr(module, 'module2'))
|
||||
self.assertEqual(module.module1.__name__, 'pkg.module1')
|
||||
self.assertEqual(module.module2.__name__, 'pkg.module2')
|
||||
|
||||
def test_nonexistent_in_all(self):
|
||||
with util.mock_modules('pkg.__init__') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
importer['pkg'].__all__ = ['non_existent']
|
||||
module = self.__import__('pkg', fromlist=['*'])
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertFalse(hasattr(module, 'non_existent'))
|
||||
|
||||
def test_star_in_all(self):
|
||||
with util.mock_modules('pkg.__init__') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
importer['pkg'].__all__ = ['*']
|
||||
module = self.__import__('pkg', fromlist=['*'])
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertFalse(hasattr(module, '*'))
|
||||
|
||||
def test_invalid_type(self):
|
||||
with util.mock_modules('pkg.__init__') as importer:
|
||||
with util.import_state(meta_path=[importer]), \
|
||||
warnings.catch_warnings():
|
||||
warnings.simplefilter('error', BytesWarning)
|
||||
with self.assertRaisesRegex(TypeError, r'\bfrom\b'):
|
||||
self.__import__('pkg', fromlist=[b'attr'])
|
||||
with self.assertRaisesRegex(TypeError, r'\bfrom\b'):
|
||||
self.__import__('pkg', fromlist=iter([b'attr']))
|
||||
|
||||
def test_invalid_type_in_all(self):
|
||||
with util.mock_modules('pkg.__init__') as importer:
|
||||
with util.import_state(meta_path=[importer]), \
|
||||
warnings.catch_warnings():
|
||||
warnings.simplefilter('error', BytesWarning)
|
||||
importer['pkg'].__all__ = [b'attr']
|
||||
with self.assertRaisesRegex(TypeError, r'\bpkg\.__all__\b'):
|
||||
self.__import__('pkg', fromlist=['*'])
|
||||
|
||||
|
||||
(Frozen_FromList,
|
||||
Source_FromList
|
||||
) = util.test_both(HandlingFromlist, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
125
third_party/python/Lib/test/test_importlib/import_/test_meta_path.py
vendored
Normal file
125
third_party/python/Lib/test/test_importlib/import_/test_meta_path.py
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
from .. import util
|
||||
import importlib._bootstrap
|
||||
import sys
|
||||
from types import MethodType
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class CallingOrder:
|
||||
|
||||
"""Calls to the importers on sys.meta_path happen in order that they are
|
||||
specified in the sequence, starting with the first importer
|
||||
[first called], and then continuing on down until one is found that doesn't
|
||||
return None [continuing]."""
|
||||
|
||||
|
||||
def test_first_called(self):
|
||||
# [first called]
|
||||
mod = 'top_level'
|
||||
with util.mock_spec(mod) as first, util.mock_spec(mod) as second:
|
||||
with util.import_state(meta_path=[first, second]):
|
||||
self.assertIs(self.__import__(mod), first.modules[mod])
|
||||
|
||||
def test_continuing(self):
|
||||
# [continuing]
|
||||
mod_name = 'for_real'
|
||||
with util.mock_spec('nonexistent') as first, \
|
||||
util.mock_spec(mod_name) as second:
|
||||
first.find_spec = lambda self, fullname, path=None, parent=None: None
|
||||
with util.import_state(meta_path=[first, second]):
|
||||
self.assertIs(self.__import__(mod_name), second.modules[mod_name])
|
||||
|
||||
def test_empty(self):
|
||||
# Raise an ImportWarning if sys.meta_path is empty.
|
||||
module_name = 'nothing'
|
||||
try:
|
||||
del sys.modules[module_name]
|
||||
except KeyError:
|
||||
pass
|
||||
with util.import_state(meta_path=[]):
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
self.assertIsNone(importlib._bootstrap._find_spec('nothing',
|
||||
None))
|
||||
self.assertEqual(len(w), 1)
|
||||
self.assertTrue(issubclass(w[-1].category, ImportWarning))
|
||||
|
||||
|
||||
(Frozen_CallingOrder,
|
||||
Source_CallingOrder
|
||||
) = util.test_both(CallingOrder, __import__=util.__import__)
|
||||
|
||||
|
||||
class CallSignature:
|
||||
|
||||
"""If there is no __path__ entry on the parent module, then 'path' is None
|
||||
[no path]. Otherwise, the value for __path__ is passed in for the 'path'
|
||||
argument [path set]."""
|
||||
|
||||
def log_finder(self, importer):
|
||||
fxn = getattr(importer, self.finder_name)
|
||||
log = []
|
||||
def wrapper(self, *args, **kwargs):
|
||||
log.append([args, kwargs])
|
||||
return fxn(*args, **kwargs)
|
||||
return log, wrapper
|
||||
|
||||
def test_no_path(self):
|
||||
# [no path]
|
||||
mod_name = 'top_level'
|
||||
assert '.' not in mod_name
|
||||
with self.mock_modules(mod_name) as importer:
|
||||
log, wrapped_call = self.log_finder(importer)
|
||||
setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__(mod_name)
|
||||
assert len(log) == 1
|
||||
args = log[0][0]
|
||||
# Assuming all arguments are positional.
|
||||
self.assertEqual(args[0], mod_name)
|
||||
self.assertIsNone(args[1])
|
||||
|
||||
def test_with_path(self):
|
||||
# [path set]
|
||||
pkg_name = 'pkg'
|
||||
mod_name = pkg_name + '.module'
|
||||
path = [42]
|
||||
assert '.' in mod_name
|
||||
with self.mock_modules(pkg_name+'.__init__', mod_name) as importer:
|
||||
importer.modules[pkg_name].__path__ = path
|
||||
log, wrapped_call = self.log_finder(importer)
|
||||
setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__(mod_name)
|
||||
assert len(log) == 2
|
||||
args = log[1][0]
|
||||
kwargs = log[1][1]
|
||||
# Assuming all arguments are positional.
|
||||
self.assertFalse(kwargs)
|
||||
self.assertEqual(args[0], mod_name)
|
||||
self.assertIs(args[1], path)
|
||||
|
||||
|
||||
class CallSignaturePEP302(CallSignature):
|
||||
mock_modules = util.mock_modules
|
||||
finder_name = 'find_module'
|
||||
|
||||
|
||||
(Frozen_CallSignaturePEP302,
|
||||
Source_CallSignaturePEP302
|
||||
) = util.test_both(CallSignaturePEP302, __import__=util.__import__)
|
||||
|
||||
|
||||
class CallSignaturePEP451(CallSignature):
|
||||
mock_modules = util.mock_spec
|
||||
finder_name = 'find_spec'
|
||||
|
||||
|
||||
(Frozen_CallSignaturePEP451,
|
||||
Source_CallSignaturePEP451
|
||||
) = util.test_both(CallSignaturePEP451, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
110
third_party/python/Lib/test/test_importlib/import_/test_packages.py
vendored
Normal file
110
third_party/python/Lib/test/test_importlib/import_/test_packages.py
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
from .. import util
|
||||
import sys
|
||||
import unittest
|
||||
from test import support
|
||||
|
||||
|
||||
class ParentModuleTests:
|
||||
|
||||
"""Importing a submodule should import the parent modules."""
|
||||
|
||||
def test_import_parent(self):
|
||||
with util.mock_spec('pkg.__init__', 'pkg.module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
module = self.__import__('pkg.module')
|
||||
self.assertIn('pkg', sys.modules)
|
||||
|
||||
def test_bad_parent(self):
|
||||
with util.mock_spec('pkg.module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.__import__('pkg.module')
|
||||
self.assertEqual(cm.exception.name, 'pkg')
|
||||
|
||||
def test_raising_parent_after_importing_child(self):
|
||||
def __init__():
|
||||
import pkg.module
|
||||
1/0
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.module',
|
||||
module_code={'pkg': __init__})
|
||||
with mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
with self.assertRaises(ZeroDivisionError):
|
||||
self.__import__('pkg')
|
||||
self.assertNotIn('pkg', sys.modules)
|
||||
self.assertIn('pkg.module', sys.modules)
|
||||
with self.assertRaises(ZeroDivisionError):
|
||||
self.__import__('pkg.module')
|
||||
self.assertNotIn('pkg', sys.modules)
|
||||
self.assertIn('pkg.module', sys.modules)
|
||||
|
||||
def test_raising_parent_after_relative_importing_child(self):
|
||||
def __init__():
|
||||
from . import module
|
||||
1/0
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.module',
|
||||
module_code={'pkg': __init__})
|
||||
with mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
with self.assertRaises((ZeroDivisionError, ImportError)):
|
||||
# This raises ImportError on the "from . import module"
|
||||
# line, not sure why.
|
||||
self.__import__('pkg')
|
||||
self.assertNotIn('pkg', sys.modules)
|
||||
with self.assertRaises((ZeroDivisionError, ImportError)):
|
||||
self.__import__('pkg.module')
|
||||
self.assertNotIn('pkg', sys.modules)
|
||||
# XXX False
|
||||
#self.assertIn('pkg.module', sys.modules)
|
||||
|
||||
def test_raising_parent_after_double_relative_importing_child(self):
|
||||
def __init__():
|
||||
from ..subpkg import module
|
||||
1/0
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.subpkg.__init__',
|
||||
'pkg.subpkg.module',
|
||||
module_code={'pkg.subpkg': __init__})
|
||||
with mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
with self.assertRaises((ZeroDivisionError, ImportError)):
|
||||
# This raises ImportError on the "from ..subpkg import module"
|
||||
# line, not sure why.
|
||||
self.__import__('pkg.subpkg')
|
||||
self.assertNotIn('pkg.subpkg', sys.modules)
|
||||
with self.assertRaises((ZeroDivisionError, ImportError)):
|
||||
self.__import__('pkg.subpkg.module')
|
||||
self.assertNotIn('pkg.subpkg', sys.modules)
|
||||
# XXX False
|
||||
#self.assertIn('pkg.subpkg.module', sys.modules)
|
||||
|
||||
def test_module_not_package(self):
|
||||
# Try to import a submodule from a non-package should raise ImportError.
|
||||
assert not hasattr(sys, '__path__')
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.__import__('sys.no_submodules_here')
|
||||
self.assertEqual(cm.exception.name, 'sys.no_submodules_here')
|
||||
|
||||
def test_module_not_package_but_side_effects(self):
|
||||
# If a module injects something into sys.modules as a side-effect, then
|
||||
# pick up on that fact.
|
||||
name = 'mod'
|
||||
subname = name + '.b'
|
||||
def module_injection():
|
||||
sys.modules[subname] = 'total bunk'
|
||||
mock_spec = util.mock_spec('mod',
|
||||
module_code={'mod': module_injection})
|
||||
with mock_spec as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
try:
|
||||
submodule = self.__import__(subname)
|
||||
finally:
|
||||
support.unload(subname)
|
||||
|
||||
|
||||
(Frozen_ParentTests,
|
||||
Source_ParentTests
|
||||
) = util.test_both(ParentModuleTests, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
257
third_party/python/Lib/test/test_importlib/import_/test_path.py
vendored
Normal file
257
third_party/python/Lib/test/test_importlib/import_/test_path.py
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
from .. 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:
|
||||
|
||||
"""Tests for PathFinder."""
|
||||
|
||||
find = None
|
||||
check_found = None
|
||||
|
||||
def test_failure(self):
|
||||
# Test None returned upon not finding a suitable loader.
|
||||
module = '<test module>'
|
||||
with util.import_state():
|
||||
self.assertIsNone(self.find(module))
|
||||
|
||||
def test_sys_path(self):
|
||||
# Test that sys.path is used when 'path' is None.
|
||||
# Implicitly tests that sys.path_importer_cache is used.
|
||||
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):
|
||||
# Test that 'path' is used when set.
|
||||
# Implicitly tests that sys.path_importer_cache is used.
|
||||
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):
|
||||
# An empty list should not count as asking for sys.path.
|
||||
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):
|
||||
# Test that sys.path_hooks is used.
|
||||
# Test that sys.path_importer_cache is set.
|
||||
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):
|
||||
# Test that if sys.path_hooks is empty a warning is raised,
|
||||
# sys.path_importer_cache gets None set, and PathFinder returns None.
|
||||
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')
|
||||
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):
|
||||
# The empty string should create a finder using the cwd.
|
||||
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):
|
||||
# Putting None in sys.path[0] caused an import regression from Python
|
||||
# 3.2: http://bugs.python.org/issue16514
|
||||
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_module(self):
|
||||
class TestFinder:
|
||||
def find_module(self, fullname):
|
||||
return self.to_return
|
||||
failing_finder = TestFinder()
|
||||
failing_finder.to_return = None
|
||||
path = 'testing path'
|
||||
with util.import_state(path_importer_cache={path: failing_finder}):
|
||||
self.assertIsNone(
|
||||
self.machinery.PathFinder.find_spec('whatever', [path]))
|
||||
success_finder = TestFinder()
|
||||
success_finder.to_return = __loader__
|
||||
with util.import_state(path_importer_cache={path: success_finder}):
|
||||
spec = self.machinery.PathFinder.find_spec('whatever', [path])
|
||||
self.assertEqual(spec.loader, __loader__)
|
||||
|
||||
def test_finder_with_find_loader(self):
|
||||
class TestFinder:
|
||||
loader = None
|
||||
portions = []
|
||||
def find_loader(self, fullname):
|
||||
return self.loader, self.portions
|
||||
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.loader = __loader__
|
||||
with util.import_state(path_importer_cache={path: success_finder}):
|
||||
spec = self.machinery.PathFinder.find_spec('whatever', [path])
|
||||
self.assertEqual(spec.loader, __loader__)
|
||||
|
||||
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):
|
||||
# Issue #22834
|
||||
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:
|
||||
# EINVAL on Solaris, EBUSY on AIX, ENOTEMPTY on Windows
|
||||
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=['']):
|
||||
# Do not want FileNotFoundError raised.
|
||||
self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
|
||||
|
||||
|
||||
class FindModuleTests(FinderTests):
|
||||
def find(self, *args, **kwargs):
|
||||
return self.machinery.PathFinder.find_module(*args, **kwargs)
|
||||
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):
|
||||
# PathEntryFinder with find_module() defined should work.
|
||||
# Issue #20763.
|
||||
class Finder:
|
||||
path_location = 'test_finder_with_find_module'
|
||||
def __init__(self, path):
|
||||
if path != self.path_location:
|
||||
raise ImportError
|
||||
|
||||
@staticmethod
|
||||
def find_module(fullname):
|
||||
return None
|
||||
|
||||
|
||||
with util.import_state(path=[Finder.path_location]+sys.path[:],
|
||||
path_hooks=[Finder]):
|
||||
self.machinery.PathFinder.find_spec('importlib')
|
||||
|
||||
def test_finder_with_failing_find_module(self):
|
||||
# PathEntryFinder with find_module() defined should work.
|
||||
# Issue #20763.
|
||||
class Finder:
|
||||
path_location = 'test_finder_with_find_module'
|
||||
def __init__(self, path):
|
||||
if path != self.path_location:
|
||||
raise ImportError
|
||||
|
||||
@staticmethod
|
||||
def find_module(fullname):
|
||||
return None
|
||||
|
||||
|
||||
with util.import_state(path=[Finder.path_location]+sys.path[:],
|
||||
path_hooks=[Finder]):
|
||||
self.machinery.PathFinder.find_module('importlib')
|
||||
|
||||
|
||||
(Frozen_PEFTests,
|
||||
Source_PEFTests
|
||||
) = util.test_both(PathEntryFinderTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
232
third_party/python/Lib/test/test_importlib/import_/test_relative_imports.py
vendored
Normal file
232
third_party/python/Lib/test/test_importlib/import_/test_relative_imports.py
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
"""Test relative imports (PEP 328)."""
|
||||
from .. import util
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class RelativeImports:
|
||||
|
||||
"""PEP 328 introduced relative imports. This allows for imports to occur
|
||||
from within a package without having to specify the actual package name.
|
||||
|
||||
A simple example is to import another module within the same package
|
||||
[module from module]::
|
||||
|
||||
# From pkg.mod1 with pkg.mod2 being a module.
|
||||
from . import mod2
|
||||
|
||||
This also works for getting an attribute from a module that is specified
|
||||
in a relative fashion [attr from module]::
|
||||
|
||||
# From pkg.mod1.
|
||||
from .mod2 import attr
|
||||
|
||||
But this is in no way restricted to working between modules; it works
|
||||
from [package to module],::
|
||||
|
||||
# From pkg, importing pkg.module which is a module.
|
||||
from . import module
|
||||
|
||||
[module to package],::
|
||||
|
||||
# Pull attr from pkg, called from pkg.module which is a module.
|
||||
from . import attr
|
||||
|
||||
and [package to package]::
|
||||
|
||||
# From pkg.subpkg1 (both pkg.subpkg[1,2] are packages).
|
||||
from .. import subpkg2
|
||||
|
||||
The number of dots used is in no way restricted [deep import]::
|
||||
|
||||
# Import pkg.attr from pkg.pkg1.pkg2.pkg3.pkg4.pkg5.
|
||||
from ...... import attr
|
||||
|
||||
To prevent someone from accessing code that is outside of a package, one
|
||||
cannot reach the location containing the root package itself::
|
||||
|
||||
# From pkg.__init__ [too high from package]
|
||||
from .. import top_level
|
||||
|
||||
# From pkg.module [too high from module]
|
||||
from .. import top_level
|
||||
|
||||
Relative imports are the only type of import that allow for an empty
|
||||
module name for an import [empty name].
|
||||
|
||||
"""
|
||||
|
||||
def relative_import_test(self, create, globals_, callback):
|
||||
"""Abstract out boilerplace for setting up for an import test."""
|
||||
uncache_names = []
|
||||
for name in create:
|
||||
if not name.endswith('.__init__'):
|
||||
uncache_names.append(name)
|
||||
else:
|
||||
uncache_names.append(name[:-len('.__init__')])
|
||||
with util.mock_spec(*create) as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
for global_ in globals_:
|
||||
with util.uncache(*uncache_names):
|
||||
callback(global_)
|
||||
|
||||
|
||||
def test_module_from_module(self):
|
||||
# [module from module]
|
||||
create = 'pkg.__init__', 'pkg.mod2'
|
||||
globals_ = {'__package__': 'pkg'}, {'__name__': 'pkg.mod1'}
|
||||
def callback(global_):
|
||||
self.__import__('pkg') # For __import__().
|
||||
module = self.__import__('', global_, fromlist=['mod2'], level=1)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'mod2'))
|
||||
self.assertEqual(module.mod2.attr, 'pkg.mod2')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_attr_from_module(self):
|
||||
# [attr from module]
|
||||
create = 'pkg.__init__', 'pkg.mod2'
|
||||
globals_ = {'__package__': 'pkg'}, {'__name__': 'pkg.mod1'}
|
||||
def callback(global_):
|
||||
self.__import__('pkg') # For __import__().
|
||||
module = self.__import__('mod2', global_, fromlist=['attr'],
|
||||
level=1)
|
||||
self.assertEqual(module.__name__, 'pkg.mod2')
|
||||
self.assertEqual(module.attr, 'pkg.mod2')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_package_to_module(self):
|
||||
# [package to module]
|
||||
create = 'pkg.__init__', 'pkg.module'
|
||||
globals_ = ({'__package__': 'pkg'},
|
||||
{'__name__': 'pkg', '__path__': ['blah']})
|
||||
def callback(global_):
|
||||
self.__import__('pkg') # For __import__().
|
||||
module = self.__import__('', global_, fromlist=['module'],
|
||||
level=1)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(module.module.attr, 'pkg.module')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_module_to_package(self):
|
||||
# [module to package]
|
||||
create = 'pkg.__init__', 'pkg.module'
|
||||
globals_ = {'__package__': 'pkg'}, {'__name__': 'pkg.module'}
|
||||
def callback(global_):
|
||||
self.__import__('pkg') # For __import__().
|
||||
module = self.__import__('', global_, fromlist=['attr'], level=1)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_package_to_package(self):
|
||||
# [package to package]
|
||||
create = ('pkg.__init__', 'pkg.subpkg1.__init__',
|
||||
'pkg.subpkg2.__init__')
|
||||
globals_ = ({'__package__': 'pkg.subpkg1'},
|
||||
{'__name__': 'pkg.subpkg1', '__path__': ['blah']})
|
||||
def callback(global_):
|
||||
module = self.__import__('', global_, fromlist=['subpkg2'],
|
||||
level=2)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.assertTrue(hasattr(module, 'subpkg2'))
|
||||
self.assertEqual(module.subpkg2.attr, 'pkg.subpkg2.__init__')
|
||||
|
||||
def test_deep_import(self):
|
||||
# [deep import]
|
||||
create = ['pkg.__init__']
|
||||
for count in range(1,6):
|
||||
create.append('{0}.pkg{1}.__init__'.format(
|
||||
create[-1][:-len('.__init__')], count))
|
||||
globals_ = ({'__package__': 'pkg.pkg1.pkg2.pkg3.pkg4.pkg5'},
|
||||
{'__name__': 'pkg.pkg1.pkg2.pkg3.pkg4.pkg5',
|
||||
'__path__': ['blah']})
|
||||
def callback(global_):
|
||||
self.__import__(globals_[0]['__package__'])
|
||||
module = self.__import__('', global_, fromlist=['attr'], level=6)
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_too_high_from_package(self):
|
||||
# [too high from package]
|
||||
create = ['top_level', 'pkg.__init__']
|
||||
globals_ = ({'__package__': 'pkg'},
|
||||
{'__name__': 'pkg', '__path__': ['blah']})
|
||||
def callback(global_):
|
||||
self.__import__('pkg')
|
||||
with self.assertRaises(ValueError):
|
||||
self.__import__('', global_, fromlist=['top_level'],
|
||||
level=2)
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_too_high_from_module(self):
|
||||
# [too high from module]
|
||||
create = ['top_level', 'pkg.__init__', 'pkg.module']
|
||||
globals_ = {'__package__': 'pkg'}, {'__name__': 'pkg.module'}
|
||||
def callback(global_):
|
||||
self.__import__('pkg')
|
||||
with self.assertRaises(ValueError):
|
||||
self.__import__('', global_, fromlist=['top_level'],
|
||||
level=2)
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_empty_name_w_level_0(self):
|
||||
# [empty name]
|
||||
with self.assertRaises(ValueError):
|
||||
self.__import__('')
|
||||
|
||||
def test_import_from_different_package(self):
|
||||
# Test importing from a different package than the caller.
|
||||
# in pkg.subpkg1.mod
|
||||
# from ..subpkg2 import mod
|
||||
create = ['__runpy_pkg__.__init__',
|
||||
'__runpy_pkg__.__runpy_pkg__.__init__',
|
||||
'__runpy_pkg__.uncle.__init__',
|
||||
'__runpy_pkg__.uncle.cousin.__init__',
|
||||
'__runpy_pkg__.uncle.cousin.nephew']
|
||||
globals_ = {'__package__': '__runpy_pkg__.__runpy_pkg__'}
|
||||
def callback(global_):
|
||||
self.__import__('__runpy_pkg__.__runpy_pkg__')
|
||||
module = self.__import__('uncle.cousin', globals_, {},
|
||||
fromlist=['nephew'],
|
||||
level=2)
|
||||
self.assertEqual(module.__name__, '__runpy_pkg__.uncle.cousin')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_import_relative_import_no_fromlist(self):
|
||||
# Import a relative module w/ no fromlist.
|
||||
create = ['crash.__init__', 'crash.mod']
|
||||
globals_ = [{'__package__': 'crash', '__name__': 'crash'}]
|
||||
def callback(global_):
|
||||
self.__import__('crash')
|
||||
mod = self.__import__('mod', global_, {}, [], 1)
|
||||
self.assertEqual(mod.__name__, 'crash.mod')
|
||||
self.relative_import_test(create, globals_, callback)
|
||||
|
||||
def test_relative_import_no_globals(self):
|
||||
# No globals for a relative import is an error.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
with self.assertRaises(KeyError):
|
||||
self.__import__('sys', level=1)
|
||||
|
||||
def test_relative_import_no_package(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.__import__('a', {'__package__': '', '__spec__': None},
|
||||
level=1)
|
||||
|
||||
def test_relative_import_no_package_exists_absolute(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.__import__('sys', {'__package__': '', '__spec__': None},
|
||||
level=1)
|
||||
|
||||
|
||||
(Frozen_RelativeImports,
|
||||
Source_RelativeImports
|
||||
) = util.test_both(RelativeImports, __import__=util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/one.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/one.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'both_portions foo one'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/two.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/two.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'both_portions foo two'
|
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/missing_directory.zip
vendored
Normal file
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/missing_directory.zip
vendored
Normal file
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
attr = 'in module'
|
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/nested_portion1.zip
vendored
Normal file
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/nested_portion1.zip
vendored
Normal file
Binary file not shown.
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/one.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/one.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'portion1 foo one'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/portion1/foo/one.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/portion1/foo/one.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'portion1 foo one'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/portion2/foo/two.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/portion2/foo/two.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'portion2 foo two'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project1/parent/child/one.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project1/parent/child/one.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'parent child one'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project2/parent/child/two.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project2/parent/child/two.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'parent child two'
|
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project3/parent/child/three.py
vendored
Normal file
1
third_party/python/Lib/test/test_importlib/namespace_pkgs/project3/parent/child/three.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
attr = 'parent child three'
|
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/top_level_portion1.zip
vendored
Normal file
BIN
third_party/python/Lib/test/test_importlib/namespace_pkgs/top_level_portion1.zip
vendored
Normal file
Binary file not shown.
5
third_party/python/Lib/test/test_importlib/source/__init__.py
vendored
Normal file
5
third_party/python/Lib/test/test_importlib/source/__init__.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import os
|
||||
from test.support import load_package_tests
|
||||
|
||||
def load_tests(*args):
|
||||
return load_package_tests(os.path.dirname(__file__), *args)
|
4
third_party/python/Lib/test/test_importlib/source/__main__.py
vendored
Normal file
4
third_party/python/Lib/test/test_importlib/source/__main__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from . import load_tests
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
85
third_party/python/Lib/test/test_importlib/source/test_case_sensitivity.py
vendored
Normal file
85
third_party/python/Lib/test/test_importlib/source/test_case_sensitivity.py
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
"""Test case-sensitivity (PEP 235)."""
|
||||
from .. import util
|
||||
|
||||
importlib = util.import_importlib('importlib')
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import os
|
||||
from test import support as test_support
|
||||
import unittest
|
||||
|
||||
|
||||
@util.case_insensitive_tests
|
||||
class CaseSensitivityTest(util.CASEOKTestBase):
|
||||
|
||||
"""PEP 235 dictates that on case-preserving, case-insensitive file systems
|
||||
that imports are case-sensitive unless the PYTHONCASEOK environment
|
||||
variable is set."""
|
||||
|
||||
name = 'MoDuLe'
|
||||
assert name != name.lower()
|
||||
|
||||
def finder(self, path):
|
||||
return self.machinery.FileFinder(path,
|
||||
(self.machinery.SourceFileLoader,
|
||||
self.machinery.SOURCE_SUFFIXES),
|
||||
(self.machinery.SourcelessFileLoader,
|
||||
self.machinery.BYTECODE_SUFFIXES))
|
||||
|
||||
def sensitivity_test(self):
|
||||
"""Look for a module with matching and non-matching sensitivity."""
|
||||
sensitive_pkg = 'sensitive.{0}'.format(self.name)
|
||||
insensitive_pkg = 'insensitive.{0}'.format(self.name.lower())
|
||||
context = util.create_modules(insensitive_pkg, sensitive_pkg)
|
||||
with context as mapping:
|
||||
sensitive_path = os.path.join(mapping['.root'], 'sensitive')
|
||||
insensitive_path = os.path.join(mapping['.root'], 'insensitive')
|
||||
sensitive_finder = self.finder(sensitive_path)
|
||||
insensitive_finder = self.finder(insensitive_path)
|
||||
return self.find(sensitive_finder), self.find(insensitive_finder)
|
||||
|
||||
def test_sensitive(self):
|
||||
with test_support.EnvironmentVarGuard() as env:
|
||||
env.unset('PYTHONCASEOK')
|
||||
self.caseok_env_changed(should_exist=False)
|
||||
sensitive, insensitive = self.sensitivity_test()
|
||||
self.assertIsNotNone(sensitive)
|
||||
self.assertIn(self.name, sensitive.get_filename(self.name))
|
||||
self.assertIsNone(insensitive)
|
||||
|
||||
def test_insensitive(self):
|
||||
with test_support.EnvironmentVarGuard() as env:
|
||||
env.set('PYTHONCASEOK', '1')
|
||||
self.caseok_env_changed(should_exist=True)
|
||||
sensitive, insensitive = self.sensitivity_test()
|
||||
self.assertIsNotNone(sensitive)
|
||||
self.assertIn(self.name, sensitive.get_filename(self.name))
|
||||
self.assertIsNotNone(insensitive)
|
||||
self.assertIn(self.name, insensitive.get_filename(self.name))
|
||||
|
||||
|
||||
class CaseSensitivityTestPEP302(CaseSensitivityTest):
|
||||
def find(self, finder):
|
||||
return finder.find_module(self.name)
|
||||
|
||||
|
||||
(Frozen_CaseSensitivityTestPEP302,
|
||||
Source_CaseSensitivityTestPEP302
|
||||
) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
class CaseSensitivityTestPEP451(CaseSensitivityTest):
|
||||
def find(self, finder):
|
||||
found = finder.find_spec(self.name)
|
||||
return found.loader if found is not None else found
|
||||
|
||||
|
||||
(Frozen_CaseSensitivityTestPEP451,
|
||||
Source_CaseSensitivityTestPEP451
|
||||
) = util.test_both(CaseSensitivityTestPEP451, importlib=importlib,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
602
third_party/python/Lib/test/test_importlib/source/test_file_loader.py
vendored
Normal file
602
third_party/python/Lib/test/test_importlib/source/test_file_loader.py
vendored
Normal file
|
@ -0,0 +1,602 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
importlib = util.import_importlib('importlib')
|
||||
importlib_abc = util.import_importlib('importlib.abc')
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
importlib_util = util.import_importlib('importlib.util')
|
||||
|
||||
import errno
|
||||
import marshal
|
||||
import os
|
||||
import py_compile
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from test.support import make_legacy_pyc, unload
|
||||
|
||||
|
||||
class SimpleTest(abc.LoaderTests):
|
||||
|
||||
"""Should have no issue importing a source module [basic]. And if there is
|
||||
a syntax error, it should raise a SyntaxError [syntax error].
|
||||
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.name = 'spam'
|
||||
self.filepath = os.path.join('ham', self.name + '.py')
|
||||
self.loader = self.machinery.SourceFileLoader(self.name, self.filepath)
|
||||
|
||||
def test_load_module_API(self):
|
||||
class Tester(self.abc.FileLoader):
|
||||
def get_source(self, _): return 'attr = 42'
|
||||
def is_package(self, _): return False
|
||||
|
||||
loader = Tester('blah', 'blah.py')
|
||||
self.addCleanup(unload, 'blah')
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module() # Should not raise an exception.
|
||||
|
||||
def test_get_filename_API(self):
|
||||
# If fullname is not set then assume self.path is desired.
|
||||
class Tester(self.abc.FileLoader):
|
||||
def get_code(self, _): pass
|
||||
def get_source(self, _): pass
|
||||
def is_package(self, _): pass
|
||||
def module_repr(self, _): pass
|
||||
|
||||
path = 'some_path'
|
||||
name = 'some_name'
|
||||
loader = Tester(name, path)
|
||||
self.assertEqual(path, loader.get_filename(name))
|
||||
self.assertEqual(path, loader.get_filename())
|
||||
self.assertEqual(path, loader.get_filename(None))
|
||||
with self.assertRaises(ImportError):
|
||||
loader.get_filename(name + 'XXX')
|
||||
|
||||
def test_equality(self):
|
||||
other = self.machinery.SourceFileLoader(self.name, self.filepath)
|
||||
self.assertEqual(self.loader, other)
|
||||
|
||||
def test_inequality(self):
|
||||
other = self.machinery.SourceFileLoader('_' + self.name, self.filepath)
|
||||
self.assertNotEqual(self.loader, other)
|
||||
|
||||
# [basic]
|
||||
def test_module(self):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module('_temp')
|
||||
self.assertIn('_temp', sys.modules)
|
||||
check = {'__name__': '_temp', '__file__': mapping['_temp'],
|
||||
'__package__': ''}
|
||||
for attr, value in check.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
|
||||
def test_package(self):
|
||||
with util.create_modules('_pkg.__init__') as mapping:
|
||||
loader = self.machinery.SourceFileLoader('_pkg',
|
||||
mapping['_pkg.__init__'])
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module('_pkg')
|
||||
self.assertIn('_pkg', sys.modules)
|
||||
check = {'__name__': '_pkg', '__file__': mapping['_pkg.__init__'],
|
||||
'__path__': [os.path.dirname(mapping['_pkg.__init__'])],
|
||||
'__package__': '_pkg'}
|
||||
for attr, value in check.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
|
||||
|
||||
def test_lacking_parent(self):
|
||||
with util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
|
||||
loader = self.machinery.SourceFileLoader('_pkg.mod',
|
||||
mapping['_pkg.mod'])
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module('_pkg.mod')
|
||||
self.assertIn('_pkg.mod', sys.modules)
|
||||
check = {'__name__': '_pkg.mod', '__file__': mapping['_pkg.mod'],
|
||||
'__package__': '_pkg'}
|
||||
for attr, value in check.items():
|
||||
self.assertEqual(getattr(module, attr), value)
|
||||
|
||||
def fake_mtime(self, fxn):
|
||||
"""Fake mtime to always be higher than expected."""
|
||||
return lambda name: fxn(name) + 1
|
||||
|
||||
def test_module_reuse(self):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module('_temp')
|
||||
module_id = id(module)
|
||||
module_dict_id = id(module.__dict__)
|
||||
with open(mapping['_temp'], 'w') as file:
|
||||
file.write("testing_var = 42\n")
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module('_temp')
|
||||
self.assertIn('testing_var', module.__dict__,
|
||||
"'testing_var' not in "
|
||||
"{0}".format(list(module.__dict__.keys())))
|
||||
self.assertEqual(module, sys.modules['_temp'])
|
||||
self.assertEqual(id(module), module_id)
|
||||
self.assertEqual(id(module.__dict__), module_dict_id)
|
||||
|
||||
def test_state_after_failure(self):
|
||||
# A failed reload should leave the original module intact.
|
||||
attributes = ('__file__', '__path__', '__package__')
|
||||
value = '<test>'
|
||||
name = '_temp'
|
||||
with util.create_modules(name) as mapping:
|
||||
orig_module = types.ModuleType(name)
|
||||
for attr in attributes:
|
||||
setattr(orig_module, attr, value)
|
||||
with open(mapping[name], 'w') as file:
|
||||
file.write('+++ bad syntax +++')
|
||||
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
|
||||
with self.assertRaises(SyntaxError):
|
||||
loader.exec_module(orig_module)
|
||||
for attr in attributes:
|
||||
self.assertEqual(getattr(orig_module, attr), value)
|
||||
with self.assertRaises(SyntaxError):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
loader.load_module(name)
|
||||
for attr in attributes:
|
||||
self.assertEqual(getattr(orig_module, attr), value)
|
||||
|
||||
# [syntax error]
|
||||
def test_bad_syntax(self):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
with open(mapping['_temp'], 'w') as file:
|
||||
file.write('=')
|
||||
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
|
||||
with self.assertRaises(SyntaxError):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
loader.load_module('_temp')
|
||||
self.assertNotIn('_temp', sys.modules)
|
||||
|
||||
def test_file_from_empty_string_dir(self):
|
||||
# Loading a module found from an empty string entry on sys.path should
|
||||
# not only work, but keep all attributes relative.
|
||||
file_path = '_temp.py'
|
||||
with open(file_path, 'w') as file:
|
||||
file.write("# test file for importlib")
|
||||
try:
|
||||
with util.uncache('_temp'):
|
||||
loader = self.machinery.SourceFileLoader('_temp', file_path)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
mod = loader.load_module('_temp')
|
||||
self.assertEqual(file_path, mod.__file__)
|
||||
self.assertEqual(self.util.cache_from_source(file_path),
|
||||
mod.__cached__)
|
||||
finally:
|
||||
os.unlink(file_path)
|
||||
pycache = os.path.dirname(self.util.cache_from_source(file_path))
|
||||
if os.path.exists(pycache):
|
||||
shutil.rmtree(pycache)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_timestamp_overflow(self):
|
||||
# When a modification timestamp is larger than 2**32, it should be
|
||||
# truncated rather than raise an OverflowError.
|
||||
with util.create_modules('_temp') as mapping:
|
||||
source = mapping['_temp']
|
||||
compiled = self.util.cache_from_source(source)
|
||||
with open(source, 'w') as f:
|
||||
f.write("x = 5")
|
||||
try:
|
||||
os.utime(source, (2 ** 33 - 5, 2 ** 33 - 5))
|
||||
except OverflowError:
|
||||
self.skipTest("cannot set modification time to large integer")
|
||||
except OSError as e:
|
||||
if e.errno != getattr(errno, 'EOVERFLOW', None):
|
||||
raise
|
||||
self.skipTest("cannot set modification time to large integer ({})".format(e))
|
||||
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
|
||||
# PEP 451
|
||||
module = types.ModuleType('_temp')
|
||||
module.__spec__ = self.util.spec_from_loader('_temp', loader)
|
||||
loader.exec_module(module)
|
||||
self.assertEqual(module.x, 5)
|
||||
self.assertTrue(os.path.exists(compiled))
|
||||
os.unlink(compiled)
|
||||
# PEP 302
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
mod = loader.load_module('_temp')
|
||||
# Sanity checks.
|
||||
self.assertEqual(mod.__cached__, compiled)
|
||||
self.assertEqual(mod.x, 5)
|
||||
# The pyc file was created.
|
||||
self.assertTrue(os.path.exists(compiled))
|
||||
|
||||
def test_unloadable(self):
|
||||
loader = self.machinery.SourceFileLoader('good name', {})
|
||||
module = types.ModuleType('bad name')
|
||||
module.__spec__ = self.machinery.ModuleSpec('bad name', loader)
|
||||
with self.assertRaises(ImportError):
|
||||
loader.exec_module(module)
|
||||
with self.assertRaises(ImportError):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
loader.load_module('bad name')
|
||||
|
||||
|
||||
(Frozen_SimpleTest,
|
||||
Source_SimpleTest
|
||||
) = util.test_both(SimpleTest, importlib=importlib, machinery=machinery,
|
||||
abc=importlib_abc, util=importlib_util)
|
||||
|
||||
|
||||
class BadBytecodeTest:
|
||||
|
||||
def import_(self, file, module_name):
|
||||
raise NotImplementedError
|
||||
|
||||
def manipulate_bytecode(self, name, mapping, manipulator, *,
|
||||
del_source=False):
|
||||
"""Manipulate the bytecode of a module by passing it into a callable
|
||||
that returns what to use as the new bytecode."""
|
||||
try:
|
||||
del sys.modules['_temp']
|
||||
except KeyError:
|
||||
pass
|
||||
py_compile.compile(mapping[name])
|
||||
if not del_source:
|
||||
bytecode_path = self.util.cache_from_source(mapping[name])
|
||||
else:
|
||||
os.unlink(mapping[name])
|
||||
bytecode_path = make_legacy_pyc(mapping[name])
|
||||
if manipulator:
|
||||
with open(bytecode_path, 'rb') as file:
|
||||
bc = file.read()
|
||||
new_bc = manipulator(bc)
|
||||
with open(bytecode_path, 'wb') as file:
|
||||
if new_bc is not None:
|
||||
file.write(new_bc)
|
||||
return bytecode_path
|
||||
|
||||
def _test_empty_file(self, test, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: b'',
|
||||
del_source=del_source)
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def _test_partial_magic(self, test, *, del_source=False):
|
||||
# When their are less than 4 bytes to a .pyc, regenerate it if
|
||||
# possible, else raise ImportError.
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:3],
|
||||
del_source=del_source)
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
def _test_magic_only(self, test, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:4],
|
||||
del_source=del_source)
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
def _test_partial_timestamp(self, test, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:7],
|
||||
del_source=del_source)
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
def _test_partial_size(self, test, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:11],
|
||||
del_source=del_source)
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
def _test_no_marshal(self, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:12],
|
||||
del_source=del_source)
|
||||
file_path = mapping['_temp'] if not del_source else bc_path
|
||||
with self.assertRaises(EOFError):
|
||||
self.import_(file_path, '_temp')
|
||||
|
||||
def _test_non_code_marshal(self, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bytecode_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:12] + marshal.dumps(b'abcd'),
|
||||
del_source=del_source)
|
||||
file_path = mapping['_temp'] if not del_source else bytecode_path
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.import_(file_path, '_temp')
|
||||
self.assertEqual(cm.exception.name, '_temp')
|
||||
self.assertEqual(cm.exception.path, bytecode_path)
|
||||
|
||||
def _test_bad_marshal(self, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bytecode_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: bc[:12] + b'<test>',
|
||||
del_source=del_source)
|
||||
file_path = mapping['_temp'] if not del_source else bytecode_path
|
||||
with self.assertRaises(EOFError):
|
||||
self.import_(file_path, '_temp')
|
||||
|
||||
def _test_bad_magic(self, test, *, del_source=False):
|
||||
with util.create_modules('_temp') as mapping:
|
||||
bc_path = self.manipulate_bytecode('_temp', mapping,
|
||||
lambda bc: b'\x00\x00\x00\x00' + bc[4:])
|
||||
test('_temp', mapping, bc_path)
|
||||
|
||||
|
||||
class BadBytecodeTestPEP451(BadBytecodeTest):
|
||||
|
||||
def import_(self, file, module_name):
|
||||
loader = self.loader(module_name, file)
|
||||
module = types.ModuleType(module_name)
|
||||
module.__spec__ = self.util.spec_from_loader(module_name, loader)
|
||||
loader.exec_module(module)
|
||||
|
||||
|
||||
class BadBytecodeTestPEP302(BadBytecodeTest):
|
||||
|
||||
def import_(self, file, module_name):
|
||||
loader = self.loader(module_name, file)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = loader.load_module(module_name)
|
||||
self.assertIn(module_name, sys.modules)
|
||||
|
||||
|
||||
class SourceLoaderBadBytecodeTest:
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.loader = cls.machinery.SourceFileLoader
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_empty_file(self):
|
||||
# When a .pyc is empty, regenerate it if possible, else raise
|
||||
# ImportError.
|
||||
def test(name, mapping, bytecode_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bytecode_path, 'rb') as file:
|
||||
self.assertGreater(len(file.read()), 12)
|
||||
|
||||
self._test_empty_file(test)
|
||||
|
||||
def test_partial_magic(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bytecode_path, 'rb') as file:
|
||||
self.assertGreater(len(file.read()), 12)
|
||||
|
||||
self._test_partial_magic(test)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_magic_only(self):
|
||||
# When there is only the magic number, regenerate the .pyc if possible,
|
||||
# else raise EOFError.
|
||||
def test(name, mapping, bytecode_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bytecode_path, 'rb') as file:
|
||||
self.assertGreater(len(file.read()), 12)
|
||||
|
||||
self._test_magic_only(test)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_bad_magic(self):
|
||||
# When the magic number is different, the bytecode should be
|
||||
# regenerated.
|
||||
def test(name, mapping, bytecode_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bytecode_path, 'rb') as bytecode_file:
|
||||
self.assertEqual(bytecode_file.read(4),
|
||||
self.util.MAGIC_NUMBER)
|
||||
|
||||
self._test_bad_magic(test)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_partial_timestamp(self):
|
||||
# When the timestamp is partial, regenerate the .pyc, else
|
||||
# raise EOFError.
|
||||
def test(name, mapping, bc_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bc_path, 'rb') as file:
|
||||
self.assertGreater(len(file.read()), 12)
|
||||
|
||||
self._test_partial_timestamp(test)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_partial_size(self):
|
||||
# When the size is partial, regenerate the .pyc, else
|
||||
# raise EOFError.
|
||||
def test(name, mapping, bc_path):
|
||||
self.import_(mapping[name], name)
|
||||
with open(bc_path, 'rb') as file:
|
||||
self.assertGreater(len(file.read()), 12)
|
||||
|
||||
self._test_partial_size(test)
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_no_marshal(self):
|
||||
# When there is only the magic number and timestamp, raise EOFError.
|
||||
self._test_no_marshal()
|
||||
|
||||
@util.writes_bytecode_files
|
||||
def test_non_code_marshal(self):
|
||||
self._test_non_code_marshal()
|
||||
# XXX ImportError when sourceless
|
||||
|
||||
# [bad marshal]
|
||||
@util.writes_bytecode_files
|
||||
def test_bad_marshal(self):
|
||||
# Bad marshal data should raise a ValueError.
|
||||
self._test_bad_marshal()
|
||||
|
||||
# [bad timestamp]
|
||||
@util.writes_bytecode_files
|
||||
def test_old_timestamp(self):
|
||||
# When the timestamp is older than the source, bytecode should be
|
||||
# regenerated.
|
||||
zeros = b'\x00\x00\x00\x00'
|
||||
with util.create_modules('_temp') as mapping:
|
||||
py_compile.compile(mapping['_temp'])
|
||||
bytecode_path = self.util.cache_from_source(mapping['_temp'])
|
||||
with open(bytecode_path, 'r+b') as bytecode_file:
|
||||
bytecode_file.seek(4)
|
||||
bytecode_file.write(zeros)
|
||||
self.import_(mapping['_temp'], '_temp')
|
||||
source_mtime = os.path.getmtime(mapping['_temp'])
|
||||
source_timestamp = self.importlib._w_long(source_mtime)
|
||||
with open(bytecode_path, 'rb') as bytecode_file:
|
||||
bytecode_file.seek(4)
|
||||
self.assertEqual(bytecode_file.read(4), source_timestamp)
|
||||
|
||||
# [bytecode read-only]
|
||||
@util.writes_bytecode_files
|
||||
def test_read_only_bytecode(self):
|
||||
# When bytecode is read-only but should be rewritten, fail silently.
|
||||
with util.create_modules('_temp') as mapping:
|
||||
# Create bytecode that will need to be re-created.
|
||||
py_compile.compile(mapping['_temp'])
|
||||
bytecode_path = self.util.cache_from_source(mapping['_temp'])
|
||||
with open(bytecode_path, 'r+b') as bytecode_file:
|
||||
bytecode_file.seek(0)
|
||||
bytecode_file.write(b'\x00\x00\x00\x00')
|
||||
# Make the bytecode read-only.
|
||||
os.chmod(bytecode_path,
|
||||
stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||
try:
|
||||
# Should not raise OSError!
|
||||
self.import_(mapping['_temp'], '_temp')
|
||||
finally:
|
||||
# Make writable for eventual clean-up.
|
||||
os.chmod(bytecode_path, stat.S_IWUSR)
|
||||
|
||||
|
||||
class SourceLoaderBadBytecodeTestPEP451(
|
||||
SourceLoaderBadBytecodeTest, BadBytecodeTestPEP451):
|
||||
pass
|
||||
|
||||
|
||||
(Frozen_SourceBadBytecodePEP451,
|
||||
Source_SourceBadBytecodePEP451
|
||||
) = util.test_both(SourceLoaderBadBytecodeTestPEP451, importlib=importlib,
|
||||
machinery=machinery, abc=importlib_abc,
|
||||
util=importlib_util)
|
||||
|
||||
|
||||
class SourceLoaderBadBytecodeTestPEP302(
|
||||
SourceLoaderBadBytecodeTest, BadBytecodeTestPEP302):
|
||||
pass
|
||||
|
||||
|
||||
(Frozen_SourceBadBytecodePEP302,
|
||||
Source_SourceBadBytecodePEP302
|
||||
) = util.test_both(SourceLoaderBadBytecodeTestPEP302, importlib=importlib,
|
||||
machinery=machinery, abc=importlib_abc,
|
||||
util=importlib_util)
|
||||
|
||||
|
||||
class SourcelessLoaderBadBytecodeTest:
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.loader = cls.machinery.SourcelessFileLoader
|
||||
|
||||
def test_empty_file(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.import_(bytecode_path, name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
self.assertEqual(cm.exception.path, bytecode_path)
|
||||
|
||||
self._test_empty_file(test, del_source=True)
|
||||
|
||||
def test_partial_magic(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.import_(bytecode_path, name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
self.assertEqual(cm.exception.path, bytecode_path)
|
||||
self._test_partial_magic(test, del_source=True)
|
||||
|
||||
def test_magic_only(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(EOFError):
|
||||
self.import_(bytecode_path, name)
|
||||
|
||||
self._test_magic_only(test, del_source=True)
|
||||
|
||||
def test_bad_magic(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.import_(bytecode_path, name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
self.assertEqual(cm.exception.path, bytecode_path)
|
||||
|
||||
self._test_bad_magic(test, del_source=True)
|
||||
|
||||
def test_partial_timestamp(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(EOFError):
|
||||
self.import_(bytecode_path, name)
|
||||
|
||||
self._test_partial_timestamp(test, del_source=True)
|
||||
|
||||
def test_partial_size(self):
|
||||
def test(name, mapping, bytecode_path):
|
||||
with self.assertRaises(EOFError):
|
||||
self.import_(bytecode_path, name)
|
||||
|
||||
self._test_partial_size(test, del_source=True)
|
||||
|
||||
def test_no_marshal(self):
|
||||
self._test_no_marshal(del_source=True)
|
||||
|
||||
def test_non_code_marshal(self):
|
||||
self._test_non_code_marshal(del_source=True)
|
||||
|
||||
|
||||
class SourcelessLoaderBadBytecodeTestPEP451(SourcelessLoaderBadBytecodeTest,
|
||||
BadBytecodeTestPEP451):
|
||||
pass
|
||||
|
||||
|
||||
(Frozen_SourcelessBadBytecodePEP451,
|
||||
Source_SourcelessBadBytecodePEP451
|
||||
) = util.test_both(SourcelessLoaderBadBytecodeTestPEP451, importlib=importlib,
|
||||
machinery=machinery, abc=importlib_abc,
|
||||
util=importlib_util)
|
||||
|
||||
|
||||
class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest,
|
||||
BadBytecodeTestPEP302):
|
||||
pass
|
||||
|
||||
|
||||
(Frozen_SourcelessBadBytecodePEP302,
|
||||
Source_SourcelessBadBytecodePEP302
|
||||
) = util.test_both(SourcelessLoaderBadBytecodeTestPEP302, importlib=importlib,
|
||||
machinery=machinery, abc=importlib_abc,
|
||||
util=importlib_util)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
236
third_party/python/Lib/test/test_importlib/source/test_finder.py
vendored
Normal file
236
third_party/python/Lib/test/test_importlib/source/test_finder.py
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
from .. import abc
|
||||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import errno
|
||||
import os
|
||||
import py_compile
|
||||
import stat
|
||||
import sys
|
||||
import tempfile
|
||||
from test.support import make_legacy_pyc
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class FinderTests(abc.FinderTests):
|
||||
|
||||
"""For a top-level module, it should just be found directly in the
|
||||
directory being searched. This is true for a directory with source
|
||||
[top-level source], bytecode [top-level bc], or both [top-level both].
|
||||
There is also the possibility that it is a package [top-level package], in
|
||||
which case there will be a directory with the module name and an
|
||||
__init__.py file. If there is a directory without an __init__.py an
|
||||
ImportWarning is returned [empty dir].
|
||||
|
||||
For sub-modules and sub-packages, the same happens as above but only use
|
||||
the tail end of the name [sub module] [sub package] [sub empty].
|
||||
|
||||
When there is a conflict between a package and module having the same name
|
||||
in the same directory, the package wins out [package over module]. This is
|
||||
so that imports of modules within the package can occur rather than trigger
|
||||
an import error.
|
||||
|
||||
When there is a package and module with the same name, always pick the
|
||||
package over the module [package over module]. This is so that imports from
|
||||
the package have the possibility of succeeding.
|
||||
|
||||
"""
|
||||
|
||||
def get_finder(self, root):
|
||||
loader_details = [(self.machinery.SourceFileLoader,
|
||||
self.machinery.SOURCE_SUFFIXES),
|
||||
(self.machinery.SourcelessFileLoader,
|
||||
self.machinery.BYTECODE_SUFFIXES)]
|
||||
return self.machinery.FileFinder(root, *loader_details)
|
||||
|
||||
def import_(self, root, module):
|
||||
finder = self.get_finder(root)
|
||||
return self._find(finder, module, loader_only=True)
|
||||
|
||||
def run_test(self, test, create=None, *, compile_=None, unlink=None):
|
||||
"""Test the finding of 'test' with the creation of modules listed in
|
||||
'create'.
|
||||
|
||||
Any names listed in 'compile_' are byte-compiled. Modules
|
||||
listed in 'unlink' have their source files deleted.
|
||||
|
||||
"""
|
||||
if create is None:
|
||||
create = {test}
|
||||
with util.create_modules(*create) as mapping:
|
||||
if compile_:
|
||||
for name in compile_:
|
||||
py_compile.compile(mapping[name])
|
||||
if unlink:
|
||||
for name in unlink:
|
||||
os.unlink(mapping[name])
|
||||
try:
|
||||
make_legacy_pyc(mapping[name])
|
||||
except OSError as error:
|
||||
# Some tests do not set compile_=True so the source
|
||||
# module will not get compiled and there will be no
|
||||
# PEP 3147 pyc file to rename.
|
||||
if error.errno != errno.ENOENT:
|
||||
raise
|
||||
loader = self.import_(mapping['.root'], test)
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
return loader
|
||||
|
||||
def test_module(self):
|
||||
# [top-level source]
|
||||
self.run_test('top_level')
|
||||
# [top-level bc]
|
||||
self.run_test('top_level', compile_={'top_level'},
|
||||
unlink={'top_level'})
|
||||
# [top-level both]
|
||||
self.run_test('top_level', compile_={'top_level'})
|
||||
|
||||
# [top-level package]
|
||||
def test_package(self):
|
||||
# Source.
|
||||
self.run_test('pkg', {'pkg.__init__'})
|
||||
# Bytecode.
|
||||
self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'},
|
||||
unlink={'pkg.__init__'})
|
||||
# Both.
|
||||
self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'})
|
||||
|
||||
# [sub module]
|
||||
def test_module_in_package(self):
|
||||
with util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
|
||||
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
|
||||
loader = self.import_(pkg_dir, 'pkg.sub')
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
# [sub package]
|
||||
def test_package_in_package(self):
|
||||
context = util.create_modules('pkg.__init__', 'pkg.sub.__init__')
|
||||
with context as mapping:
|
||||
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
|
||||
loader = self.import_(pkg_dir, 'pkg.sub')
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
|
||||
# [package over modules]
|
||||
def test_package_over_module(self):
|
||||
name = '_temp'
|
||||
loader = self.run_test(name, {'{0}.__init__'.format(name), name})
|
||||
self.assertIn('__init__', loader.get_filename(name))
|
||||
|
||||
def test_failure(self):
|
||||
with util.create_modules('blah') as mapping:
|
||||
nothing = self.import_(mapping['.root'], 'sdfsadsadf')
|
||||
self.assertIsNone(nothing)
|
||||
|
||||
def test_empty_string_for_dir(self):
|
||||
# The empty string from sys.path means to search in the cwd.
|
||||
finder = self.machinery.FileFinder('', (self.machinery.SourceFileLoader,
|
||||
self.machinery.SOURCE_SUFFIXES))
|
||||
with open('mod.py', 'w') as file:
|
||||
file.write("# test file for importlib")
|
||||
try:
|
||||
loader = self._find(finder, 'mod', loader_only=True)
|
||||
self.assertTrue(hasattr(loader, 'load_module'))
|
||||
finally:
|
||||
os.unlink('mod.py')
|
||||
|
||||
def test_invalidate_caches(self):
|
||||
# invalidate_caches() should reset the mtime.
|
||||
finder = self.machinery.FileFinder('', (self.machinery.SourceFileLoader,
|
||||
self.machinery.SOURCE_SUFFIXES))
|
||||
finder._path_mtime = 42
|
||||
finder.invalidate_caches()
|
||||
self.assertEqual(finder._path_mtime, -1)
|
||||
|
||||
# Regression test for http://bugs.python.org/issue14846
|
||||
def test_dir_removal_handling(self):
|
||||
mod = 'mod'
|
||||
with util.create_modules(mod) as mapping:
|
||||
finder = self.get_finder(mapping['.root'])
|
||||
found = self._find(finder, 'mod', loader_only=True)
|
||||
self.assertIsNotNone(found)
|
||||
found = self._find(finder, 'mod', loader_only=True)
|
||||
self.assertIsNone(found)
|
||||
|
||||
@unittest.skipUnless(sys.platform != 'win32',
|
||||
'os.chmod() does not support the needed arguments under Windows')
|
||||
def test_no_read_directory(self):
|
||||
# Issue #16730
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
original_mode = os.stat(tempdir.name).st_mode
|
||||
def cleanup(tempdir):
|
||||
"""Cleanup function for the temporary directory.
|
||||
|
||||
Since we muck with the permissions, we want to set them back to
|
||||
their original values to make sure the directory can be properly
|
||||
cleaned up.
|
||||
|
||||
"""
|
||||
os.chmod(tempdir.name, original_mode)
|
||||
# If this is not explicitly called then the __del__ method is used,
|
||||
# but since already mucking around might as well explicitly clean
|
||||
# up.
|
||||
tempdir.__exit__(None, None, None)
|
||||
self.addCleanup(cleanup, tempdir)
|
||||
os.chmod(tempdir.name, stat.S_IWUSR | stat.S_IXUSR)
|
||||
finder = self.get_finder(tempdir.name)
|
||||
found = self._find(finder, 'doesnotexist')
|
||||
self.assertEqual(found, self.NOT_FOUND)
|
||||
|
||||
def test_ignore_file(self):
|
||||
# If a directory got changed to a file from underneath us, then don't
|
||||
# worry about looking for submodules.
|
||||
with tempfile.NamedTemporaryFile() as file_obj:
|
||||
finder = self.get_finder(file_obj.name)
|
||||
found = self._find(finder, 'doesnotexist')
|
||||
self.assertEqual(found, self.NOT_FOUND)
|
||||
|
||||
|
||||
class FinderTestsPEP451(FinderTests):
|
||||
|
||||
NOT_FOUND = None
|
||||
|
||||
def _find(self, finder, name, loader_only=False):
|
||||
spec = finder.find_spec(name)
|
||||
return spec.loader if spec is not None else spec
|
||||
|
||||
|
||||
(Frozen_FinderTestsPEP451,
|
||||
Source_FinderTestsPEP451
|
||||
) = util.test_both(FinderTestsPEP451, machinery=machinery)
|
||||
|
||||
|
||||
class FinderTestsPEP420(FinderTests):
|
||||
|
||||
NOT_FOUND = (None, [])
|
||||
|
||||
def _find(self, finder, name, loader_only=False):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
loader_portions = finder.find_loader(name)
|
||||
return loader_portions[0] if loader_only else loader_portions
|
||||
|
||||
|
||||
(Frozen_FinderTestsPEP420,
|
||||
Source_FinderTestsPEP420
|
||||
) = util.test_both(FinderTestsPEP420, machinery=machinery)
|
||||
|
||||
|
||||
class FinderTestsPEP302(FinderTests):
|
||||
|
||||
NOT_FOUND = None
|
||||
|
||||
def _find(self, finder, name, loader_only=False):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
return finder.find_module(name)
|
||||
|
||||
|
||||
(Frozen_FinderTestsPEP302,
|
||||
Source_FinderTestsPEP302
|
||||
) = util.test_both(FinderTestsPEP302, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
41
third_party/python/Lib/test/test_importlib/source/test_path_hook.py
vendored
Normal file
41
third_party/python/Lib/test/test_importlib/source/test_path_hook.py
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class PathHookTest:
|
||||
|
||||
"""Test the path hook for source."""
|
||||
|
||||
def path_hook(self):
|
||||
return self.machinery.FileFinder.path_hook((self.machinery.SourceFileLoader,
|
||||
self.machinery.SOURCE_SUFFIXES))
|
||||
|
||||
def test_success(self):
|
||||
with util.create_modules('dummy') as mapping:
|
||||
self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
|
||||
'find_spec'))
|
||||
|
||||
def test_success_legacy(self):
|
||||
with util.create_modules('dummy') as mapping:
|
||||
self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
|
||||
'find_module'))
|
||||
|
||||
def test_empty_string(self):
|
||||
# The empty string represents the cwd.
|
||||
self.assertTrue(hasattr(self.path_hook()(''), 'find_spec'))
|
||||
|
||||
def test_empty_string_legacy(self):
|
||||
# The empty string represents the cwd.
|
||||
self.assertTrue(hasattr(self.path_hook()(''), 'find_module'))
|
||||
|
||||
|
||||
(Frozen_PathHookTest,
|
||||
Source_PathHooktest
|
||||
) = util.test_both(PathHookTest, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
175
third_party/python/Lib/test/test_importlib/source/test_source_encoding.py
vendored
Normal file
175
third_party/python/Lib/test/test_importlib/source/test_source_encoding.py
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
from .. import util
|
||||
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
|
||||
import codecs
|
||||
import importlib.util
|
||||
import re
|
||||
import types
|
||||
# Because sys.path gets essentially blanked, need to have unicodedata already
|
||||
# imported for the parser to use.
|
||||
import unicodedata
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
CODING_RE = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
|
||||
|
||||
|
||||
class EncodingTest:
|
||||
|
||||
"""PEP 3120 makes UTF-8 the default encoding for source code
|
||||
[default encoding].
|
||||
|
||||
PEP 263 specifies how that can change on a per-file basis. Either the first
|
||||
or second line can contain the encoding line [encoding first line]
|
||||
encoding second line]. If the file has the BOM marker it is considered UTF-8
|
||||
implicitly [BOM]. If any encoding is specified it must be UTF-8, else it is
|
||||
an error [BOM and utf-8][BOM conflict].
|
||||
|
||||
"""
|
||||
|
||||
variable = '\u00fc'
|
||||
character = '\u00c9'
|
||||
source_line = "{0} = '{1}'\n".format(variable, character)
|
||||
module_name = '_temp'
|
||||
|
||||
def run_test(self, source):
|
||||
with util.create_modules(self.module_name) as mapping:
|
||||
with open(mapping[self.module_name], 'wb') as file:
|
||||
file.write(source)
|
||||
loader = self.machinery.SourceFileLoader(self.module_name,
|
||||
mapping[self.module_name])
|
||||
return self.load(loader)
|
||||
|
||||
def create_source(self, encoding):
|
||||
encoding_line = "# coding={0}".format(encoding)
|
||||
assert CODING_RE.match(encoding_line)
|
||||
source_lines = [encoding_line.encode('utf-8')]
|
||||
source_lines.append(self.source_line.encode(encoding))
|
||||
return b'\n'.join(source_lines)
|
||||
|
||||
def test_non_obvious_encoding(self):
|
||||
# Make sure that an encoding that has never been a standard one for
|
||||
# Python works.
|
||||
encoding_line = "# coding=koi8-r"
|
||||
assert CODING_RE.match(encoding_line)
|
||||
source = "{0}\na=42\n".format(encoding_line).encode("koi8-r")
|
||||
self.run_test(source)
|
||||
|
||||
# [default encoding]
|
||||
def test_default_encoding(self):
|
||||
self.run_test(self.source_line.encode('utf-8'))
|
||||
|
||||
# [encoding first line]
|
||||
def test_encoding_on_first_line(self):
|
||||
encoding = 'Latin-1'
|
||||
source = self.create_source(encoding)
|
||||
self.run_test(source)
|
||||
|
||||
# [encoding second line]
|
||||
def test_encoding_on_second_line(self):
|
||||
source = b"#/usr/bin/python\n" + self.create_source('Latin-1')
|
||||
self.run_test(source)
|
||||
|
||||
# [BOM]
|
||||
def test_bom(self):
|
||||
self.run_test(codecs.BOM_UTF8 + self.source_line.encode('utf-8'))
|
||||
|
||||
# [BOM and utf-8]
|
||||
def test_bom_and_utf_8(self):
|
||||
source = codecs.BOM_UTF8 + self.create_source('utf-8')
|
||||
self.run_test(source)
|
||||
|
||||
# [BOM conflict]
|
||||
def test_bom_conflict(self):
|
||||
source = codecs.BOM_UTF8 + self.create_source('latin-1')
|
||||
with self.assertRaises(SyntaxError):
|
||||
self.run_test(source)
|
||||
|
||||
|
||||
class EncodingTestPEP451(EncodingTest):
|
||||
|
||||
def load(self, loader):
|
||||
module = types.ModuleType(self.module_name)
|
||||
module.__spec__ = importlib.util.spec_from_loader(self.module_name, loader)
|
||||
loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
(Frozen_EncodingTestPEP451,
|
||||
Source_EncodingTestPEP451
|
||||
) = util.test_both(EncodingTestPEP451, machinery=machinery)
|
||||
|
||||
|
||||
class EncodingTestPEP302(EncodingTest):
|
||||
|
||||
def load(self, loader):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
return loader.load_module(self.module_name)
|
||||
|
||||
|
||||
(Frozen_EncodingTestPEP302,
|
||||
Source_EncodingTestPEP302
|
||||
) = util.test_both(EncodingTestPEP302, machinery=machinery)
|
||||
|
||||
|
||||
class LineEndingTest:
|
||||
|
||||
r"""Source written with the three types of line endings (\n, \r\n, \r)
|
||||
need to be readable [cr][crlf][lf]."""
|
||||
|
||||
def run_test(self, line_ending):
|
||||
module_name = '_temp'
|
||||
source_lines = [b"a = 42", b"b = -13", b'']
|
||||
source = line_ending.join(source_lines)
|
||||
with util.create_modules(module_name) as mapping:
|
||||
with open(mapping[module_name], 'wb') as file:
|
||||
file.write(source)
|
||||
loader = self.machinery.SourceFileLoader(module_name,
|
||||
mapping[module_name])
|
||||
return self.load(loader, module_name)
|
||||
|
||||
# [cr]
|
||||
def test_cr(self):
|
||||
self.run_test(b'\r')
|
||||
|
||||
# [crlf]
|
||||
def test_crlf(self):
|
||||
self.run_test(b'\r\n')
|
||||
|
||||
# [lf]
|
||||
def test_lf(self):
|
||||
self.run_test(b'\n')
|
||||
|
||||
|
||||
class LineEndingTestPEP451(LineEndingTest):
|
||||
|
||||
def load(self, loader, module_name):
|
||||
module = types.ModuleType(module_name)
|
||||
module.__spec__ = importlib.util.spec_from_loader(module_name, loader)
|
||||
loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
(Frozen_LineEndingTestPEP451,
|
||||
Source_LineEndingTestPEP451
|
||||
) = util.test_both(LineEndingTestPEP451, machinery=machinery)
|
||||
|
||||
|
||||
class LineEndingTestPEP302(LineEndingTest):
|
||||
|
||||
def load(self, loader, module_name):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
return loader.load_module(module_name)
|
||||
|
||||
|
||||
(Frozen_LineEndingTestPEP302,
|
||||
Source_LineEndingTestPEP302
|
||||
) = util.test_both(LineEndingTestPEP302, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
953
third_party/python/Lib/test/test_importlib/test_abc.py
vendored
Normal file
953
third_party/python/Lib/test/test_importlib/test_abc.py
vendored
Normal file
|
@ -0,0 +1,953 @@
|
|||
import contextlib
|
||||
import inspect
|
||||
import io
|
||||
import marshal
|
||||
import os
|
||||
import sys
|
||||
from test import support
|
||||
import types
|
||||
import unittest
|
||||
from unittest import mock
|
||||
import warnings
|
||||
|
||||
from . import util as test_util
|
||||
|
||||
init = test_util.import_importlib('importlib')
|
||||
abc = test_util.import_importlib('importlib.abc')
|
||||
machinery = test_util.import_importlib('importlib.machinery')
|
||||
util = test_util.import_importlib('importlib.util')
|
||||
|
||||
|
||||
##### Inheritance ##############################################################
|
||||
class InheritanceTests:
|
||||
|
||||
"""Test that the specified class is a subclass/superclass of the expected
|
||||
classes."""
|
||||
|
||||
subclasses = []
|
||||
superclasses = []
|
||||
|
||||
def setUp(self):
|
||||
self.superclasses = [getattr(self.abc, class_name)
|
||||
for class_name in self.superclass_names]
|
||||
if hasattr(self, 'subclass_names'):
|
||||
# Because test.support.import_fresh_module() creates a new
|
||||
# importlib._bootstrap per module, inheritance checks fail when
|
||||
# checking across module boundaries (i.e. the _bootstrap in abc is
|
||||
# not the same as the one in machinery). That means stealing one of
|
||||
# the modules from the other to make sure the same instance is used.
|
||||
machinery = self.abc.machinery
|
||||
self.subclasses = [getattr(machinery, class_name)
|
||||
for class_name in self.subclass_names]
|
||||
assert self.subclasses or self.superclasses, self.__class__
|
||||
self.__test = getattr(self.abc, self._NAME)
|
||||
|
||||
def test_subclasses(self):
|
||||
# Test that the expected subclasses inherit.
|
||||
for subclass in self.subclasses:
|
||||
self.assertTrue(issubclass(subclass, self.__test),
|
||||
"{0} is not a subclass of {1}".format(subclass, self.__test))
|
||||
|
||||
def test_superclasses(self):
|
||||
# Test that the class inherits from the expected superclasses.
|
||||
for superclass in self.superclasses:
|
||||
self.assertTrue(issubclass(self.__test, superclass),
|
||||
"{0} is not a superclass of {1}".format(superclass, self.__test))
|
||||
|
||||
|
||||
class MetaPathFinder(InheritanceTests):
|
||||
superclass_names = ['Finder']
|
||||
subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder',
|
||||
'WindowsRegistryFinder']
|
||||
|
||||
|
||||
(Frozen_MetaPathFinderInheritanceTests,
|
||||
Source_MetaPathFinderInheritanceTests
|
||||
) = test_util.test_both(MetaPathFinder, abc=abc)
|
||||
|
||||
|
||||
class PathEntryFinder(InheritanceTests):
|
||||
superclass_names = ['Finder']
|
||||
subclass_names = ['FileFinder']
|
||||
|
||||
|
||||
(Frozen_PathEntryFinderInheritanceTests,
|
||||
Source_PathEntryFinderInheritanceTests
|
||||
) = test_util.test_both(PathEntryFinder, abc=abc)
|
||||
|
||||
|
||||
class ResourceLoader(InheritanceTests):
|
||||
superclass_names = ['Loader']
|
||||
|
||||
|
||||
(Frozen_ResourceLoaderInheritanceTests,
|
||||
Source_ResourceLoaderInheritanceTests
|
||||
) = test_util.test_both(ResourceLoader, abc=abc)
|
||||
|
||||
|
||||
class InspectLoader(InheritanceTests):
|
||||
superclass_names = ['Loader']
|
||||
subclass_names = ['BuiltinImporter', 'FrozenImporter', 'ExtensionFileLoader']
|
||||
|
||||
|
||||
(Frozen_InspectLoaderInheritanceTests,
|
||||
Source_InspectLoaderInheritanceTests
|
||||
) = test_util.test_both(InspectLoader, abc=abc)
|
||||
|
||||
|
||||
class ExecutionLoader(InheritanceTests):
|
||||
superclass_names = ['InspectLoader']
|
||||
subclass_names = ['ExtensionFileLoader']
|
||||
|
||||
|
||||
(Frozen_ExecutionLoaderInheritanceTests,
|
||||
Source_ExecutionLoaderInheritanceTests
|
||||
) = test_util.test_both(ExecutionLoader, abc=abc)
|
||||
|
||||
|
||||
class FileLoader(InheritanceTests):
|
||||
superclass_names = ['ResourceLoader', 'ExecutionLoader']
|
||||
subclass_names = ['SourceFileLoader', 'SourcelessFileLoader']
|
||||
|
||||
|
||||
(Frozen_FileLoaderInheritanceTests,
|
||||
Source_FileLoaderInheritanceTests
|
||||
) = test_util.test_both(FileLoader, abc=abc)
|
||||
|
||||
|
||||
class SourceLoader(InheritanceTests):
|
||||
superclass_names = ['ResourceLoader', 'ExecutionLoader']
|
||||
subclass_names = ['SourceFileLoader']
|
||||
|
||||
|
||||
(Frozen_SourceLoaderInheritanceTests,
|
||||
Source_SourceLoaderInheritanceTests
|
||||
) = test_util.test_both(SourceLoader, abc=abc)
|
||||
|
||||
|
||||
##### Default return values ####################################################
|
||||
|
||||
def make_abc_subclasses(base_class, name=None, inst=False, **kwargs):
|
||||
if name is None:
|
||||
name = base_class.__name__
|
||||
base = {kind: getattr(splitabc, name)
|
||||
for kind, splitabc in abc.items()}
|
||||
return {cls._KIND: cls() if inst else cls
|
||||
for cls in test_util.split_frozen(base_class, base, **kwargs)}
|
||||
|
||||
|
||||
class ABCTestHarness:
|
||||
|
||||
@property
|
||||
def ins(self):
|
||||
# Lazily set ins on the class.
|
||||
cls = self.SPLIT[self._KIND]
|
||||
ins = cls()
|
||||
self.__class__.ins = ins
|
||||
return ins
|
||||
|
||||
|
||||
class MetaPathFinder:
|
||||
|
||||
def find_module(self, fullname, path):
|
||||
return super().find_module(fullname, path)
|
||||
|
||||
|
||||
class MetaPathFinderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = make_abc_subclasses(MetaPathFinder)
|
||||
|
||||
def test_find_module(self):
|
||||
# Default should return None.
|
||||
self.assertIsNone(self.ins.find_module('something', None))
|
||||
|
||||
def test_invalidate_caches(self):
|
||||
# Calling the method is a no-op.
|
||||
self.ins.invalidate_caches()
|
||||
|
||||
|
||||
(Frozen_MPFDefaultTests,
|
||||
Source_MPFDefaultTests
|
||||
) = test_util.test_both(MetaPathFinderDefaultsTests)
|
||||
|
||||
|
||||
class PathEntryFinder:
|
||||
|
||||
def find_loader(self, fullname):
|
||||
return super().find_loader(fullname)
|
||||
|
||||
|
||||
class PathEntryFinderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = make_abc_subclasses(PathEntryFinder)
|
||||
|
||||
def test_find_loader(self):
|
||||
self.assertEqual((None, []), self.ins.find_loader('something'))
|
||||
|
||||
def find_module(self):
|
||||
self.assertEqual(None, self.ins.find_module('something'))
|
||||
|
||||
def test_invalidate_caches(self):
|
||||
# Should be a no-op.
|
||||
self.ins.invalidate_caches()
|
||||
|
||||
|
||||
(Frozen_PEFDefaultTests,
|
||||
Source_PEFDefaultTests
|
||||
) = test_util.test_both(PathEntryFinderDefaultsTests)
|
||||
|
||||
|
||||
class Loader:
|
||||
|
||||
def load_module(self, fullname):
|
||||
return super().load_module(fullname)
|
||||
|
||||
|
||||
class LoaderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = make_abc_subclasses(Loader)
|
||||
|
||||
def test_create_module(self):
|
||||
spec = 'a spec'
|
||||
self.assertIsNone(self.ins.create_module(spec))
|
||||
|
||||
def test_load_module(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.ins.load_module('something')
|
||||
|
||||
def test_module_repr(self):
|
||||
mod = types.ModuleType('blah')
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.ins.module_repr(mod)
|
||||
original_repr = repr(mod)
|
||||
mod.__loader__ = self.ins
|
||||
# Should still return a proper repr.
|
||||
self.assertTrue(repr(mod))
|
||||
|
||||
|
||||
(Frozen_LDefaultTests,
|
||||
SourceLDefaultTests
|
||||
) = test_util.test_both(LoaderDefaultsTests)
|
||||
|
||||
|
||||
class ResourceLoader(Loader):
|
||||
|
||||
def get_data(self, path):
|
||||
return super().get_data(path)
|
||||
|
||||
|
||||
class ResourceLoaderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = make_abc_subclasses(ResourceLoader)
|
||||
|
||||
def test_get_data(self):
|
||||
with self.assertRaises(IOError):
|
||||
self.ins.get_data('/some/path')
|
||||
|
||||
|
||||
(Frozen_RLDefaultTests,
|
||||
Source_RLDefaultTests
|
||||
) = test_util.test_both(ResourceLoaderDefaultsTests)
|
||||
|
||||
|
||||
class InspectLoader(Loader):
|
||||
|
||||
def is_package(self, fullname):
|
||||
return super().is_package(fullname)
|
||||
|
||||
def get_source(self, fullname):
|
||||
return super().get_source(fullname)
|
||||
|
||||
|
||||
SPLIT_IL = make_abc_subclasses(InspectLoader)
|
||||
|
||||
|
||||
class InspectLoaderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = SPLIT_IL
|
||||
|
||||
def test_is_package(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.ins.is_package('blah')
|
||||
|
||||
def test_get_source(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.ins.get_source('blah')
|
||||
|
||||
|
||||
(Frozen_ILDefaultTests,
|
||||
Source_ILDefaultTests
|
||||
) = test_util.test_both(InspectLoaderDefaultsTests)
|
||||
|
||||
|
||||
class ExecutionLoader(InspectLoader):
|
||||
|
||||
def get_filename(self, fullname):
|
||||
return super().get_filename(fullname)
|
||||
|
||||
|
||||
SPLIT_EL = make_abc_subclasses(ExecutionLoader)
|
||||
|
||||
|
||||
class ExecutionLoaderDefaultsTests(ABCTestHarness):
|
||||
|
||||
SPLIT = SPLIT_EL
|
||||
|
||||
def test_get_filename(self):
|
||||
with self.assertRaises(ImportError):
|
||||
self.ins.get_filename('blah')
|
||||
|
||||
|
||||
(Frozen_ELDefaultTests,
|
||||
Source_ELDefaultsTests
|
||||
) = test_util.test_both(InspectLoaderDefaultsTests)
|
||||
|
||||
|
||||
##### MetaPathFinder concrete methods ##########################################
|
||||
class MetaPathFinderFindModuleTests:
|
||||
|
||||
@classmethod
|
||||
def finder(cls, spec):
|
||||
class MetaPathSpecFinder(cls.abc.MetaPathFinder):
|
||||
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
self.called_for = fullname, path
|
||||
return spec
|
||||
|
||||
return MetaPathSpecFinder()
|
||||
|
||||
def test_no_spec(self):
|
||||
finder = self.finder(None)
|
||||
path = ['a', 'b', 'c']
|
||||
name = 'blah'
|
||||
found = finder.find_module(name, path)
|
||||
self.assertIsNone(found)
|
||||
self.assertEqual(name, finder.called_for[0])
|
||||
self.assertEqual(path, finder.called_for[1])
|
||||
|
||||
def test_spec(self):
|
||||
loader = object()
|
||||
spec = self.util.spec_from_loader('blah', loader)
|
||||
finder = self.finder(spec)
|
||||
found = finder.find_module('blah', None)
|
||||
self.assertIs(found, spec.loader)
|
||||
|
||||
|
||||
(Frozen_MPFFindModuleTests,
|
||||
Source_MPFFindModuleTests
|
||||
) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util)
|
||||
|
||||
|
||||
##### PathEntryFinder concrete methods #########################################
|
||||
class PathEntryFinderFindLoaderTests:
|
||||
|
||||
@classmethod
|
||||
def finder(cls, spec):
|
||||
class PathEntrySpecFinder(cls.abc.PathEntryFinder):
|
||||
|
||||
def find_spec(self, fullname, target=None):
|
||||
self.called_for = fullname
|
||||
return spec
|
||||
|
||||
return PathEntrySpecFinder()
|
||||
|
||||
def test_no_spec(self):
|
||||
finder = self.finder(None)
|
||||
name = 'blah'
|
||||
found = finder.find_loader(name)
|
||||
self.assertIsNone(found[0])
|
||||
self.assertEqual([], found[1])
|
||||
self.assertEqual(name, finder.called_for)
|
||||
|
||||
def test_spec_with_loader(self):
|
||||
loader = object()
|
||||
spec = self.util.spec_from_loader('blah', loader)
|
||||
finder = self.finder(spec)
|
||||
found = finder.find_loader('blah')
|
||||
self.assertIs(found[0], spec.loader)
|
||||
|
||||
def test_spec_with_portions(self):
|
||||
spec = self.machinery.ModuleSpec('blah', None)
|
||||
paths = ['a', 'b', 'c']
|
||||
spec.submodule_search_locations = paths
|
||||
finder = self.finder(spec)
|
||||
found = finder.find_loader('blah')
|
||||
self.assertIsNone(found[0])
|
||||
self.assertEqual(paths, found[1])
|
||||
|
||||
|
||||
(Frozen_PEFFindLoaderTests,
|
||||
Source_PEFFindLoaderTests
|
||||
) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
##### Loader concrete methods ##################################################
|
||||
class LoaderLoadModuleTests:
|
||||
|
||||
def loader(self):
|
||||
class SpecLoader(self.abc.Loader):
|
||||
found = None
|
||||
def exec_module(self, module):
|
||||
self.found = module
|
||||
|
||||
def is_package(self, fullname):
|
||||
"""Force some non-default module state to be set."""
|
||||
return True
|
||||
|
||||
return SpecLoader()
|
||||
|
||||
def test_fresh(self):
|
||||
loader = self.loader()
|
||||
name = 'blah'
|
||||
with test_util.uncache(name):
|
||||
loader.load_module(name)
|
||||
module = loader.found
|
||||
self.assertIs(sys.modules[name], module)
|
||||
self.assertEqual(loader, module.__loader__)
|
||||
self.assertEqual(loader, module.__spec__.loader)
|
||||
self.assertEqual(name, module.__name__)
|
||||
self.assertEqual(name, module.__spec__.name)
|
||||
self.assertIsNotNone(module.__path__)
|
||||
self.assertIsNotNone(module.__path__,
|
||||
module.__spec__.submodule_search_locations)
|
||||
|
||||
def test_reload(self):
|
||||
name = 'blah'
|
||||
loader = self.loader()
|
||||
module = types.ModuleType(name)
|
||||
module.__spec__ = self.util.spec_from_loader(name, loader)
|
||||
module.__loader__ = loader
|
||||
with test_util.uncache(name):
|
||||
sys.modules[name] = module
|
||||
loader.load_module(name)
|
||||
found = loader.found
|
||||
self.assertIs(found, sys.modules[name])
|
||||
self.assertIs(module, sys.modules[name])
|
||||
|
||||
|
||||
(Frozen_LoaderLoadModuleTests,
|
||||
Source_LoaderLoadModuleTests
|
||||
) = test_util.test_both(LoaderLoadModuleTests, abc=abc, util=util)
|
||||
|
||||
|
||||
##### InspectLoader concrete methods ###########################################
|
||||
class InspectLoaderSourceToCodeTests:
|
||||
|
||||
def source_to_module(self, data, path=None):
|
||||
"""Help with source_to_code() tests."""
|
||||
module = types.ModuleType('blah')
|
||||
loader = self.InspectLoaderSubclass()
|
||||
if path is None:
|
||||
code = loader.source_to_code(data)
|
||||
else:
|
||||
code = loader.source_to_code(data, path)
|
||||
exec(code, module.__dict__)
|
||||
return module
|
||||
|
||||
def test_source_to_code_source(self):
|
||||
# Since compile() can handle strings, so should source_to_code().
|
||||
source = 'attr = 42'
|
||||
module = self.source_to_module(source)
|
||||
self.assertTrue(hasattr(module, 'attr'))
|
||||
self.assertEqual(module.attr, 42)
|
||||
|
||||
def test_source_to_code_bytes(self):
|
||||
# Since compile() can handle bytes, so should source_to_code().
|
||||
source = b'attr = 42'
|
||||
module = self.source_to_module(source)
|
||||
self.assertTrue(hasattr(module, 'attr'))
|
||||
self.assertEqual(module.attr, 42)
|
||||
|
||||
def test_source_to_code_path(self):
|
||||
# Specifying a path should set it for the code object.
|
||||
path = 'path/to/somewhere'
|
||||
loader = self.InspectLoaderSubclass()
|
||||
code = loader.source_to_code('', path)
|
||||
self.assertEqual(code.co_filename, path)
|
||||
|
||||
def test_source_to_code_no_path(self):
|
||||
# Not setting a path should still work and be set to <string> since that
|
||||
# is a pre-existing practice as a default to compile().
|
||||
loader = self.InspectLoaderSubclass()
|
||||
code = loader.source_to_code('')
|
||||
self.assertEqual(code.co_filename, '<string>')
|
||||
|
||||
|
||||
(Frozen_ILSourceToCodeTests,
|
||||
Source_ILSourceToCodeTests
|
||||
) = test_util.test_both(InspectLoaderSourceToCodeTests,
|
||||
InspectLoaderSubclass=SPLIT_IL)
|
||||
|
||||
|
||||
class InspectLoaderGetCodeTests:
|
||||
|
||||
def test_get_code(self):
|
||||
# Test success.
|
||||
module = types.ModuleType('blah')
|
||||
with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked:
|
||||
mocked.return_value = 'attr = 42'
|
||||
loader = self.InspectLoaderSubclass()
|
||||
code = loader.get_code('blah')
|
||||
exec(code, module.__dict__)
|
||||
self.assertEqual(module.attr, 42)
|
||||
|
||||
def test_get_code_source_is_None(self):
|
||||
# If get_source() is None then this should be None.
|
||||
with mock.patch.object(self.InspectLoaderSubclass, 'get_source') as mocked:
|
||||
mocked.return_value = None
|
||||
loader = self.InspectLoaderSubclass()
|
||||
code = loader.get_code('blah')
|
||||
self.assertIsNone(code)
|
||||
|
||||
def test_get_code_source_not_found(self):
|
||||
# If there is no source then there is no code object.
|
||||
loader = self.InspectLoaderSubclass()
|
||||
with self.assertRaises(ImportError):
|
||||
loader.get_code('blah')
|
||||
|
||||
|
||||
(Frozen_ILGetCodeTests,
|
||||
Source_ILGetCodeTests
|
||||
) = test_util.test_both(InspectLoaderGetCodeTests,
|
||||
InspectLoaderSubclass=SPLIT_IL)
|
||||
|
||||
|
||||
class InspectLoaderLoadModuleTests:
|
||||
|
||||
"""Test InspectLoader.load_module()."""
|
||||
|
||||
module_name = 'blah'
|
||||
|
||||
def setUp(self):
|
||||
support.unload(self.module_name)
|
||||
self.addCleanup(support.unload, self.module_name)
|
||||
|
||||
def load(self, loader):
|
||||
spec = self.util.spec_from_loader(self.module_name, loader)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
return self.init._bootstrap._load_unlocked(spec)
|
||||
|
||||
def mock_get_code(self):
|
||||
return mock.patch.object(self.InspectLoaderSubclass, 'get_code')
|
||||
|
||||
def test_get_code_ImportError(self):
|
||||
# If get_code() raises ImportError, it should propagate.
|
||||
with self.mock_get_code() as mocked_get_code:
|
||||
mocked_get_code.side_effect = ImportError
|
||||
with self.assertRaises(ImportError):
|
||||
loader = self.InspectLoaderSubclass()
|
||||
self.load(loader)
|
||||
|
||||
def test_get_code_None(self):
|
||||
# If get_code() returns None, raise ImportError.
|
||||
with self.mock_get_code() as mocked_get_code:
|
||||
mocked_get_code.return_value = None
|
||||
with self.assertRaises(ImportError):
|
||||
loader = self.InspectLoaderSubclass()
|
||||
self.load(loader)
|
||||
|
||||
def test_module_returned(self):
|
||||
# The loaded module should be returned.
|
||||
code = compile('attr = 42', '<string>', 'exec')
|
||||
with self.mock_get_code() as mocked_get_code:
|
||||
mocked_get_code.return_value = code
|
||||
loader = self.InspectLoaderSubclass()
|
||||
module = self.load(loader)
|
||||
self.assertEqual(module, sys.modules[self.module_name])
|
||||
|
||||
|
||||
(Frozen_ILLoadModuleTests,
|
||||
Source_ILLoadModuleTests
|
||||
) = test_util.test_both(InspectLoaderLoadModuleTests,
|
||||
InspectLoaderSubclass=SPLIT_IL,
|
||||
init=init,
|
||||
util=util)
|
||||
|
||||
|
||||
##### ExecutionLoader concrete methods #########################################
|
||||
class ExecutionLoaderGetCodeTests:
|
||||
|
||||
def mock_methods(self, *, get_source=False, get_filename=False):
|
||||
source_mock_context, filename_mock_context = None, None
|
||||
if get_source:
|
||||
source_mock_context = mock.patch.object(self.ExecutionLoaderSubclass,
|
||||
'get_source')
|
||||
if get_filename:
|
||||
filename_mock_context = mock.patch.object(self.ExecutionLoaderSubclass,
|
||||
'get_filename')
|
||||
return source_mock_context, filename_mock_context
|
||||
|
||||
def test_get_code(self):
|
||||
path = 'blah.py'
|
||||
source_mock_context, filename_mock_context = self.mock_methods(
|
||||
get_source=True, get_filename=True)
|
||||
with source_mock_context as source_mock, filename_mock_context as name_mock:
|
||||
source_mock.return_value = 'attr = 42'
|
||||
name_mock.return_value = path
|
||||
loader = self.ExecutionLoaderSubclass()
|
||||
code = loader.get_code('blah')
|
||||
self.assertEqual(code.co_filename, path)
|
||||
module = types.ModuleType('blah')
|
||||
exec(code, module.__dict__)
|
||||
self.assertEqual(module.attr, 42)
|
||||
|
||||
def test_get_code_source_is_None(self):
|
||||
# If get_source() is None then this should be None.
|
||||
source_mock_context, _ = self.mock_methods(get_source=True)
|
||||
with source_mock_context as mocked:
|
||||
mocked.return_value = None
|
||||
loader = self.ExecutionLoaderSubclass()
|
||||
code = loader.get_code('blah')
|
||||
self.assertIsNone(code)
|
||||
|
||||
def test_get_code_source_not_found(self):
|
||||
# If there is no source then there is no code object.
|
||||
loader = self.ExecutionLoaderSubclass()
|
||||
with self.assertRaises(ImportError):
|
||||
loader.get_code('blah')
|
||||
|
||||
def test_get_code_no_path(self):
|
||||
# If get_filename() raises ImportError then simply skip setting the path
|
||||
# on the code object.
|
||||
source_mock_context, filename_mock_context = self.mock_methods(
|
||||
get_source=True, get_filename=True)
|
||||
with source_mock_context as source_mock, filename_mock_context as name_mock:
|
||||
source_mock.return_value = 'attr = 42'
|
||||
name_mock.side_effect = ImportError
|
||||
loader = self.ExecutionLoaderSubclass()
|
||||
code = loader.get_code('blah')
|
||||
self.assertEqual(code.co_filename, '<string>')
|
||||
module = types.ModuleType('blah')
|
||||
exec(code, module.__dict__)
|
||||
self.assertEqual(module.attr, 42)
|
||||
|
||||
|
||||
(Frozen_ELGetCodeTests,
|
||||
Source_ELGetCodeTests
|
||||
) = test_util.test_both(ExecutionLoaderGetCodeTests,
|
||||
ExecutionLoaderSubclass=SPLIT_EL)
|
||||
|
||||
|
||||
##### SourceLoader concrete methods ############################################
|
||||
class SourceOnlyLoader:
|
||||
|
||||
# Globals that should be defined for all modules.
|
||||
source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, "
|
||||
b"repr(__loader__)])")
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
def get_data(self, path):
|
||||
if path != self.path:
|
||||
raise IOError
|
||||
return self.source
|
||||
|
||||
def get_filename(self, fullname):
|
||||
return self.path
|
||||
|
||||
def module_repr(self, module):
|
||||
return '<module>'
|
||||
|
||||
|
||||
SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader')
|
||||
|
||||
|
||||
class SourceLoader(SourceOnlyLoader):
|
||||
|
||||
source_mtime = 1
|
||||
|
||||
def __init__(self, path, magic=None):
|
||||
super().__init__(path)
|
||||
self.bytecode_path = self.util.cache_from_source(self.path)
|
||||
self.source_size = len(self.source)
|
||||
if magic is None:
|
||||
magic = self.util.MAGIC_NUMBER
|
||||
data = bytearray(magic)
|
||||
data.extend(self.init._w_long(self.source_mtime))
|
||||
data.extend(self.init._w_long(self.source_size))
|
||||
code_object = compile(self.source, self.path, 'exec',
|
||||
dont_inherit=True)
|
||||
data.extend(marshal.dumps(code_object))
|
||||
self.bytecode = bytes(data)
|
||||
self.written = {}
|
||||
|
||||
def get_data(self, path):
|
||||
if path == self.path:
|
||||
return super().get_data(path)
|
||||
elif path == self.bytecode_path:
|
||||
return self.bytecode
|
||||
else:
|
||||
raise OSError
|
||||
|
||||
def path_stats(self, path):
|
||||
if path != self.path:
|
||||
raise IOError
|
||||
return {'mtime': self.source_mtime, 'size': self.source_size}
|
||||
|
||||
def set_data(self, path, data):
|
||||
self.written[path] = bytes(data)
|
||||
return path == self.bytecode_path
|
||||
|
||||
|
||||
SPLIT_SL = make_abc_subclasses(SourceLoader, util=util, init=init)
|
||||
|
||||
|
||||
class SourceLoaderTestHarness:
|
||||
|
||||
def setUp(self, *, is_package=True, **kwargs):
|
||||
self.package = 'pkg'
|
||||
if is_package:
|
||||
self.path = os.path.join(self.package, '__init__.py')
|
||||
self.name = self.package
|
||||
else:
|
||||
module_name = 'mod'
|
||||
self.path = os.path.join(self.package, '.'.join(['mod', 'py']))
|
||||
self.name = '.'.join([self.package, module_name])
|
||||
self.cached = self.util.cache_from_source(self.path)
|
||||
self.loader = self.loader_mock(self.path, **kwargs)
|
||||
|
||||
def verify_module(self, module):
|
||||
self.assertEqual(module.__name__, self.name)
|
||||
self.assertEqual(module.__file__, self.path)
|
||||
self.assertEqual(module.__cached__, self.cached)
|
||||
self.assertEqual(module.__package__, self.package)
|
||||
self.assertEqual(module.__loader__, self.loader)
|
||||
values = module._.split('::')
|
||||
self.assertEqual(values[0], self.name)
|
||||
self.assertEqual(values[1], self.path)
|
||||
self.assertEqual(values[2], self.cached)
|
||||
self.assertEqual(values[3], self.package)
|
||||
self.assertEqual(values[4], repr(self.loader))
|
||||
|
||||
def verify_code(self, code_object):
|
||||
module = types.ModuleType(self.name)
|
||||
module.__file__ = self.path
|
||||
module.__cached__ = self.cached
|
||||
module.__package__ = self.package
|
||||
module.__loader__ = self.loader
|
||||
module.__path__ = []
|
||||
exec(code_object, module.__dict__)
|
||||
self.verify_module(module)
|
||||
|
||||
|
||||
class SourceOnlyLoaderTests(SourceLoaderTestHarness):
|
||||
|
||||
"""Test importlib.abc.SourceLoader for source-only loading.
|
||||
|
||||
Reload testing is subsumed by the tests for
|
||||
importlib.util.module_for_loader.
|
||||
|
||||
"""
|
||||
|
||||
def test_get_source(self):
|
||||
# Verify the source code is returned as a string.
|
||||
# If an OSError is raised by get_data then raise ImportError.
|
||||
expected_source = self.loader.source.decode('utf-8')
|
||||
self.assertEqual(self.loader.get_source(self.name), expected_source)
|
||||
def raise_OSError(path):
|
||||
raise OSError
|
||||
self.loader.get_data = raise_OSError
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.loader.get_source(self.name)
|
||||
self.assertEqual(cm.exception.name, self.name)
|
||||
|
||||
def test_is_package(self):
|
||||
# Properly detect when loading a package.
|
||||
self.setUp(is_package=False)
|
||||
self.assertFalse(self.loader.is_package(self.name))
|
||||
self.setUp(is_package=True)
|
||||
self.assertTrue(self.loader.is_package(self.name))
|
||||
self.assertFalse(self.loader.is_package(self.name + '.__init__'))
|
||||
|
||||
def test_get_code(self):
|
||||
# Verify the code object is created.
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object)
|
||||
|
||||
def test_source_to_code(self):
|
||||
# Verify the compiled code object.
|
||||
code = self.loader.source_to_code(self.loader.source, self.path)
|
||||
self.verify_code(code)
|
||||
|
||||
def test_load_module(self):
|
||||
# Loading a module should set __name__, __loader__, __package__,
|
||||
# __path__ (for packages), __file__, and __cached__.
|
||||
# The module should also be put into sys.modules.
|
||||
with test_util.uncache(self.name):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.loader.load_module(self.name)
|
||||
self.verify_module(module)
|
||||
self.assertEqual(module.__path__, [os.path.dirname(self.path)])
|
||||
self.assertIn(self.name, sys.modules)
|
||||
|
||||
def test_package_settings(self):
|
||||
# __package__ needs to be set, while __path__ is set on if the module
|
||||
# is a package.
|
||||
# Testing the values for a package are covered by test_load_module.
|
||||
self.setUp(is_package=False)
|
||||
with test_util.uncache(self.name):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
module = self.loader.load_module(self.name)
|
||||
self.verify_module(module)
|
||||
self.assertFalse(hasattr(module, '__path__'))
|
||||
|
||||
def test_get_source_encoding(self):
|
||||
# Source is considered encoded in UTF-8 by default unless otherwise
|
||||
# specified by an encoding line.
|
||||
source = "_ = 'ü'"
|
||||
self.loader.source = source.encode('utf-8')
|
||||
returned_source = self.loader.get_source(self.name)
|
||||
self.assertEqual(returned_source, source)
|
||||
source = "# coding: latin-1\n_ = ü"
|
||||
self.loader.source = source.encode('latin-1')
|
||||
returned_source = self.loader.get_source(self.name)
|
||||
self.assertEqual(returned_source, source)
|
||||
|
||||
|
||||
(Frozen_SourceOnlyLoaderTests,
|
||||
Source_SourceOnlyLoaderTests
|
||||
) = test_util.test_both(SourceOnlyLoaderTests, util=util,
|
||||
loader_mock=SPLIT_SOL)
|
||||
|
||||
|
||||
@unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true")
|
||||
class SourceLoaderBytecodeTests(SourceLoaderTestHarness):
|
||||
|
||||
"""Test importlib.abc.SourceLoader's use of bytecode.
|
||||
|
||||
Source-only testing handled by SourceOnlyLoaderTests.
|
||||
|
||||
"""
|
||||
|
||||
def verify_code(self, code_object, *, bytecode_written=False):
|
||||
super().verify_code(code_object)
|
||||
if bytecode_written:
|
||||
self.assertIn(self.cached, self.loader.written)
|
||||
data = bytearray(self.util.MAGIC_NUMBER)
|
||||
data.extend(self.init._w_long(self.loader.source_mtime))
|
||||
data.extend(self.init._w_long(self.loader.source_size))
|
||||
data.extend(marshal.dumps(code_object))
|
||||
self.assertEqual(self.loader.written[self.cached], bytes(data))
|
||||
|
||||
def test_code_with_everything(self):
|
||||
# When everything should work.
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object)
|
||||
|
||||
def test_no_bytecode(self):
|
||||
# If no bytecode exists then move on to the source.
|
||||
self.loader.bytecode_path = "<does not exist>"
|
||||
# Sanity check
|
||||
with self.assertRaises(OSError):
|
||||
bytecode_path = self.util.cache_from_source(self.path)
|
||||
self.loader.get_data(bytecode_path)
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object, bytecode_written=True)
|
||||
|
||||
def test_code_bad_timestamp(self):
|
||||
# Bytecode is only used when the timestamp matches the source EXACTLY.
|
||||
for source_mtime in (0, 2):
|
||||
assert source_mtime != self.loader.source_mtime
|
||||
original = self.loader.source_mtime
|
||||
self.loader.source_mtime = source_mtime
|
||||
# If bytecode is used then EOFError would be raised by marshal.
|
||||
self.loader.bytecode = self.loader.bytecode[8:]
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object, bytecode_written=True)
|
||||
self.loader.source_mtime = original
|
||||
|
||||
def test_code_bad_magic(self):
|
||||
# Skip over bytecode with a bad magic number.
|
||||
self.setUp(magic=b'0000')
|
||||
# If bytecode is used then EOFError would be raised by marshal.
|
||||
self.loader.bytecode = self.loader.bytecode[8:]
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object, bytecode_written=True)
|
||||
|
||||
def test_dont_write_bytecode(self):
|
||||
# Bytecode is not written if sys.dont_write_bytecode is true.
|
||||
# Can assume it is false already thanks to the skipIf class decorator.
|
||||
try:
|
||||
sys.dont_write_bytecode = True
|
||||
self.loader.bytecode_path = "<does not exist>"
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.assertNotIn(self.cached, self.loader.written)
|
||||
finally:
|
||||
sys.dont_write_bytecode = False
|
||||
|
||||
def test_no_set_data(self):
|
||||
# If set_data is not defined, one can still read bytecode.
|
||||
self.setUp(magic=b'0000')
|
||||
original_set_data = self.loader.__class__.mro()[1].set_data
|
||||
try:
|
||||
del self.loader.__class__.mro()[1].set_data
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object)
|
||||
finally:
|
||||
self.loader.__class__.mro()[1].set_data = original_set_data
|
||||
|
||||
def test_set_data_raises_exceptions(self):
|
||||
# Raising NotImplementedError or OSError is okay for set_data.
|
||||
def raise_exception(exc):
|
||||
def closure(*args, **kwargs):
|
||||
raise exc
|
||||
return closure
|
||||
|
||||
self.setUp(magic=b'0000')
|
||||
self.loader.set_data = raise_exception(NotImplementedError)
|
||||
code_object = self.loader.get_code(self.name)
|
||||
self.verify_code(code_object)
|
||||
|
||||
|
||||
(Frozen_SLBytecodeTests,
|
||||
SourceSLBytecodeTests
|
||||
) = test_util.test_both(SourceLoaderBytecodeTests, init=init, util=util,
|
||||
loader_mock=SPLIT_SL)
|
||||
|
||||
|
||||
class SourceLoaderGetSourceTests:
|
||||
|
||||
"""Tests for importlib.abc.SourceLoader.get_source()."""
|
||||
|
||||
def test_default_encoding(self):
|
||||
# Should have no problems with UTF-8 text.
|
||||
name = 'mod'
|
||||
mock = self.SourceOnlyLoaderMock('mod.file')
|
||||
source = 'x = "ü"'
|
||||
mock.source = source.encode('utf-8')
|
||||
returned_source = mock.get_source(name)
|
||||
self.assertEqual(returned_source, source)
|
||||
|
||||
def test_decoded_source(self):
|
||||
# Decoding should work.
|
||||
name = 'mod'
|
||||
mock = self.SourceOnlyLoaderMock("mod.file")
|
||||
source = "# coding: Latin-1\nx='ü'"
|
||||
assert source.encode('latin-1') != source.encode('utf-8')
|
||||
mock.source = source.encode('latin-1')
|
||||
returned_source = mock.get_source(name)
|
||||
self.assertEqual(returned_source, source)
|
||||
|
||||
def test_universal_newlines(self):
|
||||
# PEP 302 says universal newlines should be used.
|
||||
name = 'mod'
|
||||
mock = self.SourceOnlyLoaderMock('mod.file')
|
||||
source = "x = 42\r\ny = -13\r\n"
|
||||
mock.source = source.encode('utf-8')
|
||||
expect = io.IncrementalNewlineDecoder(None, True).decode(source)
|
||||
self.assertEqual(mock.get_source(name), expect)
|
||||
|
||||
|
||||
(Frozen_SourceOnlyLoaderGetSourceTests,
|
||||
Source_SourceOnlyLoaderGetSourceTests
|
||||
) = test_util.test_both(SourceLoaderGetSourceTests,
|
||||
SourceOnlyLoaderMock=SPLIT_SOL)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
449
third_party/python/Lib/test/test_importlib/test_api.py
vendored
Normal file
449
third_party/python/Lib/test/test_importlib/test_api.py
vendored
Normal file
|
@ -0,0 +1,449 @@
|
|||
from . import util as test_util
|
||||
|
||||
init = test_util.import_importlib('importlib')
|
||||
util = test_util.import_importlib('importlib.util')
|
||||
machinery = test_util.import_importlib('importlib.machinery')
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
from test import support
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class ImportModuleTests:
|
||||
|
||||
"""Test importlib.import_module."""
|
||||
|
||||
def test_module_import(self):
|
||||
# Test importing a top-level module.
|
||||
with test_util.mock_modules('top_level') as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
module = self.init.import_module('top_level')
|
||||
self.assertEqual(module.__name__, 'top_level')
|
||||
|
||||
def test_absolute_package_import(self):
|
||||
# Test importing a module from a package with an absolute name.
|
||||
pkg_name = 'pkg'
|
||||
pkg_long_name = '{0}.__init__'.format(pkg_name)
|
||||
name = '{0}.mod'.format(pkg_name)
|
||||
with test_util.mock_modules(pkg_long_name, name) as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
module = self.init.import_module(name)
|
||||
self.assertEqual(module.__name__, name)
|
||||
|
||||
def test_shallow_relative_package_import(self):
|
||||
# Test importing a module from a package through a relative import.
|
||||
pkg_name = 'pkg'
|
||||
pkg_long_name = '{0}.__init__'.format(pkg_name)
|
||||
module_name = 'mod'
|
||||
absolute_name = '{0}.{1}'.format(pkg_name, module_name)
|
||||
relative_name = '.{0}'.format(module_name)
|
||||
with test_util.mock_modules(pkg_long_name, absolute_name) as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
self.init.import_module(pkg_name)
|
||||
module = self.init.import_module(relative_name, pkg_name)
|
||||
self.assertEqual(module.__name__, absolute_name)
|
||||
|
||||
def test_deep_relative_package_import(self):
|
||||
modules = ['a.__init__', 'a.b.__init__', 'a.c']
|
||||
with test_util.mock_modules(*modules) as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
self.init.import_module('a')
|
||||
self.init.import_module('a.b')
|
||||
module = self.init.import_module('..c', 'a.b')
|
||||
self.assertEqual(module.__name__, 'a.c')
|
||||
|
||||
def test_absolute_import_with_package(self):
|
||||
# Test importing a module from a package with an absolute name with
|
||||
# the 'package' argument given.
|
||||
pkg_name = 'pkg'
|
||||
pkg_long_name = '{0}.__init__'.format(pkg_name)
|
||||
name = '{0}.mod'.format(pkg_name)
|
||||
with test_util.mock_modules(pkg_long_name, name) as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
self.init.import_module(pkg_name)
|
||||
module = self.init.import_module(name, pkg_name)
|
||||
self.assertEqual(module.__name__, name)
|
||||
|
||||
def test_relative_import_wo_package(self):
|
||||
# Relative imports cannot happen without the 'package' argument being
|
||||
# set.
|
||||
with self.assertRaises(TypeError):
|
||||
self.init.import_module('.support')
|
||||
|
||||
|
||||
def test_loaded_once(self):
|
||||
# Issue #13591: Modules should only be loaded once when
|
||||
# initializing the parent package attempts to import the
|
||||
# module currently being imported.
|
||||
b_load_count = 0
|
||||
def load_a():
|
||||
self.init.import_module('a.b')
|
||||
def load_b():
|
||||
nonlocal b_load_count
|
||||
b_load_count += 1
|
||||
code = {'a': load_a, 'a.b': load_b}
|
||||
modules = ['a.__init__', 'a.b']
|
||||
with test_util.mock_modules(*modules, module_code=code) as mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
self.init.import_module('a.b')
|
||||
self.assertEqual(b_load_count, 1)
|
||||
|
||||
|
||||
(Frozen_ImportModuleTests,
|
||||
Source_ImportModuleTests
|
||||
) = test_util.test_both(ImportModuleTests, init=init)
|
||||
|
||||
|
||||
class FindLoaderTests:
|
||||
|
||||
FakeMetaFinder = None
|
||||
|
||||
def test_sys_modules(self):
|
||||
# If a module with __loader__ is in sys.modules, then return it.
|
||||
name = 'some_mod'
|
||||
with test_util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
loader = 'a loader!'
|
||||
module.__loader__ = loader
|
||||
sys.modules[name] = module
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
found = self.init.find_loader(name)
|
||||
self.assertEqual(loader, found)
|
||||
|
||||
def test_sys_modules_loader_is_None(self):
|
||||
# If sys.modules[name].__loader__ is None, raise ValueError.
|
||||
name = 'some_mod'
|
||||
with test_util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
module.__loader__ = None
|
||||
sys.modules[name] = module
|
||||
with self.assertRaises(ValueError):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.init.find_loader(name)
|
||||
|
||||
def test_sys_modules_loader_is_not_set(self):
|
||||
# Should raise ValueError
|
||||
# Issue #17099
|
||||
name = 'some_mod'
|
||||
with test_util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
try:
|
||||
del module.__loader__
|
||||
except AttributeError:
|
||||
pass
|
||||
sys.modules[name] = module
|
||||
with self.assertRaises(ValueError):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.init.find_loader(name)
|
||||
|
||||
def test_success(self):
|
||||
# Return the loader found on sys.meta_path.
|
||||
name = 'some_mod'
|
||||
with test_util.uncache(name):
|
||||
with test_util.import_state(meta_path=[self.FakeMetaFinder]):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertEqual((name, None), self.init.find_loader(name))
|
||||
|
||||
def test_success_path(self):
|
||||
# Searching on a path should work.
|
||||
name = 'some_mod'
|
||||
path = 'path to some place'
|
||||
with test_util.uncache(name):
|
||||
with test_util.import_state(meta_path=[self.FakeMetaFinder]):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertEqual((name, path),
|
||||
self.init.find_loader(name, path))
|
||||
|
||||
def test_nothing(self):
|
||||
# None is returned upon failure to find a loader.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule'))
|
||||
|
||||
|
||||
class FindLoaderPEP451Tests(FindLoaderTests):
|
||||
|
||||
class FakeMetaFinder:
|
||||
@staticmethod
|
||||
def find_spec(name, path=None, target=None):
|
||||
return machinery['Source'].ModuleSpec(name, (name, path))
|
||||
|
||||
|
||||
(Frozen_FindLoaderPEP451Tests,
|
||||
Source_FindLoaderPEP451Tests
|
||||
) = test_util.test_both(FindLoaderPEP451Tests, init=init)
|
||||
|
||||
|
||||
class FindLoaderPEP302Tests(FindLoaderTests):
|
||||
|
||||
class FakeMetaFinder:
|
||||
@staticmethod
|
||||
def find_module(name, path=None):
|
||||
return name, path
|
||||
|
||||
|
||||
(Frozen_FindLoaderPEP302Tests,
|
||||
Source_FindLoaderPEP302Tests
|
||||
) = test_util.test_both(FindLoaderPEP302Tests, init=init)
|
||||
|
||||
|
||||
class ReloadTests:
|
||||
|
||||
"""Test module reloading for builtin and extension modules."""
|
||||
|
||||
def test_reload_modules(self):
|
||||
for mod in ('tokenize', 'time', 'marshal'):
|
||||
with self.subTest(module=mod):
|
||||
with support.CleanImport(mod):
|
||||
module = self.init.import_module(mod)
|
||||
self.init.reload(module)
|
||||
|
||||
def test_module_replaced(self):
|
||||
def code():
|
||||
import sys
|
||||
module = type(sys)('top_level')
|
||||
module.spam = 3
|
||||
sys.modules['top_level'] = module
|
||||
mock = test_util.mock_modules('top_level',
|
||||
module_code={'top_level': code})
|
||||
with mock:
|
||||
with test_util.import_state(meta_path=[mock]):
|
||||
module = self.init.import_module('top_level')
|
||||
reloaded = self.init.reload(module)
|
||||
actual = sys.modules['top_level']
|
||||
self.assertEqual(actual.spam, 3)
|
||||
self.assertEqual(reloaded.spam, 3)
|
||||
|
||||
def test_reload_missing_loader(self):
|
||||
with support.CleanImport('types'):
|
||||
import types
|
||||
loader = types.__loader__
|
||||
del types.__loader__
|
||||
reloaded = self.init.reload(types)
|
||||
|
||||
self.assertIs(reloaded, types)
|
||||
self.assertIs(sys.modules['types'], types)
|
||||
self.assertEqual(reloaded.__loader__.path, loader.path)
|
||||
|
||||
def test_reload_loader_replaced(self):
|
||||
with support.CleanImport('types'):
|
||||
import types
|
||||
types.__loader__ = None
|
||||
self.init.invalidate_caches()
|
||||
reloaded = self.init.reload(types)
|
||||
|
||||
self.assertIsNot(reloaded.__loader__, None)
|
||||
self.assertIs(reloaded, types)
|
||||
self.assertIs(sys.modules['types'], types)
|
||||
|
||||
def test_reload_location_changed(self):
|
||||
name = 'spam'
|
||||
with support.temp_cwd(None) as cwd:
|
||||
with test_util.uncache('spam'):
|
||||
with support.DirsOnSysPath(cwd):
|
||||
# Start as a plain module.
|
||||
self.init.invalidate_caches()
|
||||
path = os.path.join(cwd, name + '.py')
|
||||
cached = self.util.cache_from_source(path)
|
||||
expected = {'__name__': name,
|
||||
'__package__': '',
|
||||
'__file__': path,
|
||||
'__cached__': cached,
|
||||
'__doc__': None,
|
||||
}
|
||||
support.create_empty_file(path)
|
||||
module = self.init.import_module(name)
|
||||
ns = vars(module).copy()
|
||||
loader = ns.pop('__loader__')
|
||||
spec = ns.pop('__spec__')
|
||||
ns.pop('__builtins__', None) # An implementation detail.
|
||||
self.assertEqual(spec.name, name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertEqual(loader.path, path)
|
||||
self.assertEqual(ns, expected)
|
||||
|
||||
# Change to a package.
|
||||
self.init.invalidate_caches()
|
||||
init_path = os.path.join(cwd, name, '__init__.py')
|
||||
cached = self.util.cache_from_source(init_path)
|
||||
expected = {'__name__': name,
|
||||
'__package__': name,
|
||||
'__file__': init_path,
|
||||
'__cached__': cached,
|
||||
'__path__': [os.path.dirname(init_path)],
|
||||
'__doc__': None,
|
||||
}
|
||||
os.mkdir(name)
|
||||
os.rename(path, init_path)
|
||||
reloaded = self.init.reload(module)
|
||||
ns = vars(reloaded).copy()
|
||||
loader = ns.pop('__loader__')
|
||||
spec = ns.pop('__spec__')
|
||||
ns.pop('__builtins__', None) # An implementation detail.
|
||||
self.assertEqual(spec.name, name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertIs(reloaded, module)
|
||||
self.assertEqual(loader.path, init_path)
|
||||
self.maxDiff = None
|
||||
self.assertEqual(ns, expected)
|
||||
|
||||
def test_reload_namespace_changed(self):
|
||||
name = 'spam'
|
||||
with support.temp_cwd(None) as cwd:
|
||||
with test_util.uncache('spam'):
|
||||
with support.DirsOnSysPath(cwd):
|
||||
# Start as a namespace package.
|
||||
self.init.invalidate_caches()
|
||||
bad_path = os.path.join(cwd, name, '__init.py')
|
||||
cached = self.util.cache_from_source(bad_path)
|
||||
expected = {'__name__': name,
|
||||
'__package__': name,
|
||||
'__doc__': None,
|
||||
}
|
||||
os.mkdir(name)
|
||||
with open(bad_path, 'w') as init_file:
|
||||
init_file.write('eggs = None')
|
||||
module = self.init.import_module(name)
|
||||
ns = vars(module).copy()
|
||||
loader = ns.pop('__loader__')
|
||||
path = ns.pop('__path__')
|
||||
spec = ns.pop('__spec__')
|
||||
ns.pop('__builtins__', None) # An implementation detail.
|
||||
self.assertEqual(spec.name, name)
|
||||
self.assertIs(spec.loader, None)
|
||||
self.assertIsNot(loader, None)
|
||||
self.assertEqual(set(path),
|
||||
set([os.path.dirname(bad_path)]))
|
||||
with self.assertRaises(AttributeError):
|
||||
# a NamespaceLoader
|
||||
loader.path
|
||||
self.assertEqual(ns, expected)
|
||||
|
||||
# Change to a regular package.
|
||||
self.init.invalidate_caches()
|
||||
init_path = os.path.join(cwd, name, '__init__.py')
|
||||
cached = self.util.cache_from_source(init_path)
|
||||
expected = {'__name__': name,
|
||||
'__package__': name,
|
||||
'__file__': init_path,
|
||||
'__cached__': cached,
|
||||
'__path__': [os.path.dirname(init_path)],
|
||||
'__doc__': None,
|
||||
'eggs': None,
|
||||
}
|
||||
os.rename(bad_path, init_path)
|
||||
reloaded = self.init.reload(module)
|
||||
ns = vars(reloaded).copy()
|
||||
loader = ns.pop('__loader__')
|
||||
spec = ns.pop('__spec__')
|
||||
ns.pop('__builtins__', None) # An implementation detail.
|
||||
self.assertEqual(spec.name, name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertIs(reloaded, module)
|
||||
self.assertEqual(loader.path, init_path)
|
||||
self.assertEqual(ns, expected)
|
||||
|
||||
def test_reload_submodule(self):
|
||||
# See #19851.
|
||||
name = 'spam'
|
||||
subname = 'ham'
|
||||
with test_util.temp_module(name, pkg=True) as pkg_dir:
|
||||
fullname, _ = test_util.submodule(name, subname, pkg_dir)
|
||||
ham = self.init.import_module(fullname)
|
||||
reloaded = self.init.reload(ham)
|
||||
self.assertIs(reloaded, ham)
|
||||
|
||||
|
||||
(Frozen_ReloadTests,
|
||||
Source_ReloadTests
|
||||
) = test_util.test_both(ReloadTests, init=init, util=util)
|
||||
|
||||
|
||||
class InvalidateCacheTests:
|
||||
|
||||
def test_method_called(self):
|
||||
# If defined the method should be called.
|
||||
class InvalidatingNullFinder:
|
||||
def __init__(self, *ignored):
|
||||
self.called = False
|
||||
def find_module(self, *args):
|
||||
return None
|
||||
def invalidate_caches(self):
|
||||
self.called = True
|
||||
|
||||
key = 'gobledeegook'
|
||||
meta_ins = InvalidatingNullFinder()
|
||||
path_ins = InvalidatingNullFinder()
|
||||
sys.meta_path.insert(0, meta_ins)
|
||||
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
|
||||
sys.path_importer_cache[key] = path_ins
|
||||
self.addCleanup(lambda: sys.meta_path.remove(meta_ins))
|
||||
self.init.invalidate_caches()
|
||||
self.assertTrue(meta_ins.called)
|
||||
self.assertTrue(path_ins.called)
|
||||
|
||||
def test_method_lacking(self):
|
||||
# There should be no issues if the method is not defined.
|
||||
key = 'gobbledeegook'
|
||||
sys.path_importer_cache[key] = None
|
||||
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
|
||||
self.init.invalidate_caches() # Shouldn't trigger an exception.
|
||||
|
||||
|
||||
(Frozen_InvalidateCacheTests,
|
||||
Source_InvalidateCacheTests
|
||||
) = test_util.test_both(InvalidateCacheTests, init=init)
|
||||
|
||||
|
||||
class FrozenImportlibTests(unittest.TestCase):
|
||||
|
||||
def test_no_frozen_importlib(self):
|
||||
# Should be able to import w/o _frozen_importlib being defined.
|
||||
# Can't do an isinstance() check since separate copies of importlib
|
||||
# may have been used for import, so just check the name is not for the
|
||||
# frozen loader.
|
||||
source_init = init['Source']
|
||||
self.assertNotEqual(source_init.__loader__.__class__.__name__,
|
||||
'FrozenImporter')
|
||||
|
||||
|
||||
class StartupTests:
|
||||
|
||||
def test_everyone_has___loader__(self):
|
||||
# Issue #17098: all modules should have __loader__ defined.
|
||||
for name, module in sys.modules.items():
|
||||
if isinstance(module, types.ModuleType):
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(hasattr(module, '__loader__'),
|
||||
'{!r} lacks a __loader__ attribute'.format(name))
|
||||
if self.machinery.BuiltinImporter.find_module(name):
|
||||
self.assertIsNot(module.__loader__, None)
|
||||
elif self.machinery.FrozenImporter.find_module(name):
|
||||
self.assertIsNot(module.__loader__, None)
|
||||
|
||||
def test_everyone_has___spec__(self):
|
||||
for name, module in sys.modules.items():
|
||||
if isinstance(module, types.ModuleType):
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(hasattr(module, '__spec__'))
|
||||
if self.machinery.BuiltinImporter.find_module(name):
|
||||
self.assertIsNot(module.__spec__, None)
|
||||
elif self.machinery.FrozenImporter.find_module(name):
|
||||
self.assertIsNot(module.__spec__, None)
|
||||
|
||||
|
||||
(Frozen_StartupTests,
|
||||
Source_StartupTests
|
||||
) = test_util.test_both(StartupTests, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
145
third_party/python/Lib/test/test_importlib/test_lazy.py
vendored
Normal file
145
third_party/python/Lib/test/test_importlib/test_lazy.py
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
import importlib
|
||||
from importlib import abc
|
||||
from importlib import util
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
|
||||
from . import util as test_util
|
||||
|
||||
|
||||
class CollectInit:
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
def exec_module(self, module):
|
||||
return self
|
||||
|
||||
|
||||
class LazyLoaderFactoryTests(unittest.TestCase):
|
||||
|
||||
def test_init(self):
|
||||
factory = util.LazyLoader.factory(CollectInit)
|
||||
# E.g. what importlib.machinery.FileFinder instantiates loaders with
|
||||
# plus keyword arguments.
|
||||
lazy_loader = factory('module name', 'module path', kw='kw')
|
||||
loader = lazy_loader.loader
|
||||
self.assertEqual(('module name', 'module path'), loader.args)
|
||||
self.assertEqual({'kw': 'kw'}, loader.kwargs)
|
||||
|
||||
def test_validation(self):
|
||||
# No exec_module(), no lazy loading.
|
||||
with self.assertRaises(TypeError):
|
||||
util.LazyLoader.factory(object)
|
||||
|
||||
|
||||
class TestingImporter(abc.MetaPathFinder, abc.Loader):
|
||||
|
||||
module_name = 'lazy_loader_test'
|
||||
mutated_name = 'changed'
|
||||
loaded = None
|
||||
source_code = 'attr = 42; __name__ = {!r}'.format(mutated_name)
|
||||
|
||||
def find_spec(self, name, path, target=None):
|
||||
if name != self.module_name:
|
||||
return None
|
||||
return util.spec_from_loader(name, util.LazyLoader(self))
|
||||
|
||||
def exec_module(self, module):
|
||||
exec(self.source_code, module.__dict__)
|
||||
self.loaded = module
|
||||
|
||||
|
||||
class LazyLoaderTests(unittest.TestCase):
|
||||
|
||||
def test_init(self):
|
||||
with self.assertRaises(TypeError):
|
||||
# Classes that dono't define exec_module() trigger TypeError.
|
||||
util.LazyLoader(object)
|
||||
|
||||
def new_module(self, source_code=None):
|
||||
loader = TestingImporter()
|
||||
if source_code is not None:
|
||||
loader.source_code = source_code
|
||||
spec = util.spec_from_loader(TestingImporter.module_name,
|
||||
util.LazyLoader(loader))
|
||||
module = spec.loader.create_module(spec)
|
||||
if module is None:
|
||||
module = types.ModuleType(TestingImporter.module_name)
|
||||
module.__spec__ = spec
|
||||
module.__loader__ = spec.loader
|
||||
spec.loader.exec_module(module)
|
||||
# Module is now lazy.
|
||||
self.assertIsNone(loader.loaded)
|
||||
return module
|
||||
|
||||
def test_e2e(self):
|
||||
# End-to-end test to verify the load is in fact lazy.
|
||||
importer = TestingImporter()
|
||||
assert importer.loaded is None
|
||||
with test_util.uncache(importer.module_name):
|
||||
with test_util.import_state(meta_path=[importer]):
|
||||
module = importlib.import_module(importer.module_name)
|
||||
self.assertIsNone(importer.loaded)
|
||||
# Trigger load.
|
||||
self.assertEqual(module.__loader__, importer)
|
||||
self.assertIsNotNone(importer.loaded)
|
||||
self.assertEqual(module, importer.loaded)
|
||||
|
||||
def test_attr_unchanged(self):
|
||||
# An attribute only mutated as a side-effect of import should not be
|
||||
# changed needlessly.
|
||||
module = self.new_module()
|
||||
self.assertEqual(TestingImporter.mutated_name, module.__name__)
|
||||
|
||||
def test_new_attr(self):
|
||||
# A new attribute should persist.
|
||||
module = self.new_module()
|
||||
module.new_attr = 42
|
||||
self.assertEqual(42, module.new_attr)
|
||||
|
||||
def test_mutated_preexisting_attr(self):
|
||||
# Changing an attribute that already existed on the module --
|
||||
# e.g. __name__ -- should persist.
|
||||
module = self.new_module()
|
||||
module.__name__ = 'bogus'
|
||||
self.assertEqual('bogus', module.__name__)
|
||||
|
||||
def test_mutated_attr(self):
|
||||
# Changing an attribute that comes into existence after an import
|
||||
# should persist.
|
||||
module = self.new_module()
|
||||
module.attr = 6
|
||||
self.assertEqual(6, module.attr)
|
||||
|
||||
def test_delete_eventual_attr(self):
|
||||
# Deleting an attribute should stay deleted.
|
||||
module = self.new_module()
|
||||
del module.attr
|
||||
self.assertFalse(hasattr(module, 'attr'))
|
||||
|
||||
def test_delete_preexisting_attr(self):
|
||||
module = self.new_module()
|
||||
del module.__name__
|
||||
self.assertFalse(hasattr(module, '__name__'))
|
||||
|
||||
def test_module_substitution_error(self):
|
||||
with test_util.uncache(TestingImporter.module_name):
|
||||
fresh_module = types.ModuleType(TestingImporter.module_name)
|
||||
sys.modules[TestingImporter.module_name] = fresh_module
|
||||
module = self.new_module()
|
||||
with self.assertRaisesRegex(ValueError, "substituted"):
|
||||
module.__name__
|
||||
|
||||
def test_module_already_in_sys(self):
|
||||
with test_util.uncache(TestingImporter.module_name):
|
||||
module = self.new_module()
|
||||
sys.modules[TestingImporter.module_name] = module
|
||||
# Force the load; just care that no exception is raised.
|
||||
module.__name__
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
175
third_party/python/Lib/test/test_importlib/test_locks.py
vendored
Normal file
175
third_party/python/Lib/test/test_importlib/test_locks.py
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
from . import util as test_util
|
||||
|
||||
init = test_util.import_importlib('importlib')
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
import weakref
|
||||
|
||||
from test import support
|
||||
|
||||
try:
|
||||
import threading
|
||||
except ImportError:
|
||||
threading = None
|
||||
else:
|
||||
from test import lock_tests
|
||||
|
||||
if threading is not None:
|
||||
class ModuleLockAsRLockTests:
|
||||
locktype = classmethod(lambda cls: cls.LockType("some_lock"))
|
||||
|
||||
# _is_owned() unsupported
|
||||
test__is_owned = None
|
||||
# acquire(blocking=False) unsupported
|
||||
test_try_acquire = None
|
||||
test_try_acquire_contended = None
|
||||
# `with` unsupported
|
||||
test_with = None
|
||||
# acquire(timeout=...) unsupported
|
||||
test_timeout = None
|
||||
# _release_save() unsupported
|
||||
test_release_save_unacquired = None
|
||||
# lock status in repr unsupported
|
||||
test_repr = None
|
||||
test_locked_repr = None
|
||||
|
||||
LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
|
||||
for kind, splitinit in init.items()}
|
||||
|
||||
(Frozen_ModuleLockAsRLockTests,
|
||||
Source_ModuleLockAsRLockTests
|
||||
) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests,
|
||||
LockType=LOCK_TYPES)
|
||||
else:
|
||||
LOCK_TYPES = {}
|
||||
|
||||
class Frozen_ModuleLockAsRLockTests(unittest.TestCase):
|
||||
pass
|
||||
|
||||
class Source_ModuleLockAsRLockTests(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
if threading is not None:
|
||||
class DeadlockAvoidanceTests:
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
self.old_switchinterval = sys.getswitchinterval()
|
||||
support.setswitchinterval(0.000001)
|
||||
except AttributeError:
|
||||
self.old_switchinterval = None
|
||||
|
||||
def tearDown(self):
|
||||
if self.old_switchinterval is not None:
|
||||
sys.setswitchinterval(self.old_switchinterval)
|
||||
|
||||
def run_deadlock_avoidance_test(self, create_deadlock):
|
||||
NLOCKS = 10
|
||||
locks = [self.LockType(str(i)) for i in range(NLOCKS)]
|
||||
pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)]
|
||||
if create_deadlock:
|
||||
NTHREADS = NLOCKS
|
||||
else:
|
||||
NTHREADS = NLOCKS - 1
|
||||
barrier = threading.Barrier(NTHREADS)
|
||||
results = []
|
||||
|
||||
def _acquire(lock):
|
||||
"""Try to acquire the lock. Return True on success,
|
||||
False on deadlock."""
|
||||
try:
|
||||
lock.acquire()
|
||||
except self.DeadlockError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def f():
|
||||
a, b = pairs.pop()
|
||||
ra = _acquire(a)
|
||||
barrier.wait()
|
||||
rb = _acquire(b)
|
||||
results.append((ra, rb))
|
||||
if rb:
|
||||
b.release()
|
||||
if ra:
|
||||
a.release()
|
||||
lock_tests.Bunch(f, NTHREADS).wait_for_finished()
|
||||
self.assertEqual(len(results), NTHREADS)
|
||||
return results
|
||||
|
||||
def test_deadlock(self):
|
||||
results = self.run_deadlock_avoidance_test(True)
|
||||
# At least one of the threads detected a potential deadlock on its
|
||||
# second acquire() call. It may be several of them, because the
|
||||
# deadlock avoidance mechanism is conservative.
|
||||
nb_deadlocks = results.count((True, False))
|
||||
self.assertGreaterEqual(nb_deadlocks, 1)
|
||||
self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks)
|
||||
|
||||
def test_no_deadlock(self):
|
||||
results = self.run_deadlock_avoidance_test(False)
|
||||
self.assertEqual(results.count((True, False)), 0)
|
||||
self.assertEqual(results.count((True, True)), len(results))
|
||||
|
||||
|
||||
DEADLOCK_ERRORS = {kind: splitinit._bootstrap._DeadlockError
|
||||
for kind, splitinit in init.items()}
|
||||
|
||||
(Frozen_DeadlockAvoidanceTests,
|
||||
Source_DeadlockAvoidanceTests
|
||||
) = test_util.test_both(DeadlockAvoidanceTests,
|
||||
LockType=LOCK_TYPES,
|
||||
DeadlockError=DEADLOCK_ERRORS)
|
||||
else:
|
||||
DEADLOCK_ERRORS = {}
|
||||
|
||||
class Frozen_DeadlockAvoidanceTests(unittest.TestCase):
|
||||
pass
|
||||
|
||||
class Source_DeadlockAvoidanceTests(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
class LifetimeTests:
|
||||
|
||||
@property
|
||||
def bootstrap(self):
|
||||
return self.init._bootstrap
|
||||
|
||||
def test_lock_lifetime(self):
|
||||
name = "xyzzy"
|
||||
self.assertNotIn(name, self.bootstrap._module_locks)
|
||||
lock = self.bootstrap._get_module_lock(name)
|
||||
self.assertIn(name, self.bootstrap._module_locks)
|
||||
wr = weakref.ref(lock)
|
||||
del lock
|
||||
support.gc_collect()
|
||||
self.assertNotIn(name, self.bootstrap._module_locks)
|
||||
self.assertIsNone(wr())
|
||||
|
||||
def test_all_locks(self):
|
||||
support.gc_collect()
|
||||
self.assertEqual(0, len(self.bootstrap._module_locks),
|
||||
self.bootstrap._module_locks)
|
||||
|
||||
|
||||
(Frozen_LifetimeTests,
|
||||
Source_LifetimeTests
|
||||
) = test_util.test_both(LifetimeTests, init=init)
|
||||
|
||||
|
||||
@support.reap_threads
|
||||
def test_main():
|
||||
support.run_unittest(Frozen_ModuleLockAsRLockTests,
|
||||
Source_ModuleLockAsRLockTests,
|
||||
Frozen_DeadlockAvoidanceTests,
|
||||
Source_DeadlockAvoidanceTests,
|
||||
Frozen_LifetimeTests,
|
||||
Source_LifetimeTests)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_main()
|
321
third_party/python/Lib/test/test_importlib/test_namespace_pkgs.py
vendored
Normal file
321
third_party/python/Lib/test/test_importlib/test_namespace_pkgs.py
vendored
Normal file
|
@ -0,0 +1,321 @@
|
|||
import contextlib
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from test.test_importlib import util
|
||||
|
||||
# needed tests:
|
||||
#
|
||||
# need to test when nested, so that the top-level path isn't sys.path
|
||||
# need to test dynamic path detection, both at top-level and nested
|
||||
# with dynamic path, check when a loader is returned on path reload (that is,
|
||||
# trying to switch from a namespace package to a regular package)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def sys_modules_context():
|
||||
"""
|
||||
Make sure sys.modules is the same object and has the same content
|
||||
when exiting the context as when entering.
|
||||
|
||||
Similar to importlib.test.util.uncache, but doesn't require explicit
|
||||
names.
|
||||
"""
|
||||
sys_modules_saved = sys.modules
|
||||
sys_modules_copy = sys.modules.copy()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
sys.modules = sys_modules_saved
|
||||
sys.modules.clear()
|
||||
sys.modules.update(sys_modules_copy)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def namespace_tree_context(**kwargs):
|
||||
"""
|
||||
Save import state and sys.modules cache and restore it on exit.
|
||||
Typical usage:
|
||||
|
||||
>>> with namespace_tree_context(path=['/tmp/xxyy/portion1',
|
||||
... '/tmp/xxyy/portion2']):
|
||||
... pass
|
||||
"""
|
||||
# use default meta_path and path_hooks unless specified otherwise
|
||||
kwargs.setdefault('meta_path', sys.meta_path)
|
||||
kwargs.setdefault('path_hooks', sys.path_hooks)
|
||||
import_context = util.import_state(**kwargs)
|
||||
with import_context, sys_modules_context():
|
||||
yield
|
||||
|
||||
class NamespacePackageTest(unittest.TestCase):
|
||||
"""
|
||||
Subclasses should define self.root and self.paths (under that root)
|
||||
to be added to sys.path.
|
||||
"""
|
||||
root = os.path.join(os.path.dirname(__file__), 'namespace_pkgs')
|
||||
|
||||
def setUp(self):
|
||||
self.resolved_paths = [
|
||||
os.path.join(self.root, path) for path in self.paths
|
||||
]
|
||||
self.ctx = namespace_tree_context(path=self.resolved_paths)
|
||||
self.ctx.__enter__()
|
||||
|
||||
def tearDown(self):
|
||||
# TODO: will we ever want to pass exc_info to __exit__?
|
||||
self.ctx.__exit__(None, None, None)
|
||||
|
||||
|
||||
class SingleNamespacePackage(NamespacePackageTest):
|
||||
paths = ['portion1']
|
||||
|
||||
def test_simple_package(self):
|
||||
import foo.one
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
|
||||
def test_cant_import_other(self):
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
def test_module_repr(self):
|
||||
import foo.one
|
||||
self.assertEqual(repr(foo), "<module 'foo' (namespace)>")
|
||||
|
||||
|
||||
class DynamicPathNamespacePackage(NamespacePackageTest):
|
||||
paths = ['portion1']
|
||||
|
||||
def test_dynamic_path(self):
|
||||
# Make sure only 'foo.one' can be imported
|
||||
import foo.one
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
# Now modify sys.path
|
||||
sys.path.append(os.path.join(self.root, 'portion2'))
|
||||
|
||||
# And make sure foo.two is now importable
|
||||
import foo.two
|
||||
self.assertEqual(foo.two.attr, 'portion2 foo two')
|
||||
|
||||
|
||||
class CombinedNamespacePackages(NamespacePackageTest):
|
||||
paths = ['both_portions']
|
||||
|
||||
def test_imports(self):
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'both_portions foo one')
|
||||
self.assertEqual(foo.two.attr, 'both_portions foo two')
|
||||
|
||||
|
||||
class SeparatedNamespacePackages(NamespacePackageTest):
|
||||
paths = ['portion1', 'portion2']
|
||||
|
||||
def test_imports(self):
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
self.assertEqual(foo.two.attr, 'portion2 foo two')
|
||||
|
||||
|
||||
class SeparatedOverlappingNamespacePackages(NamespacePackageTest):
|
||||
paths = ['portion1', 'both_portions']
|
||||
|
||||
def test_first_path_wins(self):
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
self.assertEqual(foo.two.attr, 'both_portions foo two')
|
||||
|
||||
def test_first_path_wins_again(self):
|
||||
sys.path.reverse()
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'both_portions foo one')
|
||||
self.assertEqual(foo.two.attr, 'both_portions foo two')
|
||||
|
||||
def test_first_path_wins_importing_second_first(self):
|
||||
import foo.two
|
||||
import foo.one
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
self.assertEqual(foo.two.attr, 'both_portions foo two')
|
||||
|
||||
|
||||
class SingleZipNamespacePackage(NamespacePackageTest):
|
||||
paths = ['top_level_portion1.zip']
|
||||
|
||||
def test_simple_package(self):
|
||||
import foo.one
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
|
||||
def test_cant_import_other(self):
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
|
||||
class SeparatedZipNamespacePackages(NamespacePackageTest):
|
||||
paths = ['top_level_portion1.zip', 'portion2']
|
||||
|
||||
def test_imports(self):
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
self.assertEqual(foo.two.attr, 'portion2 foo two')
|
||||
self.assertIn('top_level_portion1.zip', foo.one.__file__)
|
||||
self.assertNotIn('.zip', foo.two.__file__)
|
||||
|
||||
|
||||
class SingleNestedZipNamespacePackage(NamespacePackageTest):
|
||||
paths = ['nested_portion1.zip/nested_portion1']
|
||||
|
||||
def test_simple_package(self):
|
||||
import foo.one
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
|
||||
def test_cant_import_other(self):
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
|
||||
class SeparatedNestedZipNamespacePackages(NamespacePackageTest):
|
||||
paths = ['nested_portion1.zip/nested_portion1', 'portion2']
|
||||
|
||||
def test_imports(self):
|
||||
import foo.one
|
||||
import foo.two
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
self.assertEqual(foo.two.attr, 'portion2 foo two')
|
||||
fn = os.path.join('nested_portion1.zip', 'nested_portion1')
|
||||
self.assertIn(fn, foo.one.__file__)
|
||||
self.assertNotIn('.zip', foo.two.__file__)
|
||||
|
||||
|
||||
class LegacySupport(NamespacePackageTest):
|
||||
paths = ['not_a_namespace_pkg', 'portion1', 'portion2', 'both_portions']
|
||||
|
||||
def test_non_namespace_package_takes_precedence(self):
|
||||
import foo.one
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
self.assertIn('__init__', foo.__file__)
|
||||
self.assertNotIn('namespace', str(foo.__loader__).lower())
|
||||
|
||||
|
||||
class DynamicPathCalculation(NamespacePackageTest):
|
||||
paths = ['project1', 'project2']
|
||||
|
||||
def test_project3_fails(self):
|
||||
import parent.child.one
|
||||
self.assertEqual(len(parent.__path__), 2)
|
||||
self.assertEqual(len(parent.child.__path__), 2)
|
||||
import parent.child.two
|
||||
self.assertEqual(len(parent.__path__), 2)
|
||||
self.assertEqual(len(parent.child.__path__), 2)
|
||||
|
||||
self.assertEqual(parent.child.one.attr, 'parent child one')
|
||||
self.assertEqual(parent.child.two.attr, 'parent child two')
|
||||
|
||||
with self.assertRaises(ImportError):
|
||||
import parent.child.three
|
||||
|
||||
self.assertEqual(len(parent.__path__), 2)
|
||||
self.assertEqual(len(parent.child.__path__), 2)
|
||||
|
||||
def test_project3_succeeds(self):
|
||||
import parent.child.one
|
||||
self.assertEqual(len(parent.__path__), 2)
|
||||
self.assertEqual(len(parent.child.__path__), 2)
|
||||
import parent.child.two
|
||||
self.assertEqual(len(parent.__path__), 2)
|
||||
self.assertEqual(len(parent.child.__path__), 2)
|
||||
|
||||
self.assertEqual(parent.child.one.attr, 'parent child one')
|
||||
self.assertEqual(parent.child.two.attr, 'parent child two')
|
||||
|
||||
with self.assertRaises(ImportError):
|
||||
import parent.child.three
|
||||
|
||||
# now add project3
|
||||
sys.path.append(os.path.join(self.root, 'project3'))
|
||||
import parent.child.three
|
||||
|
||||
# the paths dynamically get longer, to include the new directories
|
||||
self.assertEqual(len(parent.__path__), 3)
|
||||
self.assertEqual(len(parent.child.__path__), 3)
|
||||
|
||||
self.assertEqual(parent.child.three.attr, 'parent child three')
|
||||
|
||||
|
||||
class ZipWithMissingDirectory(NamespacePackageTest):
|
||||
paths = ['missing_directory.zip']
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_missing_directory(self):
|
||||
# This will fail because missing_directory.zip contains:
|
||||
# Length Date Time Name
|
||||
# --------- ---------- ----- ----
|
||||
# 29 2012-05-03 18:13 foo/one.py
|
||||
# 0 2012-05-03 20:57 bar/
|
||||
# 38 2012-05-03 20:57 bar/two.py
|
||||
# --------- -------
|
||||
# 67 3 files
|
||||
|
||||
# Because there is no 'foo/', the zipimporter currently doesn't
|
||||
# know that foo is a namespace package
|
||||
|
||||
import foo.one
|
||||
|
||||
def test_present_directory(self):
|
||||
# This succeeds because there is a "bar/" in the zip file
|
||||
import bar.two
|
||||
self.assertEqual(bar.two.attr, 'missing_directory foo two')
|
||||
|
||||
|
||||
class ModuleAndNamespacePackageInSameDir(NamespacePackageTest):
|
||||
paths = ['module_and_namespace_package']
|
||||
|
||||
def test_module_before_namespace_package(self):
|
||||
# Make sure we find the module in preference to the
|
||||
# namespace package.
|
||||
import a_test
|
||||
self.assertEqual(a_test.attr, 'in module')
|
||||
|
||||
|
||||
class ReloadTests(NamespacePackageTest):
|
||||
paths = ['portion1']
|
||||
|
||||
def test_simple_package(self):
|
||||
import foo.one
|
||||
foo = importlib.reload(foo)
|
||||
self.assertEqual(foo.one.attr, 'portion1 foo one')
|
||||
|
||||
def test_cant_import_other(self):
|
||||
import foo
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
foo = importlib.reload(foo)
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
def test_dynamic_path(self):
|
||||
import foo.one
|
||||
with self.assertRaises(ImportError):
|
||||
import foo.two
|
||||
|
||||
# Now modify sys.path and reload.
|
||||
sys.path.append(os.path.join(self.root, 'portion2'))
|
||||
foo = importlib.reload(foo)
|
||||
|
||||
# And make sure foo.two is now importable
|
||||
import foo.two
|
||||
self.assertEqual(foo.two.attr, 'portion2 foo two')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
819
third_party/python/Lib/test/test_importlib/test_spec.py
vendored
Normal file
819
third_party/python/Lib/test/test_importlib/test_spec.py
vendored
Normal file
|
@ -0,0 +1,819 @@
|
|||
from . import util as test_util
|
||||
|
||||
init = test_util.import_importlib('importlib')
|
||||
machinery = test_util.import_importlib('importlib.machinery')
|
||||
util = test_util.import_importlib('importlib.util')
|
||||
|
||||
import os.path
|
||||
import pathlib
|
||||
from test.support import CleanImport
|
||||
import unittest
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
|
||||
|
||||
class TestLoader:
|
||||
|
||||
def __init__(self, path=None, is_package=None):
|
||||
self.path = path
|
||||
self.package = is_package
|
||||
|
||||
def __repr__(self):
|
||||
return '<TestLoader object>'
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'get_filename' and self.path is not None:
|
||||
return self._get_filename
|
||||
if name == 'is_package':
|
||||
return self._is_package
|
||||
raise AttributeError(name)
|
||||
|
||||
def _get_filename(self, name):
|
||||
return self.path
|
||||
|
||||
def _is_package(self, name):
|
||||
return self.package
|
||||
|
||||
def create_module(self, spec):
|
||||
return None
|
||||
|
||||
|
||||
class NewLoader(TestLoader):
|
||||
|
||||
EGGS = 1
|
||||
|
||||
def exec_module(self, module):
|
||||
module.eggs = self.EGGS
|
||||
|
||||
|
||||
class LegacyLoader(TestLoader):
|
||||
|
||||
HAM = -1
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
|
||||
frozen_util = util['Frozen']
|
||||
|
||||
@frozen_util.module_for_loader
|
||||
def load_module(self, module):
|
||||
module.ham = self.HAM
|
||||
return module
|
||||
|
||||
|
||||
class ModuleSpecTests:
|
||||
|
||||
def setUp(self):
|
||||
self.name = 'spam'
|
||||
self.path = 'spam.py'
|
||||
self.cached = self.util.cache_from_source(self.path)
|
||||
self.loader = TestLoader()
|
||||
self.spec = self.machinery.ModuleSpec(self.name, self.loader)
|
||||
self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
origin=self.path)
|
||||
self.loc_spec._set_fileattr = True
|
||||
|
||||
def test_default(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_default_no_loader(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, None)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertIs(spec.loader, None)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_default_is_package_false(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
is_package=False)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_default_is_package_true(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
is_package=True)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [])
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_has_location_setter(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
origin='somewhere')
|
||||
self.assertFalse(spec.has_location)
|
||||
spec.has_location = True
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_equality(self):
|
||||
other = type(sys.implementation)(name=self.name,
|
||||
loader=self.loader,
|
||||
origin=None,
|
||||
submodule_search_locations=None,
|
||||
has_location=False,
|
||||
cached=None,
|
||||
)
|
||||
|
||||
self.assertTrue(self.spec == other)
|
||||
|
||||
def test_equality_location(self):
|
||||
other = type(sys.implementation)(name=self.name,
|
||||
loader=self.loader,
|
||||
origin=self.path,
|
||||
submodule_search_locations=None,
|
||||
has_location=True,
|
||||
cached=self.cached,
|
||||
)
|
||||
|
||||
self.assertEqual(self.loc_spec, other)
|
||||
|
||||
def test_inequality(self):
|
||||
other = type(sys.implementation)(name='ham',
|
||||
loader=self.loader,
|
||||
origin=None,
|
||||
submodule_search_locations=None,
|
||||
has_location=False,
|
||||
cached=None,
|
||||
)
|
||||
|
||||
self.assertNotEqual(self.spec, other)
|
||||
|
||||
def test_inequality_incomplete(self):
|
||||
other = type(sys.implementation)(name=self.name,
|
||||
loader=self.loader,
|
||||
)
|
||||
|
||||
self.assertNotEqual(self.spec, other)
|
||||
|
||||
def test_package(self):
|
||||
spec = self.machinery.ModuleSpec('spam.eggs', self.loader)
|
||||
|
||||
self.assertEqual(spec.parent, 'spam')
|
||||
|
||||
def test_package_is_package(self):
|
||||
spec = self.machinery.ModuleSpec('spam.eggs', self.loader,
|
||||
is_package=True)
|
||||
|
||||
self.assertEqual(spec.parent, 'spam.eggs')
|
||||
|
||||
# cached
|
||||
|
||||
def test_cached_set(self):
|
||||
before = self.spec.cached
|
||||
self.spec.cached = 'there'
|
||||
after = self.spec.cached
|
||||
|
||||
self.assertIs(before, None)
|
||||
self.assertEqual(after, 'there')
|
||||
|
||||
def test_cached_no_origin(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader)
|
||||
|
||||
self.assertIs(spec.cached, None)
|
||||
|
||||
def test_cached_with_origin_not_location(self):
|
||||
spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
origin=self.path)
|
||||
|
||||
self.assertIs(spec.cached, None)
|
||||
|
||||
def test_cached_source(self):
|
||||
expected = self.util.cache_from_source(self.path)
|
||||
|
||||
self.assertEqual(self.loc_spec.cached, expected)
|
||||
|
||||
def test_cached_source_unknown_suffix(self):
|
||||
self.loc_spec.origin = 'spam.spamspamspam'
|
||||
|
||||
self.assertIs(self.loc_spec.cached, None)
|
||||
|
||||
def test_cached_source_missing_cache_tag(self):
|
||||
original = sys.implementation.cache_tag
|
||||
sys.implementation.cache_tag = None
|
||||
try:
|
||||
cached = self.loc_spec.cached
|
||||
finally:
|
||||
sys.implementation.cache_tag = original
|
||||
|
||||
self.assertIs(cached, None)
|
||||
|
||||
def test_cached_sourceless(self):
|
||||
self.loc_spec.origin = 'spam.pyc'
|
||||
|
||||
self.assertEqual(self.loc_spec.cached, 'spam.pyc')
|
||||
|
||||
|
||||
(Frozen_ModuleSpecTests,
|
||||
Source_ModuleSpecTests
|
||||
) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery)
|
||||
|
||||
|
||||
class ModuleSpecMethodsTests:
|
||||
|
||||
@property
|
||||
def bootstrap(self):
|
||||
return self.init._bootstrap
|
||||
|
||||
def setUp(self):
|
||||
self.name = 'spam'
|
||||
self.path = 'spam.py'
|
||||
self.cached = self.util.cache_from_source(self.path)
|
||||
self.loader = TestLoader()
|
||||
self.spec = self.machinery.ModuleSpec(self.name, self.loader)
|
||||
self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader,
|
||||
origin=self.path)
|
||||
self.loc_spec._set_fileattr = True
|
||||
|
||||
# exec()
|
||||
|
||||
def test_exec(self):
|
||||
self.spec.loader = NewLoader()
|
||||
module = self.util.module_from_spec(self.spec)
|
||||
sys.modules[self.name] = module
|
||||
self.assertFalse(hasattr(module, 'eggs'))
|
||||
self.bootstrap._exec(self.spec, module)
|
||||
|
||||
self.assertEqual(module.eggs, 1)
|
||||
|
||||
# load()
|
||||
|
||||
def test_load(self):
|
||||
self.spec.loader = NewLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
installed = sys.modules[self.spec.name]
|
||||
|
||||
self.assertEqual(loaded.eggs, 1)
|
||||
self.assertIs(loaded, installed)
|
||||
|
||||
def test_load_replaced(self):
|
||||
replacement = object()
|
||||
class ReplacingLoader(TestLoader):
|
||||
def exec_module(self, module):
|
||||
sys.modules[module.__name__] = replacement
|
||||
self.spec.loader = ReplacingLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
installed = sys.modules[self.spec.name]
|
||||
|
||||
self.assertIs(loaded, replacement)
|
||||
self.assertIs(installed, replacement)
|
||||
|
||||
def test_load_failed(self):
|
||||
class FailedLoader(TestLoader):
|
||||
def exec_module(self, module):
|
||||
raise RuntimeError
|
||||
self.spec.loader = FailedLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
with self.assertRaises(RuntimeError):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
self.assertNotIn(self.spec.name, sys.modules)
|
||||
|
||||
def test_load_failed_removed(self):
|
||||
class FailedLoader(TestLoader):
|
||||
def exec_module(self, module):
|
||||
del sys.modules[module.__name__]
|
||||
raise RuntimeError
|
||||
self.spec.loader = FailedLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
with self.assertRaises(RuntimeError):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
self.assertNotIn(self.spec.name, sys.modules)
|
||||
|
||||
def test_load_legacy(self):
|
||||
self.spec.loader = LegacyLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
|
||||
self.assertEqual(loaded.ham, -1)
|
||||
|
||||
def test_load_legacy_attributes(self):
|
||||
self.spec.loader = LegacyLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
|
||||
self.assertIs(loaded.__loader__, self.spec.loader)
|
||||
self.assertEqual(loaded.__package__, self.spec.parent)
|
||||
self.assertIs(loaded.__spec__, self.spec)
|
||||
|
||||
def test_load_legacy_attributes_immutable(self):
|
||||
module = object()
|
||||
class ImmutableLoader(TestLoader):
|
||||
def load_module(self, name):
|
||||
sys.modules[name] = module
|
||||
return module
|
||||
self.spec.loader = ImmutableLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
|
||||
self.assertIs(sys.modules[self.spec.name], module)
|
||||
|
||||
# reload()
|
||||
|
||||
def test_reload(self):
|
||||
self.spec.loader = NewLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
reloaded = self.bootstrap._exec(self.spec, loaded)
|
||||
installed = sys.modules[self.spec.name]
|
||||
|
||||
self.assertEqual(loaded.eggs, 1)
|
||||
self.assertIs(reloaded, loaded)
|
||||
self.assertIs(installed, loaded)
|
||||
|
||||
def test_reload_modified(self):
|
||||
self.spec.loader = NewLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
loaded.eggs = 2
|
||||
reloaded = self.bootstrap._exec(self.spec, loaded)
|
||||
|
||||
self.assertEqual(loaded.eggs, 1)
|
||||
self.assertIs(reloaded, loaded)
|
||||
|
||||
def test_reload_extra_attributes(self):
|
||||
self.spec.loader = NewLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
loaded.available = False
|
||||
reloaded = self.bootstrap._exec(self.spec, loaded)
|
||||
|
||||
self.assertFalse(loaded.available)
|
||||
self.assertIs(reloaded, loaded)
|
||||
|
||||
def test_reload_init_module_attrs(self):
|
||||
self.spec.loader = NewLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
loaded.__name__ = 'ham'
|
||||
del loaded.__loader__
|
||||
del loaded.__package__
|
||||
del loaded.__spec__
|
||||
self.bootstrap._exec(self.spec, loaded)
|
||||
|
||||
self.assertEqual(loaded.__name__, self.spec.name)
|
||||
self.assertIs(loaded.__loader__, self.spec.loader)
|
||||
self.assertEqual(loaded.__package__, self.spec.parent)
|
||||
self.assertIs(loaded.__spec__, self.spec)
|
||||
self.assertFalse(hasattr(loaded, '__path__'))
|
||||
self.assertFalse(hasattr(loaded, '__file__'))
|
||||
self.assertFalse(hasattr(loaded, '__cached__'))
|
||||
|
||||
def test_reload_legacy(self):
|
||||
self.spec.loader = LegacyLoader()
|
||||
with CleanImport(self.spec.name):
|
||||
loaded = self.bootstrap._load(self.spec)
|
||||
reloaded = self.bootstrap._exec(self.spec, loaded)
|
||||
installed = sys.modules[self.spec.name]
|
||||
|
||||
self.assertEqual(loaded.ham, -1)
|
||||
self.assertIs(reloaded, loaded)
|
||||
self.assertIs(installed, loaded)
|
||||
|
||||
|
||||
(Frozen_ModuleSpecMethodsTests,
|
||||
Source_ModuleSpecMethodsTests
|
||||
) = test_util.test_both(ModuleSpecMethodsTests, init=init, util=util,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
class ModuleReprTests:
|
||||
|
||||
@property
|
||||
def bootstrap(self):
|
||||
return self.init._bootstrap
|
||||
|
||||
def setUp(self):
|
||||
self.module = type(os)('spam')
|
||||
self.spec = self.machinery.ModuleSpec('spam', TestLoader())
|
||||
|
||||
def test_module___loader___module_repr(self):
|
||||
class Loader:
|
||||
def module_repr(self, module):
|
||||
return '<delicious {}>'.format(module.__name__)
|
||||
self.module.__loader__ = Loader()
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr, '<delicious spam>')
|
||||
|
||||
def test_module___loader___module_repr_bad(self):
|
||||
class Loader(TestLoader):
|
||||
def module_repr(self, module):
|
||||
raise Exception
|
||||
self.module.__loader__ = Loader()
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr,
|
||||
'<module {!r} (<TestLoader object>)>'.format('spam'))
|
||||
|
||||
def test_module___spec__(self):
|
||||
origin = 'in a hole, in the ground'
|
||||
self.spec.origin = origin
|
||||
self.module.__spec__ = self.spec
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr, '<module {!r} ({})>'.format('spam', origin))
|
||||
|
||||
def test_module___spec___location(self):
|
||||
location = 'in_a_galaxy_far_far_away.py'
|
||||
self.spec.origin = location
|
||||
self.spec._set_fileattr = True
|
||||
self.module.__spec__ = self.spec
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr,
|
||||
'<module {!r} from {!r}>'.format('spam', location))
|
||||
|
||||
def test_module___spec___no_origin(self):
|
||||
self.spec.loader = TestLoader()
|
||||
self.module.__spec__ = self.spec
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr,
|
||||
'<module {!r} (<TestLoader object>)>'.format('spam'))
|
||||
|
||||
def test_module___spec___no_origin_no_loader(self):
|
||||
self.spec.loader = None
|
||||
self.module.__spec__ = self.spec
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr, '<module {!r}>'.format('spam'))
|
||||
|
||||
def test_module_no_name(self):
|
||||
del self.module.__name__
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr, '<module {!r}>'.format('?'))
|
||||
|
||||
def test_module_with_file(self):
|
||||
filename = 'e/i/e/i/o/spam.py'
|
||||
self.module.__file__ = filename
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr,
|
||||
'<module {!r} from {!r}>'.format('spam', filename))
|
||||
|
||||
def test_module_no_file(self):
|
||||
self.module.__loader__ = TestLoader()
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr,
|
||||
'<module {!r} (<TestLoader object>)>'.format('spam'))
|
||||
|
||||
def test_module_no_file_no_loader(self):
|
||||
modrepr = self.bootstrap._module_repr(self.module)
|
||||
|
||||
self.assertEqual(modrepr, '<module {!r}>'.format('spam'))
|
||||
|
||||
|
||||
(Frozen_ModuleReprTests,
|
||||
Source_ModuleReprTests
|
||||
) = test_util.test_both(ModuleReprTests, init=init, util=util,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
class FactoryTests:
|
||||
|
||||
def setUp(self):
|
||||
self.name = 'spam'
|
||||
self.path = 'spam.py'
|
||||
self.cached = self.util.cache_from_source(self.path)
|
||||
self.loader = TestLoader()
|
||||
self.fileloader = TestLoader(self.path)
|
||||
self.pkgloader = TestLoader(self.path, True)
|
||||
|
||||
# spec_from_loader()
|
||||
|
||||
def test_spec_from_loader_default(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_default_with_bad_is_package(self):
|
||||
class Loader:
|
||||
def is_package(self, name):
|
||||
raise ImportError
|
||||
loader = Loader()
|
||||
spec = self.util.spec_from_loader(self.name, loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_origin(self):
|
||||
origin = 'somewhere over the rainbow'
|
||||
spec = self.util.spec_from_loader(self.name, self.loader,
|
||||
origin=origin)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, origin)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_false(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.loader,
|
||||
is_package=False)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_true(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.loader,
|
||||
is_package=True)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [])
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_origin_and_is_package(self):
|
||||
origin = 'where the streets have no name'
|
||||
spec = self.util.spec_from_loader(self.name, self.loader,
|
||||
origin=origin, is_package=True)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertIs(spec.origin, origin)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [])
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_with_loader_false(self):
|
||||
loader = TestLoader(is_package=False)
|
||||
spec = self.util.spec_from_loader(self.name, loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_with_loader_true(self):
|
||||
loader = TestLoader(is_package=True)
|
||||
spec = self.util.spec_from_loader(self.name, loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertIs(spec.origin, None)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [])
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertFalse(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_default_with_file_loader(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.fileloader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_false_with_fileloader(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.fileloader,
|
||||
is_package=False)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_loader_is_package_true_with_fileloader(self):
|
||||
spec = self.util.spec_from_loader(self.name, self.fileloader,
|
||||
is_package=True)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [''])
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
# spec_from_file_location()
|
||||
|
||||
def test_spec_from_file_location_default(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
# Need to use a circuitous route to get at importlib.machinery to make
|
||||
# sure the same class object is used in the isinstance() check as
|
||||
# would have been used to create the loader.
|
||||
self.assertIsInstance(spec.loader,
|
||||
self.util.abc.machinery.SourceFileLoader)
|
||||
self.assertEqual(spec.loader.name, self.name)
|
||||
self.assertEqual(spec.loader.path, self.path)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_path_like_arg(self):
|
||||
spec = self.util.spec_from_file_location(self.name,
|
||||
pathlib.PurePath(self.path))
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
|
||||
def test_spec_from_file_location_default_without_location(self):
|
||||
spec = self.util.spec_from_file_location(self.name)
|
||||
|
||||
self.assertIs(spec, None)
|
||||
|
||||
def test_spec_from_file_location_default_bad_suffix(self):
|
||||
spec = self.util.spec_from_file_location(self.name, 'spam.eggs')
|
||||
|
||||
self.assertIs(spec, None)
|
||||
|
||||
def test_spec_from_file_location_loader_no_location(self):
|
||||
spec = self.util.spec_from_file_location(self.name,
|
||||
loader=self.fileloader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_loader_no_location_no_get_filename(self):
|
||||
spec = self.util.spec_from_file_location(self.name,
|
||||
loader=self.loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.loader)
|
||||
self.assertEqual(spec.origin, '<unknown>')
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_loader_no_location_bad_get_filename(self):
|
||||
class Loader:
|
||||
def get_filename(self, name):
|
||||
raise ImportError
|
||||
loader = Loader()
|
||||
spec = self.util.spec_from_file_location(self.name, loader=loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertEqual(spec.origin, '<unknown>')
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertIs(spec.cached, None)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_none(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=self.fileloader,
|
||||
submodule_search_locations=None)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_empty(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=self.fileloader,
|
||||
submodule_search_locations=[])
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [''])
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_not_empty(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=self.fileloader,
|
||||
submodule_search_locations=['eggs'])
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, ['eggs'])
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_default(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=self.pkgloader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.pkgloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertEqual(spec.submodule_search_locations, [''])
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_default_not_package(self):
|
||||
class Loader:
|
||||
def is_package(self, name):
|
||||
return False
|
||||
loader = Loader()
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_default_no_is_package(self):
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=self.fileloader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, self.fileloader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
def test_spec_from_file_location_smsl_default_bad_is_package(self):
|
||||
class Loader:
|
||||
def is_package(self, name):
|
||||
raise ImportError
|
||||
loader = Loader()
|
||||
spec = self.util.spec_from_file_location(self.name, self.path,
|
||||
loader=loader)
|
||||
|
||||
self.assertEqual(spec.name, self.name)
|
||||
self.assertEqual(spec.loader, loader)
|
||||
self.assertEqual(spec.origin, self.path)
|
||||
self.assertIs(spec.loader_state, None)
|
||||
self.assertIs(spec.submodule_search_locations, None)
|
||||
self.assertEqual(spec.cached, self.cached)
|
||||
self.assertTrue(spec.has_location)
|
||||
|
||||
|
||||
(Frozen_FactoryTests,
|
||||
Source_FactoryTests
|
||||
) = test_util.test_both(FactoryTests, util=util, machinery=machinery)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
805
third_party/python/Lib/test/test_importlib/test_util.py
vendored
Normal file
805
third_party/python/Lib/test/test_importlib/test_util.py
vendored
Normal file
|
@ -0,0 +1,805 @@
|
|||
from . import util
|
||||
abc = util.import_importlib('importlib.abc')
|
||||
init = util.import_importlib('importlib')
|
||||
machinery = util.import_importlib('importlib.machinery')
|
||||
importlib_util = util.import_importlib('importlib.util')
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import pathlib
|
||||
import string
|
||||
import sys
|
||||
from test import support
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
class DecodeSourceBytesTests:
|
||||
|
||||
source = "string ='ü'"
|
||||
|
||||
def test_ut8_default(self):
|
||||
source_bytes = self.source.encode('utf-8')
|
||||
self.assertEqual(self.util.decode_source(source_bytes), self.source)
|
||||
|
||||
def test_specified_encoding(self):
|
||||
source = '# coding=latin-1\n' + self.source
|
||||
source_bytes = source.encode('latin-1')
|
||||
assert source_bytes != source.encode('utf-8')
|
||||
self.assertEqual(self.util.decode_source(source_bytes), source)
|
||||
|
||||
def test_universal_newlines(self):
|
||||
source = '\r\n'.join([self.source, self.source])
|
||||
source_bytes = source.encode('utf-8')
|
||||
self.assertEqual(self.util.decode_source(source_bytes),
|
||||
'\n'.join([self.source, self.source]))
|
||||
|
||||
|
||||
(Frozen_DecodeSourceBytesTests,
|
||||
Source_DecodeSourceBytesTests
|
||||
) = util.test_both(DecodeSourceBytesTests, util=importlib_util)
|
||||
|
||||
|
||||
class ModuleFromSpecTests:
|
||||
|
||||
def test_no_create_module(self):
|
||||
class Loader:
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
spec = self.machinery.ModuleSpec('test', Loader())
|
||||
with self.assertRaises(ImportError):
|
||||
module = self.util.module_from_spec(spec)
|
||||
|
||||
def test_create_module_returns_None(self):
|
||||
class Loader(self.abc.Loader):
|
||||
def create_module(self, spec):
|
||||
return None
|
||||
spec = self.machinery.ModuleSpec('test', Loader())
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
self.assertEqual(module.__name__, spec.name)
|
||||
|
||||
def test_create_module(self):
|
||||
name = 'already set'
|
||||
class CustomModule(types.ModuleType):
|
||||
pass
|
||||
class Loader(self.abc.Loader):
|
||||
def create_module(self, spec):
|
||||
module = CustomModule(spec.name)
|
||||
module.__name__ = name
|
||||
return module
|
||||
spec = self.machinery.ModuleSpec('test', Loader())
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertIsInstance(module, CustomModule)
|
||||
self.assertEqual(module.__name__, name)
|
||||
|
||||
def test___name__(self):
|
||||
spec = self.machinery.ModuleSpec('test', object())
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__name__, spec.name)
|
||||
|
||||
def test___spec__(self):
|
||||
spec = self.machinery.ModuleSpec('test', object())
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__spec__, spec)
|
||||
|
||||
def test___loader__(self):
|
||||
loader = object()
|
||||
spec = self.machinery.ModuleSpec('test', loader)
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertIs(module.__loader__, loader)
|
||||
|
||||
def test___package__(self):
|
||||
spec = self.machinery.ModuleSpec('test.pkg', object())
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__package__, spec.parent)
|
||||
|
||||
def test___path__(self):
|
||||
spec = self.machinery.ModuleSpec('test', object(), is_package=True)
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__path__, spec.submodule_search_locations)
|
||||
|
||||
def test___file__(self):
|
||||
spec = self.machinery.ModuleSpec('test', object(), origin='some/path')
|
||||
spec.has_location = True
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__file__, spec.origin)
|
||||
|
||||
def test___cached__(self):
|
||||
spec = self.machinery.ModuleSpec('test', object())
|
||||
spec.cached = 'some/path'
|
||||
spec.has_location = True
|
||||
module = self.util.module_from_spec(spec)
|
||||
self.assertEqual(module.__cached__, spec.cached)
|
||||
|
||||
(Frozen_ModuleFromSpecTests,
|
||||
Source_ModuleFromSpecTests
|
||||
) = util.test_both(ModuleFromSpecTests, abc=abc, machinery=machinery,
|
||||
util=importlib_util)
|
||||
|
||||
|
||||
class ModuleForLoaderTests:
|
||||
|
||||
"""Tests for importlib.util.module_for_loader."""
|
||||
|
||||
@classmethod
|
||||
def module_for_loader(cls, func):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
return cls.util.module_for_loader(func)
|
||||
|
||||
def test_warning(self):
|
||||
# Should raise a PendingDeprecationWarning when used.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error', DeprecationWarning)
|
||||
with self.assertRaises(DeprecationWarning):
|
||||
func = self.util.module_for_loader(lambda x: x)
|
||||
|
||||
def return_module(self, name):
|
||||
fxn = self.module_for_loader(lambda self, module: module)
|
||||
return fxn(self, name)
|
||||
|
||||
def raise_exception(self, name):
|
||||
def to_wrap(self, module):
|
||||
raise ImportError
|
||||
fxn = self.module_for_loader(to_wrap)
|
||||
try:
|
||||
fxn(self, name)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def test_new_module(self):
|
||||
# Test that when no module exists in sys.modules a new module is
|
||||
# created.
|
||||
module_name = 'a.b.c'
|
||||
with util.uncache(module_name):
|
||||
module = self.return_module(module_name)
|
||||
self.assertIn(module_name, sys.modules)
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
self.assertEqual(module.__name__, module_name)
|
||||
|
||||
def test_reload(self):
|
||||
# Test that a module is reused if already in sys.modules.
|
||||
class FakeLoader:
|
||||
def is_package(self, name):
|
||||
return True
|
||||
@self.module_for_loader
|
||||
def load_module(self, module):
|
||||
return module
|
||||
name = 'a.b.c'
|
||||
module = types.ModuleType('a.b.c')
|
||||
module.__loader__ = 42
|
||||
module.__package__ = 42
|
||||
with util.uncache(name):
|
||||
sys.modules[name] = module
|
||||
loader = FakeLoader()
|
||||
returned_module = loader.load_module(name)
|
||||
self.assertIs(returned_module, sys.modules[name])
|
||||
self.assertEqual(module.__loader__, loader)
|
||||
self.assertEqual(module.__package__, name)
|
||||
|
||||
def test_new_module_failure(self):
|
||||
# Test that a module is removed from sys.modules if added but an
|
||||
# exception is raised.
|
||||
name = 'a.b.c'
|
||||
with util.uncache(name):
|
||||
self.raise_exception(name)
|
||||
self.assertNotIn(name, sys.modules)
|
||||
|
||||
def test_reload_failure(self):
|
||||
# Test that a failure on reload leaves the module in-place.
|
||||
name = 'a.b.c'
|
||||
module = types.ModuleType(name)
|
||||
with util.uncache(name):
|
||||
sys.modules[name] = module
|
||||
self.raise_exception(name)
|
||||
self.assertIs(module, sys.modules[name])
|
||||
|
||||
def test_decorator_attrs(self):
|
||||
def fxn(self, module): pass
|
||||
wrapped = self.module_for_loader(fxn)
|
||||
self.assertEqual(wrapped.__name__, fxn.__name__)
|
||||
self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
|
||||
|
||||
def test_false_module(self):
|
||||
# If for some odd reason a module is considered false, still return it
|
||||
# from sys.modules.
|
||||
class FalseModule(types.ModuleType):
|
||||
def __bool__(self): return False
|
||||
|
||||
name = 'mod'
|
||||
module = FalseModule(name)
|
||||
with util.uncache(name):
|
||||
self.assertFalse(module)
|
||||
sys.modules[name] = module
|
||||
given = self.return_module(name)
|
||||
self.assertIs(given, module)
|
||||
|
||||
def test_attributes_set(self):
|
||||
# __name__, __loader__, and __package__ should be set (when
|
||||
# is_package() is defined; undefined implicitly tested elsewhere).
|
||||
class FakeLoader:
|
||||
def __init__(self, is_package):
|
||||
self._pkg = is_package
|
||||
def is_package(self, name):
|
||||
return self._pkg
|
||||
@self.module_for_loader
|
||||
def load_module(self, module):
|
||||
return module
|
||||
|
||||
name = 'pkg.mod'
|
||||
with util.uncache(name):
|
||||
loader = FakeLoader(False)
|
||||
module = loader.load_module(name)
|
||||
self.assertEqual(module.__name__, name)
|
||||
self.assertIs(module.__loader__, loader)
|
||||
self.assertEqual(module.__package__, 'pkg')
|
||||
|
||||
name = 'pkg.sub'
|
||||
with util.uncache(name):
|
||||
loader = FakeLoader(True)
|
||||
module = loader.load_module(name)
|
||||
self.assertEqual(module.__name__, name)
|
||||
self.assertIs(module.__loader__, loader)
|
||||
self.assertEqual(module.__package__, name)
|
||||
|
||||
|
||||
(Frozen_ModuleForLoaderTests,
|
||||
Source_ModuleForLoaderTests
|
||||
) = util.test_both(ModuleForLoaderTests, util=importlib_util)
|
||||
|
||||
|
||||
class SetPackageTests:
|
||||
|
||||
"""Tests for importlib.util.set_package."""
|
||||
|
||||
def verify(self, module, expect):
|
||||
"""Verify the module has the expected value for __package__ after
|
||||
passing through set_package."""
|
||||
fxn = lambda: module
|
||||
wrapped = self.util.set_package(fxn)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
wrapped()
|
||||
self.assertTrue(hasattr(module, '__package__'))
|
||||
self.assertEqual(expect, module.__package__)
|
||||
|
||||
def test_top_level(self):
|
||||
# __package__ should be set to the empty string if a top-level module.
|
||||
# Implicitly tests when package is set to None.
|
||||
module = types.ModuleType('module')
|
||||
module.__package__ = None
|
||||
self.verify(module, '')
|
||||
|
||||
def test_package(self):
|
||||
# Test setting __package__ for a package.
|
||||
module = types.ModuleType('pkg')
|
||||
module.__path__ = ['<path>']
|
||||
module.__package__ = None
|
||||
self.verify(module, 'pkg')
|
||||
|
||||
def test_submodule(self):
|
||||
# Test __package__ for a module in a package.
|
||||
module = types.ModuleType('pkg.mod')
|
||||
module.__package__ = None
|
||||
self.verify(module, 'pkg')
|
||||
|
||||
def test_setting_if_missing(self):
|
||||
# __package__ should be set if it is missing.
|
||||
module = types.ModuleType('mod')
|
||||
if hasattr(module, '__package__'):
|
||||
delattr(module, '__package__')
|
||||
self.verify(module, '')
|
||||
|
||||
def test_leaving_alone(self):
|
||||
# If __package__ is set and not None then leave it alone.
|
||||
for value in (True, False):
|
||||
module = types.ModuleType('mod')
|
||||
module.__package__ = value
|
||||
self.verify(module, value)
|
||||
|
||||
def test_decorator_attrs(self):
|
||||
def fxn(module): pass
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
wrapped = self.util.set_package(fxn)
|
||||
self.assertEqual(wrapped.__name__, fxn.__name__)
|
||||
self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
|
||||
|
||||
|
||||
(Frozen_SetPackageTests,
|
||||
Source_SetPackageTests
|
||||
) = util.test_both(SetPackageTests, util=importlib_util)
|
||||
|
||||
|
||||
class SetLoaderTests:
|
||||
|
||||
"""Tests importlib.util.set_loader()."""
|
||||
|
||||
@property
|
||||
def DummyLoader(self):
|
||||
# Set DummyLoader on the class lazily.
|
||||
class DummyLoader:
|
||||
@self.util.set_loader
|
||||
def load_module(self, module):
|
||||
return self.module
|
||||
self.__class__.DummyLoader = DummyLoader
|
||||
return DummyLoader
|
||||
|
||||
def test_no_attribute(self):
|
||||
loader = self.DummyLoader()
|
||||
loader.module = types.ModuleType('blah')
|
||||
try:
|
||||
del loader.module.__loader__
|
||||
except AttributeError:
|
||||
pass
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertEqual(loader, loader.load_module('blah').__loader__)
|
||||
|
||||
def test_attribute_is_None(self):
|
||||
loader = self.DummyLoader()
|
||||
loader.module = types.ModuleType('blah')
|
||||
loader.module.__loader__ = None
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertEqual(loader, loader.load_module('blah').__loader__)
|
||||
|
||||
def test_not_reset(self):
|
||||
loader = self.DummyLoader()
|
||||
loader.module = types.ModuleType('blah')
|
||||
loader.module.__loader__ = 42
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', DeprecationWarning)
|
||||
self.assertEqual(42, loader.load_module('blah').__loader__)
|
||||
|
||||
|
||||
(Frozen_SetLoaderTests,
|
||||
Source_SetLoaderTests
|
||||
) = util.test_both(SetLoaderTests, util=importlib_util)
|
||||
|
||||
|
||||
class ResolveNameTests:
|
||||
|
||||
"""Tests importlib.util.resolve_name()."""
|
||||
|
||||
def test_absolute(self):
|
||||
# bacon
|
||||
self.assertEqual('bacon', self.util.resolve_name('bacon', None))
|
||||
|
||||
def test_absolute_within_package(self):
|
||||
# bacon in spam
|
||||
self.assertEqual('bacon', self.util.resolve_name('bacon', 'spam'))
|
||||
|
||||
def test_no_package(self):
|
||||
# .bacon in ''
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.resolve_name('.bacon', '')
|
||||
|
||||
def test_in_package(self):
|
||||
# .bacon in spam
|
||||
self.assertEqual('spam.eggs.bacon',
|
||||
self.util.resolve_name('.bacon', 'spam.eggs'))
|
||||
|
||||
def test_other_package(self):
|
||||
# ..bacon in spam.bacon
|
||||
self.assertEqual('spam.bacon',
|
||||
self.util.resolve_name('..bacon', 'spam.eggs'))
|
||||
|
||||
def test_escape(self):
|
||||
# ..bacon in spam
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.resolve_name('..bacon', 'spam')
|
||||
|
||||
|
||||
(Frozen_ResolveNameTests,
|
||||
Source_ResolveNameTests
|
||||
) = util.test_both(ResolveNameTests, util=importlib_util)
|
||||
|
||||
|
||||
class FindSpecTests:
|
||||
|
||||
class FakeMetaFinder:
|
||||
@staticmethod
|
||||
def find_spec(name, path=None, target=None): return name, path, target
|
||||
|
||||
def test_sys_modules(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
loader = 'a loader!'
|
||||
spec = self.machinery.ModuleSpec(name, loader)
|
||||
module.__loader__ = loader
|
||||
module.__spec__ = spec
|
||||
sys.modules[name] = module
|
||||
found = self.util.find_spec(name)
|
||||
self.assertEqual(found, spec)
|
||||
|
||||
def test_sys_modules_without___loader__(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
del module.__loader__
|
||||
loader = 'a loader!'
|
||||
spec = self.machinery.ModuleSpec(name, loader)
|
||||
module.__spec__ = spec
|
||||
sys.modules[name] = module
|
||||
found = self.util.find_spec(name)
|
||||
self.assertEqual(found, spec)
|
||||
|
||||
def test_sys_modules_spec_is_None(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
module.__spec__ = None
|
||||
sys.modules[name] = module
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.find_spec(name)
|
||||
|
||||
def test_sys_modules_loader_is_None(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
spec = self.machinery.ModuleSpec(name, None)
|
||||
module.__spec__ = spec
|
||||
sys.modules[name] = module
|
||||
found = self.util.find_spec(name)
|
||||
self.assertEqual(found, spec)
|
||||
|
||||
def test_sys_modules_spec_is_not_set(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
module = types.ModuleType(name)
|
||||
try:
|
||||
del module.__spec__
|
||||
except AttributeError:
|
||||
pass
|
||||
sys.modules[name] = module
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.find_spec(name)
|
||||
|
||||
def test_success(self):
|
||||
name = 'some_mod'
|
||||
with util.uncache(name):
|
||||
with util.import_state(meta_path=[self.FakeMetaFinder]):
|
||||
self.assertEqual((name, None, None),
|
||||
self.util.find_spec(name))
|
||||
|
||||
def test_nothing(self):
|
||||
# None is returned upon failure to find a loader.
|
||||
self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule'))
|
||||
|
||||
def test_find_submodule(self):
|
||||
name = 'spam'
|
||||
subname = 'ham'
|
||||
with util.temp_module(name, pkg=True) as pkg_dir:
|
||||
fullname, _ = util.submodule(name, subname, pkg_dir)
|
||||
spec = self.util.find_spec(fullname)
|
||||
self.assertIsNot(spec, None)
|
||||
self.assertIn(name, sorted(sys.modules))
|
||||
self.assertNotIn(fullname, sorted(sys.modules))
|
||||
# Ensure successive calls behave the same.
|
||||
spec_again = self.util.find_spec(fullname)
|
||||
self.assertEqual(spec_again, spec)
|
||||
|
||||
def test_find_submodule_parent_already_imported(self):
|
||||
name = 'spam'
|
||||
subname = 'ham'
|
||||
with util.temp_module(name, pkg=True) as pkg_dir:
|
||||
self.init.import_module(name)
|
||||
fullname, _ = util.submodule(name, subname, pkg_dir)
|
||||
spec = self.util.find_spec(fullname)
|
||||
self.assertIsNot(spec, None)
|
||||
self.assertIn(name, sorted(sys.modules))
|
||||
self.assertNotIn(fullname, sorted(sys.modules))
|
||||
# Ensure successive calls behave the same.
|
||||
spec_again = self.util.find_spec(fullname)
|
||||
self.assertEqual(spec_again, spec)
|
||||
|
||||
def test_find_relative_module(self):
|
||||
name = 'spam'
|
||||
subname = 'ham'
|
||||
with util.temp_module(name, pkg=True) as pkg_dir:
|
||||
fullname, _ = util.submodule(name, subname, pkg_dir)
|
||||
relname = '.' + subname
|
||||
spec = self.util.find_spec(relname, name)
|
||||
self.assertIsNot(spec, None)
|
||||
self.assertIn(name, sorted(sys.modules))
|
||||
self.assertNotIn(fullname, sorted(sys.modules))
|
||||
# Ensure successive calls behave the same.
|
||||
spec_again = self.util.find_spec(fullname)
|
||||
self.assertEqual(spec_again, spec)
|
||||
|
||||
def test_find_relative_module_missing_package(self):
|
||||
name = 'spam'
|
||||
subname = 'ham'
|
||||
with util.temp_module(name, pkg=True) as pkg_dir:
|
||||
fullname, _ = util.submodule(name, subname, pkg_dir)
|
||||
relname = '.' + subname
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.find_spec(relname)
|
||||
self.assertNotIn(name, sorted(sys.modules))
|
||||
self.assertNotIn(fullname, sorted(sys.modules))
|
||||
|
||||
|
||||
(Frozen_FindSpecTests,
|
||||
Source_FindSpecTests
|
||||
) = util.test_both(FindSpecTests, init=init, util=importlib_util,
|
||||
machinery=machinery)
|
||||
|
||||
|
||||
class MagicNumberTests:
|
||||
|
||||
def test_length(self):
|
||||
# Should be 4 bytes.
|
||||
self.assertEqual(len(self.util.MAGIC_NUMBER), 4)
|
||||
|
||||
def test_incorporates_rn(self):
|
||||
# The magic number uses \r\n to come out wrong when splitting on lines.
|
||||
self.assertTrue(self.util.MAGIC_NUMBER.endswith(b'\r\n'))
|
||||
|
||||
|
||||
(Frozen_MagicNumberTests,
|
||||
Source_MagicNumberTests
|
||||
) = util.test_both(MagicNumberTests, util=importlib_util)
|
||||
|
||||
|
||||
class PEP3147Tests:
|
||||
|
||||
"""Tests of PEP 3147-related functions: cache_from_source and source_from_cache."""
|
||||
|
||||
tag = sys.implementation.cache_tag
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag not be None')
|
||||
def test_cache_from_source(self):
|
||||
# Given the path to a .py file, return the path to its PEP 3147
|
||||
# defined .pyc file (i.e. under __pycache__).
|
||||
path = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=''),
|
||||
expect)
|
||||
|
||||
def test_cache_from_source_no_cache_tag(self):
|
||||
# No cache tag means NotImplementedError.
|
||||
with support.swap_attr(sys.implementation, 'cache_tag', None):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.util.cache_from_source('whatever.py')
|
||||
|
||||
def test_cache_from_source_no_dot(self):
|
||||
# Directory with a dot, filename without dot.
|
||||
path = os.path.join('foo.bar', 'file')
|
||||
expect = os.path.join('foo.bar', '__pycache__',
|
||||
'file{}.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=''),
|
||||
expect)
|
||||
|
||||
def test_cache_from_source_debug_override(self):
|
||||
# Given the path to a .py file, return the path to its PEP 3147/PEP 488
|
||||
# defined .pyc file (i.e. under __pycache__).
|
||||
path = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
self.assertEqual(self.util.cache_from_source(path, False),
|
||||
self.util.cache_from_source(path, optimization=1))
|
||||
self.assertEqual(self.util.cache_from_source(path, True),
|
||||
self.util.cache_from_source(path, optimization=''))
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error')
|
||||
with self.assertRaises(DeprecationWarning):
|
||||
self.util.cache_from_source(path, False)
|
||||
with self.assertRaises(DeprecationWarning):
|
||||
self.util.cache_from_source(path, True)
|
||||
|
||||
def test_cache_from_source_cwd(self):
|
||||
path = 'foo.py'
|
||||
expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=''),
|
||||
expect)
|
||||
|
||||
def test_cache_from_source_override(self):
|
||||
# When debug_override is not None, it can be any true-ish or false-ish
|
||||
# value.
|
||||
path = os.path.join('foo', 'bar', 'baz.py')
|
||||
# However if the bool-ishness can't be determined, the exception
|
||||
# propagates.
|
||||
class Bearish:
|
||||
def __bool__(self): raise RuntimeError
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
self.assertEqual(self.util.cache_from_source(path, []),
|
||||
self.util.cache_from_source(path, optimization=1))
|
||||
self.assertEqual(self.util.cache_from_source(path, [17]),
|
||||
self.util.cache_from_source(path, optimization=''))
|
||||
with self.assertRaises(RuntimeError):
|
||||
self.util.cache_from_source('/foo/bar/baz.py', Bearish())
|
||||
|
||||
|
||||
def test_cache_from_source_optimization_empty_string(self):
|
||||
# Setting 'optimization' to '' leads to no optimization tag (PEP 488).
|
||||
path = 'foo.py'
|
||||
expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=''),
|
||||
expect)
|
||||
|
||||
def test_cache_from_source_optimization_None(self):
|
||||
# Setting 'optimization' to None uses the interpreter's optimization.
|
||||
# (PEP 488)
|
||||
path = 'foo.py'
|
||||
optimization_level = sys.flags.optimize
|
||||
almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
|
||||
if optimization_level == 0:
|
||||
expect = almost_expect + '.pyc'
|
||||
elif optimization_level <= 2:
|
||||
expect = almost_expect + '.opt-{}.pyc'.format(optimization_level)
|
||||
else:
|
||||
msg = '{!r} is a non-standard optimization level'.format(optimization_level)
|
||||
self.skipTest(msg)
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=None),
|
||||
expect)
|
||||
|
||||
def test_cache_from_source_optimization_set(self):
|
||||
# The 'optimization' parameter accepts anything that has a string repr
|
||||
# that passes str.alnum().
|
||||
path = 'foo.py'
|
||||
valid_characters = string.ascii_letters + string.digits
|
||||
almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
|
||||
got = self.util.cache_from_source(path, optimization=valid_characters)
|
||||
# Test all valid characters are accepted.
|
||||
self.assertEqual(got,
|
||||
almost_expect + '.opt-{}.pyc'.format(valid_characters))
|
||||
# str() should be called on argument.
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=42),
|
||||
almost_expect + '.opt-42.pyc')
|
||||
# Invalid characters raise ValueError.
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.cache_from_source(path, optimization='path/is/bad')
|
||||
|
||||
def test_cache_from_source_debug_override_optimization_both_set(self):
|
||||
# Can only set one of the optimization-related parameters.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
with self.assertRaises(TypeError):
|
||||
self.util.cache_from_source('foo.py', False, optimization='')
|
||||
|
||||
@unittest.skipUnless(os.sep == '\\' and os.altsep == '/',
|
||||
'test meaningful only where os.altsep is defined')
|
||||
def test_sep_altsep_and_sep_cache_from_source(self):
|
||||
# Windows path and PEP 3147 where sep is right of altsep.
|
||||
self.assertEqual(
|
||||
self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''),
|
||||
'\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag))
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag not be None')
|
||||
def test_source_from_cache_path_like_arg(self):
|
||||
path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py')
|
||||
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.cache_from_source(path, optimization=''),
|
||||
expect)
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag to not be '
|
||||
'None')
|
||||
def test_source_from_cache(self):
|
||||
# Given the path to a PEP 3147 defined .pyc file, return the path to
|
||||
# its source. This tests the good path.
|
||||
path = os.path.join('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
self.assertEqual(self.util.source_from_cache(path), expect)
|
||||
|
||||
def test_source_from_cache_no_cache_tag(self):
|
||||
# If sys.implementation.cache_tag is None, raise NotImplementedError.
|
||||
path = os.path.join('blah', '__pycache__', 'whatever.pyc')
|
||||
with support.swap_attr(sys.implementation, 'cache_tag', None):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.util.source_from_cache(path)
|
||||
|
||||
def test_source_from_cache_bad_path(self):
|
||||
# When the path to a pyc file is not in PEP 3147 format, a ValueError
|
||||
# is raised.
|
||||
self.assertRaises(
|
||||
ValueError, self.util.source_from_cache, '/foo/bar/bazqux.pyc')
|
||||
|
||||
def test_source_from_cache_no_slash(self):
|
||||
# No slashes at all in path -> ValueError
|
||||
self.assertRaises(
|
||||
ValueError, self.util.source_from_cache, 'foo.cpython-32.pyc')
|
||||
|
||||
def test_source_from_cache_too_few_dots(self):
|
||||
# Too few dots in final path component -> ValueError
|
||||
self.assertRaises(
|
||||
ValueError, self.util.source_from_cache, '__pycache__/foo.pyc')
|
||||
|
||||
def test_source_from_cache_too_many_dots(self):
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.source_from_cache(
|
||||
'__pycache__/foo.cpython-32.opt-1.foo.pyc')
|
||||
|
||||
def test_source_from_cache_not_opt(self):
|
||||
# Non-`opt-` path component -> ValueError
|
||||
self.assertRaises(
|
||||
ValueError, self.util.source_from_cache,
|
||||
'__pycache__/foo.cpython-32.foo.pyc')
|
||||
|
||||
def test_source_from_cache_no__pycache__(self):
|
||||
# Another problem with the path -> ValueError
|
||||
self.assertRaises(
|
||||
ValueError, self.util.source_from_cache,
|
||||
'/foo/bar/foo.cpython-32.foo.pyc')
|
||||
|
||||
def test_source_from_cache_optimized_bytecode(self):
|
||||
# Optimized bytecode is not an issue.
|
||||
path = os.path.join('__pycache__', 'foo.{}.opt-1.pyc'.format(self.tag))
|
||||
self.assertEqual(self.util.source_from_cache(path), 'foo.py')
|
||||
|
||||
def test_source_from_cache_missing_optimization(self):
|
||||
# An empty optimization level is a no-no.
|
||||
path = os.path.join('__pycache__', 'foo.{}.opt-.pyc'.format(self.tag))
|
||||
with self.assertRaises(ValueError):
|
||||
self.util.source_from_cache(path)
|
||||
|
||||
@unittest.skipUnless(sys.implementation.cache_tag is not None,
|
||||
'requires sys.implementation.cache_tag to not be '
|
||||
'None')
|
||||
def test_source_from_cache_path_like_arg(self):
|
||||
path = pathlib.PurePath('foo', 'bar', 'baz', '__pycache__',
|
||||
'qux.{}.pyc'.format(self.tag))
|
||||
expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
|
||||
self.assertEqual(self.util.source_from_cache(path), expect)
|
||||
|
||||
|
||||
(Frozen_PEP3147Tests,
|
||||
Source_PEP3147Tests
|
||||
) = util.test_both(PEP3147Tests, util=importlib_util)
|
||||
|
||||
|
||||
class MagicNumberTests(unittest.TestCase):
|
||||
"""
|
||||
Test release compatibility issues relating to importlib
|
||||
"""
|
||||
@unittest.skipUnless(
|
||||
sys.version_info.releaselevel in ('candidate', 'final'),
|
||||
'only applies to candidate or final python release levels'
|
||||
)
|
||||
def test_magic_number(self):
|
||||
"""
|
||||
Each python minor release should generally have a MAGIC_NUMBER
|
||||
that does not change once the release reaches candidate status.
|
||||
|
||||
Once a release reaches candidate status, the value of the constant
|
||||
EXPECTED_MAGIC_NUMBER in this test should be changed.
|
||||
This test will then check that the actual MAGIC_NUMBER matches
|
||||
the expected value for the release.
|
||||
|
||||
In exceptional cases, it may be required to change the MAGIC_NUMBER
|
||||
for a maintenance release. In this case the change should be
|
||||
discussed in python-dev. If a change is required, community
|
||||
stakeholders such as OS package maintainers must be notified
|
||||
in advance. Such exceptional releases will then require an
|
||||
adjustment to this test case.
|
||||
"""
|
||||
EXPECTED_MAGIC_NUMBER = 3379
|
||||
actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little')
|
||||
|
||||
msg = (
|
||||
"To avoid breaking backwards compatibility with cached bytecode "
|
||||
"files that can't be automatically regenerated by the current "
|
||||
"user, candidate and final releases require the current "
|
||||
"importlib.util.MAGIC_NUMBER to match the expected "
|
||||
"magic number in this test. Set the expected "
|
||||
"magic number in this test to the current MAGIC_NUMBER to "
|
||||
"continue with the release.\n\n"
|
||||
"Changing the MAGIC_NUMBER for a maintenance release "
|
||||
"requires discussion in python-dev and notification of "
|
||||
"community stakeholders."
|
||||
)
|
||||
self.assertEqual(EXPECTED_MAGIC_NUMBER, actual, msg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
109
third_party/python/Lib/test/test_importlib/test_windows.py
vendored
Normal file
109
third_party/python/Lib/test/test_importlib/test_windows.py
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
from . import util as test_util
|
||||
machinery = test_util.import_importlib('importlib.machinery')
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
from test import support
|
||||
from distutils.util import get_platform
|
||||
from contextlib import contextmanager
|
||||
from .util import temp_module
|
||||
|
||||
support.import_module('winreg', required_on=['win'])
|
||||
from winreg import (
|
||||
CreateKey, HKEY_CURRENT_USER,
|
||||
SetValue, REG_SZ, KEY_ALL_ACCESS,
|
||||
EnumKey, CloseKey, DeleteKey, OpenKey
|
||||
)
|
||||
|
||||
def delete_registry_tree(root, subkey):
|
||||
try:
|
||||
hkey = OpenKey(root, subkey, access=KEY_ALL_ACCESS)
|
||||
except OSError:
|
||||
# subkey does not exist
|
||||
return
|
||||
while True:
|
||||
try:
|
||||
subsubkey = EnumKey(hkey, 0)
|
||||
except OSError:
|
||||
# no more subkeys
|
||||
break
|
||||
delete_registry_tree(hkey, subsubkey)
|
||||
CloseKey(hkey)
|
||||
DeleteKey(root, subkey)
|
||||
|
||||
@contextmanager
|
||||
def setup_module(machinery, name, path=None):
|
||||
if machinery.WindowsRegistryFinder.DEBUG_BUILD:
|
||||
root = machinery.WindowsRegistryFinder.REGISTRY_KEY_DEBUG
|
||||
else:
|
||||
root = machinery.WindowsRegistryFinder.REGISTRY_KEY
|
||||
key = root.format(fullname=name,
|
||||
sys_version='%d.%d' % sys.version_info[:2])
|
||||
try:
|
||||
with temp_module(name, "a = 1") as location:
|
||||
subkey = CreateKey(HKEY_CURRENT_USER, key)
|
||||
if path is None:
|
||||
path = location + ".py"
|
||||
SetValue(subkey, "", REG_SZ, path)
|
||||
yield
|
||||
finally:
|
||||
if machinery.WindowsRegistryFinder.DEBUG_BUILD:
|
||||
key = os.path.dirname(key)
|
||||
delete_registry_tree(HKEY_CURRENT_USER, key)
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
|
||||
class WindowsRegistryFinderTests:
|
||||
# The module name is process-specific, allowing for
|
||||
# simultaneous runs of the same test on a single machine.
|
||||
test_module = "spamham{}".format(os.getpid())
|
||||
|
||||
def test_find_spec_missing(self):
|
||||
spec = self.machinery.WindowsRegistryFinder.find_spec('spam')
|
||||
self.assertIs(spec, None)
|
||||
|
||||
def test_find_module_missing(self):
|
||||
loader = self.machinery.WindowsRegistryFinder.find_module('spam')
|
||||
self.assertIs(loader, None)
|
||||
|
||||
def test_module_found(self):
|
||||
with setup_module(self.machinery, self.test_module):
|
||||
loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
|
||||
spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
|
||||
self.assertIsNot(loader, None)
|
||||
self.assertIsNot(spec, None)
|
||||
|
||||
def test_module_not_found(self):
|
||||
with setup_module(self.machinery, self.test_module, path="."):
|
||||
loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
|
||||
spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
|
||||
self.assertIsNone(loader)
|
||||
self.assertIsNone(spec)
|
||||
|
||||
(Frozen_WindowsRegistryFinderTests,
|
||||
Source_WindowsRegistryFinderTests
|
||||
) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery)
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
|
||||
class WindowsExtensionSuffixTests:
|
||||
def test_tagged_suffix(self):
|
||||
suffixes = self.machinery.EXTENSION_SUFFIXES
|
||||
expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info,
|
||||
re.sub('[^a-zA-Z0-9]', '_', get_platform()))
|
||||
try:
|
||||
untagged_i = suffixes.index(".pyd")
|
||||
except ValueError:
|
||||
untagged_i = suffixes.index("_d.pyd")
|
||||
expected_tag = "_d" + expected_tag
|
||||
|
||||
self.assertIn(expected_tag, suffixes)
|
||||
|
||||
# Ensure the tags are in the correct order
|
||||
tagged_i = suffixes.index(expected_tag)
|
||||
self.assertLess(tagged_i, untagged_i)
|
||||
|
||||
(Frozen_WindowsExtensionSuffixTests,
|
||||
Source_WindowsExtensionSuffixTests
|
||||
) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery)
|
388
third_party/python/Lib/test/test_importlib/util.py
vendored
Normal file
388
third_party/python/Lib/test/test_importlib/util.py
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
import builtins
|
||||
import contextlib
|
||||
import errno
|
||||
import functools
|
||||
import importlib
|
||||
from importlib import machinery, util, invalidate_caches
|
||||
import os
|
||||
import os.path
|
||||
from test import support
|
||||
import unittest
|
||||
import sys
|
||||
import tempfile
|
||||
import types
|
||||
|
||||
|
||||
BUILTINS = types.SimpleNamespace()
|
||||
BUILTINS.good_name = None
|
||||
BUILTINS.bad_name = None
|
||||
if 'errno' in sys.builtin_module_names:
|
||||
BUILTINS.good_name = 'errno'
|
||||
if 'importlib' not in sys.builtin_module_names:
|
||||
BUILTINS.bad_name = 'importlib'
|
||||
|
||||
EXTENSIONS = types.SimpleNamespace()
|
||||
EXTENSIONS.path = None
|
||||
EXTENSIONS.ext = None
|
||||
EXTENSIONS.filename = None
|
||||
EXTENSIONS.file_path = None
|
||||
EXTENSIONS.name = '_testcapi'
|
||||
|
||||
def _extension_details():
|
||||
global EXTENSIONS
|
||||
for path in sys.path:
|
||||
for ext in machinery.EXTENSION_SUFFIXES:
|
||||
filename = EXTENSIONS.name + ext
|
||||
file_path = os.path.join(path, filename)
|
||||
if os.path.exists(file_path):
|
||||
EXTENSIONS.path = path
|
||||
EXTENSIONS.ext = ext
|
||||
EXTENSIONS.filename = filename
|
||||
EXTENSIONS.file_path = file_path
|
||||
return
|
||||
|
||||
_extension_details()
|
||||
|
||||
|
||||
def import_importlib(module_name):
|
||||
"""Import a module from importlib both w/ and w/o _frozen_importlib."""
|
||||
fresh = ('importlib',) if '.' in module_name else ()
|
||||
frozen = support.import_fresh_module(module_name)
|
||||
source = support.import_fresh_module(module_name, fresh=fresh,
|
||||
blocked=('_frozen_importlib', '_frozen_importlib_external'))
|
||||
return {'Frozen': frozen, 'Source': source}
|
||||
|
||||
|
||||
def specialize_class(cls, kind, base=None, **kwargs):
|
||||
# XXX Support passing in submodule names--load (and cache) them?
|
||||
# That would clean up the test modules a bit more.
|
||||
if base is None:
|
||||
base = unittest.TestCase
|
||||
elif not isinstance(base, type):
|
||||
base = base[kind]
|
||||
name = '{}_{}'.format(kind, cls.__name__)
|
||||
bases = (cls, base)
|
||||
specialized = types.new_class(name, bases)
|
||||
specialized.__module__ = cls.__module__
|
||||
specialized._NAME = cls.__name__
|
||||
specialized._KIND = kind
|
||||
for attr, values in kwargs.items():
|
||||
value = values[kind]
|
||||
setattr(specialized, attr, value)
|
||||
return specialized
|
||||
|
||||
|
||||
def split_frozen(cls, base=None, **kwargs):
|
||||
frozen = specialize_class(cls, 'Frozen', base, **kwargs)
|
||||
source = specialize_class(cls, 'Source', base, **kwargs)
|
||||
return frozen, source
|
||||
|
||||
|
||||
def test_both(test_class, base=None, **kwargs):
|
||||
return split_frozen(test_class, base, **kwargs)
|
||||
|
||||
|
||||
CASE_INSENSITIVE_FS = True
|
||||
# Windows is the only OS that is *always* case-insensitive
|
||||
# (OS X *can* be case-sensitive).
|
||||
if sys.platform not in ('win32', 'cygwin'):
|
||||
changed_name = __file__.upper()
|
||||
if changed_name == __file__:
|
||||
changed_name = __file__.lower()
|
||||
if not os.path.exists(changed_name):
|
||||
CASE_INSENSITIVE_FS = False
|
||||
|
||||
source_importlib = import_importlib('importlib')['Source']
|
||||
__import__ = {'Frozen': staticmethod(builtins.__import__),
|
||||
'Source': staticmethod(source_importlib.__import__)}
|
||||
|
||||
|
||||
def case_insensitive_tests(test):
|
||||
"""Class decorator that nullifies tests requiring a case-insensitive
|
||||
file system."""
|
||||
return unittest.skipIf(not CASE_INSENSITIVE_FS,
|
||||
"requires a case-insensitive filesystem")(test)
|
||||
|
||||
|
||||
def submodule(parent, name, pkg_dir, content=''):
|
||||
path = os.path.join(pkg_dir, name + '.py')
|
||||
with open(path, 'w') as subfile:
|
||||
subfile.write(content)
|
||||
return '{}.{}'.format(parent, name), path
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def uncache(*names):
|
||||
"""Uncache a module from sys.modules.
|
||||
|
||||
A basic sanity check is performed to prevent uncaching modules that either
|
||||
cannot/shouldn't be uncached.
|
||||
|
||||
"""
|
||||
for name in names:
|
||||
if name in ('sys', 'marshal', 'imp'):
|
||||
raise ValueError(
|
||||
"cannot uncache {0}".format(name))
|
||||
try:
|
||||
del sys.modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
for name in names:
|
||||
try:
|
||||
del sys.modules[name]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temp_module(name, content='', *, pkg=False):
|
||||
conflicts = [n for n in sys.modules if n.partition('.')[0] == name]
|
||||
with support.temp_cwd(None) as cwd:
|
||||
with uncache(name, *conflicts):
|
||||
with support.DirsOnSysPath(cwd):
|
||||
invalidate_caches()
|
||||
|
||||
location = os.path.join(cwd, name)
|
||||
if pkg:
|
||||
modpath = os.path.join(location, '__init__.py')
|
||||
os.mkdir(name)
|
||||
else:
|
||||
modpath = location + '.py'
|
||||
if content is None:
|
||||
# Make sure the module file gets created.
|
||||
content = ''
|
||||
if content is not None:
|
||||
# not a namespace package
|
||||
with open(modpath, 'w') as modfile:
|
||||
modfile.write(content)
|
||||
yield location
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def import_state(**kwargs):
|
||||
"""Context manager to manage the various importers and stored state in the
|
||||
sys module.
|
||||
|
||||
The 'modules' attribute is not supported as the interpreter state stores a
|
||||
pointer to the dict that the interpreter uses internally;
|
||||
reassigning to sys.modules does not have the desired effect.
|
||||
|
||||
"""
|
||||
originals = {}
|
||||
try:
|
||||
for attr, default in (('meta_path', []), ('path', []),
|
||||
('path_hooks', []),
|
||||
('path_importer_cache', {})):
|
||||
originals[attr] = getattr(sys, attr)
|
||||
if attr in kwargs:
|
||||
new_value = kwargs[attr]
|
||||
del kwargs[attr]
|
||||
else:
|
||||
new_value = default
|
||||
setattr(sys, attr, new_value)
|
||||
if len(kwargs):
|
||||
raise ValueError(
|
||||
'unrecognized arguments: {0}'.format(kwargs.keys()))
|
||||
yield
|
||||
finally:
|
||||
for attr, value in originals.items():
|
||||
setattr(sys, attr, value)
|
||||
|
||||
|
||||
class _ImporterMock:
|
||||
|
||||
"""Base class to help with creating importer mocks."""
|
||||
|
||||
def __init__(self, *names, module_code={}):
|
||||
self.modules = {}
|
||||
self.module_code = {}
|
||||
for name in names:
|
||||
if not name.endswith('.__init__'):
|
||||
import_name = name
|
||||
else:
|
||||
import_name = name[:-len('.__init__')]
|
||||
if '.' not in name:
|
||||
package = None
|
||||
elif import_name == name:
|
||||
package = name.rsplit('.', 1)[0]
|
||||
else:
|
||||
package = import_name
|
||||
module = types.ModuleType(import_name)
|
||||
module.__loader__ = self
|
||||
module.__file__ = '<mock __file__>'
|
||||
module.__package__ = package
|
||||
module.attr = name
|
||||
if import_name != name:
|
||||
module.__path__ = ['<mock __path__>']
|
||||
self.modules[import_name] = module
|
||||
if import_name in module_code:
|
||||
self.module_code[import_name] = module_code[import_name]
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.modules[name]
|
||||
|
||||
def __enter__(self):
|
||||
self._uncache = uncache(*self.modules.keys())
|
||||
self._uncache.__enter__()
|
||||
return self
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
self._uncache.__exit__(None, None, None)
|
||||
|
||||
|
||||
class mock_modules(_ImporterMock):
|
||||
|
||||
"""Importer mock using PEP 302 APIs."""
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
if fullname not in self.modules:
|
||||
return None
|
||||
else:
|
||||
return self
|
||||
|
||||
def load_module(self, fullname):
|
||||
if fullname not in self.modules:
|
||||
raise ImportError
|
||||
else:
|
||||
sys.modules[fullname] = self.modules[fullname]
|
||||
if fullname in self.module_code:
|
||||
try:
|
||||
self.module_code[fullname]()
|
||||
except Exception:
|
||||
del sys.modules[fullname]
|
||||
raise
|
||||
return self.modules[fullname]
|
||||
|
||||
|
||||
class mock_spec(_ImporterMock):
|
||||
|
||||
"""Importer mock using PEP 451 APIs."""
|
||||
|
||||
def find_spec(self, fullname, path=None, parent=None):
|
||||
try:
|
||||
module = self.modules[fullname]
|
||||
except KeyError:
|
||||
return None
|
||||
spec = util.spec_from_file_location(
|
||||
fullname, module.__file__, loader=self,
|
||||
submodule_search_locations=getattr(module, '__path__', None))
|
||||
return spec
|
||||
|
||||
def create_module(self, spec):
|
||||
if spec.name not in self.modules:
|
||||
raise ImportError
|
||||
return self.modules[spec.name]
|
||||
|
||||
def exec_module(self, module):
|
||||
try:
|
||||
self.module_code[module.__spec__.name]()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def writes_bytecode_files(fxn):
|
||||
"""Decorator to protect sys.dont_write_bytecode from mutation and to skip
|
||||
tests that require it to be set to False."""
|
||||
if sys.dont_write_bytecode:
|
||||
return lambda *args, **kwargs: None
|
||||
@functools.wraps(fxn)
|
||||
def wrapper(*args, **kwargs):
|
||||
original = sys.dont_write_bytecode
|
||||
sys.dont_write_bytecode = False
|
||||
try:
|
||||
to_return = fxn(*args, **kwargs)
|
||||
finally:
|
||||
sys.dont_write_bytecode = original
|
||||
return to_return
|
||||
return wrapper
|
||||
|
||||
|
||||
def ensure_bytecode_path(bytecode_path):
|
||||
"""Ensure that the __pycache__ directory for PEP 3147 pyc file exists.
|
||||
|
||||
:param bytecode_path: File system path to PEP 3147 pyc file.
|
||||
"""
|
||||
try:
|
||||
os.mkdir(os.path.dirname(bytecode_path))
|
||||
except OSError as error:
|
||||
if error.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def create_modules(*names):
|
||||
"""Temporarily create each named module with an attribute (named 'attr')
|
||||
that contains the name passed into the context manager that caused the
|
||||
creation of the module.
|
||||
|
||||
All files are created in a temporary directory returned by
|
||||
tempfile.mkdtemp(). This directory is inserted at the beginning of
|
||||
sys.path. When the context manager exits all created files (source and
|
||||
bytecode) are explicitly deleted.
|
||||
|
||||
No magic is performed when creating packages! This means that if you create
|
||||
a module within a package you must also create the package's __init__ as
|
||||
well.
|
||||
|
||||
"""
|
||||
source = 'attr = {0!r}'
|
||||
created_paths = []
|
||||
mapping = {}
|
||||
state_manager = None
|
||||
uncache_manager = None
|
||||
try:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
mapping['.root'] = temp_dir
|
||||
import_names = set()
|
||||
for name in names:
|
||||
if not name.endswith('__init__'):
|
||||
import_name = name
|
||||
else:
|
||||
import_name = name[:-len('.__init__')]
|
||||
import_names.add(import_name)
|
||||
if import_name in sys.modules:
|
||||
del sys.modules[import_name]
|
||||
name_parts = name.split('.')
|
||||
file_path = temp_dir
|
||||
for directory in name_parts[:-1]:
|
||||
file_path = os.path.join(file_path, directory)
|
||||
if not os.path.exists(file_path):
|
||||
os.mkdir(file_path)
|
||||
created_paths.append(file_path)
|
||||
file_path = os.path.join(file_path, name_parts[-1] + '.py')
|
||||
with open(file_path, 'w') as file:
|
||||
file.write(source.format(name))
|
||||
created_paths.append(file_path)
|
||||
mapping[name] = file_path
|
||||
uncache_manager = uncache(*import_names)
|
||||
uncache_manager.__enter__()
|
||||
state_manager = import_state(path=[temp_dir])
|
||||
state_manager.__enter__()
|
||||
yield mapping
|
||||
finally:
|
||||
if state_manager is not None:
|
||||
state_manager.__exit__(None, None, None)
|
||||
if uncache_manager is not None:
|
||||
uncache_manager.__exit__(None, None, None)
|
||||
support.rmtree(temp_dir)
|
||||
|
||||
|
||||
def mock_path_hook(*entries, importer):
|
||||
"""A mock sys.path_hooks entry."""
|
||||
def hook(entry):
|
||||
if entry not in entries:
|
||||
raise ImportError
|
||||
return importer
|
||||
return hook
|
||||
|
||||
|
||||
class CASEOKTestBase:
|
||||
|
||||
def caseok_env_changed(self, *, should_exist):
|
||||
possibilities = b'PYTHONCASEOK', 'PYTHONCASEOK'
|
||||
if any(x in self.importlib._bootstrap_external._os.environ
|
||||
for x in possibilities) != should_exist:
|
||||
self.skipTest('os.environ changes not reflected in _os.environ')
|
Loading…
Add table
Add a link
Reference in a new issue