Visitar URL original
[3.5] bpo-29537: Tolerate legacy invalid bytecode by ncoghlan · Pull Request #169 · python/cpython · GitHub
Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add legacy bytecode compatibility tests
  • Loading branch information
ncoghlan committed Mar 8, 2017
commit ca248646d497d06580d02dcc43d9607d4e2f1dfd
104 changes: 104 additions & 0 deletions Lib/test/test_importlib/source/test_file_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,5 +603,109 @@ class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest,
util=importlib_util)


###########################################################################
# Issue #29537: Test backwards compatibility with legacy 3.5.0/1/2 bytecode
###########################################################################

class LegacyBytecodeTest:

def _test_legacy_magic(self, test, *, del_source=False):
# Replace the default magic number with one copied from a pyc file
# generated by Python 3.5.2
with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: b'\x16\r\r\n' + bc[4:])
test('_temp', mapping, bc_path)

LegacyBytecodeTestPEP451 = BadBytecodeTestPEP451
LegacyBytecodeTestPEP302 = BadBytecodeTestPEP302

# SourceLoader via both PEP 451 and 302 hooks

class SourceLoaderLegacyBytecodeTest(LegacyBytecodeTest):

@classmethod
def setUpClass(cls):
cls.loader = cls.machinery.SourceFileLoader

@util.writes_bytecode_files
def test_legacy_magic(self):
# The magic number from 3.5.0/1/2 should be accepted as is
def test(name, mapping, bytecode_path):
self.import_(mapping[name], name)
with open(bytecode_path, 'rb') as bytecode_file:
self.assertEqual(bytecode_file.read(4),
self.util._BACKCOMPAT_MAGIC_NUMBER)

self._test_legacy_magic(test)


class SourceLoaderLegacyBytecodeTestPEP451(
SourceLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP451):
pass


(Frozen_SourceLegacyBytecodePEP451,
Source_SourceLegacyBytecodePEP451
) = util.test_both(SourceLoaderLegacyBytecodeTestPEP451, importlib=importlib,
machinery=machinery, abc=importlib_abc,
util=importlib_util)


class SourceLoaderLegacyBytecodeTestPEP302(
SourceLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP302):
pass


(Frozen_SourceLegacyBytecodePEP302,
Source_SourceLegacyBytecodePEP302
) = util.test_both(SourceLoaderLegacyBytecodeTestPEP302, importlib=importlib,
machinery=machinery, abc=importlib_abc,
util=importlib_util)

# SourcelessLoader via both PEP 451 and 302 hooks

class SourcelessLoaderLegacyBytecodeTest(LegacyBytecodeTest):

@classmethod
def setUpClass(cls):
cls.loader = cls.machinery.SourcelessFileLoader


@util.writes_bytecode_files
def test_legacy_magic(self):
# The magic number from 3.5.0/1/2 should be accepted as is
def test(name, mapping, bytecode_path):
self.import_(bytecode_path, name)
with open(bytecode_path, 'rb') as bytecode_file:
self.assertEqual(bytecode_file.read(4),
self.util._BACKCOMPAT_MAGIC_NUMBER)

self._test_legacy_magic(test)

class SourcelessLoaderLegacyBytecodeTestPEP451(
SourcelessLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP451):
pass

(Frozen_SourcelessLegacyBytecodePEP451,
Source_SourcelessLegacyBytecodePEP451
) = util.test_both(SourcelessLoaderLegacyBytecodeTestPEP451, importlib=importlib,
machinery=machinery, abc=importlib_abc,
util=importlib_util)


class SourcelessLoaderLegacyBytecodeTestPEP302(SourcelessLoaderLegacyBytecodeTest,
LegacyBytecodeTestPEP302):
pass


(Frozen_SourcelessLegacyBytecodePEP302,
Source_SourcelessLegacyBytecodePEP302
) = util.test_both(SourcelessLoaderLegacyBytecodeTestPEP302, importlib=importlib,
machinery=machinery, abc=importlib_abc,
util=importlib_util)

# End of Issue #29537 legacy bytecode compatibility tests

if __name__ == '__main__':
unittest.main()