Why is PyObject_SetAttrString returning -1 (Python C-API) -
Why is PyObject_SetAttrString returning -1 (Python C-API) -
i working on bridging c++ , python.
when new instance of custom type gets created, need register c++ instance methods attributes on python object beingness created.
the relevant code flow goes this:
class="lang-c prettyprint-override">// during setup, fill slots 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 ); :
of involvement here set_tp_init
class="lang-c prettyprint-override"> static int extension_object_init( pyobject* _self, pyobject* _args, pyobject* _kwds ) { seek { py::tuple args{_args}; py::dict kwds = _kwds ? py::dict{_kwds} : py::dict{}; pythonclassinstance* self{ reinterpret_cast<pythonclassinstance*>(_self) }; if( self->m_pycxx_object ) { self->m_pycxx_object->reinit( args, kwds ); dbg_print( "reinit -" ); } else self->m_pycxx_object = new finalclass{ self, args, kwds }; // here forcefulness c++ relevant class instance methods register attributes finalclass* f = (finalclass*)(self->m_pycxx_object); f->addall(); } catch(...) : void addall() { auto& methods = funcmapper<finalclass>::methods(); //auto py_method_table = new pymethoddef[ methods.size() + 1 ]{}; // sentinel must 0'd, thx {} for( auto& m : methods ) { pyobject* a{ selfptr() }; // 'this' class derives pyobject
backing pyobject* const char* str = m.first.c_str();
class="lang-c prettyprint-override"> 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 }; } }
i've declared of variables in pedantic way create sure getting passed correctly pyobject_setattrstring, appears are.
however, pyobject_setattrstring returning -1 (error).
looking @ cpython source code, can't create out error coming from:
class="lang-c prettyprint-override">int pyobject_setattrstring(pyobject *v, const char *name, pyobject *w) { pyobject *s; int res; if (py_type(v)->tp_setattr != null) homecoming (*py_type(v)->tp_setattr)(v, (char*)name, w); s = pyunicode_internfromstring(name); if (s == null) homecoming -1; res = pyobject_setattr(v, s, w); py_xdecref(s); homecoming 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 string, not '%.200s'", name->ob_type->tp_name); homecoming -1; } py_incref(name); pyunicode_interninplace(&name); if (tp->tp_setattro != null) { err = (*tp->tp_setattro)(v, name, value); // <-- should nail here py_decref(name); homecoming err; } if (tp->tp_setattr != null) { char *name_str = _pyunicode_asstring(name); if (name_str == null) homecoming -1; err = (*tp->tp_setattr)(v, name_str, value); py_decref(name); homecoming 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 read-only attributes " "(%s .%u)", tp->tp_name, value==null ? "del" : "assign to", name); homecoming -1; }
is there can seek short of having add together cpython source project , single step through it?
by looking @ values going in, should reach point i've marked:
class="lang-c prettyprint-override"> pyunicode_interninplace(&name); if (tp->tp_setattro != null) { err = (*tp->tp_setattro)(v, name, value); // <-- should nail here py_decref(name); homecoming err; }
but can't see how debug tp_setattro. slot in function table. grepping through source code reveals huge number of accesses.
python python-c-api cpython
Comments
Post a Comment