#define _RESOLVE_MODINIT_FUNC_NAME(NAME) \ PyInit_ ## NAME #define RESOLVE_MODINIT_FUNC_NAME(NAME) \ _RESOLVE_MODINIT_FUNC_NAME(NAME) #define GETDATA(FUNC) ((_PyXIData_getdata_t){.basic=FUNC}) static int ensure_xid_class(PyTypeObject *cls, _PyXIData_getdata_t getdata) { PyThreadState *tstate = PyThreadState_Get(); return _PyXIData_RegisterClass(tstate, cls, getdata); } #ifdef REGISTERS_HEAP_TYPES static int clear_xid_class(PyTypeObject *cls) { PyThreadState *tstate = PyThreadState_Get(); return _PyXIData_UnregisterClass(tstate, cls); } #endif static inline int64_t _get_interpid(_PyXIData_t *data) { int64_t interpid; if (data != NULL) { interpid = _PyXIData_INTERPID(data); assert(!PyErr_Occurred()); } else { interpid = PyInterpreterState_GetID(PyInterpreterState_Get()); } return interpid; } #ifdef HAS_FALLBACK static int resolve_fallback(int arg, xidata_fallback_t dflt, xidata_fallback_t *p_fallback) { if (arg < 0) { *p_fallback = dflt; return 0; } xidata_fallback_t fallback; if (arg == _PyXIDATA_XIDATA_ONLY) { fallback =_PyXIDATA_XIDATA_ONLY; } else if (arg == _PyXIDATA_FULL_FALLBACK) { fallback = _PyXIDATA_FULL_FALLBACK; } else { PyErr_Format(PyExc_ValueError, "unsupported fallback %d", arg); return -1; } *p_fallback = fallback; return 0; } #endif /* unbound items ************************************************************/ #ifdef HAS_UNBOUND_ITEMS typedef int unboundop_t; #define UNBOUND_REMOVE 1 #define UNBOUND_ERROR 2 #define UNBOUND_REPLACE 3 // It would also be possible to add UNBOUND_REPLACE where the replacement // value is user-provided. There would be some limitations there, though. // Another possibility would be something like UNBOUND_COPY, where the // object is released but the underlying data is copied (with the "raw" // allocator) and used when the item is popped off the queue. #ifndef NDEBUG static int check_unbound(int unboundop) { switch (unboundop) { case UNBOUND_REMOVE: case UNBOUND_ERROR: case UNBOUND_REPLACE: return 1; default: return 0; } } #endif static int resolve_unboundop(int arg, unboundop_t dflt, unboundop_t *p_unboundop) { if (arg < 0) { *p_unboundop = dflt; return 0; } unboundop_t op; if (arg == UNBOUND_REMOVE) { op = UNBOUND_REMOVE; } else if (arg == UNBOUND_ERROR) { op = UNBOUND_ERROR; } else if (arg == UNBOUND_REPLACE) { op = UNBOUND_REPLACE; } else { PyErr_Format(PyExc_ValueError, "unsupported unboundop %d", arg); return -1; } *p_unboundop = op; return 0; } #endif