8000 gh-113024: C API: Add PyObject_GenericHash() function (GH-113025) · adorilson/cpython@2b3da73 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b3da73

Browse files
serhiy-storchakaadorilson
authored andcommitted
pythongh-113024: C API: Add PyObject_GenericHash() function (pythonGH-113025)
1 parent c175734 commit 2b3da73

File tree

14 files changed

+51
-13
lines changed

14 files changed

+51
-13
lines changed

Doc/c-api/hash.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,14 @@ See also the :c:member:`PyTypeObject.tp_hash` member and :ref:`numeric-hash`.
8282
The function cannot fail: it cannot return ``-1``.
8383
8484
.. versionadded:: 3.13
85+
86+
.. c:function:: Py_hash_t PyObject_GenericHash(PyObject *obj)
87+
88+
Generic hashing function that is meant to be put into a type
89+
object's ``tp_hash`` slot.
90+
Its result only depends on the object's identity.
91+
92+
.. impl-detail::
93+
In CPython, it is equivalent to :c:func:`Py_HashPointer`.
94+
95+
.. versionadded:: 3.13

Doc/c-api/typeobj.rst

Lines changed: 4 additions & 0 deletions
  • Original file line numberDiff line numberDiff line change
    @@ -883,6 +883,10 @@ and :c:data:`PyType_Type` effectively act as defaults.)
    883883
    :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash`, when the subtype's
    884884
    :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both ``NULL``.
    885885

    886+
    **Default:**
    887+
    888+
    :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_GenericHash`.
    889+
    886890

    887891
    .. c:member:: ternaryfunc PyTypeObject.tp_call
    888892

    Doc/whatsnew/3.13.rst

    Lines changed: 4 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1702,6 +1702,10 @@ New Features
    17021702
    * Add :c:func:`Py_HashPointer` function to hash a pointer.
    17031703
    (Contributed by Victor Stinner in :gh:`111545`.)
    17041704

    1705+
    * Add :c:func:`PyObject_GenericHash` function that implements the default
    1706+
    hashing function of a Python object.
    1707+
    (Contributed by Serhiy Storchaka in :gh:`113024`.)
    1708+
    17051709
    * Add PyTime C API:
    17061710

    17071711
    * :c:type:`PyTime_t` type.

    Include/cpython/pyhash.h

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -43,3 +43,4 @@ typedef struct {
    4343
    PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);
    4444

    4545
    PyAPI_FUNC(Py_hash_t) Py_HashPointer(const void *ptr);
    46+
    PyAPI_FUNC(Py_hash_t) PyObject_GenericHash(PyObject *);

    Lib/test/test_capi/test_abstract.py

    Lines changed: 6 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1001,6 +1001,12 @@ def test_number_check(self):
    10011001
    self.assertTrue(number_check(0.5))
    10021002
    self.assertFalse(number_check("1 + 1j"))
    10031003

    1004+
    def test_object_generichash(self):
    1005+
    # Test PyObject_GenericHash()
    1006+
    generichash = _testcapi.object_generichash
    1007+
    for obj in object(), 1, 'string', []:
    1008+
    self.assertEqual(generichash(obj), object.__hash__(obj))
    1009+
    10041010

    10051011
    if __name__ == "__main__":
    10061012
    unittest.main()
    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1 @@
    1+
    Add :c:func:`PyObject_GenericHash` function.

    Modules/_decimal/_decimal.c

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -4780,7 +4780,7 @@ _dec_hash(PyDecObject *v)
    47804780
    return -1;
    47814781
    }
    47824782
    else if (mpd_isnan(MPD(v))) {
    4783-
    return _Py_HashPointer(v);
    4783+
    return PyObject_GenericHash((PyObject *)v);
    47844784
    }
    47854785
    else {
    47864786
    return py_hash_inf * mpd_arith_sign(MPD(v));

    Modules/_testcapi/hash.c

    Lines changed: 11 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -59,9 +59,20 @@ hash_pointer(PyObject *Py_UNUSED(module), PyObject *arg)
    5959
    }
    6060

    6161

    62+
    static PyObject *
    63+
    object_generichash(PyObject *Py_UNUSED(module), PyObject *arg)
    64+
    {
    65+
    NULLABLE(arg);
    66+
    Py_hash_t hash = PyObject_GenericHash(arg);
    67+
    Py_BUILD_ASSERT(sizeof(long long) >= sizeof(hash));
    68+
    return PyLong_FromLongLong(hash);
    69+
    }
    70+
    71+
    6272
    static PyMethodDef test_methods[] = {
    6373
    {"hash_getfuncdef", hash_getfuncdef, METH_NOARGS},
    6474
    {"hash_pointer", hash_pointer, METH_O},
    75+
    {"object_generichash", object_generichash, METH_O},
    6576
    {NULL},
    6677
    };
    6778

    Objects/classobject.c

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -301,7 +301,7 @@ static Py_hash_t
    301301
    method_hash(PyMethodObject *a)
    302302
    {
    303303
    Py_hash_t x, y;
    304-
    x = _Py_HashPointer(a->im_self);
    304+
    x = PyObject_GenericHash(a->im_self);
    305305
    y = PyObject_Hash(a->im_func);
    306306
    if (y == -1)
    307307
    return -1;

    Objects/descrobject.c

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -1346,7 +1346,7 @@ wrapper_hash(PyObject *self)
    13461346
    {
    13471347
    wrapperobject *wp = (wrapperobject *)self;
    13481348
    Py_hash_t x, y;
    1349-
    x = _Py_HashPointer(wp->self);
    1349+
    x = PyObject_GenericHash(wp->self);
    13501350
    y = _Py_HashPointer(wp->descr);
    13511351
    x = x ^ y;
    13521352
    if (x == -1)

    0 commit comments

    Comments
     (0)
    0