Skip to content

Commit 88bef6c

Browse files
fangerertimfel
authored andcommitted
Fix slot precedence wrt installed attributes
1 parent aaa15de commit 88bef6c

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

graalpython/com.oracle.graal.python.cext/src/typeobject.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,12 @@ int PyType_Ready(PyTypeObject* cls) {
538538
type_ready_set_new(cls, dict, base);
539539

540540
/* fill dict */
541+
542+
/*
543+
* NOTE: ADD_SLOT_CONV won't overwrite existing attributes, so the order is crucial and must
544+
* reflect CPython's 'slotdefs' array.
545+
*/
546+
541547
// add special methods defined directly on the type structs
542548
ADD_SLOT_CONV("__dealloc__", cls->tp_dealloc, -1, JWRAPPER_DIRECT);
543549
// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_getattr
@@ -583,20 +589,7 @@ int PyType_Ready(PyTypeObject* cls) {
583589
ADD_SLOT_CONV("__del__", cls->tp_del, -1, JWRAPPER_DIRECT);
584590
ADD_SLOT_CONV("__finalize__", cls->tp_finalize, -1, JWRAPPER_DIRECT);
585591

586-
PySequenceMethods* sequences = PyTypeObject_tp_as_sequence(cls);
587-
if (sequences) {
588-
// sequence functions first, so that the number functions take precendence
589-
ADD_SLOT_CONV("__len__", sequences->sq_length, -1, JWRAPPER_LENFUNC);
590-
ADD_SLOT_CONV("__add__", sequences->sq_concat, -2, JWRAPPER_BINARYFUNC);
591-
ADD_SLOT_CONV("__mul__", sequences->sq_repeat, -2, JWRAPPER_SSIZE_ARG);
592-
ADD_SLOT_CONV("__getitem__", sequences->sq_item, -2, JWRAPPER_GETITEM);
593-
ADD_SLOT_CONV("__setitem__", sequences->sq_ass_item, -3, JWRAPPER_SETITEM);
594-
ADD_SLOT_CONV("__delitem__", sequences->sq_ass_item, -3, JWRAPPER_DELITEM);
595-
ADD_SLOT_CONV("__contains__", sequences->sq_contains, -2, JWRAPPER_OBJOBJPROC);
596-
ADD_SLOT_CONV("__iadd__", sequences->sq_inplace_concat, -2, JWRAPPER_BINARYFUNC);
597-
ADD_SLOT_CONV("__imul__", sequences->sq_inplace_repeat, -2, JWRAPPER_SSIZE_ARG);
598-
}
599-
592+
// 'tp_as_number' takes precedence over 'tp_as_mapping' and 'tp_as_sequence' !
600593
PyNumberMethods* numbers = PyTypeObject_tp_as_number(cls);
601594
if (numbers) {
602595
ADD_SLOT_CONV("__add__", numbers->nb_add, -2, JWRAPPER_BINARYFUNC_L);
@@ -650,6 +643,7 @@ int PyType_Ready(PyTypeObject* cls) {
650643
ADD_SLOT_CONV("__imatmul__", numbers->nb_inplace_matrix_multiply, -2, JWRAPPER_BINARYFUNC_L);
651644
}
652645

646+
// 'tp_as_mapping' takes precedence over 'tp_as_sequence' !
653647
PyMappingMethods* mappings = PyTypeObject_tp_as_mapping(cls);
654648
if (mappings) {
655649
ADD_SLOT_CONV("__len__", mappings->mp_length, -1, JWRAPPER_LENFUNC);
@@ -658,6 +652,20 @@ int PyType_Ready(PyTypeObject* cls) {
658652
ADD_SLOT_CONV("__delitem__", mappings->mp_ass_subscript, -3, JWRAPPER_MP_DELITEM);
659653
}
660654

655+
PySequenceMethods* sequences = PyTypeObject_tp_as_sequence(cls);
656+
if (sequences) {
657+
// sequence functions first, so that the number functions take precendence
658+
ADD_SLOT_CONV("__len__", sequences->sq_length, -1, JWRAPPER_LENFUNC);
659+
ADD_SLOT_CONV("__add__", sequences->sq_concat, -2, JWRAPPER_BINARYFUNC);
660+
ADD_SLOT_CONV("__mul__", sequences->sq_repeat, -2, JWRAPPER_SSIZE_ARG);
661+
ADD_SLOT_CONV("__getitem__", sequences->sq_item, -2, JWRAPPER_GETITEM);
662+
ADD_SLOT_CONV("__setitem__", sequences->sq_ass_item, -3, JWRAPPER_SETITEM);
663+
ADD_SLOT_CONV("__delitem__", sequences->sq_ass_item, -3, JWRAPPER_DELITEM);
664+
ADD_SLOT_CONV("__contains__", sequences->sq_contains, -2, JWRAPPER_OBJOBJPROC);
665+
ADD_SLOT_CONV("__iadd__", sequences->sq_inplace_concat, -2, JWRAPPER_BINARYFUNC);
666+
ADD_SLOT_CONV("__imul__", sequences->sq_inplace_repeat, -2, JWRAPPER_SSIZE_ARG);
667+
}
668+
661669
PyAsyncMethods* async = PyTypeObject_tp_as_async(cls);
662670
if (async) {
663671
ADD_SLOT_CONV("__await__", async->am_await, -1, JWRAPPER_DIRECT);

0 commit comments

Comments
 (0)