| 
									
										
										
										
											2023-11-15 03:41:29 +01:00
										 |  |  | #include "parts.h"
 | 
					
						
							|  |  |  | #include "util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | hash_getfuncdef(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // bind PyHash_GetFuncDef()
 | 
					
						
							|  |  |  |     PyHash_FuncDef *def = PyHash_GetFuncDef(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *types = PyImport_ImportModule("types"); | 
					
						
							|  |  |  |     if (types == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *result = PyObject_CallMethod(types, "SimpleNamespace", NULL); | 
					
						
							|  |  |  |     Py_DECREF(types); | 
					
						
							|  |  |  |     if (result == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ignore PyHash_FuncDef.hash
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyObject *value = PyUnicode_FromString(def->name); | 
					
						
							|  |  |  |     int res = PyObject_SetAttrString(result, "name", value); | 
					
						
							|  |  |  |     Py_DECREF(value); | 
					
						
							|  |  |  |     if (res < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     value = PyLong_FromLong(def->hash_bits); | 
					
						
							|  |  |  |     res = PyObject_SetAttrString(result, "hash_bits", value); | 
					
						
							|  |  |  |     Py_DECREF(value); | 
					
						
							|  |  |  |     if (res < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     value = PyLong_FromLong(def->seed_bits); | 
					
						
							|  |  |  |     res = PyObject_SetAttrString(result, "seed_bits", value); | 
					
						
							|  |  |  |     Py_DECREF(value); | 
					
						
							|  |  |  |     if (res < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 15:09:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 17:42:27 +02:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | long_from_hash(Py_hash_t hash) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_BUILD_ASSERT(sizeof(long long) >= sizeof(hash)); | 
					
						
							|  |  |  |     return PyLong_FromLongLong(hash); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 15:09:22 +01:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | hash_pointer(PyObject *Py_UNUSED(module), PyObject *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *ptr = PyLong_AsVoidPtr(arg); | 
					
						
							|  |  |  |     if (ptr == NULL && PyErr_Occurred()) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_hash_t hash = Py_HashPointer(ptr); | 
					
						
							| 
									
										
										
										
											2024-08-30 17:42:27 +02:00
										 |  |  |     return long_from_hash(hash); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | hash_buffer(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     char *ptr; | 
					
						
							|  |  |  |     Py_ssize_t len; | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "y#", &ptr, &len)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_hash_t hash = Py_HashBuffer(ptr, len); | 
					
						
							|  |  |  |     return long_from_hash(hash); | 
					
						
							| 
									
										
										
										
											2023-12-06 15:09:22 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-22 20:19:10 +02:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | object_generichash(PyObject *Py_UNUSED(module), PyObject *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NULLABLE(arg); | 
					
						
							|  |  |  |     Py_hash_t hash = PyObject_GenericHash(arg); | 
					
						
							| 
									
										
										
										
											2024-08-30 17:42:27 +02:00
										 |  |  |     return long_from_hash(hash); | 
					
						
							| 
									
										
										
										
											2024-03-22 20:19:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-15 03:41:29 +01:00
										 |  |  | static PyMethodDef test_methods[] = { | 
					
						
							|  |  |  |     {"hash_getfuncdef", hash_getfuncdef, METH_NOARGS}, | 
					
						
							| 
									
										
										
										
											2023-12-06 15:09:22 +01:00
										 |  |  |     {"hash_pointer", hash_pointer, METH_O}, | 
					
						
							| 
									
										
										
										
											2024-08-30 17:42:27 +02:00
										 |  |  |     {"hash_buffer", hash_buffer, METH_VARARGS}, | 
					
						
							| 
									
										
										
										
											2024-03-22 20:19:10 +02:00
										 |  |  |     {"object_generichash", object_generichash, METH_O}, | 
					
						
							| 
									
										
										
										
											2023-11-15 03:41:29 +01:00
										 |  |  |     {NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyTestCapi_Init_Hash(PyObject *m) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyModule_AddFunctions(m, test_methods); | 
					
						
							|  |  |  | } |