diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2022-07-20 20:33:20 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2022-07-20 20:33:20 +0200 |
commit | 64b1cb116a223f48a08edd97bbd7c63188cb0b0b (patch) | |
tree | acad7dc7dcd65a6693e3ed34546fbc25750399d3 | |
parent | 87329f1f9747a5a7e483cf4827d40457f6354c7c (diff) | |
parent | 3cb3c2fd3a1359c46c81675610f7458ac6dcf223 (diff) | |
download | cython-64b1cb116a223f48a08edd97bbd7c63188cb0b0b.tar.gz |
Merge branch '0.29.x'
-rw-r--r-- | Cython/Compiler/ParseTreeTransforms.py | 40 | ||||
-rw-r--r-- | Cython/Compiler/Tests/TestParseTreeTransforms.py | 9 |
2 files changed, 32 insertions, 17 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 89620cd45..34fbce72f 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -6,10 +6,12 @@ import cython cython.declare(PyrexTypes=object, Naming=object, ExprNodes=object, Nodes=object, Options=object, UtilNodes=object, LetNode=object, LetRefNode=object, TreeFragment=object, EncodedString=object, - error=object, warning=object, copy=object, _unicode=object) + error=object, warning=object, copy=object, hashlib=object, sys=object, + _unicode=object) import copy import hashlib +import sys from . import PyrexTypes from . import Naming @@ -2035,22 +2037,10 @@ if VALUE is not None: if not e.type.is_pyobject: e.type.create_to_py_utility_code(env) e.type.create_from_py_utility_code(env) - all_members_names = sorted([e.name for e in all_members]) - - # Cython 0.x used MD5 for the checksum, which a few Python installations remove for security reasons. - # SHA-256 should be ok for years to come, but early Cython 3.0 alpha releases used SHA-1, - # which may not be. - checksum_algos = [hashlib.sha256, hashlib.sha1] - try: - checksum_algos.append(hashlib.md5) - except AttributeError: - pass - member_names_string = ' '.join(all_members_names).encode('utf-8') - checksums = [ - '0x' + mkchecksum(member_names_string).hexdigest()[:7] - for mkchecksum in checksum_algos - ] + all_members_names = [e.name for e in all_members] + checksums = _calculate_pickle_checksums(all_members_names) + unpickle_func_name = '__pyx_unpickle_%s' % node.punycode_class_name # TODO(robertwb): Move the state into the third argument @@ -2467,6 +2457,24 @@ if VALUE is not None: return node +def _calculate_pickle_checksums(member_names): + # Cython 0.x used MD5 for the checksum, which a few Python installations remove for security reasons. + # SHA-256 should be ok for years to come, but early Cython 3.0 alpha releases used SHA-1, + # which may not be. + member_names_string = ' '.join(member_names).encode('utf-8') + hash_kwargs = {'usedforsecurity': False} if sys.version_info >= (3, 9) else {} + checksums = [] + for algo_name in ['sha256', 'sha1', 'md5']: + try: + mkchecksum = getattr(hashlib, algo_name) + checksum = mkchecksum(member_names_string, **hash_kwargs).hexdigest() + except (AttributeError, ValueError): + # The algorithm (i.e. MD5) might not be there at all, or might be blocked at runtime. + continue + checksums.append('0x' + checksum[:7]) + return checksums + + class CalculateQualifiedNamesTransform(EnvTransform): """ Calculate and store the '__qualname__' and the global diff --git a/Cython/Compiler/Tests/TestParseTreeTransforms.py b/Cython/Compiler/Tests/TestParseTreeTransforms.py index e6889f8f2..6e29263e5 100644 --- a/Cython/Compiler/Tests/TestParseTreeTransforms.py +++ b/Cython/Compiler/Tests/TestParseTreeTransforms.py @@ -1,7 +1,9 @@ -import os +import os.path +import unittest from Cython.TestUtils import TransformTest from Cython.Compiler.ParseTreeTransforms import * +from Cython.Compiler.ParseTreeTransforms import _calculate_pickle_checksums from Cython.Compiler.Nodes import * from Cython.Compiler import Main, Symtab, Options @@ -276,6 +278,11 @@ class TestDebugTransform(DebuggerTestCase): raise +class TestAnalyseDeclarationsTransform(unittest.TestCase): + def test_calculate_pickle_checksums(self): + checksums = _calculate_pickle_checksums(['member1', 'member2', 'member3']) + assert 2 <= len(checksums) <= 3, checksums # expecting ['0xc0af380' (MD5), '0x0c75bd4', '0xa7a7b94'] + if __name__ == "__main__": import unittest |