summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2022-07-20 20:33:20 +0200
committerStefan Behnel <stefan_ml@behnel.de>2022-07-20 20:33:20 +0200
commit64b1cb116a223f48a08edd97bbd7c63188cb0b0b (patch)
treeacad7dc7dcd65a6693e3ed34546fbc25750399d3
parent87329f1f9747a5a7e483cf4827d40457f6354c7c (diff)
parent3cb3c2fd3a1359c46c81675610f7458ac6dcf223 (diff)
downloadcython-64b1cb116a223f48a08edd97bbd7c63188cb0b0b.tar.gz
Merge branch '0.29.x'
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py40
-rw-r--r--Cython/Compiler/Tests/TestParseTreeTransforms.py9
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