Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2024-10-30 13:37:17 +01:00
commit 7560a1edd1
22 changed files with 89 additions and 33 deletions

View File

@ -387,6 +387,23 @@ jobs:
rmdir panda3d-1.10.14
(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
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@v5
with:

View File

@ -278,8 +278,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) {
std::string result = PyUnicode_AsUTF8(typestr);
Py_DECREF(typestr);

View File

@ -87,7 +87,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,

View File

@ -47,7 +47,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;

View File

@ -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
@ -221,8 +221,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
@ -281,6 +285,28 @@ ALWAYS_INLINE PyObject *Py_XNewRef(PyObject *obj) {
}
#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

View File

@ -321,7 +321,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)) {
return Py_NewRef(arg);
}

View File

@ -1723,7 +1723,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)

View File

@ -2129,6 +2129,10 @@ def SdkLocatePython(prefer_thirdparty_python=False):
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"
@ -2140,11 +2144,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"]))
@ -2155,7 +2159,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]
@ -3389,7 +3393,14 @@ def GetPythonABI():
if soabi:
return soabi
return 'cpython-%d%d' % (sys.version_info[:2])
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'
return soabi
def CalcLocation(fn, ipath):
if fn.startswith("panda3d/") and fn.endswith(".py"):

View File

@ -175,7 +175,7 @@ set_result(PyObject *result) {
else if (DtoolInstance_Check(result)) {
// If this is a Python subclass of a C++ type, fall through to below, since
// we don't want to lose that extra information.
if (Py_TYPE(result) == (PyTypeObject *)DtoolInstance_TYPE(result)) {
if (Py_IS_TYPE(result, Dtool_GetPyTypeObject(DtoolInstance_TYPE(result)))) {
void *ptr;
if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedWritableReferenceCount))) {
_this->set_result((TypedWritableReferenceCount *)ptr);

View File

@ -300,13 +300,13 @@ __setattr__(PyObject *self, PyObject *attr, PyObject *v) {
if (!PyUnicode_Check(attr)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
attr->ob_type->tp_name);
Py_TYPE(attr)->tp_name);
return -1;
}
PyObject *descr = _PyType_Lookup(Py_TYPE(self), attr);
if (descr != nullptr) {
descrsetfunc f = descr->ob_type->tp_descr_set;
descrsetfunc f = Py_TYPE(descr)->tp_descr_set;
if (f != nullptr) {
return f(descr, self, v);
}
@ -469,7 +469,7 @@ cancel() {
#endif
// Shortcut for unextended AsyncFuture.
if (Py_TYPE(_fut_waiter) == (PyTypeObject *)&Dtool_AsyncFuture) {
if (Py_IS_TYPE(_fut_waiter, Dtool_GetPyTypeObject(&Dtool_AsyncFuture))) {
AsyncFuture *fut = (AsyncFuture *)DtoolInstance_VOID_PTR(_fut_waiter);
if (!fut->done()) {
fut->cancel();
@ -717,7 +717,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 {
@ -862,7 +862,7 @@ do_python_task() {
PyMethodDef *meth = nullptr;
if (PyCFunction_Check(result)) {
meth = ((PyCFunctionObject *)result)->m_ml;
} else if (Py_TYPE(result) == &PyMethodDescr_Type) {
} else if (Py_IS_TYPE(result, &PyMethodDescr_Type)) {
meth = ((PyMethodDescrObject *)result)->d_method;
}

View File

@ -47,7 +47,7 @@ __reduce__() const {
}
extern struct Dtool_PyTypedObject Dtool_Datagram;
PyObject *tp = (PyObject *)&Dtool_Datagram._PyType;
PyObject *tp = (PyObject *)Dtool_GetPyTypeObject(&Dtool_Datagram);
PyObject *result = PyTuple_New(2);
PyTuple_SET_ITEM(result, 0, Py_NewRef(tp));

View File

@ -96,7 +96,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();

View File

@ -74,7 +74,7 @@ PyObject *Extension<InternalName>::
__reduce__() const {
std::string name = _this->get_name();
return Py_BuildValue("(N(s#))",
PyObject_GetAttrString((PyObject *)&Dtool_InternalName._PyType, "make"), name.c_str(), name.size());
PyObject_GetAttrString((PyObject *)Dtool_GetPyTypeObject(&Dtool_InternalName), "make"), name.c_str(), name.size());
}
#endif // HAVE_PYTHON

View File

@ -183,7 +183,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;
}

View File

@ -187,7 +187,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;
}

View File

@ -196,7 +196,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;
}

View File

@ -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) {

View File

@ -28,7 +28,7 @@ int Extension<OdeUtil>::
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 = Py_XNewRef(callback);

View File

@ -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;
}

View File

@ -85,7 +85,7 @@ static TypedWritable *factory_callback(const FactoryParams &params){
Py_DECREF(result);
}
else if (DtoolInstance_TYPE(result) == &Dtool_TypedWritable &&
Py_TYPE(result) != &Dtool_TypedWritable._PyType) {
!Py_IS_TYPE(result, Dtool_GetPyTypeObject(&Dtool_TypedWritable))) {
// It is a custom subclass of TypedWritable, so we have to keep it
// alive, and decrement it in finalize(), see typedWritable_ext.cxx.
manager->register_finalize(ptr);

View File

@ -87,7 +87,7 @@ get_function() {
*/
PyObject *PythonCallbackObject::
__reduce__() const {
return Py_BuildValue("O(O)", (PyObject *)&Dtool_PythonCallbackObject._PyType, _function);
return Py_BuildValue("O(O)", (PyObject *)Dtool_GetPyTypeObject(&Dtool_PythonCallbackObject), _function);
}
/**

View File

@ -134,10 +134,10 @@ wrap_typed_writable(void *from_this, PyTypeObject *from_type) {
nassertr(from_type != nullptr, nullptr);
TypedWritableProxy *to_this;
if (from_type == &Dtool_TypedWritable._PyType) {
if (from_type == Dtool_GetPyTypeObject(&Dtool_TypedWritable)) {
to_this = (TypedWritableProxy *)(TypedWritable *)from_this;
}
else if (from_type == (PyTypeObject *)&Dtool_TypedObject._PyType) {
else if (from_type == Dtool_GetPyTypeObject(&Dtool_TypedObject)) {
to_this = (TypedWritableProxy *)(TypedObject *)from_this;
}
else {