Python 3.7 和 excess_args 的 SWIG 问题

SWIG issues with Python 3.7 and excess_args

本文关键字:args SWIG 问题 excess Python      更新时间:2023-10-16

我有一些扩展模块的代码C++代码,我刚刚从带有旧SWIG的Python2.7.11升级到带有SWIG 3.0.12的python3.7.1。我遇到了类似于 https://bugs.python.org/issue34495 的问题,只有它的Py_None而不是nullptr.SWIG_Python_NewShadowInstance中生成的代码调用tp_new,第 2 个和第 3 个参数带有Py_None

SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
{
...
#if PY_VERSION_HEX >= 0x03000000
inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); 

这会导致object_new呼叫,argskwds都指向Py_None

object_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
if (excess_args(args, kwds)) {

然后用argskwds呼叫excess_args

excess_args(PyObject *args, PyObject *kwds)
{
return PyTuple_GET_SIZE(args) ||
(kwds && PyDict_Check(kwds) && PyDict_GET_SIZE(kwds));

PyTuple_GET_SIZE(args)Py_None窒息的地方.

有谁知道如何解决这个问题?

经过更多的研究,我在SWIGs GitHub页面上发现了这个问题。显然问题已解决,但没有新版本发布修复程序。

乌德帕特

显然不需要更新。我用 github 的当前版本替换了LIbpythonpyrun.swg。这解决了我的问题。如果有人发现风险太大,可以在SWIG_Python_NewShadowInstance中修补有问题的代码部分,替换

SWIGRUNTIME PyObject* 
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
{
...
#if PY_VERSION_HEX >= 0x03000000
inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
...
}

有了这个

SWIGRUNTIME PyObject* 
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
{
...
#if PY_VERSION_HEX >= 0x03000000
PyObject *empty_args = PyTuple_New(0);
if (empty_args) {
inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, Py_None);
Py_DECREF(empty_args);
...
}
...
}

或者只是用固定版本替换整个功能。