diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst index 8a75d4c2ccb..890c171a15d 100644 --- a/Doc/library/imp.rst +++ b/Doc/library/imp.rst @@ -21,6 +21,9 @@ This module provides an interface to the mechanisms used to implement the Return the magic string value used to recognize byte-compiled code files (:file:`.pyc` files). (This value may be different for each Python version.) + .. deprecated:: 3.4 + Use :attr:`importlib.util.MAGIC_NUMBER` instead. + .. function:: get_suffixes() diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 0caabaa188d..e9b771758b4 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -879,6 +879,13 @@ find and load modules. This module contains the various objects that help in the construction of an :term:`importer`. +.. attribute:: MAGIC_NUMBER + + The bytes which represent the bytecode version number. If you need help with + loading/writing bytecode then consider :class:`importlib.abc.SourceLoader`. + + .. versionadded:: 3.4 + .. function:: resolve_name(name, package) Resolve a relative module name to an absolute one. diff --git a/Lib/imp.py b/Lib/imp.py index ad0fd6a4781..e06fbe64c28 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -23,6 +23,7 @@ from importlib._bootstrap import cache_from_source, source_from_cache from importlib import _bootstrap from importlib import machinery +from importlib import util import importlib import os import sys @@ -44,8 +45,11 @@ IMP_HOOK = 9 def get_magic(): - """Return the magic number for .pyc or .pyo files.""" - return _bootstrap._MAGIC_BYTES + """**DEPRECATED** + + Return the magic number for .pyc or .pyo files. + """ + return util.MAGIC_NUMBER def get_tag(): diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 9a82bd1ee5f..455805416f7 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -383,8 +383,8 @@ def _call_with_frames_removed(f, *args, **kwds): # longer be understood by older implementations of the eval loop (usually # due to the addition of new opcodes). -_MAGIC_BYTES = (3280).to_bytes(2, 'little') + b'\r\n' -_RAW_MAGIC_NUMBER = int.from_bytes(_MAGIC_BYTES, 'little') # For import.c +MAGIC_NUMBER = (3280).to_bytes(2, 'little') + b'\r\n' +_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' @@ -663,7 +663,7 @@ def _validate_bytecode_header(data, source_stats=None, name=None, path=None): magic = data[:4] raw_timestamp = data[4:8] raw_size = data[8:12] - if magic != _MAGIC_BYTES: + if magic != MAGIC_NUMBER: message = 'bad magic number in {!r}: {!r}'.format(name, magic) _verbose_message(message) raise ImportError(message, **exc_details) @@ -711,7 +711,7 @@ def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): def _code_to_bytecode(code, mtime=0, source_size=0): """Compile a code object into bytecode for writing out to a byte-compiled file.""" - data = bytearray(_MAGIC_BYTES) + data = bytearray(MAGIC_NUMBER) data.extend(_w_long(mtime)) data.extend(_w_long(source_size)) data.extend(marshal.dumps(code)) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 9cf0eb7e280..09ec03c1424 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -1,5 +1,6 @@ """Utility code for constructing importers, etc.""" +from ._bootstrap import MAGIC_NUMBER from ._bootstrap import module_to_load from ._bootstrap import set_loader from ._bootstrap import set_package diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index e6b0084fa7f..78f5a3e99ac 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -313,5 +313,16 @@ class ResolveNameTests(unittest.TestCase): util.resolve_name('..bacon', 'spam') +class MagicNumberTests(unittest.TestCase): + + def test_length(self): + # Should be 4 bytes. + self.assertEqual(len(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(util.MAGIC_NUMBER.endswith(b'\r\n')) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index a1b63b0c906..f676dba49f1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -123,6 +123,9 @@ Core and Builtins Library ------- +- Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document as deprecated + imp.get_magic(). + - Issue #18149: Add filecmp.clear_cache() to manually clear the filecmp cache. Patch by Mark Levitt diff --git a/Python/importlib.h b/Python/importlib.h index e2f60c905dd..e1ec0e6962a 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1273,8 +1273,8 @@ const unsigned char _Py_M__importlib[] = { 0,98,121,116,101,99,111,100,101,32,105,115,32,115,116,97, 108,101,32,102,111,114,32,123,33,114,125,244,4,0,0,0, 115,105,122,101,108,3,0,0,0,255,127,255,127,3,0,40, - 9,0,0,0,244,12,0,0,0,95,77,65,71,73,67,95, - 66,89,84,69,83,114,46,0,0,0,114,140,0,0,0,114, + 9,0,0,0,244,12,0,0,0,77,65,71,73,67,95,78, + 85,77,66,69,82,114,46,0,0,0,114,140,0,0,0,114, 156,0,0,0,114,31,0,0,0,244,8,0,0,0,69,79, 70,69,114,114,111,114,114,14,0,0,0,114,93,0,0,0, 114,19,0,0,0,40,11,0,0,0,114,52,0,0,0,114,