Hi all,

Sorry for the noise, I was wrong, and I retract.
I was somehow mislead and hunted a phantom.

Best - Chris


On 10.12.19 00:29, Christian Tismer wrote:
> On 09.12.19 23:26, Nick Coghlan wrote:
>>
>>
>> On Tue., 10 Dec. 2019, 5:17 am MRAB, <pyt...@mrabarnett.plus.com
>> <mailto:pyt...@mrabarnett.plus.com>> wrote:
>>
>>     On 2019-12-09 18:22, Christian Tismer wrote:
>>     >
>>     >
>>     > Hi Nick,
>>     >
>>     > after staring long at the code, I fount something funny in
>>     > typeobject.c #286 ff:
>>     >
>>     >
>>     > static void
>>     > type_mro_modified(PyTypeObject *type, PyObject *bases) {
>>     >      /*
>>     >         Check that all base classes or elements of the MRO of type are
>>     >         able to be cached.  This function is called after the base
>>     >         classes or mro of the type are altered.
>>     >
>>     >         Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
>>     >         has a custom MRO that includes a type which is not officially
>>     >         super type, or if the type implements its own mro() method.
>>     >
>>     >         Called from mro_internal, which will subsequently be called on
>>     >         each subclass when their mro is recursively updated.
>>     >       */
>>     >      Py_ssize_t i, n;
>>     >      int custom = (Py_TYPE(type) != &PyType_Type);
>>     >      int unbound;
>>     >      PyObject *mro_meth = NULL;
>>     >      PyObject *type_mro_meth = NULL;
>>     >
>>     >      if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
>>     >          return;
>>     >
>>     >      if (custom) {
>>     >          _Py_IDENTIFIER(mro);
>>     >          mro_meth = lookup_maybe_method(
>>     >              (PyObject *)type, &PyId_mro, &unbound);
>>     >          if (mro_meth == NULL)
>>     >              goto clear;
>>     >          type_mro_meth = lookup_maybe_method(
>>     >              (PyObject *)&PyType_Type, &PyId_mro, &unbound);
>>     >          if (type_mro_meth == NULL)
>>     >              goto clear;
>>     >          if (mro_meth != type_mro_meth)
>>     >              goto clear;
>>     >          Py_XDECREF(mro_meth);
>>     >          Py_XDECREF(type_mro_meth);
>>     >      }
>>     >
>>     >
>>     > Look at the "if (custom)" clause.
>>     > "mro_meth = lookup_maybe_method(" uses lookup_maybe_method which
>>     > gives a borrowed reference. The same holds for "type_mro_meth".
>>     >
>>     > But then both are decreffed, which IMHO is not correct.
>>     >
>>     Look at what happens at the label "clear": it DECREFs them.
>>
>>     If mro_meth != NULL or mro_meth != type_mro_meth, they'll get DECREFed
>>     at "clear".
>>
>>
>> I believe Christian's point is that this entire "if (custom) {" branch
>> looks suspicious, as it assumes "lookup_maybe_method" will increment the
>> refcount on the returned object. If that assumption is incorrect, we're
>> going to get DECREFs without a preceding INCREF.
>>
>> The specific code path is also obscure enough that it's plausible the
>> test suite may not currently cover it (as it requires doing something
>> that calls "type_mro_modified" on a type with a custom metaclass).
> 
> Thanks Nick for this nice analysis. And it's exactly this codepath that
> is taken in the case of PySide: custom types all the time :-)
> 
> what-a-relief - ly y'rs -- Chris
> 
> 
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/5MTJC47BHGZW6RKKU5JDAIFLV5P6W6JA/
> Code of Conduct: http://python.org/psf/codeofconduct/
> 


-- 
Christian Tismer             :^)   tis...@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

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/5PBHW3HEQQ4KLRUATZ7YGX5TR3T24R4C/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to