From 0bacfc22ca4a08732196821d9d8749aebd9ae69b Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Wed, 21 Oct 2026 10:05:48 -0700 Subject: [PATCH] gh-114258: Use Argument Clinic for ``__hash__`` --- Lib/test/test_clinic.py | 1 + Objects/clinic/weakrefobject.c.h | 21 +++++++++++++++++ Objects/weakrefobject.c | 26 +++++++++++---------- Tools/clinic/libclinic/dsl_parser.py | 1 - Tools/clinic/libclinic/return_converters.py | 6 +++++ Tools/clinic/libclinic/slots.py | 1 + 6 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 Objects/clinic/weakrefobject.c.h diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index e3dd4a2be9e410..5845aec64d3a8f 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -4294,6 +4294,7 @@ def test_cli_converters(self): int() long() object() + Py_hash_t() Py_ssize_t() size_t() unsigned_int() diff --git a/Objects/clinic/weakrefobject.c.h b/Objects/clinic/weakrefobject.c.h new file mode 100644 index 00000000000000..9b1917f5597d68 --- /dev/null +++ b/Objects/clinic/weakrefobject.c.h @@ -0,0 +1,21 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() + +static Py_hash_t +weakref_hash_impl(PyWeakReference *self); + +static Py_hash_t +weakref_hash(PyObject *self) +{ + Py_hash_t return_value = -1; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = weakref_hash_impl((PyWeakReference *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} +/*[clinic end generated code: output=40453fff9335a3f7 input=a9049054013a1b77]*/ diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index ca55fe32875086..56007d4da12734 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -7,6 +7,13 @@ #include "pycore_pystate.h" #include "pycore_weakref.h" // _PyWeakref_GET_REF() +/*[clinic input] +class weakref "PyWeakReference *" "&_PyWeakref_RefType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad66c8b0acee6ad9]*/ + +#include "clinic/weakrefobject.c.h" + #ifdef Py_GIL_DISABLED /* * Thread-safety for free-threaded builds @@ -186,8 +193,14 @@ weakref_vectorcall(PyObject *self, PyObject *const *args, return obj; } +/*[clinic input] +@critical_section +weakref.__hash__ +[clinic start generated code]*/ + static Py_hash_t -weakref_hash_lock_held(PyWeakReference *self) +weakref_hash_impl(PyWeakReference *self) +/*[clinic end generated code: output=4904eacaabf902c9 input=703596f4b120e47c]*/ { if (self->hash != -1) return self->hash; @@ -201,17 +214,6 @@ weakref_hash_lock_held(PyWeakReference *self) return self->hash; } -static Py_hash_t -weakref_hash(PyObject *op) -{ - PyWeakReference *self = _PyWeakref_CAST(op); - Py_hash_t hash; - Py_BEGIN_CRITICAL_SECTION(self); - hash = weakref_hash_lock_held(self); - Py_END_CRITICAL_SECTION(); - return hash; -} - static PyObject * weakref_repr(PyObject *self) { diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index 4a38cb6b314fff..46e1fd0180ef23 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -53,7 +53,6 @@ __getattribute__ __getitem__ __gt__ -__hash__ __iadd__ __iand__ __ifloordiv__ diff --git a/Tools/clinic/libclinic/return_converters.py b/Tools/clinic/libclinic/return_converters.py index 4134d8e065ec43..6747f85e63f858 100644 --- a/Tools/clinic/libclinic/return_converters.py +++ b/Tools/clinic/libclinic/return_converters.py @@ -152,6 +152,12 @@ class Py_ssize_t_return_converter(long_return_converter): conversion_fn = 'PyLong_FromSsize_t' +class Py_hash_t_return_converter(long_return_converter): + type = 'Py_hash_t' + conversion_fn = 'PyLong_FromSsize_t' + cast = '(Py_ssize_t)' + + class size_t_return_converter(long_return_converter): type = 'size_t' conversion_fn = 'PyLong_FromSize_t' diff --git a/Tools/clinic/libclinic/slots.py b/Tools/clinic/libclinic/slots.py index 95137800fd868c..010bcb68a0bbd6 100644 --- a/Tools/clinic/libclinic/slots.py +++ b/Tools/clinic/libclinic/slots.py @@ -40,4 +40,5 @@ def make_return_converter(self) -> CReturnConverter: SLOTS: Final[dict[str, SlotSpec]] = { '__next__': SlotSpec(return_converter='object'), '__len__': SlotSpec(return_converter='Py_ssize_t'), + '__hash__': SlotSpec(return_converter='Py_hash_t'), }