Skip to content

Commit 3f1c06d

Browse files
authored
Add Py_HashBuffer() function (#112)
1 parent fba4977 commit 3f1c06d

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

docs/api.rst

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Supported Python versions:
1010
* Python 3.6 - 3.14
1111
* PyPy 2.7 and PyPy 3.6 - 3.10
1212

13-
Python 2.7 and Python 3.4 are no longer officially supported since GitHub
13+
Python 2.7 and Python 3.5 are no longer officially supported since GitHub
1414
Actions doesn't support them anymore: only best effort support is provided.
1515

1616
C++03 and C++11 are supported on Python 3.6 and newer.
@@ -37,6 +37,10 @@ Python 3.14
3737

3838
See `PyBytes_Join() documentation <https://docs.python.org/dev/c-api/bytes.html#c.PyBytes_Join>`__.
3939

40+
.. c:function:: Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len)
41+
42+
See `Py_HashBuffer() documentation <https://docs.python.org/dev/c-api/hash.html#c.Py_HashBuffer>`__.
43+
4044
.. c:function:: int PyUnicode_Equal(PyObject *str1, PyObject *str2)
4145

4246
See `PyUnicode_Equal() documentation <https://docs.python.org/dev/c-api/unicode.html#c.PyUnicode_Equal>`__.
@@ -83,7 +87,34 @@ Python 3.14
8387

8488
Not supported:
8589

90+
* ``PyConfig_Get()``
91+
* ``PyConfig_GetInt()``
92+
* ``PyConfig_Names()``
93+
* ``PyConfig_Set()``
94+
* ``PyInitConfig_AddModule()``
95+
* ``PyInitConfig_Create()``
96+
* ``PyInitConfig_Free()``
97+
* ``PyInitConfig_FreeStrList()``
98+
* ``PyInitConfig_GetError()``
99+
* ``PyInitConfig_GetExitCode()``
100+
* ``PyInitConfig_GetInt()``
101+
* ``PyInitConfig_GetStr()``
102+
* ``PyInitConfig_GetStrList()``
103+
* ``PyInitConfig_HasOption()``
104+
* ``PyInitConfig_SetInt()``
105+
* ``PyInitConfig_SetStr()``
106+
* ``PyInitConfig_SetStrList()``
107+
* ``PyLong_AsInt32()``
108+
* ``PyLong_AsInt64()``
109+
* ``PyLong_AsUInt32()``
110+
* ``PyLong_AsUInt64()``
111+
* ``PyLong_FromInt32()``
112+
* ``PyLong_FromInt64()``
113+
* ``PyLong_FromUInt32()``
114+
* ``PyLong_FromUInt64()``
115+
* ``PyType_GetBaseByToken()``
86116
* ``PyUnicodeWriter_DecodeUTF8Stateful()``
117+
* ``Py_InitializeFromInitConfig()``
87118

88119

89120
Python 3.13

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55

66
* ``PyBytes_Join()``
77
* ``PyUnicode_Equal()``
8+
* ``Py_HashBuffer()``
89

910
* 2024-07-18: Add functions:
1011

pythoncapi_compat.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,27 @@ static inline PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
15551555
#endif
15561556

15571557

1558+
#if PY_VERSION_HEX < 0x030E00A0
1559+
static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len)
1560+
{
1561+
#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION)
1562+
extern Py_hash_t _Py_HashBytes(const void *src, Py_ssize_t len);
1563+
1564+
return _Py_HashBytes(ptr, len);
1565+
#else
1566+
Py_hash_t hash;
1567+
PyObject *bytes = PyBytes_FromStringAndSize((const char*)ptr, len);
1568+
if (bytes == NULL) {
1569+
return -1;
1570+
}
1571+
hash = PyObject_Hash(bytes);
1572+
Py_DECREF(bytes);
1573+
return hash;
1574+
#endif
1575+
}
1576+
#endif
1577+
1578+
15581579
#ifdef __cplusplus
15591580
}
15601581
#endif

tests/test_pythoncapi_compat_cext.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,20 @@ test_hash(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
16181618
assert(imag != 0);
16191619
#endif
16201620

1621+
// Test Py_HashBuffer()
1622+
{
1623+
PyObject *abc = PyBytes_FromString("abc");
1624+
if (abc == NULL) {
1625+
return NULL;
1626+
}
1627+
Py_hash_t hash = Py_HashBuffer(PyBytes_AS_STRING(abc),
1628+
PyBytes_GET_SIZE(abc));
1629+
Py_hash_t hash2 = PyObject_Hash(abc);
1630+
assert(hash == hash2);
1631+
1632+
Py_DECREF(abc);
1633+
}
1634+
16211635
Py_RETURN_NONE;
16221636
}
16231637

@@ -1884,6 +1898,7 @@ test_unicodewriter_format(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
18841898
static PyObject *
18851899
test_bytes(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
18861900
{
1901+
// Test PyBytes_Join()
18871902
PyObject *abc = PyBytes_FromString("a b c");
18881903
if (abc == NULL) {
18891904
return NULL;

0 commit comments

Comments
 (0)