[Python-checkins] cpython: Issue #15056: imp.cache_from_source() and source_from_cache() raise

brett.cannon python-checkins at python.org
Mon Jul 9 19:58:17 CEST 2012


http://hg.python.org/cpython/rev/e86330669bb5
changeset: 78026:e86330669bb5
user: Brett Cannon <brett at python.org>
date: Mon Jul 09 13:58:07 2012 -0400
summary:
 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.
files:
 Doc/library/imp.rst | 21 +-
 Lib/imp.py | 5 +-
 Lib/importlib/_bootstrap.py | 21 +-
 Lib/test/test_imp.py | 18 +
 Misc/NEWS | 3 +
 Python/importlib.h | 7621 +++++++++++-----------
 6 files changed, 3881 insertions(+), 3808 deletions(-)
diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst
--- a/Doc/library/imp.rst
+++ b/Doc/library/imp.rst
@@ -180,14 +180,19 @@
 source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
 value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2.
 The ``cpython-32`` string comes from the current magic tag (see
- :func:`get_tag`). The returned path will end in ``.pyc`` when
- ``__debug__`` is True or ``.pyo`` for an optimized Python
+ :func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then
+ :exc:`NotImplementedError` will be raised). The returned path will end in
+ ``.pyc`` when ``__debug__`` is True or ``.pyo`` for an optimized Python
 (i.e. ``__debug__`` is False). By passing in True or False for
 *debug_override* you can override the system's value for ``__debug__`` for
 extension selection.
 
 *path* need not exist.
 
+ .. versionchanged:: 3.3
+ If :attr:`sys.implementation.cache_tag` is ``None``, then
+ :exc:`NotImplementedError` is raised.
+
 
 .. function:: source_from_cache(path)
 
@@ -195,7 +200,13 @@
 file path. For example, if *path* is
 ``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be
 ``/foo/bar/baz.py``. *path* need not exist, however if it does not conform
- to :pep:`3147` format, a ``ValueError`` is raised.
+ to :pep:`3147` format, a ``ValueError`` is raised. If
+ :attr:`sys.implementation.cache_tag` is not defined,
+ :exc:`NotImplementedError` is raised.
+
+ .. versionchanged:: 3.3
+ Raise :exc:`NotImplementedError` when
+ :attr:`sys.implementation.cache_tag` is not defined.
 
 
 .. function:: get_tag()
@@ -203,6 +214,10 @@
 Return the :pep:`3147` magic tag string matching this version of Python's
 magic number, as returned by :func:`get_magic`.
 
+ .. note::
+ You may use :attr:`sys.implementation.cache_tag` directly starting
+ in Python 3.3.
+
 
 The following functions help interact with the import system's internal
 locking mechanism. Locking semantics of imports are an implementation
diff --git a/Lib/imp.py b/Lib/imp.py
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -58,9 +58,12 @@
 
 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
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -321,6 +321,8 @@
 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 @@
 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 @@
 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 @@
 
 """
 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 @@
 
 
 _MAGIC_NUMBER = None # Set in _setup()
-_TAG = None # Set in _setup()
 
 
 def _setup(sys_module, _imp_module):
@@ -1479,7 +1489,6 @@
 # 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
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -231,6 +231,8 @@
 
 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 @@
 '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 @@
 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 @@
 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.
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -31,6 +31,9 @@
 Library
 -------
 
+- Issue #15056: imp.cache_from_source() and source_from_cache() raise
+ NotImplementedError when sys.implementation.cache_tag is set to None.
+
 - Issue #15256: Grammatical mistake in exception raised by imp.find_module().
 
 - Issue #5931: wsgiref environ variable SERVER_SOFTWARE will specify an
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /