|
|
@@ -0,0 +1,169 @@
|
|
|
+/**
|
|
|
+ * PANDA 3D SOFTWARE
|
|
|
+ * Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
|
+ *
|
|
|
+ * All use of this software is subject to the terms of the revised BSD
|
|
|
+ * license. You should have received a copy of this license along
|
|
|
+ * with this source code in a file named "LICENSE."
|
|
|
+ *
|
|
|
+ * @file py_compat.h
|
|
|
+ * @author rdb
|
|
|
+ * @date 2017-12-02
|
|
|
+ */
|
|
|
+
|
|
|
+#ifndef PY_COMPAT_H
|
|
|
+#define PY_COMPAT_H
|
|
|
+
|
|
|
+#include "dtoolbase.h"
|
|
|
+
|
|
|
+#ifdef HAVE_PYTHON
|
|
|
+
|
|
|
+// The contents of this file were originally part of py_panda.h. It
|
|
|
+// specifically contains polyfills that are required to maintain compatibility
|
|
|
+// with Python 2 and older versions of Python 3.
|
|
|
+
|
|
|
+// These compatibility hacks are sorted by Python version that removes the
|
|
|
+// need for the respective hack.
|
|
|
+
|
|
|
+#ifdef _POSIX_C_SOURCE
|
|
|
+# undef _POSIX_C_SOURCE
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef _XOPEN_SOURCE
|
|
|
+# undef _XOPEN_SOURCE
|
|
|
+#endif
|
|
|
+
|
|
|
+// See PEP 353
|
|
|
+#define PY_SSIZE_T_CLEAN 1
|
|
|
+
|
|
|
+#include "Python.h"
|
|
|
+
|
|
|
+/* Python 2.4 */
|
|
|
+
|
|
|
+// 2.4 macros which aren't available in 2.3
|
|
|
+#ifndef Py_RETURN_NONE
|
|
|
+# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef Py_RETURN_TRUE
|
|
|
+# define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef Py_RETURN_FALSE
|
|
|
+# define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 2.5 */
|
|
|
+
|
|
|
+// Prior to Python 2.5, we didn't have Py_ssize_t.
|
|
|
+#if PY_VERSION_HEX < 0x02050000
|
|
|
+typedef int Py_ssize_t;
|
|
|
+# define PyInt_FromSsize_t PyInt_FromLong
|
|
|
+# define PyInt_AsSsize_t PyInt_AsLong
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 2.6 */
|
|
|
+
|
|
|
+#ifndef Py_TYPE
|
|
|
+# define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 2.7, 3.1 */
|
|
|
+
|
|
|
+#ifndef PyVarObject_HEAD_INIT
|
|
|
+ #define PyVarObject_HEAD_INIT(type, size) \
|
|
|
+ PyObject_HEAD_INIT(type) size,
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 2.7, 3.2 */
|
|
|
+
|
|
|
+#if PY_VERSION_HEX < 0x03020000
|
|
|
+# define PyErr_NewExceptionWithDoc(name, doc, base, dict) \
|
|
|
+ PyErr_NewException(name, base, dict)
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 3.0 */
|
|
|
+
|
|
|
+// Always on in Python 3
|
|
|
+#ifndef Py_TPFLAGS_CHECKTYPES
|
|
|
+# define Py_TPFLAGS_CHECKTYPES 0
|
|
|
+#endif
|
|
|
+
|
|
|
+// Macros for writing code that will compile in both versions.
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
|
+# define nb_nonzero nb_bool
|
|
|
+# define nb_divide nb_true_divide
|
|
|
+# define nb_inplace_divide nb_inplace_true_divide
|
|
|
+
|
|
|
+# define PyLongOrInt_Check(x) PyLong_Check(x)
|
|
|
+# define PyLongOrInt_AS_LONG PyLong_AS_LONG
|
|
|
+# define PyInt_Check PyLong_Check
|
|
|
+# define PyInt_AsLong PyLong_AsLong
|
|
|
+# define PyInt_AS_LONG PyLong_AS_LONG
|
|
|
+# define PyLongOrInt_AsSize_t PyLong_AsSize_t
|
|
|
+#else
|
|
|
+# define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
|
|
|
+// PyInt_FromSize_t automatically picks the right type.
|
|
|
+# define PyLongOrInt_AS_LONG PyInt_AsLong
|
|
|
+
|
|
|
+EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *);
|
|
|
+#endif
|
|
|
+
|
|
|
+// Which character to use in PyArg_ParseTuple et al for a byte string.
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
|
+# define FMTCHAR_BYTES "y"
|
|
|
+#else
|
|
|
+# define FMTCHAR_BYTES "s"
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 3.2 */
|
|
|
+
|
|
|
+#if PY_VERSION_HEX < 0x03020000
|
|
|
+typedef long Py_hash_t;
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 3.3 */
|
|
|
+
|
|
|
+#if PY_MAJOR_VERSION >= 3
|
|
|
+// Python 3 versions before 3.3.3 defined this incorrectly.
|
|
|
+# undef _PyErr_OCCURRED
|
|
|
+# define _PyErr_OCCURRED() (PyThreadState_GET()->curexc_type)
|
|
|
+
|
|
|
+// Python versions before 3.3 did not define this.
|
|
|
+# if PY_VERSION_HEX < 0x03030000
|
|
|
+# define PyUnicode_AsUTF8 _PyUnicode_AsString
|
|
|
+# define PyUnicode_AsUTF8AndSize _PyUnicode_AsStringAndSize
|
|
|
+# endif
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Python 3.6 */
|
|
|
+
|
|
|
+// Used to implement _PyObject_CallNoArg
|
|
|
+extern EXPCL_INTERROGATEDB PyTupleObject Dtool_EmptyTuple;
|
|
|
+
|
|
|
+#ifndef _PyObject_CallNoArg
|
|
|
+# define _PyObject_CallNoArg(func) PyObject_Call((func), (PyObject *)&Dtool_EmptyTuple, nullptr)
|
|
|
+#endif
|
|
|
+
|
|
|
+// Python versions before 3.6 didn't require longlong support to be enabled.
|
|
|
+#ifndef HAVE_LONG_LONG
|
|
|
+# define PyLong_FromLongLong(x) PyLong_FromLong((long) (x))
|
|
|
+# define PyLong_FromUnsignedLongLong(x) PyLong_FromUnsignedLong((unsigned long) (x))
|
|
|
+# define PyLong_AsLongLong(x) PyLong_AsLong(x)
|
|
|
+# define PyLong_AsUnsignedLongLong(x) PyLong_AsUnsignedLong(x)
|
|
|
+# define PyLong_AsUnsignedLongLongMask(x) PyLong_AsUnsignedLongMask(x)
|
|
|
+# define PyLong_AsLongLongAndOverflow(x) PyLong_AsLongAndOverflow(x)
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Other Python implementations */
|
|
|
+
|
|
|
+// _PyErr_OCCURRED is an undocumented macro version of PyErr_Occurred.
|
|
|
+// Some implementations of the CPython API (e.g. PyPy's cpyext) do not define
|
|
|
+// it, so in these cases we just silently fall back to PyErr_Occurred.
|
|
|
+#ifndef _PyErr_OCCURRED
|
|
|
+# define _PyErr_OCCURRED() PyErr_Occurred()
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif // HAVE_PYTHON
|
|
|
+
|
|
|
+#endif // PY_COMPAT_H
|