相关的代码流程如下:
// during setup, we fill slots for the underlying PyTypeObject
p = new wrapperFor_PyTypeObject{ sizeof(FinalClass), 0, default_name };
p->set_tp_new( extension_object_new );
p->set_tp_init( extension_object_init );
p->set_tp_dealloc( extension_object_deallocator );
:
这里感兴趣的是set_tp_init
^{pr2}$支持PyObject* const char*str=m.first.c_str()
Object callable{ m.second->ConstructCFunc(this) }; // ConstructCFunc uses PyCFunction_New
callable.increment_reference_count();
PyObject* c{ callable.ptr() }; // extract backing PyObject* pointer
int ret = PyObject_SetAttrString( a, str, c );
if( ret == -1 )
throw AttributeError{ m.first };
}
}
我以一种非常迂腐的方式声明了所有的变量,以确保它们正确地传递到PyObject_SetAttrString中,看起来确实是这样。在
但是,PyObject_SetAttrString返回-1(错误)。在
查看CPython源代码,我不知道这个错误是从哪里来的:
int
PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
{
PyObject *s;
int res;
if (Py_TYPE(v)->tp_setattr != NULL)
return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w);
s = PyUnicode_InternFromString(name);
if (s == NULL)
return -1;
res = PyObject_SetAttr(v, s, w);
Py_XDECREF(s);
return res;
}
int
PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
{
PyTypeObject *tp = Py_TYPE(v);
int err;
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
name->ob_type->tp_name);
return -1;
}
Py_INCREF(name);
PyUnicode_InternInPlace(&name);
if (tp->tp_setattro != NULL) {
err = (*tp->tp_setattro)(v, name, value); // <-- SHOULD HIT HERE
Py_DECREF(name);
return err;
}
if (tp->tp_setattr != NULL) {
char *name_str = _PyUnicode_AsString(name);
if (name_str == NULL)
return -1;
err = (*tp->tp_setattr)(v, name_str, value);
Py_DECREF(name);
return err;
}
Py_DECREF(name);
assert(name->ob_refcnt >= 1);
if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
PyErr_Format(PyExc_TypeError,
"'%.100s' object has no attributes "
"(%s .%U)",
tp->tp_name,
value==NULL ? "del" : "assign to",
name);
else
PyErr_Format(PyExc_TypeError,
"'%.100s' object has only read-only attributes "
"(%s .%U)",
tp->tp_name,
value==NULL ? "del" : "assign to",
name);
return -1;
}
除了必须将CPython源代码添加到我的项目中并一步一步地完成它之外,还有什么可以尝试的吗?在
通过查看输入的值,它应该达到我标记的点:
PyUnicode_InternInPlace(&name);
if (tp->tp_setattro != NULL) {
err = (*tp->tp_setattro)(v, name, value); // <-- SHOULD HIT HERE
Py_DECREF(name);
return err;
}
但我不知道如何调试到tp_setattro中。它是函数表中的一个槽。对源代码进行greping会显示出大量的访问。在
目前没有回答
相关问题 更多 >
编程相关推荐