| 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 os |
| 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 warnings.catch_warnings(record=True) as w: |
| warnings.simplefilter('always') |
| module = self.util.module_from_spec(spec) |
| self.assertEqual(1, len(w)) |
| self.assertTrue(issubclass(w[0].category, DeprecationWarning)) |
| self.assertIn('create_module', str(w[0].message)) |
| self.assertIsInstance(module, types.ModuleType) |
| self.assertEqual(module.__name__, spec.name) |
| |
| 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_aboslute_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 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) |
| |
| |
| (Frozen_PEP3147Tests, |
| Source_PEP3147Tests |
| ) = util.test_both(PEP3147Tests, util=importlib_util) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |