@@ -533,16 +533,19 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
533
533
{
534
534
continue ;
535
535
}
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
+ }
536
541
PyObject *extra_value = PyDict_GetItem (kwargs, child->_clean_name ); // - borrowed ref +/- 0
537
542
PyDict_SetItem (extras, child->_clean_name , extra_value); // +1
538
543
PyDict_DelItem (kwargs, child->_clean_name ); // -1
539
544
}
540
545
541
546
if (PyDict_Size (extras) == 0 )
542
547
{
543
- Py_DECREF (clz); // 1->0
544
- clz = PyObject_GetAttrString (config->classes , " UnknownObject" ); // 0->1
545
- PyDict_SetItemString (kwargs, " __node__" , (PyObject *)node);
548
+ goto PARSE_CLASS_UNKNOWN;
546
549
}
547
550
548
551
instance = PyObject_Call (clz, args, kwargs);
@@ -551,23 +554,29 @@ inline PyObject *parse_class(PyObject *kwargs, TypeTreeNodeObject *node, TypeTre
551
554
pos = 0 ;
552
555
while (PyDict_Next (extras, &pos, &key, &value))
553
556
{
554
- PyObject_GenericSetAttr (instance, key, value);
557
+ if (PyObject_GenericSetAttr (instance, key, value) != 0 )
558
+ {
559
+ Py_DECREF (instance);
560
+ goto PARSE_CLASS_UNKNOWN;
561
+ }
555
562
}
556
- goto PARSE_CLASS_CLEANUP;
557
563
}
558
- PyErr_Clear ();
559
-
560
- // if we still failed to create an instance, fallback to UnknownObject
561
- Py_DECREF (clz);
562
- clz = PyObject_GetAttrString (config->classes , " UnknownObject" );
563
- PyDict_SetItemString (kwargs, " __node__" , (PyObject *)node);
564
- // merge extras back into kwargs
565
- pos = 0 ;
566
- while (PyDict_Next (extras, &pos, &key, &value))
564
+ else
567
565
{
568
- PyDict_SetItem (kwargs, key, value);
566
+ PARSE_CLASS_UNKNOWN:
567
+ PyErr_Clear ();
568
+ // if we still failed to create an instance, fallback to UnknownObject
569
+ Py_DECREF (clz);
570
+ clz = PyObject_GetAttrString (config->classes , " UnknownObject" );
571
+ PyDict_SetItemString (kwargs, " __node__" , (PyObject *)node);
572
+ // merge extras back into kwargs
573
+ pos = 0 ;
574
+ while (PyDict_Next (extras, &pos, &key, &value))
575
+ {
576
+ PyDict_SetItem (kwargs, key, value);
577
+ }
578
+ instance = PyObject_Call (clz, args, kwargs);
569
579
}
570
- instance = PyObject_Call (clz, args, kwargs);
571
580
572
581
PARSE_CLASS_CLEANUP:
573
582
Py_DECREF (args);
@@ -852,7 +861,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
852
861
{
853
862
value = read_class<swap, true >(reader, node, config);
854
863
}
855
- if (!config-> as_dict )
864
+ else
856
865
{
857
866
value = read_class<swap, false >(reader, node, config);
858
867
value = parse_class (value, node, config);
0 commit comments