summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-07-09 17:58:07 (GMT)
committerBrett Cannon <brett@python.org>2012-07-09 17:58:07 (GMT)
commit19a2f5961ce235e9ca9944069b0f5f21b340de9c (patch)
treec6d4a0a02d2eff9004046b5b3b478722431d43c5 /Lib
parentbf7eab077fe146dd76f5e7ddad3ff8b2d271fe6c (diff)
downloadcpython-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.py5
-rw-r--r--Lib/importlib/_bootstrap.py21
-rw-r--r--Lib/test/test_imp.py18
3 files changed, 37 insertions, 7 deletions
diff --git a/Lib/imp.py b/Lib/imp.py
index f947c3d..dab8312 100644
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -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.