From 9cbc45b9bf6b9994d8a2782b08359afb8eaf0902 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 28 Oct 2024 11:57:27 +0100 Subject: [PATCH 01/10] collide: Handle CollisionBox bam read without 2D info --- panda/src/collide/collisionBox.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 3e80650d6b..5ec26a705e 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -1449,5 +1449,13 @@ fillin(DatagramIterator& scan, BamReader* manager) { v.read_datagram(scan); _points[i].push_back(PointDef(p, v)); } + if (size < 4) { + LPoint3 array[4]; + array[0] = _vertex[plane_def[i][0]]; + array[1] = _vertex[plane_def[i][1]]; + array[2] = _vertex[plane_def[i][2]]; + array[3] = _vertex[plane_def[i][3]]; + setup_points(array, array+4, i); + } } } From 12bb7d12bb0678ac229375a81aebc921e49c9958 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Oct 2024 17:34:48 +0100 Subject: [PATCH 02/10] showbase: Fix DistancePhasedNode exception at module clean-up time --- direct/src/showbase/DistancePhasedNode.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/direct/src/showbase/DistancePhasedNode.py b/direct/src/showbase/DistancePhasedNode.py index 385f94ae70..34841078f2 100755 --- a/direct/src/showbase/DistancePhasedNode.py +++ b/direct/src/showbase/DistancePhasedNode.py @@ -78,7 +78,8 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath): """ Reuse abandoned ids. """ - DistancePhasedNode.__InstanceDeque.append(id) + if DistancePhasedNode is not None: + DistancePhasedNode.__InstanceDeque.append(id) def __init__(self, name, phaseParamMap = {}, autoCleanup = True, From dbeab0b97bc7b0b363fb72ed9b1b8137b2626e25 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Oct 2024 19:20:27 +0100 Subject: [PATCH 03/10] makepanda: Backport Python 3.13t build fixes --- makepanda/makepackage.py | 2 +- makepanda/makepandacore.py | 21 ++++++++++++++++----- makepanda/makewheel.py | 14 +++++++++++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py index 68c74523dc..e7d0092486 100755 --- a/makepanda/makepackage.py +++ b/makepanda/makepackage.py @@ -876,7 +876,7 @@ def MakeInstallerFreeBSD(version, runtime=False, python_versions=[], **kwargs): oscmd("rm -f %s/tmp/python_dep" % outputdir) if "PYTHONVERSION" in SDK: - pyver_nodot = SDK["PYTHONVERSION"][6:].rstrip('dmu').replace('.', '') + pyver_nodot = SDK["PYTHONVERSION"][6:].rstrip('dmut').replace('.', '') else: pyver_nodot = "%d%d" % (sys.version_info[:2]) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 9f80c8f9cf..ff67806eb8 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2252,11 +2252,15 @@ def SdkLocatePython(prefer_thirdparty_python=False): sysroot = SDK.get("MACOSX", "") version = locations.get_python_version() - py_fwx = "{0}/System/Library/Frameworks/Python.framework/Versions/{1}".format(sysroot, version) + framework_name = "Python" + if 't' in abiflags: + framework_name += "T" + + py_fwx = "{0}/System/Library/Frameworks/{1}.framework/Versions/{2}".format(sysroot, framework_name, version) if not os.path.exists(py_fwx): # Fall back to looking on the system. - py_fwx = "/Library/Frameworks/Python.framework/Versions/" + version + py_fwx = "/Library/Frameworks/{0}.framework/Versions/{1}".format(framework_name, version) if not os.path.exists(py_fwx): # Newer macOS versions use this scheme. @@ -3505,10 +3509,12 @@ def GetExtensionSuffix(): else: dllext = '' + gil_disabled = locations.get_config_var("Py_GIL_DISABLED") + suffix = 't' if gil_disabled and int(gil_disabled) else '' if GetTargetArch() == 'x64': - return dllext + '.cp%d%d-win_amd64.pyd' % (sys.version_info[:2]) + return dllext + '.cp%d%d%s-win_amd64.pyd' % (sys.version_info[0], sys.version_info[1], suffix) else: - return dllext + '.cp%d%d-win32.pyd' % (sys.version_info[:2]) + return dllext + '.cp%d%d%s-win32.pyd' % (sys.version_info[0], sys.version_info[1], suffix) elif sys.version_info >= (3, 0): import _imp @@ -3526,6 +3532,11 @@ def GetPythonABI(): soabi = 'cpython-%d%d' % (sys.version_info[:2]) + if sys.version_info >= (3, 13): + gil_disabled = locations.get_config_var("Py_GIL_DISABLED") + if gil_disabled and int(gil_disabled): + return soabi + 't' + if sys.version_info >= (3, 8): return soabi @@ -3655,7 +3666,7 @@ def GetCurrentPythonVersionInfo(): return return { - "version": SDK["PYTHONVERSION"][6:].rstrip('dmu'), + "version": SDK["PYTHONVERSION"][6:].rstrip('dmut'), "soabi": GetPythonABI(), "ext_suffix": GetExtensionSuffix(), "executable": sys.executable, diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 3cd431c51d..5be77f4b5c 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -20,6 +20,17 @@ from sysconfig import get_platform def get_abi_tag(): + if sys.version_info >= (3, 13): + ver = 'cp%d%d' % sys.version_info[:2] + if hasattr(sys, 'abiflags'): + return ver + sys.abiflags + + gil_disabled = get_config_var("Py_GIL_DISABLED") + if gil_disabled and int(gil_disabled): + return ver + 't' + + return ver + if sys.version_info >= (3, 0): soabi = get_config_var('SOABI') if soabi and soabi.startswith('cpython-'): @@ -432,7 +443,8 @@ class WheelFile(object): continue new_dep = os.path.join(deps_path, os.path.relpath(target_dep, os.path.dirname(target_path))) - elif dep.startswith('/Library/Frameworks/Python.framework/'): + elif dep.startswith('/Library/Frameworks/Python.framework/') or \ + dep.startswith('/Library/Frameworks/PythonT.framework/'): # Add this dependency if it's in the Python directory. target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep) target_dep = self.consider_add_dependency(target_dep, dep, loader_path) From f9a5445d42f1eefa027d9b043727eb3ebd810747 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 29 Oct 2024 19:23:47 +0100 Subject: [PATCH 04/10] workflow: Test Python 3.13, update setup-python to v5 --- .github/workflows/ci.yml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cdcbfdc07..5d25208e35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,22 @@ jobs: rmdir panda3d-1.10.14 (cd thirdparty/darwin-libs-a && rm -rf rocket) + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - name: Build Python 3.13 + shell: bash + run: | + python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 + - name: Test Python 3.13 + shell: bash + run: | + python -m pip install pytest setuptools + PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest + - name: Set up Python 3.12 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.12' - name: Build Python 3.12 @@ -47,7 +61,7 @@ jobs: PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.11 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Build Python 3.11 @@ -61,7 +75,7 @@ jobs: PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' - name: Build Python 3.10 @@ -75,7 +89,7 @@ jobs: PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.9 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.9' - name: Build Python 3.9 @@ -89,7 +103,7 @@ jobs: PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.8' - name: Build Python 3.8 From 10da05e2a64ae20db6ef351b3469039a352ce82d Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 12:53:54 +0100 Subject: [PATCH 05/10] workflow: Skip Windows builds for Python 3.13 for now --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d25208e35..69508618d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,14 +33,17 @@ jobs: (cd thirdparty/darwin-libs-a && rm -rf rocket) - name: Set up Python 3.13 + if: runner.os != 'Windows' uses: actions/setup-python@v5 with: python-version: '3.13' - name: Build Python 3.13 + if: runner.os != 'Windows' shell: bash run: | python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 - name: Test Python 3.13 + if: runner.os != 'Windows' shell: bash run: | python -m pip install pytest setuptools From 64454b1c9ff4fe7eb9a96a51cd2e3cccd1789038 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 12:57:18 +0100 Subject: [PATCH 06/10] Replace direct uses of ob_type, which gives problems in nogil build --- direct/src/dcparser/dcField.cxx | 5 +++-- dtool/src/interrogatedb/py_compat.h | 2 +- panda/src/linmath/lvecBase2_ext_src.I | 2 +- panda/src/linmath/lvecBase3_ext_src.I | 2 +- panda/src/linmath/lvecBase4_ext_src.I | 2 +- panda/src/ode/odeSpace_ext.cxx | 2 +- panda/src/ode/odeUtil_ext.cxx | 2 +- panda/src/pgraph/nodePathCollection_ext.cxx | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/direct/src/dcparser/dcField.cxx b/direct/src/dcparser/dcField.cxx index 5880fd5097..80cb211f40 100644 --- a/direct/src/dcparser/dcField.cxx +++ b/direct/src/dcparser/dcField.cxx @@ -538,8 +538,9 @@ get_pystr(PyObject *value) { return result; } - if (value->ob_type != nullptr) { - PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type)); + PyTypeObject *type = Py_TYPE(value); + if (type != nullptr) { + PyObject *typestr = PyObject_Str((PyObject *)type); if (typestr != nullptr) { #if PY_MAJOR_VERSION >= 3 string result = PyUnicode_AsUTF8(typestr); diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index a386c06136..65ef2ec39a 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -65,7 +65,7 @@ typedef int Py_ssize_t; /* Python 2.6 */ -#ifndef Py_TYPE +#if PY_VERSION_HEX < 0x02060000 # define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif diff --git a/panda/src/linmath/lvecBase2_ext_src.I b/panda/src/linmath/lvecBase2_ext_src.I index edb0a69af6..4fea21a1df 100644 --- a/panda/src/linmath/lvecBase2_ext_src.I +++ b/panda/src/linmath/lvecBase2_ext_src.I @@ -188,7 +188,7 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { #endif } else { PyErr_Format(PyExc_ValueError, "'%.200s' object is not iterable", - assign->ob_type->tp_name); + Py_TYPE(assign)->tp_name); } return -1; } diff --git a/panda/src/linmath/lvecBase3_ext_src.I b/panda/src/linmath/lvecBase3_ext_src.I index 72913c816c..67b7f8d21f 100644 --- a/panda/src/linmath/lvecBase3_ext_src.I +++ b/panda/src/linmath/lvecBase3_ext_src.I @@ -192,7 +192,7 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { #endif } else { PyErr_Format(PyExc_ValueError, "'%.200s' object is not iterable", - assign->ob_type->tp_name); + Py_TYPE(assign)->tp_name); } return -1; } diff --git a/panda/src/linmath/lvecBase4_ext_src.I b/panda/src/linmath/lvecBase4_ext_src.I index 1a120e678d..013a921e73 100644 --- a/panda/src/linmath/lvecBase4_ext_src.I +++ b/panda/src/linmath/lvecBase4_ext_src.I @@ -201,7 +201,7 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { #endif } else { PyErr_Format(PyExc_ValueError, "'%.200s' object is not iterable", - assign->ob_type->tp_name); + Py_TYPE(assign)->tp_name); } return -1; } diff --git a/panda/src/ode/odeSpace_ext.cxx b/panda/src/ode/odeSpace_ext.cxx index 97e841f30b..e1c5754bc8 100644 --- a/panda/src/ode/odeSpace_ext.cxx +++ b/panda/src/ode/odeSpace_ext.cxx @@ -72,7 +72,7 @@ collide(PyObject* arg, PyObject* callback) { nassertr(callback != nullptr, -1); if (!PyCallable_Check(callback)) { - PyErr_Format(PyExc_TypeError, "'%s' object is not callable", callback->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "'%s' object is not callable", Py_TYPE(callback)->tp_name); return -1; } else if (_this->get_id() == nullptr) { diff --git a/panda/src/ode/odeUtil_ext.cxx b/panda/src/ode/odeUtil_ext.cxx index c5aabaa812..ea04dc0a45 100644 --- a/panda/src/ode/odeUtil_ext.cxx +++ b/panda/src/ode/odeUtil_ext.cxx @@ -28,7 +28,7 @@ int Extension:: collide2(const OdeGeom &geom1, const OdeGeom &geom2, PyObject* arg, PyObject* callback) { nassertr(callback != nullptr, -1); if (!PyCallable_Check(callback)) { - PyErr_Format(PyExc_TypeError, "'%s' object is not callable", callback->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "'%s' object is not callable", Py_TYPE(callback)->tp_name); return -1; } else { _python_callback = (PyObject*) callback; diff --git a/panda/src/pgraph/nodePathCollection_ext.cxx b/panda/src/pgraph/nodePathCollection_ext.cxx index 836e2959e0..dee4fede7a 100644 --- a/panda/src/pgraph/nodePathCollection_ext.cxx +++ b/panda/src/pgraph/nodePathCollection_ext.cxx @@ -75,7 +75,7 @@ __reduce__(PyObject *self) const { // object whose constructor we should call (e.g. this), and the arguments // necessary to reconstruct this object. - PyObject *this_class = (PyObject *)self->ob_type; + PyObject *this_class = (PyObject *)Py_TYPE(self); if (this_class == nullptr) { return nullptr; } From 0ba2aadcd64584cc7c9b4625439e96b70daa92e5 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 13:06:36 +0100 Subject: [PATCH 07/10] Introduce Py_IS_TYPE, use for Py_TYPE comparisons --- dtool/src/dtoolutil/filename_ext.cxx | 2 +- dtool/src/interrogatedb/py_compat.h | 6 +++++- dtool/src/interrogatedb/py_panda.cxx | 2 +- panda/src/event/pythonTask.cxx | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dtool/src/dtoolutil/filename_ext.cxx b/dtool/src/dtoolutil/filename_ext.cxx index c7b7e30606..86d521a9a9 100644 --- a/dtool/src/dtoolutil/filename_ext.cxx +++ b/dtool/src/dtoolutil/filename_ext.cxx @@ -56,7 +56,7 @@ __init__(PyObject *path) { return; } - if (Py_TYPE(path) == &Dtool_Filename._PyType) { + if (Py_IS_TYPE(path, Dtool_GetPyTypeObject(&Dtool_Filename))) { // Copy constructor. *_this = *(Filename *)DtoolInstance_VOID_PTR(path); return; diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index 65ef2ec39a..e1ee9dd7bb 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -217,8 +217,12 @@ INLINE PyObject *_PyLong_Lshift(PyObject *a, size_t shiftby) { /* Python 3.9 */ +#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) +# define Py_IS_TYPE(ob, type) (Py_TYPE((PyObject *)ob) == type) +#endif + #ifndef PyCFunction_CheckExact -# define PyCFunction_CheckExact(op) (Py_TYPE(op) == &PyCFunction_Type) +# define PyCFunction_CheckExact(op) (Py_IS_TYPE(op, &PyCFunction_Type)) #endif #if PY_VERSION_HEX < 0x03090000 diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 1ce7da8328..541b7a6381 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -300,7 +300,7 @@ static PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObj subtype->tp_name); } - if (Py_TYPE(arg) == subtype) { + if (Py_IS_TYPE(arg, subtype)) { Py_INCREF(arg); return arg; } diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index b6f540fbdf..8395bd5adc 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -590,7 +590,7 @@ do_python_task() { _retrieved_exception = false; if (task_cat.is_debug()) { - if (_exception != nullptr && Py_TYPE(_exception) == &PyType_Type) { + if (_exception != nullptr && Py_IS_TYPE(_exception, &PyType_Type)) { task_cat.debug() << *this << " received " << ((PyTypeObject *)_exception)->tp_name << " from coroutine.\n"; } else { @@ -741,7 +741,7 @@ do_python_task() { if (PyCFunction_Check(result)) { meth = ((PyCFunctionObject *)result)->m_ml; #if PY_MAJOR_VERSION >= 3 - } else if (Py_TYPE(result) == &PyMethodDescr_Type) { + } else if (Py_IS_TYPE(result, &PyMethodDescr_Type)) { #else } else if (strcmp(Py_TYPE(result)->tp_name, "method_descriptor") == 0) { #endif From e2385881181fe829a484983aa70ef1dbf19dcbf2 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 13:16:25 +0100 Subject: [PATCH 08/10] makepanda: Fix wrong flag for excluding pythonXX_d.lib --- makepanda/makepanda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index f3839470a0..fc547bd234 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1967,7 +1967,7 @@ def CompileLink(dll, obj, opts): if "PYTHON" not in opts: pythonv = SDK["PYTHONVERSION"].replace('.', '') if optlevel <= 2: - cmd += ' /NOD:{}d.lib'.format(pythonv) + cmd += ' /NOD:{}_d.lib'.format(pythonv) else: cmd += ' /NOD:{}.lib'.format(pythonv) From df5f8d77daa802d030aa2277c5d7b987d7fd515a Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 12:56:48 +0100 Subject: [PATCH 09/10] makepanda: Build fixes for Python 3.13t on Windows --- makepanda/makepandacore.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index ff67806eb8..3e44d65734 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2189,6 +2189,15 @@ def SdkLocatePython(prefer_thirdparty_python=False): SDK["PYTHON"] = sdkdir SDK["PYTHONEXEC"] = SDK["PYTHON"].replace('\\', '/') + "/python" + + gil_disabled = locations.get_config_var("Py_GIL_DISABLED") + if gil_disabled and int(gil_disabled): + SDK["PYTHONEXEC"] += "3.13t" + abiflags = "t" + DefSymbol("PYTHON", "Py_GIL_DISABLED", "1") + else: + abiflags = "" + if (GetOptimize() <= 2): SDK["PYTHONEXEC"] += "_d.exe" else: @@ -2199,11 +2208,11 @@ def SdkLocatePython(prefer_thirdparty_python=False): # Determine which version it is by checking which dll is in the directory. if (GetOptimize() <= 2): - py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]_d.dll") + \ - glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]_d.dll") + py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]" + abiflags + "_d.dll") + \ + glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]" + abiflags + "_d.dll") else: - py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9].dll") + \ - glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9].dll") + py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]" + abiflags + ".dll") + \ + glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]" + abiflags + ".dll") if len(py_dlls) == 0: exit("Could not find the Python dll in %s." % (SDK["PYTHON"])) @@ -2214,7 +2223,7 @@ def SdkLocatePython(prefer_thirdparty_python=False): py_dllver = py_dll.strip(".DHLNOPTY_dhlnopty") ver = py_dllver[0] + '.' + py_dllver[1:] - SDK["PYTHONVERSION"] = "python" + ver + SDK["PYTHONVERSION"] = "python" + ver + abiflags os.environ["PYTHONHOME"] = SDK["PYTHON"] running_ver = '%d.%d' % sys.version_info[:2] From f47b34d2a13d02c67fd9e0e6cfaad2ddb0e3125f Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 30 Oct 2024 13:23:34 +0100 Subject: [PATCH 10/10] Fix remaining uses of ._PyType member in extension code This should be replaced with Dtool_GetPyTypeObject, hiding the implementation details a bit so that we can more easily change the underlying structure if we need later Also adds Py_NewRef to py_compat.h, backporting from master --- dtool/src/interrogatedb/py_compat.h | 22 ++++++++++++++++++++++ panda/src/express/datagram_ext.I | 4 ++-- panda/src/express/pointerToArray_ext.I | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index e1ee9dd7bb..a1ec1958ab 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -247,6 +247,28 @@ INLINE PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObje } #endif +/* Python 3.10 */ + +#if PY_VERSION_HEX < 0x030A0000 +INLINE int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) { + int ret = PyModule_AddObject(module, name, value); + if (ret == 0) { + Py_INCREF(value); + } + return ret; +} + +ALWAYS_INLINE PyObject *Py_NewRef(PyObject *obj) { + Py_INCREF(obj); + return obj; +} + +ALWAYS_INLINE PyObject *Py_XNewRef(PyObject *obj) { + Py_XINCREF(obj); + return obj; +} +#endif + /* Python 3.12 */ #if PY_VERSION_HEX < 0x030C0000 diff --git a/panda/src/express/datagram_ext.I b/panda/src/express/datagram_ext.I index 9c997e64f6..77e2eb5827 100644 --- a/panda/src/express/datagram_ext.I +++ b/panda/src/express/datagram_ext.I @@ -52,10 +52,10 @@ __reduce__() const { } extern struct Dtool_PyTypedObject Dtool_Datagram; - Py_INCREF((PyObject *)&Dtool_Datagram._PyType); + PyObject *tp = (PyObject *)Dtool_GetPyTypeObject(&Dtool_Datagram); PyObject *result = PyTuple_New(2); - PyTuple_SET_ITEM(result, 0, (PyObject *)&Dtool_Datagram._PyType); + PyTuple_SET_ITEM(result, 0, Py_NewRef(tp)); PyTuple_SET_ITEM(result, 1, args); return result; } diff --git a/panda/src/express/pointerToArray_ext.I b/panda/src/express/pointerToArray_ext.I index 7ebb8afd4d..c0d2c66da2 100644 --- a/panda/src/express/pointerToArray_ext.I +++ b/panda/src/express/pointerToArray_ext.I @@ -100,7 +100,7 @@ __init__(PyObject *self, PyObject *source) { // Now construct the internal list by copying the elements one-at-a-time // from Python. - PyObject *dict = DtoolInstance_TYPE(self)->_PyType.tp_dict; + PyObject *dict = Dtool_GetPyTypeObject(DtoolInstance_TYPE(self))->tp_dict; PyObject *push_back = PyDict_GetItemString(dict, "push_back"); if (push_back == nullptr) { PyErr_BadArgument();