@@ -485,6 +485,8 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
485485 // dict iterator values
486486 PyObject *key, *value = nullptr ;
487487 Py_ssize_t pos;
488+ // slots check
489+ PyObject *slots = nullptr ;
488490
489491 if (node->_data_type == NodeDataType::PPtr)
490492 {
@@ -518,6 +520,16 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
518520 }
519521 PyErr_Clear ();
520522
523+ // if __slots__ is defined, setattr for non-slots attributes will fail
524+ // so we can skip the extra field check
525+ slots = PyObject_GetAttrString (clz, " __slots__" );
526+ if (PyTuple_Check (slots) && PyTuple_GET_SIZE (slots) > 0 )
527+ {
528+ Py_XDECREF (slots);
529+ goto PARSE_CLASS_UNKNOWN;
530+ }
531+ Py_XDECREF (slots);
532+
521533 // possibly extra fields
522534 annotations = get_annotations (clz);
523535 if (annotations == nullptr )
@@ -533,11 +545,6 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
533545 {
534546 continue ;
535547 }
536- if (PyObject_HasAttrString (clz, " __slots__" ))
537- {
538- // if __slots__ is defined, setattr for non-slots attributes will fail
539- goto PARSE_CLASS_UNKNOWN;
540- }
541548 PyObject *extra_value = PyDict_GetItem (kwargs, child->_clean_name ); // - borrowed ref +/- 0
542549 PyDict_SetItem (extras, child->_clean_name , extra_value); // +1
543550 PyDict_DelItem (kwargs, child->_clean_name ); // -1
@@ -570,10 +577,13 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
570577 clz = PyObject_GetAttrString (config->classes , " UnknownObject" );
571578 PyDict_SetItemString (kwargs, " __node__" , (PyObject *)node);
572579 // merge extras back into kwargs
573- pos = 0 ;
574- while (PyDict_Next (extras, &pos, &key, &value))
580+ if (extras != nullptr )
575581 {
576- PyDict_SetItem (kwargs, key, value);
582+ pos = 0 ;
583+ while (PyDict_Next (extras, &pos, &key, &value))
584+ {
585+ PyDict_SetItem (kwargs, key, value);
586+ }
577587 }
578588 instance = PyObject_Call (clz, args, kwargs);
579589 }
0 commit comments