diff options
author | Brett Cannon <brett@python.org> | 2012-07-09 17:58:07 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2012-07-09 17:58:07 (GMT) |
commit | 19a2f5961ce235e9ca9944069b0f5f21b340de9c (patch) | |
tree | c6d4a0a02d2eff9004046b5b3b478722431d43c5 /Lib | |
parent | bf7eab077fe146dd76f5e7ddad3ff8b2d271fe6c (diff) | |
download | cpython-19a2f5961ce235e9ca9944069b0f5f21b340de9c.zip cpython-19a2f5961ce235e9ca9944069b0f5f21b340de9c.tar.gz cpython-19a2f5961ce235e9ca9944069b0f5f21b340de9c.tar.bz2 |
Issue #15056: imp.cache_from_source() and source_from_cache() raise
NotimplementedError when sys.implementation.cache_tag is None.
Thanks to Pranav Ravichandran for taking an initial stab at the patch.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/imp.py | 5 | ||||
-rw-r--r-- | Lib/importlib/_bootstrap.py | 21 | ||||
-rw-r--r-- | Lib/test/test_imp.py | 18 |
3 files changed, 37 insertions, 7 deletions
@@ -58,9 +58,12 @@ def source_from_cache(path): The .pyc/.pyo file does not need to exist; this simply returns the path to the .py file calculated to correspond to the .pyc/.pyo file. If path does - not conform to PEP 3147 format, ValueError will be raised. + not conform to PEP 3147 format, ValueError will be raised. If + sys.implementation.cache_tag is None then NotImplementedError is raised. """ + if sys.implementation.cache_tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') head, pycache_filename = os.path.split(path) head, pycache = os.path.split(head) if pycache != _bootstrap._PYCACHE: diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index d89af42..35c6e50 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -321,6 +321,8 @@ def cache_from_source(path, debug_override=None): If debug_override is not None, then it must be a boolean and is taken as the value of __debug__ instead. + If sys.implementation.cache_tag is None then NotImplementedError is raised. + """ debug = __debug__ if debug_override is None else debug_override if debug: @@ -329,7 +331,10 @@ def cache_from_source(path, debug_override=None): suffixes = OPTIMIZED_BYTECODE_SUFFIXES head, tail = _path_split(path) base_filename, sep, _ = tail.partition('.') - filename = ''.join([base_filename, sep, _TAG, suffixes[0]]) + tag = sys.implementation.cache_tag + if tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') + filename = ''.join([base_filename, sep, tag, suffixes[0]]) return _path_join(head, _PYCACHE, filename) @@ -649,7 +654,10 @@ class _LoaderBasics: code_object = self.get_code(name) module.__file__ = self.get_filename(name) if not sourceless: - module.__cached__ = cache_from_source(module.__file__) + try: + module.__cached__ = cache_from_source(module.__file__) + except NotImplementedError: + module.__cached__ = module.__file__ else: module.__cached__ = module.__file__ module.__package__ = name @@ -718,9 +726,12 @@ class SourceLoader(_LoaderBasics): """ source_path = self.get_filename(fullname) - bytecode_path = cache_from_source(source_path) source_mtime = None - if bytecode_path is not None: + try: + bytecode_path = cache_from_source(source_path) + except NotImplementedError: + bytecode_path = None + else: try: st = self.path_stats(source_path) except NotImplementedError: @@ -1417,7 +1428,6 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0): _MAGIC_NUMBER = None # Set in _setup() -_TAG = None # Set in _setup() def _setup(sys_module, _imp_module): @@ -1479,7 +1489,6 @@ def _setup(sys_module, _imp_module): # Constants setattr(self_module, '_relax_case', _make_relax_case()) setattr(self_module, '_MAGIC_NUMBER', _imp_module.get_magic()) - setattr(self_module, '_TAG', sys.implementation.cache_tag) if builtin_os == 'nt': SOURCE_SUFFIXES.append('.pyw') diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 7b0c727..a660278 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -231,6 +231,8 @@ class PEP3147Tests(unittest.TestCase): tag = imp.get_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__). @@ -239,6 +241,12 @@ class PEP3147Tests(unittest.TestCase): 'qux.{}.pyc'.format(self.tag)) self.assertEqual(imp.cache_from_source(path, True), expect) + def test_cache_from_source_no_cache_tag(self): + # Non cache tag means NotImplementedError. + with support.swap_attr(sys.implementation, 'cache_tag', None): + with self.assertRaises(NotImplementedError): + imp.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') @@ -283,6 +291,9 @@ class PEP3147Tests(unittest.TestCase): imp.cache_from_source('\\foo\\bar\\baz/qux.py', True), '\\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. @@ -291,6 +302,13 @@ class PEP3147Tests(unittest.TestCase): expect = os.path.join('foo', 'bar', 'baz', 'qux.py') self.assertEqual(imp.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): + imp.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. |