From 1e331560eea62c78ec189f2b72b59864ee315ddc Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 2 Jul 2012 14:35:34 -0400 Subject: 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. --- Doc/library/importlib.rst | 4 ++++ Lib/importlib/abc.py | 8 +++++++- Lib/importlib/test/source/test_abc_loader.py | 8 ++++++-- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 4dc1c78..cea2da0 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -455,6 +455,10 @@ are also provided to help in implementing the core ABCs. :class:`PyLoader`. Do note that this solution will not support 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) An abstract method which returns the modification time for the source diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index c171da3..8d65907 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -282,7 +282,12 @@ class PyPycLoader(PyLoader): if len(raw_timestamp) < 4: raise EOFError("bad timestamp in {}".format(fullname)) 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. if imp.get_magic() != magic: raise ImportError( @@ -318,6 +323,7 @@ class PyPycLoader(PyLoader): if not sys.dont_write_bytecode: data = bytearray(imp.get_magic()) data.extend(_bootstrap._w_long(source_timestamp)) + data.extend(_bootstrap._w_long(len(source) & 0xFFFFFFFF)) data.extend(marshal.dumps(code_object)) self.write_bytecode(fullname, data) return code_object diff --git a/Lib/importlib/test/source/test_abc_loader.py b/Lib/importlib/test/source/test_abc_loader.py index 27babb9..afcaad0 100644 --- a/Lib/importlib/test/source/test_abc_loader.py +++ b/Lib/importlib/test/source/test_abc_loader.py @@ -148,11 +148,12 @@ class PyPycLoaderMock(abc.PyPycLoader, PyLoaderMock): self.bytecode_to_path[name] = data['path'] magic = data.get('magic', imp.get_magic()) mtime = importlib._w_long(data.get('mtime', self.default_mtime)) + source_size = importlib._w_long(len(self.source) & 0xFFFFFFFF) if 'bc' in data: bc = data['bc'] else: 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): source_path = self.module_paths.get(name, '') or '' @@ -344,7 +345,10 @@ class PyPycLoaderTests(PyLoaderTests): self.assertEqual(magic, imp.get_magic()) mtime = importlib._r_long(mock.module_bytecode[name][4:8]) 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)) def test_module(self): diff --git a/Misc/ACKS b/Misc/ACKS index 9af9dcd..06dd7eb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -587,6 +587,7 @@ Vladimir Kushnir Ross Lagerwall Cameron Laird Jean-Baptiste "Jiba" Lamy +Ronan Lamy Torsten Landschoff Ɓukasz Langa Tino Lange diff --git a/Misc/NEWS b/Misc/NEWS index cdd3162..b318e50 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -17,6 +17,9 @@ Core and Builtins 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 files on flush(). -- cgit v0.12