Commit 1e331560 authored by Brett Cannon's avatar Brett Cannon

Closes #15030: Make importlib.abc.PyPycLoader respect the new .pyc

file size header field.

Thanks to Marc Abramowitz and Ronan Lamy for helping out with various
parts of the patch.
parent d57caf36
...@@ -455,6 +455,10 @@ are also provided to help in implementing the core ABCs. ...@@ -455,6 +455,10 @@ are also provided to help in implementing the core ABCs.
:class:`PyLoader`. Do note that this solution will not support :class:`PyLoader`. Do note that this solution will not support
sourceless/bytecode-only loading; only source *and* bytecode loading. sourceless/bytecode-only loading; only source *and* bytecode loading.
.. versionchanged:: 3.3
Updated to parse (but not use) the new source size field in bytecode
files when reading and to write out the field properly when writing.
.. method:: source_mtime(fullname) .. method:: source_mtime(fullname)
An abstract method which returns the modification time for the source An abstract method which returns the modification time for the source
......
...@@ -282,7 +282,12 @@ class PyPycLoader(PyLoader): ...@@ -282,7 +282,12 @@ class PyPycLoader(PyLoader):
if len(raw_timestamp) < 4: if len(raw_timestamp) < 4:
raise EOFError("bad timestamp in {}".format(fullname)) raise EOFError("bad timestamp in {}".format(fullname))
pyc_timestamp = _bootstrap._r_long(raw_timestamp) pyc_timestamp = _bootstrap._r_long(raw_timestamp)
bytecode = data[8:] raw_source_size = data[8:12]
if len(raw_source_size) != 4:
raise EOFError("bad file size in {}".format(fullname))
# Source size is unused as the ABC does not provide a way to
# get the size of the source ahead of reading it.
bytecode = data[12:]
# Verify that the magic number is valid. # Verify that the magic number is valid.
if imp.get_magic() != magic: if imp.get_magic() != magic:
raise ImportError( raise ImportError(
...@@ -318,6 +323,7 @@ class PyPycLoader(PyLoader): ...@@ -318,6 +323,7 @@ class PyPycLoader(PyLoader):
if not sys.dont_write_bytecode: if not sys.dont_write_bytecode:
data = bytearray(imp.get_magic()) data = bytearray(imp.get_magic())
data.extend(_bootstrap._w_long(source_timestamp)) data.extend(_bootstrap._w_long(source_timestamp))
data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF))
data.extend(marshal.dumps(code_object)) data.extend(marshal.dumps(code_object))
self.write_bytecode(fullname, data) self.write_bytecode(fullname, data)
return code_object return code_object
......
...@@ -148,11 +148,12 @@ class PyPycLoaderMock(abc.PyPycLoader, PyLoaderMock): ...@@ -148,11 +148,12 @@ class PyPycLoaderMock(abc.PyPycLoader, PyLoaderMock):
self.bytecode_to_path[name] = data['path'] self.bytecode_to_path[name] = data['path']
magic = data.get('magic', imp.get_magic()) magic = data.get('magic', imp.get_magic())
mtime = importlib._w_long(data.get('mtime', self.default_mtime)) mtime = importlib._w_long(data.get('mtime', self.default_mtime))
source_size = importlib._w_long(len(self.source) & 0xFFFFFFFF)
if 'bc' in data: if 'bc' in data:
bc = data['bc'] bc = data['bc']
else: else:
bc = self.compile_bc(name) bc = self.compile_bc(name)
self.module_bytecode[name] = magic + mtime + bc self.module_bytecode[name] = magic + mtime + source_size + bc
def compile_bc(self, name): def compile_bc(self, name):
source_path = self.module_paths.get(name, '<test>') or '<test>' source_path = self.module_paths.get(name, '<test>') or '<test>'
...@@ -344,7 +345,10 @@ class PyPycLoaderTests(PyLoaderTests): ...@@ -344,7 +345,10 @@ class PyPycLoaderTests(PyLoaderTests):
self.assertEqual(magic, imp.get_magic()) self.assertEqual(magic, imp.get_magic())
mtime = importlib._r_long(mock.module_bytecode[name][4:8]) mtime = importlib._r_long(mock.module_bytecode[name][4:8])
self.assertEqual(mtime, 1) self.assertEqual(mtime, 1)
bc = mock.module_bytecode[name][8:] source_size = mock.module_bytecode[name][8:12]
self.assertEqual(len(mock.source) & 0xFFFFFFFF,
importlib._r_long(source_size))
bc = mock.module_bytecode[name][12:]
self.assertEqual(bc, mock.compile_bc(name)) self.assertEqual(bc, mock.compile_bc(name))
def test_module(self): def test_module(self):
......
...@@ -587,6 +587,7 @@ Vladimir Kushnir ...@@ -587,6 +587,7 @@ Vladimir Kushnir
Ross Lagerwall Ross Lagerwall
Cameron Laird Cameron Laird
Jean-Baptiste "Jiba" Lamy Jean-Baptiste "Jiba" Lamy
Ronan Lamy
Torsten Landschoff Torsten Landschoff
Łukasz Langa Łukasz Langa
Tino Lange Tino Lange
......
...@@ -17,6 +17,9 @@ Core and Builtins ...@@ -17,6 +17,9 @@ Core and Builtins
Library Library
------- -------
- Issue #15030: importlib.abc.PyPycLoader now supports the new source size
header field in .pyc files.
- Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox - Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox
files on flush(). files on flush().
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment