Skip to content

Commit 05a647d

Browse files
committed
Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document the
deprecation of imp.get_magic().
1 parent 4d70562 commit 05a647d

8 files changed

Lines changed: 37 additions & 8 deletions

File tree

Doc/library/imp.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ This module provides an interface to the mechanisms used to implement the
2121
Return the magic string value used to recognize byte-compiled code files
2222
(:file:`.pyc` files). (This value may be different for each Python version.)
2323

24+
.. deprecated:: 3.4
25+
Use :attr:`importlib.util.MAGIC_NUMBER` instead.
26+
2427

2528
.. function:: get_suffixes()
2629

Doc/library/importlib.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,13 @@ find and load modules.
879879
This module contains the various objects that help in the construction of
880880
an :term:`importer`.
881881

882+
.. attribute:: MAGIC_NUMBER
883+
884+
The bytes which represent the bytecode version number. If you need help with
885+
loading/writing bytecode then consider :class:`importlib.abc.SourceLoader`.
886+
887+
.. versionadded:: 3.4
888+
882889
.. function:: resolve_name(name, package)
883890

884891
Resolve a relative module name to an absolute one.

Lib/imp.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from importlib import _bootstrap
2525
from importlib import machinery
26+
from importlib import util
2627
import importlib
2728
import os
2829
import sys
@@ -44,8 +45,11 @@
4445

4546

4647
def get_magic():
47-
"""Return the magic number for .pyc or .pyo files."""
48-
return _bootstrap._MAGIC_BYTES
48+
"""**DEPRECATED**
49+
50+
Return the magic number for .pyc or .pyo files.
51+
"""
52+
return util.MAGIC_NUMBER
4953

5054

5155
def get_tag():

Lib/importlib/_bootstrap.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,8 @@ def _call_with_frames_removed(f, *args, **kwds):
383383
# longer be understood by older implementations of the eval loop (usually
384384
# due to the addition of new opcodes).
385385

386-
_MAGIC_BYTES = (3280).to_bytes(2, 'little') + b'\r\n'
387-
_RAW_MAGIC_NUMBER = int.from_bytes(_MAGIC_BYTES, 'little') # For import.c
386+
MAGIC_NUMBER = (3280).to_bytes(2, 'little') + b'\r\n'
387+
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
388388

389389
_PYCACHE = '__pycache__'
390390

@@ -663,7 +663,7 @@ def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
663663
magic = data[:4]
664664
raw_timestamp = data[4:8]
665665
raw_size = data[8:12]
666-
if magic != _MAGIC_BYTES:
666+
if magic != MAGIC_NUMBER:
667667
message = 'bad magic number in {!r}: {!r}'.format(name, magic)
668668
_verbose_message(message)
669669
raise ImportError(message, **exc_details)
@@ -711,7 +711,7 @@ def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None):
711711
def _code_to_bytecode(code, mtime=0, source_size=0):
712712
"""Compile a code object into bytecode for writing out to a byte-compiled
713713
file."""
714-
data = bytearray(_MAGIC_BYTES)
714+
data = bytearray(MAGIC_NUMBER)
715715
data.extend(_w_long(mtime))
716716
data.extend(_w_long(source_size))
717717
data.extend(marshal.dumps(code))

Lib/importlib/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Utility code for constructing importers, etc."""
22

3+
from ._bootstrap import MAGIC_NUMBER
34
from ._bootstrap import module_to_load
45
from ._bootstrap import set_loader
56
from ._bootstrap import set_package

Lib/test/test_importlib/test_util.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,16 @@ def test_escape(self):
313313
util.resolve_name('..bacon', 'spam')
314314

315315

316+
class MagicNumberTests(unittest.TestCase):
317+
318+
def test_length(self):
319+
# Should be 4 bytes.
320+
self.assertEqual(len(util.MAGIC_NUMBER), 4)
321+
322+
def test_incorporates_rn(self):
323+
# The magic number uses \r\n to come out wrong when splitting on lines.
324+
self.assertTrue(util.MAGIC_NUMBER.endswith(b'\r\n'))
325+
326+
316327
if __name__ == '__main__':
317328
unittest.main()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ Core and Builtins
123123
Library
124124
-------
125125

126+
- Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document as deprecated
127+
imp.get_magic().
128+
126129
- Issue #18149: Add filecmp.clear_cache() to manually clear the filecmp cache.
127130
Patch by Mark Levitt
128131

Python/importlib.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,8 +1273,8 @@ const unsigned char _Py_M__importlib[] = {
12731273
0,98,121,116,101,99,111,100,101,32,105,115,32,115,116,97,
12741274
108,101,32,102,111,114,32,123,33,114,125,244,4,0,0,0,
12751275
115,105,122,101,108,3,0,0,0,255,127,255,127,3,0,40,
1276-
9,0,0,0,244,12,0,0,0,95,77,65,71,73,67,95,
1277-
66,89,84,69,83,114,46,0,0,0,114,140,0,0,0,114,
1276+
9,0,0,0,244,12,0,0,0,77,65,71,73,67,95,78,
1277+
85,77,66,69,82,114,46,0,0,0,114,140,0,0,0,114,
12781278
156,0,0,0,114,31,0,0,0,244,8,0,0,0,69,79,
12791279
70,69,114,114,111,114,114,14,0,0,0,114,93,0,0,0,
12801280
114,19,0,0,0,40,11,0,0,0,114,52,0,0,0,114,

0 commit comments

Comments
 (0)