On 08.12.19 09:49, Nick Coghlan wrote:
On Fri., 6 Dec. 2019, 3:31 am Christian Tismer, <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi guys,
during the last few weeks I have been struggling quite much in order to make PySide run with Python 3.8 at all.
The expected problems were refcounting leaks due to changed handling of heaptypes. But in fact, the runtime behavior was much worse, because I always got negative refcounts!
After exhaustive searching through the different 3.8 commits, I could isolate the three problems with logarithmic search.
The hard problem was this: Whenever PySide creates a new type, it crashes in PyType_Ready. The reason is the existence of the Py_TPFLAGS_METHOD_DESCRIPTOR flag. During the PyType_Ready call, the function mro() is called. This mro() call results in a negative refcount, because something behaves differently since this flag is set by default in mro().
When I patched this flag away during the type_new call, everything worked ok. I don't understand why this problem affects PySide at all. Here is the code that would normally be only the newType line:
// PYSIDE-939: This is a temporary patch that circumvents the problem // with Py_TPFLAGS_METHOD_DESCRIPTOR until this is finally solved. PyObject *ob_PyType_Type = reinterpret_cast<PyObject *>(&PyType_Type); PyObject *mro = PyObject_GetAttr(ob_PyType_Type, Shiboken::PyName::mro()); auto hold = Py_TYPE(mro)->tp_flags; Py_TYPE(mro)->tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR; auto *newType = reinterpret_cast<SbkObjectType *>(type_new(metatype, args, kwds)); Py_TYPE(mro)->tp_flags = hold;
Isn't this manipulating the flags in the tuple type, rather than anything on a custom object? Or is "mro" a custom object rather than an MRO tuple?
no, "mro" is the default mro implementation which is a method descriptor of the standard PyTypeType object. The implementation of PyType_Ready just touches the mro in some helper function lookup_maybe_method. This is so funny: This side effect seems to be totally unrelated to PySide, but something we are doing wrong.
If anything, given the combination of factors required to reproduce the problem, I would guess that there might be a ref counting problem in the __set_owner__ invocations when called on a new type rather than a regular instance, and that was somehow affected by the change to increment the type refcount in PyObject_Init rather than PyType_GenericAlloc.
Thanks a lot! I will try to use that to find finally what's wrong. Cheers -- Chris -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023