Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 55f3cce

Browse filesBrowse files
authored
gh-111545: Test PyHash_GetFuncDef() function (#112098)
Add Modules/_testcapi/hash.c and Lib/test/test_capi/test_hash.py.
1 parent e0f5127 commit 55f3cce
Copy full SHA for 55f3cce

File tree

Expand file treeCollapse file tree

9 files changed

+147
-1
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+147
-1
lines changed

‎Doc/c-api/hash.rst

Copy file name to clipboard
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.. highlight:: c
2+
3+
PyHash API
4+
----------
5+
6+
See also the :c:member:`PyTypeObject.tp_hash` member.
7+
8+
.. c:type:: Py_hash_t
9+
10+
Hash value type: signed integer.
11+
12+
.. versionadded:: 3.2
13+
14+
.. c:type:: Py_uhash_t
15+
16+
Hash value type: unsigned integer.
17+
18+
.. versionadded:: 3.2
19+
20+
21+
.. c:type:: PyHash_FuncDef
22+
23+
Hash function definition used by :c:func:`PyHash_GetFuncDef`.
24+
25+
.. c::member:: Py_hash_t (*const hash)(const void *, Py_ssize_t)
26+
27+
Hash function.
28+
29+
.. c:member:: const char *name
30+
31+
Hash function name (UTF-8 encoded string).
32+
33+
.. c:member:: const int hash_bits
34+
35+
Internal size of the hash value in bits.
36+
37+
.. c:member:: const int seed_bits
38+
39+
Size of seed input in bits.
40+
41+
.. versionadded:: 3.4
42+
43+
44+
.. c:function:: PyHash_FuncDef* PyHash_GetFuncDef(void)
45+
46+
Get the hash function definition.
47+
48+
.. versionadded:: 3.4

‎Doc/c-api/utilities.rst

Copy file name to clipboardExpand all lines: Doc/c-api/utilities.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and parsing function arguments and constructing Python values from C values.
1717
marshal.rst
1818
arg.rst
1919
conversion.rst
20+
hash.rst
2021
reflection.rst
2122
codec.rst
2223
perfmaps.rst

‎Lib/test/test_capi/test_hash.py

Copy file name to clipboard
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import sys
2+
import unittest
3+
from test.support import import_helper
4+
_testcapi = import_helper.import_module('_testcapi')
5+
6+
7+
SIZEOF_PY_HASH_T = _testcapi.SIZEOF_VOID_P
8+
9+
10+
class CAPITest(unittest.TestCase):
11+
def test_hash_getfuncdef(self):
12+
# Test PyHash_GetFuncDef()
13+
hash_getfuncdef = _testcapi.hash_getfuncdef
14+
func_def = hash_getfuncdef()
15+
16+
match func_def.name:
17+
case "fnv":
18+
self.assertEqual(func_def.hash_bits, 8 * SIZEOF_PY_HASH_T)
19+
self.assertEqual(func_def.seed_bits, 16 * SIZEOF_PY_HASH_T)
20+
case "siphash13":
21+
self.assertEqual(func_def.hash_bits, 64)
22+
self.assertEqual(func_def.seed_bits, 128)
23+
case "siphash24":
24+
self.assertEqual(func_def.hash_bits, 64)
25+
self.assertEqual(func_def.seed_bits, 128)
26+
case _:
27+
self.fail(f"unknown function name: {func_def.name!r}")
28+
29+
# compare with sys.hash_info
30+
hash_info = sys.hash_info
31+
self.assertEqual(func_def.name, hash_info.algorithm)
32+
self.assertEqual(func_def.hash_bits, hash_info.hash_bits)
33+
self.assertEqual(func_def.seed_bits, hash_info.seed_bits)

‎Modules/Setup.stdlib.in

Copy file name to clipboardExpand all lines: Modules/Setup.stdlib.in
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
160160
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
161161
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c
162-
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/bytearray.c _testcapi/bytes.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/pyos.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c _testcapi/sys.c
162+
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/bytearray.c _testcapi/bytes.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/pyos.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c _testcapi/sys.c _testcapi/hash.c
163163
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
164164
@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
165165

‎Modules/_testcapi/hash.c

Copy file name to clipboard
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include "parts.h"
2+
#include "util.h"
3+
4+
static PyObject *
5+
hash_getfuncdef(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
6+
{
7+
// bind PyHash_GetFuncDef()
8+
PyHash_FuncDef *def = PyHash_GetFuncDef();
9+
10+
PyObject *types = PyImport_ImportModule("types");
11+
if (types == NULL) {
12+
return NULL;
13+
}
14+
15+
PyObject *result = PyObject_CallMethod(types, "SimpleNamespace", NULL);
16+
Py_DECREF(types);
17+
if (result == NULL) {
18+
return NULL;
19+
}
20+
21+
// ignore PyHash_FuncDef.hash
22+
23+
PyObject *value = PyUnicode_FromString(def->name);
24+
int res = PyObject_SetAttrString(result, "name", value);
25+
Py_DECREF(value);
26+
if (res < 0) {
27+
return NULL;
28+
}
29+
30+
value = PyLong_FromLong(def->hash_bits);
31+
res = PyObject_SetAttrString(result, "hash_bits", value);
32+
Py_DECREF(value);
33+
if (res < 0) {
34+
return NULL;
35+
}
36+
37+
value = PyLong_FromLong(def->seed_bits);
38+
res = PyObject_SetAttrString(result, "seed_bits", value);
39+
Py_DECREF(value);
40+
if (res < 0) {
41+
return NULL;
42+
}
43+
44+
return result;
45+
}
46+
47+
static PyMethodDef test_methods[] = {
48+
{"hash_getfuncdef", hash_getfuncdef, METH_NOARGS},
49+
{NULL},
50+
};
51+
52+
int
53+
_PyTestCapi_Init_Hash(PyObject *m)
54+
{
55+
return PyModule_AddFunctions(m, test_methods);
56+
}

‎Modules/_testcapi/parts.h

Copy file name to clipboardExpand all lines: Modules/_testcapi/parts.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ int _PyTestCapi_Init_Codec(PyObject *module);
5858
int _PyTestCapi_Init_Immortal(PyObject *module);
5959
int _PyTestCapi_Init_GC(PyObject *module);
6060
int _PyTestCapi_Init_Sys(PyObject *module);
61+
int _PyTestCapi_Init_Hash(PyObject *module);
6162

6263
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
6364
int _PyTestCapi_Init_HeaptypeRelative(PyObject *module);

‎Modules/_testcapimodule.c

Copy file name to clipboardExpand all lines: Modules/_testcapimodule.c
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,6 +3995,9 @@ PyInit__testcapi(void)
39953995
if (_PyTestCapi_Init_HeaptypeRelative(m) < 0) {
39963996
return NULL;
39973997
}
3998+
if (_PyTestCapi_Init_Hash(m) < 0) {
3999+
return NULL;
4000+
}
39984001

39994002
PyState_AddModule(m, &_testcapimodule);
40004003
return m;

‎PCbuild/_testcapi.vcxproj

Copy file name to clipboardExpand all lines: PCbuild/_testcapi.vcxproj
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
<ClCompile Include="..\Modules\_testcapi\file.c" />
125125
<ClCompile Include="..\Modules\_testcapi\codec.c" />
126126
<ClCompile Include="..\Modules\_testcapi\sys.c" />
127+
<ClCompile Include="..\Modules\_testcapi\hash.c" />
127128
<ClCompile Include="..\Modules\_testcapi\immortal.c" />
128129
<ClCompile Include="..\Modules\_testcapi\gc.c" />
129130
</ItemGroup>

‎PCbuild/_testcapi.vcxproj.filters

Copy file name to clipboardExpand all lines: PCbuild/_testcapi.vcxproj.filters
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@
102102
<ClCompile Include="..\Modules\_testcapi\sys.c">
103103
<Filter>Source Files</Filter>
104104
</ClCompile>
105+
<ClCompile Include="..\Modules\_testcapi\hash.c">
106+
<Filter>Source Files</Filter>
107+
</ClCompile>
105108
<ClCompile Include="..\Modules\_testcapi\gc.c">
106109
<Filter>Source Files</Filter>
107110
</ClCompile>

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.