This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: string_richcompare invalid check Py_NotImplemented
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: serhiy.storchaka, yuriy_levchenko
Priority: normal Keywords:

Created on 2016-02-23 14:49 by yuriy_levchenko, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg260738 - (view) Author: yuriy_levchenko (yuriy_levchenko) Date: 2016-02-23 14:49
i have object with flag Py_TPFLAGS_STRING_SUBCLASS

stringobject.c (line 1192) in function string_richcompare

we have check string PyString_Check

but,

#define PyString_Check(op) \
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_STRING_SUBCLASS)

i successful check this. But my type is not PyStringObject

Maybe need replace this check on PyString_CheckExact?
msg260794 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-02-24 12:05
If your type is not PyStringObject, why it has the Py_TPFLAGS_STRING_SUBCLASS flag set?
msg260893 - (view) Author: yuriy_levchenko (yuriy_levchenko) Date: 2016-02-26 12:03
because,

PyObject_GetAttr(PyObject *v, PyObject *name)

have this code

if (!PyString_Check(name)) {

and 

PyDict_GetItem(PyObject *op, PyObject *key)

have this code

    if (!PyString_CheckExact(key) ||
        (hash = ((PyStringObject *) key)->ob_shash) == -1)
    {
        hash = PyObject_Hash(key);

next

lookdict_string(PyDictObject *mp, PyObject *key, register long hash)

    if (!PyString_CheckExact(key)) {
#ifdef SHOW_CONVERSION_COUNTS
        ++converted;
#endif
        mp->ma_lookup = lookdict;
        return lookdict(mp, key, hash);
    }

next

PyObject_RichCompare(PyObject *v, PyObject *w, int op)

and 

try_rich_compare(PyObject *v, PyObject *w, int op)

we have this code

    if ((f = RICHCOMPARE(v->ob_type)) != NULL) {
        res = (*f)(v, w, op);
        if (res != Py_NotImplemented)
            return res;
        Py_DECREF(res);
    }
    if ((f = RICHCOMPARE(w->ob_type)) != NULL) {
        return (*f)(w, v, _Py_SwappedOp[op]);
    }

v - PyStringObject
w - MyType

MyType have Py_TPFLAGS_HAVE_RICHCOMPARE and correct test with PyStringObject

but string_richcompare incorrect test type for object, and this code

a->ob_sval 

may cause "access violation" and crach!

if i replace PyString_Check on PyString_CheckExact, all work fine and correct!
msg260927 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-02-27 07:33
PyDict_GetItem and lookdict_string use PyString_CheckExact for fast path. String subclasses are proceeded in general way. PyObject_GetAttr and string_richcompare use PyString_Check because they work with string and string subclasses. Py_TPFLAGS_STRING_SUBCLASS shouldn't be used if the type is not string subclass.
History
Date User Action Args
2022-04-11 14:58:27adminsetgithub: 70608
2016-02-27 07:33:15serhiy.storchakasetstatus: open -> closed
resolution: not a bug
messages: + msg260927

stage: resolved
2016-02-26 12:03:48yuriy_levchenkosetmessages: + msg260893
2016-02-24 12:05:44serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg260794
2016-02-23 14:49:58yuriy_levchenkocreate