blob: af4869f7356a5bd32b49d564724254a16e4cd802 [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From f83d38687fec2239c517037453ed4a2191279796 Mon Sep 17 00:00:00 2001
2From: Victor Stinner <vstinner@python.org>
3Date: Fri, 28 Jan 2022 00:14:04 +0100
4Subject: [PATCH] Port to Python 3.11 (#410)
5
6* Replace "arg == Py_None" with Py_IsNone(arg)
7* Replace arg->ob_type with Py_TYPE(arg)
8* Replace "Py_TYPE(obj) = type" with Py_SET_TYPE(obj, type).
9* Copy pythoncapi_compat.h from:
10 https://github.com/pythoncapi/pythoncapi_compat
11* pythoncapi_compat.h provides Py_SET_TYPE() and Py_IsNone() to old
12 Python versions.
13
14Upstream-Status: Backport [https://github.com/pybluez/pybluez/commit/5096047f90a1f6a74ceb250aef6243e144170f92]
15Signed-off-by: Alexander Kanavin <alex@linutronix.de>
16---
17 bluez/btmodule.c | 14 +-
18 bluez/pythoncapi_compat.h | 364 ++++++++++++++++++++++++++++++++++++++
19 2 files changed, 372 insertions(+), 6 deletions(-)
20 create mode 100644 bluez/pythoncapi_compat.h
21
22diff --git a/bluez/btmodule.c b/bluez/btmodule.c
23index 912a489..b61f74a 100644
24--- a/bluez/btmodule.c
25+++ b/bluez/btmodule.c
26@@ -21,6 +21,8 @@ Local naming conventions:
27 #include "btmodule.h"
28 #include "structmember.h"
29
30+#include "pythoncapi_compat.h"
31+
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35@@ -678,7 +680,7 @@ sock_settimeout(PySocketSockObject *s, PyObject *arg)
36 {
37 double timeout;
38
39- if (arg == Py_None)
40+ if (Py_IsNone(arg))
41 timeout = -1.0;
42 else {
43 timeout = PyFloat_AsDouble(arg);
44@@ -1752,7 +1754,7 @@ bt_btohl(PyObject *self, PyObject *args)
45 else
46 return PyErr_Format(PyExc_TypeError,
47 "expected int/long, %s found",
48- arg->ob_type->tp_name);
49+ Py_TYPE(arg)->tp_name);
50 if (x == (unsigned long) -1 && PyErr_Occurred())
51 return NULL;
52 return PyInt_FromLong(btohl(x));
53@@ -1816,7 +1818,7 @@ bt_htobl(PyObject *self, PyObject *args)
54 else
55 return PyErr_Format(PyExc_TypeError,
56 "expected int/long, %s found",
57- arg->ob_type->tp_name);
58+ Py_TYPE(arg)->tp_name);
59 return PyInt_FromLong(htobl(x));
60 }
61
62@@ -1889,7 +1891,7 @@ bt_setdefaulttimeout(PyObject *self, PyObject *arg)
63 {
64 double timeout;
65
66- if (arg == Py_None)
67+ if (Py_IsNone(arg))
68 timeout = -1.0;
69 else {
70 timeout = PyFloat_AsDouble(arg);
71@@ -2980,8 +2982,8 @@ PyMODINIT_FUNC
72 init_bluetooth(void)
73 #endif
74 {
75- Py_TYPE(&sock_type) = &PyType_Type;
76- Py_TYPE(&sdp_session_type) = &PyType_Type;
77+ Py_SET_TYPE(&sock_type, &PyType_Type);
78+ Py_SET_TYPE(&sdp_session_type, &PyType_Type);
79 #if PY_MAJOR_VERSION >= 3
80 PyObject *m = PyModule_Create(&moduledef);
81 #else
82diff --git a/bluez/pythoncapi_compat.h b/bluez/pythoncapi_compat.h
83new file mode 100644
84index 0000000..e660b61
85--- /dev/null
86+++ b/bluez/pythoncapi_compat.h
87@@ -0,0 +1,364 @@
88+// Header file providing new functions of the Python C API to old Python
89+// versions.
90+//
91+// File distributed under the MIT license.
92+// Copyright Contributors to the pythoncapi_compat project.
93+//
94+// Homepage:
95+// https://github.com/pythoncapi/pythoncapi_compat
96+//
97+// Latest version:
98+// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
99+//
100+// SPDX-License-Identifier: MIT
101+
102+#ifndef PYTHONCAPI_COMPAT
103+#define PYTHONCAPI_COMPAT
104+
105+#ifdef __cplusplus
106+extern "C" {
107+#endif
108+
109+#include <Python.h>
110+#include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
111+
112+
113+// Compatibility with Visual Studio 2013 and older which don't support
114+// the inline keyword in C (only in C++): use __inline instead.
115+#if (defined(_MSC_VER) && _MSC_VER < 1900 \
116+ && !defined(__cplusplus) && !defined(inline))
117+# define inline __inline
118+# define PYTHONCAPI_COMPAT_MSC_INLINE
119+ // These two macros are undefined at the end of this file
120+#endif
121+
122+
123+// Cast argument to PyObject* type.
124+#ifndef _PyObject_CAST
125+# define _PyObject_CAST(op) ((PyObject*)(op))
126+#endif
127+#ifndef _PyObject_CAST_CONST
128+# define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
129+#endif
130+
131+
132+// bpo-42262 added Py_NewRef() to Python 3.10.0a3
133+#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
134+static inline PyObject* _Py_NewRef(PyObject *obj)
135+{
136+ Py_INCREF(obj);
137+ return obj;
138+}
139+#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
140+#endif
141+
142+
143+// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
144+#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
145+static inline PyObject* _Py_XNewRef(PyObject *obj)
146+{
147+ Py_XINCREF(obj);
148+ return obj;
149+}
150+#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
151+#endif
152+
153+
154+// See https://bugs.python.org/issue42522
155+#if !defined(_Py_StealRef)
156+static inline PyObject* __Py_StealRef(PyObject *obj)
157+{
158+ Py_DECREF(obj);
159+ return obj;
160+}
161+#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
162+#endif
163+
164+
165+// See https://bugs.python.org/issue42522
166+#if !defined(_Py_XStealRef)
167+static inline PyObject* __Py_XStealRef(PyObject *obj)
168+{
169+ Py_XDECREF(obj);
170+ return obj;
171+}
172+#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
173+#endif
174+
175+
176+// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
177+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
178+static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
179+{
180+ ob->ob_refcnt = refcnt;
181+}
182+#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
183+#endif
184+
185+
186+// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
187+// It is excluded from the limited C API.
188+#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API)
189+#define Py_SETREF(op, op2) \
190+ do { \
191+ PyObject *_py_tmp = _PyObject_CAST(op); \
192+ (op) = (op2); \
193+ Py_DECREF(_py_tmp); \
194+ } while (0)
195+
196+#define Py_XSETREF(op, op2) \
197+ do { \
198+ PyObject *_py_tmp = _PyObject_CAST(op); \
199+ (op) = (op2); \
200+ Py_XDECREF(_py_tmp); \
201+ } while (0)
202+#endif
203+
204+
205+// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse()
206+// to Python 3.10.0b1.
207+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is)
208+# define Py_Is(x, y) ((x) == (y))
209+#endif
210+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone)
211+# define Py_IsNone(x) Py_Is(x, Py_None)
212+#endif
213+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue)
214+# define Py_IsTrue(x) Py_Is(x, Py_True)
215+#endif
216+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse)
217+# define Py_IsFalse(x) Py_Is(x, Py_False)
218+#endif
219+
220+
221+// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
222+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
223+static inline void
224+_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
225+{
226+ ob->ob_type = type;
227+}
228+#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
229+#endif
230+
231+
232+// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
233+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
234+static inline void
235+_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
236+{
237+ ob->ob_size = size;
238+}
239+#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
240+#endif
241+
242+
243+// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
244+#if PY_VERSION_HEX < 0x030900B1
245+static inline PyCodeObject*
246+PyFrame_GetCode(PyFrameObject *frame)
247+{
248+ assert(frame != NULL);
249+ assert(frame->f_code != NULL);
250+ return (PyCodeObject*)Py_NewRef(frame->f_code);
251+}
252+#endif
253+
254+static inline PyCodeObject*
255+_PyFrame_GetCodeBorrow(PyFrameObject *frame)
256+{
257+ return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame));
258+}
259+
260+
261+// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
262+#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
263+static inline PyFrameObject*
264+PyFrame_GetBack(PyFrameObject *frame)
265+{
266+ assert(frame != NULL);
267+ return (PyFrameObject*)Py_XNewRef(frame->f_back);
268+}
269+#endif
270+
271+#if !defined(PYPY_VERSION)
272+static inline PyFrameObject*
273+_PyFrame_GetBackBorrow(PyFrameObject *frame)
274+{
275+ return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame));
276+}
277+#endif
278+
279+
280+// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
281+#if PY_VERSION_HEX < 0x030900A5
282+static inline PyInterpreterState *
283+PyThreadState_GetInterpreter(PyThreadState *tstate)
284+{
285+ assert(tstate != NULL);
286+ return tstate->interp;
287+}
288+#endif
289+
290+
291+// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
292+#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
293+static inline PyFrameObject*
294+PyThreadState_GetFrame(PyThreadState *tstate)
295+{
296+ assert(tstate != NULL);
297+ return (PyFrameObject *)Py_XNewRef(tstate->frame);
298+}
299+#endif
300+
301+#if !defined(PYPY_VERSION)
302+static inline PyFrameObject*
303+_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
304+{
305+ return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate));
306+}
307+#endif
308+
309+
310+// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
311+#if PY_VERSION_HEX < 0x030900A5
312+static inline PyInterpreterState *
313+PyInterpreterState_Get(void)
314+{
315+ PyThreadState *tstate;
316+ PyInterpreterState *interp;
317+
318+ tstate = PyThreadState_GET();
319+ if (tstate == NULL) {
320+ Py_FatalError("GIL released (tstate is NULL)");
321+ }
322+ interp = tstate->interp;
323+ if (interp == NULL) {
324+ Py_FatalError("no current interpreter");
325+ }
326+ return interp;
327+}
328+#endif
329+
330+
331+// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
332+#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
333+static inline uint64_t
334+PyThreadState_GetID(PyThreadState *tstate)
335+{
336+ assert(tstate != NULL);
337+ return tstate->id;
338+}
339+#endif
340+
341+
342+// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
343+#if PY_VERSION_HEX < 0x030900A1
344+static inline PyObject*
345+PyObject_CallNoArgs(PyObject *func)
346+{
347+ return PyObject_CallFunctionObjArgs(func, NULL);
348+}
349+#endif
350+
351+
352+// bpo-39245 made PyObject_CallOneArg() public (previously called
353+// _PyObject_CallOneArg) in Python 3.9.0a4
354+#if PY_VERSION_HEX < 0x030900A4
355+static inline PyObject*
356+PyObject_CallOneArg(PyObject *func, PyObject *arg)
357+{
358+ return PyObject_CallFunctionObjArgs(func, arg, NULL);
359+}
360+#endif
361+
362+
363+// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
364+#if PY_VERSION_HEX < 0x030A00A3
365+static inline int
366+PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
367+{
368+ Py_XINCREF(value);
369+ int res = PyModule_AddObject(module, name, value);
370+ if (res < 0) {
371+ Py_XDECREF(value);
372+ }
373+ return res;
374+}
375+#endif
376+
377+
378+// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
379+#if PY_VERSION_HEX < 0x030900A5
380+static inline int
381+PyModule_AddType(PyObject *module, PyTypeObject *type)
382+{
383+ const char *name, *dot;
384+
385+ if (PyType_Ready(type) < 0) {
386+ return -1;
387+ }
388+
389+ // inline _PyType_Name()
390+ name = type->tp_name;
391+ assert(name != NULL);
392+ dot = strrchr(name, '.');
393+ if (dot != NULL) {
394+ name = dot + 1;
395+ }
396+
397+ return PyModule_AddObjectRef(module, name, (PyObject *)type);
398+}
399+#endif
400+
401+
402+// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
403+// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
404+#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
405+static inline int
406+PyObject_GC_IsTracked(PyObject* obj)
407+{
408+ return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
409+}
410+#endif
411+
412+// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
413+// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
414+#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
415+static inline int
416+PyObject_GC_IsFinalized(PyObject *obj)
417+{
418+ return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
419+}
420+#endif
421+
422+
423+// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
424+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
425+static inline int
426+_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
427+ return ob->ob_type == type;
428+}
429+#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
430+#endif
431+
432+
433+// Py_UNUSED() was added to Python 3.4.0b2.
434+#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
435+# if defined(__GNUC__) || defined(__clang__)
436+# define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
437+# else
438+# define Py_UNUSED(name) _unused_ ## name
439+# endif
440+#endif
441+
442+
443+#ifdef PYTHONCAPI_COMPAT_MSC_INLINE
444+# undef inline
445+# undef PYTHONCAPI_COMPAT_MSC_INLINE
446+#endif
447+
448+#ifdef __cplusplus
449+}
450+#endif
451+#endif // PYTHONCAPI_COMPAT
452--
4532.30.2
454