Skip to content

Commit

Permalink
Add Py_HashPointer() (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
vstinner authored Dec 15, 2023
1 parent 2ff4441 commit 4678af4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ Python 3.13
See `PyDict_PopString() documentation <https://docs.python.org/dev/c-api/dict.html#c.PyDict_PopString>`__.
.. c:function:: Py_hash_t Py_HashPointer(const void *ptr)
See `Py_HashPointer() documentation <https://docs.python.org/dev/c-api/hash.html#c.Py_HashPointer>`__.
Python 3.12
-----------
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Changelog
=========

* 2023-12-15: Add function ``Py_HashPointer()``.
* 2023-11-14: Add functions:

* ``PyDict_Pop()``
Expand Down
19 changes: 19 additions & 0 deletions pythoncapi_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,25 @@ PyDict_PopString(PyObject *dict, const char *key, PyObject **result)
}
#endif


#if PY_VERSION_HEX < 0x030200A4
// Python 3.2.0a4 added Py_hash_t type
typedef Py_ssize_t Py_hash_t;
#endif


// gh-111545 added Py_HashPointer() to Python 3.13.0a3
#if PY_VERSION_HEX < 0x030D00A3
static inline Py_hash_t Py_HashPointer(const void *ptr)
{
#if PY_VERSION_HEX >= 0x030900A4 && !defined(PYPY_VERSION)
return _Py_HashPointer(ptr);
#else
return _Py_HashPointer(_Py_CAST(void*, ptr));
#endif
}
#endif

#ifdef __cplusplus
}
#endif
Expand Down
29 changes: 29 additions & 0 deletions tests/test_pythoncapi_compat_cext.c
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,34 @@ test_list(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
}


static PyObject *
test_hash(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
void *ptr0 = NULL;
assert(Py_HashPointer(ptr0) == 0);

#ifndef PYPY_VERSION
#if SIZEOF_VOID_P == 8
void *ptr1 = (void*)(uintptr_t)0xABCDEF1234567890;
assert(Py_HashPointer(ptr1) == (uintptr_t)0x0ABCDEF123456789);
#else
void *ptr1 = (void*)(uintptr_t)0xDEADCAFE;
assert(Py_HashPointer(ptr1) == (uintptr_t)0xEDEADCAF);
#endif
#else
// PyPy
#if SIZEOF_VOID_P == 8
void *ptr1 = (void*)(uintptr_t)0xABCDEF1234567890;
#else
void *ptr1 = (void*)(uintptr_t)0xDEADCAFE;
#endif
assert(Py_HashPointer(ptr1) == (Py_hash_t)ptr1);
#endif

Py_RETURN_NONE;
}


static struct PyMethodDef methods[] = {
{"test_object", test_object, METH_NOARGS, _Py_NULL},
{"test_py_is", test_py_is, METH_NOARGS, _Py_NULL},
Expand Down Expand Up @@ -1530,6 +1558,7 @@ static struct PyMethodDef methods[] = {
#endif
{"test_unicode", test_unicode, METH_NOARGS, _Py_NULL},
{"test_list", test_list, METH_NOARGS, _Py_NULL},
{"test_hash", test_hash, METH_NOARGS, _Py_NULL},
{_Py_NULL, _Py_NULL, 0, _Py_NULL}
};

Expand Down

0 comments on commit 4678af4

Please sign in to comment.