Files
typthon/Modules/hashlib.h
copilot-swe-agent[bot] b198f511d2 Rename Py_ to Ty_ throughout C API
Massive automated renaming of all Py_/PyObject/etc. prefixes to Ty_/TyObject/etc.
This includes:
- All public API types (TyObject, TyTypeObject, etc.)
- All public API functions (Ty_Initialize, Ty_BuildValue, etc.)
- All internal API (_Ty_ prefixes)
- Reference counting macros (Ty_INCREF, Ty_DECREF, etc.)
- Type flags (Ty_TPFLAGS_*)
- Debug flags (Ty_DEBUG, Ty_TRACE_REFS, etc.)
- All object type APIs (TyList_, TyDict_, TyUnicode_, etc.)

This changes over 60,000 occurrences across 1000+ files.

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
2025-12-29 17:37:49 +00:00

108 lines
3.5 KiB
C

/* Common code for use by all hashlib related modules. */
#include "pycore_lock.h" // PyMutex
/*
* Given a TyObject* obj, fill in the Ty_buffer* viewp with the result
* of PyObject_GetBuffer. Sets an exception and issues the erraction
* on any errors, e.g. 'return NULL' or 'goto error'.
*/
#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \
if (TyUnicode_Check((obj))) { \
TyErr_SetString(TyExc_TypeError, \
"Strings must be encoded before hashing");\
erraction; \
} \
if (!PyObject_CheckBuffer((obj))) { \
TyErr_SetString(TyExc_TypeError, \
"object supporting the buffer API required"); \
erraction; \
} \
if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \
erraction; \
} \
if ((viewp)->ndim > 1) { \
TyErr_SetString(TyExc_BufferError, \
"Buffer must be single dimension"); \
PyBuffer_Release((viewp)); \
erraction; \
} \
} while(0)
#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \
GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL)
/*
* Helper code to synchronize access to the hash object when the GIL is
* released around a CPU consuming hashlib operation. All code paths that
* access a mutable part of obj must be enclosed in an ENTER_HASHLIB /
* LEAVE_HASHLIB block or explicitly acquire and release the lock inside
* a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for
* an operation.
*
* These only drop the GIL if the lock acquisition itself is likely to
* block. Thus the non-blocking acquire gating the GIL release for a
* blocking lock acquisition. The intent of these macros is to surround
* the assumed always "fast" operations that you aren't releasing the
* GIL around. Otherwise use code similar to what you see in hash
* function update() methods.
*/
#include "pythread.h"
#define ENTER_HASHLIB(obj) \
if ((obj)->use_mutex) { \
PyMutex_Lock(&(obj)->mutex); \
}
#define LEAVE_HASHLIB(obj) \
if ((obj)->use_mutex) { \
PyMutex_Unlock(&(obj)->mutex); \
}
#ifdef Ty_GIL_DISABLED
#define HASHLIB_INIT_MUTEX(obj) \
do { \
(obj)->mutex = (PyMutex){0}; \
(obj)->use_mutex = true; \
} while (0)
#else
#define HASHLIB_INIT_MUTEX(obj) \
do { \
(obj)->mutex = (PyMutex){0}; \
(obj)->use_mutex = false; \
} while (0)
#endif
/* TODO(gpshead): We should make this a module or class attribute
* to allow the user to optimize based on the platform they're using. */
#define HASHLIB_GIL_MINSIZE 2048
static inline int
_Ty_hashlib_data_argument(TyObject **res, TyObject *data, TyObject *string)
{
if (data != NULL && string == NULL) {
// called as H(data) or H(data=...)
*res = data;
return 1;
}
else if (data == NULL && string != NULL) {
// called as H(string=...)
*res = string;
return 1;
}
else if (data == NULL && string == NULL) {
// fast path when no data is given
assert(!TyErr_Occurred());
*res = NULL;
return 0;
}
else {
// called as H(data=..., string)
*res = NULL;
TyErr_SetString(TyExc_TypeError,
"'data' and 'string' are mutually exclusive "
"and support for 'string' keyword parameter "
"is slated for removal in a future version.");
return -1;
}
}