pep384impl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. // Copyright (C) 2018 The Qt Company Ltd.
  2. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
  3. #ifndef PEP384IMPL_H
  4. #define PEP384IMPL_H
  5. #include "sbkpython.h"
  6. #include "shibokenmacros.h"
  7. extern "C"
  8. {
  9. /*****************************************************************************
  10. *
  11. * RESOLVED: object.h
  12. *
  13. */
  14. #ifdef Py_LIMITED_API
  15. // Why the hell is this useful debugging function not allowed?
  16. // BTW: When used, it breaks on Windows, intentionally!
  17. LIBSHIBOKEN_API void _PyObject_Dump(PyObject *);
  18. #endif
  19. /*
  20. * There are a few structures that are needed, but cannot be used without
  21. * breaking the API. We use some heuristics to get those fields anyway
  22. * and validate that we really found them, see pep384impl.cpp .
  23. */
  24. #ifdef Py_LIMITED_API
  25. /*
  26. * These are the type object fields that we use.
  27. * We will verify that they never change.
  28. * The unused fields are intentionally named as "void *Xnn" because
  29. * the chance is smaller to forget to validate a field.
  30. * When we need more fields, we replace it back and add it to the
  31. * validation.
  32. */
  33. typedef struct _typeobject {
  34. PyVarObject ob_base;
  35. const char *tp_name;
  36. Py_ssize_t tp_basicsize;
  37. void *X03; // Py_ssize_t tp_itemsize;
  38. #ifdef PEP384_INTERN
  39. destructor tp_dealloc;
  40. #else
  41. destructor X04;
  42. #endif
  43. void *X05; // Py_ssize_t tp_vectorcall_offset;
  44. void *X06; // getattrfunc tp_getattr;
  45. void *X07; // setattrfunc tp_setattr;
  46. void *X08; // PyAsyncMethods *tp_as_async;
  47. #ifdef PEP384_INTERN
  48. reprfunc tp_repr;
  49. #else
  50. reprfunc X09;
  51. #endif
  52. void *X10; // PyNumberMethods *tp_as_number;
  53. void *X11; // PySequenceMethods *tp_as_sequence;
  54. void *X12; // PyMappingMethods *tp_as_mapping;
  55. void *X13; // hashfunc tp_hash;
  56. #ifdef PEP384_INTERN
  57. ternaryfunc tp_call;
  58. #else
  59. ternaryfunc X14;
  60. #endif
  61. reprfunc tp_str; // Only used for PEP384_INTERN and a shiboken test
  62. getattrofunc tp_getattro;
  63. setattrofunc tp_setattro;
  64. void *X18; // PyBufferProcs *tp_as_buffer;
  65. unsigned long tp_flags;
  66. void *X20; // const char *tp_doc;
  67. #ifdef PEP384_INTERN
  68. traverseproc tp_traverse;
  69. inquiry tp_clear;
  70. #else
  71. traverseproc X21;
  72. inquiry X22;
  73. #endif
  74. void *X23; // richcmpfunc tp_richcompare;
  75. Py_ssize_t tp_weaklistoffset;
  76. void *X25; // getiterfunc tp_iter;
  77. #ifdef PEP384_INTERN
  78. iternextfunc tp_iternext;
  79. #else
  80. iternextfunc X26;
  81. #endif
  82. struct PyMethodDef *tp_methods;
  83. struct PyMemberDef *tp_members;
  84. struct PyGetSetDef *tp_getset;
  85. struct _typeobject *tp_base;
  86. #ifdef PEP384_INTERN
  87. PyObject *tp_dict;
  88. descrgetfunc tp_descr_get;
  89. descrsetfunc tp_descr_set;
  90. #else
  91. void *X31;
  92. descrgetfunc X32;
  93. descrsetfunc X33;
  94. #endif
  95. Py_ssize_t tp_dictoffset;
  96. #ifdef PEP384_INTERN
  97. initproc tp_init;
  98. allocfunc tp_alloc;
  99. #else
  100. initproc X39;
  101. allocfunc X40;
  102. #endif
  103. newfunc tp_new;
  104. #ifdef PEP384_INTERN
  105. freefunc tp_free;
  106. inquiry tp_is_gc; /* For PyObject_IS_GC */
  107. #else
  108. freefunc X41;
  109. inquiry X42; /* For PyObject_IS_GC */
  110. #endif
  111. PyObject *tp_bases;
  112. PyObject *tp_mro; /* method resolution order */
  113. } PyTypeObject;
  114. #ifndef PyObject_IS_GC
  115. /* Test if an object has a GC head */
  116. #define PyObject_IS_GC(o) \
  117. (PyType_IS_GC(Py_TYPE(o)) \
  118. && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
  119. #endif
  120. LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *name);
  121. #else // Py_LIMITED_API
  122. #define _PepType_Lookup(type, name) _PyType_Lookup(type, name)
  123. #endif // Py_LIMITED_API
  124. /// PYSIDE-939: We need the runtime version, given major << 16 + minor << 8 + micro
  125. LIBSHIBOKEN_API long _PepRuntimeVersion();
  126. /*****************************************************************************
  127. *
  128. * PYSIDE-535: Implement a clean type extension for PyPy
  129. *
  130. */
  131. struct SbkObjectTypePrivate;
  132. LIBSHIBOKEN_API SbkObjectTypePrivate *PepType_SOTP(PyTypeObject *type);
  133. LIBSHIBOKEN_API void PepType_SOTP_delete(PyTypeObject *type);
  134. struct SbkEnumType;
  135. struct SbkEnumTypePrivate;
  136. LIBSHIBOKEN_API SbkEnumTypePrivate *PepType_SETP(SbkEnumType *type);
  137. LIBSHIBOKEN_API void PepType_SETP_delete(SbkEnumType *enumType);
  138. struct PySideQFlagsType;
  139. struct SbkQFlagsTypePrivate;
  140. /*****************************************************************************/
  141. // functions used everywhere
  142. /// (convenience) Return the unqualified type name
  143. LIBSHIBOKEN_API const char *PepType_GetNameStr(PyTypeObject *type);
  144. /// (convenience) Return the fully qualified type name(PepType_GetFullyQualifiedNameStr())
  145. /// as C-string
  146. LIBSHIBOKEN_API const char *PepType_GetFullyQualifiedNameStr(PyTypeObject *type);
  147. LIBSHIBOKEN_API PyObject *Pep_GetPartialFunction(void);
  148. /*****************************************************************************
  149. *
  150. * RESOLVED: pydebug.h
  151. *
  152. */
  153. #ifdef Py_LIMITED_API
  154. /*
  155. * We have no direct access to Py_VerboseFlag because debugging is not
  156. * supported. The python developers are partially a bit too rigorous.
  157. * Instead, we compute the value and use a function call macro.
  158. * Was before: extern LIBSHIBOKEN_API int Py_VerboseFlag;
  159. */
  160. LIBSHIBOKEN_API int Pep_GetFlag(const char *name);
  161. LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
  162. #endif
  163. #if (defined(Py_LIMITED_API) && Py_LIMITED_API < 0x030C0000) || PY_VERSION_HEX < 0x030C0000
  164. # define PEP_OLD_ERR_API
  165. #endif
  166. // pyerrors.h
  167. #ifdef PEP_OLD_ERR_API
  168. LIBSHIBOKEN_API PyObject *PepErr_GetRaisedException();
  169. LIBSHIBOKEN_API PyObject *PepException_GetArgs(PyObject *ex);
  170. LIBSHIBOKEN_API void PepException_SetArgs(PyObject *ex, PyObject *args);
  171. #else
  172. inline PyObject *PepErr_GetRaisedException() { return PyErr_GetRaisedException(); }
  173. inline PyObject *PepException_GetArgs(PyObject *ex) { return PyException_GetArgs(ex); }
  174. inline void PepException_SetArgs(PyObject *ex, PyObject *args)
  175. { PyException_SetArgs(ex, args); }
  176. #endif
  177. /*****************************************************************************
  178. *
  179. * RESOLVED: unicodeobject.h
  180. *
  181. */
  182. ///////////////////////////////////////////////////////////////////////
  183. //
  184. // PYSIDE-813: About The Length Of Unicode Objects
  185. // -----------------------------------------------
  186. //
  187. // In Python 2 and before Python 3.3, the macro PyUnicode_GET_SIZE
  188. // worked fine and really like a macro.
  189. //
  190. // Meanwhile, the unicode objects have changed their layout very much,
  191. // and the former cheap macro call has become a real function call
  192. // that converts objects and needs PyMemory.
  193. //
  194. // That is not only inefficient, but also requires the GIL!
  195. // This problem was visible by debug Python and qdatastream_test.py .
  196. // It was found while fixing the refcount problem of PYSIDE-813 which
  197. // needed a debug Python.
  198. //
  199. // Unfortunately, we cannot ask this at runtime
  200. // #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
  201. // FIXME: Python 3.10: Replace _PepUnicode_AsString by PyUnicode_AsUTF8
  202. #ifdef Py_LIMITED_API
  203. LIBSHIBOKEN_API const char *_PepUnicode_AsString(PyObject *);
  204. enum PepUnicode_Kind {
  205. #if PY_VERSION_HEX < 0x030C0000
  206. PepUnicode_WCHAR_KIND = 0,
  207. #endif
  208. PepUnicode_1BYTE_KIND = 1,
  209. PepUnicode_2BYTE_KIND = 2,
  210. PepUnicode_4BYTE_KIND = 4
  211. };
  212. LIBSHIBOKEN_API int _PepUnicode_KIND(PyObject *);
  213. LIBSHIBOKEN_API int _PepUnicode_IS_ASCII(PyObject *str);
  214. LIBSHIBOKEN_API int _PepUnicode_IS_COMPACT(PyObject *str);
  215. LIBSHIBOKEN_API void *_PepUnicode_DATA(PyObject *str);
  216. #else
  217. enum PepUnicode_Kind {
  218. #if PY_VERSION_HEX < 0x030C0000
  219. PepUnicode_WCHAR_KIND = PyUnicode_WCHAR_KIND,
  220. #endif
  221. PepUnicode_1BYTE_KIND = PyUnicode_1BYTE_KIND,
  222. PepUnicode_2BYTE_KIND = PyUnicode_2BYTE_KIND,
  223. PepUnicode_4BYTE_KIND = PyUnicode_4BYTE_KIND
  224. };
  225. #define _PepUnicode_AsString PyUnicode_AsUTF8
  226. #define _PepUnicode_KIND PyUnicode_KIND
  227. #define _PepUnicode_DATA PyUnicode_DATA
  228. #define _PepUnicode_IS_COMPACT PyUnicode_IS_COMPACT
  229. #define _PepUnicode_IS_ASCII PyUnicode_IS_ASCII
  230. #endif
  231. /*****************************************************************************
  232. *
  233. * RESOLVED: methodobject.h
  234. *
  235. */
  236. #ifdef Py_LIMITED_API
  237. using PyCFunctionObject = struct _pycfunc;
  238. #define PepCFunction_GET_NAMESTR(func) \
  239. _PepUnicode_AsString(PyObject_GetAttrString((PyObject *)func, "__name__"))
  240. #else
  241. #define PepCFunction_GET_NAMESTR(func) \
  242. (reinterpret_cast<const PyCFunctionObject *>(func)->m_ml->ml_name)
  243. #endif
  244. /*****************************************************************************
  245. *
  246. * RESOLVED: pythonrun.h
  247. *
  248. */
  249. #ifdef Py_LIMITED_API
  250. LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *);
  251. #endif
  252. /*****************************************************************************
  253. *
  254. * RESOLVED: funcobject.h
  255. *
  256. */
  257. #ifdef Py_LIMITED_API
  258. typedef struct _func PyFunctionObject;
  259. extern LIBSHIBOKEN_API PyTypeObject *PepFunction_TypePtr;
  260. LIBSHIBOKEN_API PyObject *PepFunction_Get(PyObject *, const char *);
  261. #define PyFunction_Check(op) (Py_TYPE(op) == PepFunction_TypePtr)
  262. #define PyFunction_GET_CODE(func) PyFunction_GetCode(func)
  263. #define PyFunction_GetCode(func) PepFunction_Get((PyObject *)func, "__code__")
  264. #define PepFunction_GetName(func) PepFunction_Get((PyObject *)func, "__name__")
  265. #else
  266. #define PepFunction_TypePtr (&PyFunction_Type)
  267. #define PepFunction_GetName(func) (((PyFunctionObject *)func)->func_name)
  268. #endif
  269. /*****************************************************************************
  270. *
  271. * RESOLVED: classobject.h
  272. *
  273. */
  274. #ifdef Py_LIMITED_API
  275. typedef struct _meth PyMethodObject;
  276. extern LIBSHIBOKEN_API PyTypeObject *PepMethod_TypePtr;
  277. LIBSHIBOKEN_API PyObject *PyMethod_New(PyObject *, PyObject *);
  278. LIBSHIBOKEN_API PyObject *PyMethod_Function(PyObject *);
  279. LIBSHIBOKEN_API PyObject *PyMethod_Self(PyObject *);
  280. #define PyMethod_Check(op) ((op)->ob_type == PepMethod_TypePtr)
  281. #define PyMethod_GET_SELF(op) PyMethod_Self(op)
  282. #define PyMethod_GET_FUNCTION(op) PyMethod_Function(op)
  283. #endif
  284. /*****************************************************************************
  285. *
  286. * RESOLVED: code.h
  287. *
  288. */
  289. #ifdef Py_LIMITED_API
  290. /* Bytecode object */
  291. // we have to grab the code object from python
  292. typedef struct _code PepCodeObject;
  293. LIBSHIBOKEN_API int PepCode_Get(PepCodeObject *co, const char *name);
  294. LIBSHIBOKEN_API int PepCode_Check(PyObject *o);
  295. # define PepCode_GET_FLAGS(o) PepCode_Get(o, "co_flags")
  296. # define PepCode_GET_ARGCOUNT(o) PepCode_Get(o, "co_argcount")
  297. LIBSHIBOKEN_API PyObject *PepFunction_GetDefaults(PyObject *function);
  298. /* Masks for co_flags above */
  299. # define CO_OPTIMIZED 0x0001
  300. # define CO_NEWLOCALS 0x0002
  301. # define CO_VARARGS 0x0004
  302. # define CO_VARKEYWORDS 0x0008
  303. # define CO_NESTED 0x0010
  304. # define CO_GENERATOR 0x0020
  305. #else
  306. # define PepCodeObject PyCodeObject
  307. # define PepCode_GET_FLAGS(o) ((o)->co_flags)
  308. # define PepCode_GET_ARGCOUNT(o) ((o)->co_argcount)
  309. # define PepCode_Check PyCode_Check
  310. # ifdef PYPY_VERSION
  311. LIBSHIBOKEN_API PyObject *PepFunction_GetDefaults(PyObject *function);
  312. # else
  313. # define PepFunction_GetDefaults PyFunction_GetDefaults
  314. # endif
  315. #endif
  316. /*****************************************************************************
  317. *
  318. * RESOLVED: datetime.h
  319. *
  320. */
  321. #ifdef Py_LIMITED_API
  322. LIBSHIBOKEN_API int PyDateTime_Get(PyObject *ob, const char *name);
  323. #define PyDateTime_GetYear(o) PyDateTime_Get(o, "year")
  324. #define PyDateTime_GetMonth(o) PyDateTime_Get(o, "month")
  325. #define PyDateTime_GetDay(o) PyDateTime_Get(o, "day")
  326. #define PyDateTime_GetHour(o) PyDateTime_Get(o, "hour")
  327. #define PyDateTime_GetMinute(o) PyDateTime_Get(o, "minute")
  328. #define PyDateTime_GetSecond(o) PyDateTime_Get(o, "second")
  329. #define PyDateTime_GetMicrosecond(o) PyDateTime_Get(o, "microsecond")
  330. #define PyDateTime_GetFold(o) PyDateTime_Get(o, "fold")
  331. #define PyDateTime_GET_YEAR(o) PyDateTime_GetYear(o)
  332. #define PyDateTime_GET_MONTH(o) PyDateTime_GetMonth(o)
  333. #define PyDateTime_GET_DAY(o) PyDateTime_GetDay(o)
  334. #define PyDateTime_DATE_GET_HOUR(o) PyDateTime_GetHour(o)
  335. #define PyDateTime_DATE_GET_MINUTE(o) PyDateTime_GetMinute(o)
  336. #define PyDateTime_DATE_GET_SECOND(o) PyDateTime_GetSecond(o)
  337. #define PyDateTime_DATE_GET_MICROSECOND(o) PyDateTime_GetMicrosecond(o)
  338. #define PyDateTime_DATE_GET_FOLD(o) PyDateTime_GetFold(o)
  339. #define PyDateTime_TIME_GET_HOUR(o) PyDateTime_GetHour(o)
  340. #define PyDateTime_TIME_GET_MINUTE(o) PyDateTime_GetMinute(o)
  341. #define PyDateTime_TIME_GET_SECOND(o) PyDateTime_GetSecond(o)
  342. #define PyDateTime_TIME_GET_MICROSECOND(o) PyDateTime_GetMicrosecond(o)
  343. #define PyDateTime_TIME_GET_FOLD(o) PyDateTime_GetFold(o)
  344. /* Define structure slightly similar to C API. */
  345. typedef struct {
  346. PyObject *module;
  347. /* type objects */
  348. PyTypeObject *DateType;
  349. PyTypeObject *DateTimeType;
  350. PyTypeObject *TimeType;
  351. PyTypeObject *DeltaType;
  352. PyTypeObject *TZInfoType;
  353. } datetime_struc;
  354. LIBSHIBOKEN_API datetime_struc *init_DateTime(void);
  355. #define PyDateTime_IMPORT PyDateTimeAPI = init_DateTime()
  356. extern LIBSHIBOKEN_API datetime_struc *PyDateTimeAPI;
  357. #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
  358. #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
  359. #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
  360. LIBSHIBOKEN_API PyObject *PyDate_FromDate(int year, int month, int day);
  361. LIBSHIBOKEN_API PyObject *PyDateTime_FromDateAndTime(
  362. int year, int month, int day, int hour, int min, int sec, int usec);
  363. LIBSHIBOKEN_API PyObject *PyTime_FromTime(
  364. int hour, int minute, int second, int usecond);
  365. #endif /* Py_LIMITED_API */
  366. /*****************************************************************************
  367. *
  368. * Extra support for name mangling
  369. *
  370. */
  371. // PYSIDE-772: This function supports the fix, but is not meant as public.
  372. LIBSHIBOKEN_API PyObject *_Pep_PrivateMangle(PyObject *self, PyObject *name);
  373. /*****************************************************************************
  374. *
  375. * Extra support for signature.cpp
  376. *
  377. */
  378. #ifdef Py_LIMITED_API
  379. extern LIBSHIBOKEN_API PyTypeObject *PepStaticMethod_TypePtr;
  380. LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable);
  381. #else
  382. #define PepStaticMethod_TypePtr &PyStaticMethod_Type
  383. #endif
  384. #ifdef PYPY_VERSION
  385. extern LIBSHIBOKEN_API PyTypeObject *PepBuiltinMethod_TypePtr;
  386. #endif
  387. // Although not PEP specific, we resolve this similar issue, here:
  388. #define PepMethodDescr_TypePtr &PyMethodDescr_Type
  389. /*****************************************************************************
  390. *
  391. * Newly introduced convenience functions
  392. *
  393. * This is not defined if Py_LIMITED_API is defined.
  394. */
  395. // Evaluate a script and return the variable `result`
  396. LIBSHIBOKEN_API PyObject *PepRun_GetResult(const char *command);
  397. // Call PyType_Type.tp_new returning a PyType object.
  398. LIBSHIBOKEN_API PyTypeObject *PepType_Type_tp_new(PyTypeObject *metatype,
  399. PyObject *args,
  400. PyObject *kwds);
  401. /*****************************************************************************
  402. *
  403. * Runtime support for Python 3.8 incompatibilities
  404. *
  405. */
  406. #ifndef Py_TPFLAGS_METHOD_DESCRIPTOR
  407. /* Objects behave like an unbound method */
  408. #define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
  409. #endif
  410. /*****************************************************************************
  411. *
  412. * Runtime support for Python 3.12 incompatibility
  413. *
  414. */
  415. LIBSHIBOKEN_API PyObject *PepType_GetDict(PyTypeObject *type);
  416. // This function does not exist as PyType_SetDict. But because tp_dict
  417. // is no longer considered to be accessible, we treat it as such.
  418. LIBSHIBOKEN_API int PepType_SetDict(PyTypeObject *type, PyObject *dict);
  419. LIBSHIBOKEN_API void *PepType_GetSlot(PyTypeObject *type, int aSlot);
  420. // Runtime support for Python 3.13 stable ABI
  421. // Return dictionary of the global variables in the current execution frame
  422. LIBSHIBOKEN_API PyObject *PepEval_GetFrameGlobals();
  423. // Return a dictionary of the builtins in the current execution frame
  424. LIBSHIBOKEN_API PyObject *PepEval_GetFrameBuiltins();
  425. LIBSHIBOKEN_API int PepModule_AddType(PyObject *module, PyTypeObject *type);
  426. LIBSHIBOKEN_API int PepModule_Add(PyObject *module, const char *name, PyObject *value);
  427. /*****************************************************************************
  428. *
  429. * Module Initialization
  430. *
  431. */
  432. LIBSHIBOKEN_API void Pep384_Init(void);
  433. } // extern "C"
  434. #endif // PEP384IMPL_H