1 #include "parts.h"
2 #include "util.h"
3
4 static PyObject *
hash_getfuncdef(PyObject * Py_UNUSED (module),PyObject * Py_UNUSED (args))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
48 static PyObject *
hash_pointer(PyObject * Py_UNUSED (module),PyObject * arg)49 hash_pointer(PyObject *Py_UNUSED(module), PyObject *arg)
50 {
51 void *ptr = PyLong_AsVoidPtr(arg);
52 if (ptr == NULL && PyErr_Occurred()) {
53 return NULL;
54 }
55
56 Py_hash_t hash = Py_HashPointer(ptr);
57 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(hash));
58 return PyLong_FromLongLong(hash);
59 }
60
61
62 static PyObject *
object_generichash(PyObject * Py_UNUSED (module),PyObject * arg)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
72 static PyMethodDef test_methods[] = {
73 {"hash_getfuncdef", hash_getfuncdef, METH_NOARGS},
74 {"hash_pointer", hash_pointer, METH_O},
75 {"object_generichash", object_generichash, METH_O},
76 {NULL},
77 };
78
79 int
_PyTestCapi_Init_Hash(PyObject * m)80 _PyTestCapi_Init_Hash(PyObject *m)
81 {
82 return PyModule_AddFunctions(m, test_methods);
83 }
84