https://github.com/python/cpython/commit/ef4fc86afa297071cb0eb3db871640fc14694a36
commit: ef4fc86afa297071cb0eb3db871640fc14694a36
branch: main
author: Bénédikt Tran <[email protected]>
committer: picnixz <[email protected]>
date: 2025-06-24T09:58:07+02:00
summary:

gh-135532: use `defining_class` for copying BLAKE-2 and SHA-3 objects (#135838)

files:
M Lib/test/test_hashlib.py
M Modules/blake2module.c
M Modules/clinic/blake2module.c.h
M Modules/clinic/sha3module.c.h
M Modules/sha3module.c

diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index 6e4e41e4fbb4f1..7b378c45e71563 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -371,6 +371,16 @@ def test_get_builtin_constructor(self):
         self.assertIs(constructor, _md5.md5)
         self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])
 
+    def test_copy(self):
+        for cons in self.hash_constructors:
+            h1 = cons(os.urandom(16), usedforsecurity=False)
+            h2 = h1.copy()
+            self.assertIs(type(h1), type(h2))
+            self.assertEqual(h1.name, h2.name)
+            size = (16,) if h1.name in self.shakes else ()
+            self.assertEqual(h1.digest(*size), h2.digest(*size))
+            self.assertEqual(h1.hexdigest(*size), h2.hexdigest(*size))
+
     def test_hexdigest(self):
         for cons in self.hash_constructors:
             h = cons(usedforsecurity=False)
diff --git a/Modules/blake2module.c b/Modules/blake2module.c
index 6c4349ac06bb8a..9e279e11b518d2 100644
--- a/Modules/blake2module.c
+++ b/Modules/blake2module.c
@@ -787,17 +787,19 @@ blake2_blake2b_copy_unlocked(Blake2Object *self, 
Blake2Object *cpy)
 /*[clinic input]
 _blake2.blake2b.copy
 
+    cls: defining_class
+
 Return a copy of the hash object.
 [clinic start generated code]*/
 
 static PyObject *
-_blake2_blake2b_copy_impl(Blake2Object *self)
-/*[clinic end generated code: output=622d1c56b91c50d8 input=e383c2d199fd8a2e]*/
+_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls)
+/*[clinic end generated code: output=5f8ea31c56c52287 input=f38f3475e9aec98d]*/
 {
     int rc;
     Blake2Object *cpy;
 
-    if ((cpy = new_Blake2Object(Py_TYPE(self))) == NULL) {
+    if ((cpy = new_Blake2Object(cls)) == NULL) {
         return NULL;
     }
 
diff --git a/Modules/clinic/blake2module.c.h b/Modules/clinic/blake2module.c.h
index 9e9cd56e569b24..97d010d03a4b23 100644
--- a/Modules/clinic/blake2module.c.h
+++ b/Modules/clinic/blake2module.c.h
@@ -434,15 +434,19 @@ PyDoc_STRVAR(_blake2_blake2b_copy__doc__,
 "Return a copy of the hash object.");
 
 #define _BLAKE2_BLAKE2B_COPY_METHODDEF    \
-    {"copy", (PyCFunction)_blake2_blake2b_copy, METH_NOARGS, 
_blake2_blake2b_copy__doc__},
+    {"copy", _PyCFunction_CAST(_blake2_blake2b_copy), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _blake2_blake2b_copy__doc__},
 
 static PyObject *
-_blake2_blake2b_copy_impl(Blake2Object *self);
+_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls);
 
 static PyObject *
-_blake2_blake2b_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_blake2_blake2b_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, 
Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _blake2_blake2b_copy_impl((Blake2Object *)self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "copy() takes no arguments");
+        return NULL;
+    }
+    return _blake2_blake2b_copy_impl((Blake2Object *)self, cls);
 }
 
 PyDoc_STRVAR(_blake2_blake2b_update__doc__,
@@ -502,4 +506,4 @@ _blake2_blake2b_hexdigest(PyObject *self, PyObject 
*Py_UNUSED(ignored))
 {
     return _blake2_blake2b_hexdigest_impl((Blake2Object *)self);
 }
-/*[clinic end generated code: output=eed18dcfaf6f7731 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=60a4abbcb8950fe5 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h
index d6d44bf4c514c0..1f631ff406e25b 100644
--- a/Modules/clinic/sha3module.c.h
+++ b/Modules/clinic/sha3module.c.h
@@ -100,15 +100,19 @@ PyDoc_STRVAR(_sha3_sha3_224_copy__doc__,
 "Return a copy of the hash object.");
 
 #define _SHA3_SHA3_224_COPY_METHODDEF    \
-    {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, 
_sha3_sha3_224_copy__doc__},
+    {"copy", _PyCFunction_CAST(_sha3_sha3_224_copy), 
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sha3_sha3_224_copy__doc__},
 
 static PyObject *
-_sha3_sha3_224_copy_impl(SHA3object *self);
+_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls);
 
 static PyObject *
-_sha3_sha3_224_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_sha3_sha3_224_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, 
Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _sha3_sha3_224_copy_impl((SHA3object *)self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "copy() takes no arguments");
+        return NULL;
+    }
+    return _sha3_sha3_224_copy_impl((SHA3object *)self, cls);
 }
 
 PyDoc_STRVAR(_sha3_sha3_224_digest__doc__,
@@ -306,4 +310,4 @@ _sha3_shake_128_hexdigest(PyObject *self, PyObject *const 
*args, Py_ssize_t narg
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=c17e3ec670afe253 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=48be77f8a31e8a3e input=a9049054013a1b77]*/
diff --git a/Modules/sha3module.c b/Modules/sha3module.c
index face90a6094beb..5764556bb680f3 100644
--- a/Modules/sha3module.c
+++ b/Modules/sha3module.c
@@ -239,16 +239,17 @@ SHA3_traverse(PyObject *self, visitproc visit, void *arg)
 /*[clinic input]
 _sha3.sha3_224.copy
 
+    cls: defining_class
+
 Return a copy of the hash object.
 [clinic start generated code]*/
 
 static PyObject *
-_sha3_sha3_224_copy_impl(SHA3object *self)
-/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/
+_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls)
+/*[clinic end generated code: output=13958b44c244013e input=7134b4dc0a2fbcac]*/
 {
     SHA3object *newobj;
-
-    if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) {
+    if ((newobj = newSHA3object(cls)) == NULL) {
         return NULL;
     }
     HASHLIB_ACQUIRE_LOCK(self);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to