@@ -2568,6 +2568,8 @@ _PyHeapType_GET_MEMBERS(PyHeapTypeObject* type)
25682568 return PyObject_GetItemData ((PyObject * )type );
25692569}
25702570
2571+ void * _PyMember_GetOffset (PyObject * obj , PyMemberDef * l );
2572+
25712573static int
25722574traverse_slots (PyTypeObject * type , PyObject * self , visitproc visit , void * arg )
25732575{
@@ -2578,7 +2580,7 @@ traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg)
25782580 mp = _PyHeapType_GET_MEMBERS ((PyHeapTypeObject * )type );
25792581 for (i = 0 ; i < n ; i ++ , mp ++ ) {
25802582 if (mp -> type == Py_T_OBJECT_EX ) {
2581- char * addr = ( char * ) self + mp -> offset ;
2583+ void * addr = _PyMember_GetOffset ( self , mp ) ;
25822584 PyObject * obj = * (PyObject * * )addr ;
25832585 if (obj != NULL ) {
25842586 int err = visit (obj , arg );
@@ -2653,7 +2655,7 @@ clear_slots(PyTypeObject *type, PyObject *self)
26532655 mp = _PyHeapType_GET_MEMBERS ((PyHeapTypeObject * )type );
26542656 for (i = 0 ; i < n ; i ++ , mp ++ ) {
26552657 if (mp -> type == Py_T_OBJECT_EX && !(mp -> flags & Py_READONLY )) {
2656- char * addr = ( char * ) self + mp -> offset ;
2658+ void * addr = _PyMember_GetOffset ( self , mp ) ;
26572659 PyObject * obj = * (PyObject * * )addr ;
26582660 if (obj != NULL ) {
26592661 * (PyObject * * )addr = NULL ;
@@ -4641,7 +4643,11 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type, PyObject *dict
46414643 if (et -> ht_slots != NULL ) {
46424644 PyMemberDef * mp = _PyHeapType_GET_MEMBERS (et );
46434645 Py_ssize_t nslot = PyTuple_GET_SIZE (et -> ht_slots );
4644- if (ctx -> base -> tp_itemsize != 0 ) {
4646+ int after_items = (ctx -> base -> tp_itemsize != 0 &&
4647+ !(ctx -> base -> tp_flags & Py_TPFLAGS_ITEMS_AT_END ));
4648+ if (ctx -> base -> tp_itemsize != 0 &&
4649+ !(ctx -> base -> tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS ))
4650+ {
46454651 PyErr_Format (PyExc_TypeError ,
46464652 "arbitrary __slots__ not supported for subtype of '%s'" ,
46474653 ctx -> base -> tp_name );
@@ -4655,6 +4661,9 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type, PyObject *dict
46554661 }
46564662 mp -> type = Py_T_OBJECT_EX ;
46574663 mp -> offset = slotoffset ;
4664+ if (after_items ) {
4665+ mp -> flags |= _Py_AFTER_ITEMS ;
4666+ }
46584667
46594668 /* __dict__ and __weakref__ are already filtered out */
46604669 assert (strcmp (mp -> name , "__dict__" ) != 0 );
0 commit comments