@@ -180,12 +180,12 @@ inline PyObject *read_pair(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeRe
180
180
return NULL ;
181
181
}
182
182
183
- PyObject *first = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GetItem (node->m_Children , 0 ), config);
183
+ PyObject *first = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GET_ITEM (node->m_Children , 0 ), config);
184
184
if (!first)
185
185
{
186
186
return NULL ;
187
187
}
188
- PyObject *second = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GetItem (node->m_Children , 1 ), config);
188
+ PyObject *second = read_typetree_value<swap>(reader, (TypeTreeNodeObject *)PyList_GET_ITEM (node->m_Children , 1 ), config);
189
189
if (!second)
190
190
{
191
191
Py_DECREF (first);
@@ -198,10 +198,9 @@ inline PyObject *read_pair(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeRe
198
198
}
199
199
200
200
template <bool swap>
201
- inline PyObject *read_class (ReaderT *reader, TypeTreeNodeObject *node, TypeTreeReaderConfigT *config)
201
+ inline PyObject *parse_class (ReaderT *reader, PyObject *dict , TypeTreeNodeObject *node, TypeTreeReaderConfigT *config)
202
202
{
203
203
PyObject *clz = NULL ;
204
- PyObject *dict = PyDict_New ();
205
204
206
205
// Determine the class based on node's _data_type
207
206
if (node->_data_type == NodeDataType::pptr)
@@ -223,47 +222,38 @@ inline PyObject *read_class(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeR
223
222
}
224
223
}
225
224
225
+ // check if class is found
226
226
if (clz == NULL )
227
227
{
228
228
PyErr_SetString (PyExc_ValueError, " Failed to get class" );
229
+ Py_DECREF (clz);
229
230
Py_DECREF (dict);
230
231
return NULL ;
231
232
}
232
233
233
- for (int i = 0 ; i < PyList_GET_SIZE (node->m_Children ); i++)
234
- {
235
- TypeTreeNodeObject *child = (TypeTreeNodeObject *)PyList_GetItem (node->m_Children , i);
236
- PyObject *child_value = read_typetree_value<swap>(reader, child, config);
237
- if (!child_value)
238
- {
239
- Py_DECREF (dict);
240
- return NULL ;
241
- }
242
- if (PyDict_SetItem (dict, child->m_Name , child_value))
243
- {
244
- Py_DECREF (dict);
245
- Py_DECREF (child_value);
246
- return NULL ;
247
- }
248
- // dict increases ref count, so we need to decref here
249
- Py_DECREF (child_value);
250
- }
251
-
234
+ // try to create class instance
252
235
PyObject *args = PyTuple_New (0 );
253
236
PyObject *instance = PyObject_Call (clz, args, dict);
254
237
if (instance != NULL )
255
238
{
239
+ // success
240
+ // cleanup
241
+ Py_DECREF (clz);
256
242
Py_DECREF (args);
257
243
Py_DECREF (dict);
244
+ // return instance
258
245
return instance;
259
246
}
247
+ // failed, clear error
260
248
PyErr_Clear ();
261
249
250
+ // clean key names
251
+ PyObject *key = NULL ;
262
252
PyObject *keys = PyDict_Keys (dict);
263
253
PyObject *clean_args = PyTuple_New (1 );
264
- for (Py_ssize_t i = 0 ; i < PyList_Size (keys); i++)
254
+ for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (keys); i++)
265
255
{
266
- PyObject * key = PyList_GetItem (keys, i);
256
+ key = PyList_GET_ITEM (keys, i);
267
257
PyTuple_SET_ITEM (clean_args, 0 , key);
268
258
PyObject *clean_key = PyObject_Call (config->clean_name , clean_args, NULL );
269
259
if (PyUnicode_Compare (key, clean_key))
@@ -274,25 +264,33 @@ inline PyObject *read_class(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeR
274
264
}
275
265
Py_DECREF (clean_key);
276
266
}
277
- PyTuple_SET_ITEM (clean_args, 0 , Py_None);
267
+ // increase ref count for key, as PyTuple_SET_ITEM steals reference, so decref there will decref key
268
+ Py_INCREF (key);
278
269
Py_DECREF (clean_args);
279
270
Py_DECREF (keys);
280
271
272
+ // try to create class instance again with cleaned keys
281
273
instance = PyObject_Call (clz, args, dict);
282
274
if (instance != NULL )
283
275
{
276
+ // success
277
+ // cleanup
278
+ Py_DECREF (clz);
284
279
Py_DECREF (args);
285
280
Py_DECREF (dict);
281
+ // return instance
286
282
return instance;
287
283
}
284
+ // failed, clear error
288
285
PyErr_Clear ();
289
286
287
+ // some keys might be extra, check against __annotations__
290
288
PyObject *annonations = PyObject_GetAttrString (clz, " __annotations__" );
291
289
PyObject *extras = PyDict_New ();
292
290
keys = PyDict_Keys (dict);
293
291
for (Py_ssize_t i = 0 ; i < PyList_Size (keys); i++)
294
292
{
295
- PyObject *key = PyList_GetItem (keys, i);
293
+ PyObject *key = PyList_GET_ITEM (keys, i);
296
294
if (PyDict_Contains (annonations, key) == 0 )
297
295
{
298
296
PyObject *value = PyDict_GetItem (dict, key);
@@ -301,21 +299,29 @@ inline PyObject *read_class(ReaderT *reader, TypeTreeNodeObject *node, TypeTreeR
301
299
}
302
300
}
303
301
Py_DECREF (keys);
302
+ Py_DECREF (annonations);
304
303
304
+ // try to create class instance again with cleaned keys
305
305
instance = PyObject_Call (clz, args, dict);
306
306
if (instance != NULL )
307
307
{
308
+ // success, manually set extra keys
308
309
PyObject *items = PyDict_Items (extras);
309
310
for (Py_ssize_t i = 0 ; i < PyList_Size (items); i++)
310
311
{
311
- PyObject *item = PyList_GetItem (items, i);
312
+ PyObject *item = PyList_GET_ITEM (items, i);
312
313
PyObject *key = PyTuple_GetItem (item, 0 );
313
314
PyObject *value = PyTuple_GetItem (item, 1 );
314
315
PyObject_SetAttr (instance, key, value);
315
316
}
316
317
Py_DECREF (items);
317
318
}
318
-
319
+ // cleanup
320
+ Py_DECREF (clz);
321
+ Py_DECREF (args);
322
+ Py_DECREF (dict);
323
+ Py_DECREF (extras);
324
+ // return instance or NULL if failed
319
325
return instance;
320
326
}
321
327
@@ -373,7 +379,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
373
379
TypeTreeNodeObject *child = nullptr ;
374
380
if (PyList_GET_SIZE (node->m_Children ) > 0 )
375
381
{
376
- child = (TypeTreeNodeObject *)PyList_GetItem (node->m_Children , 0 );
382
+ child = (TypeTreeNodeObject *)PyList_GET_ITEM (node->m_Children , 0 );
377
383
}
378
384
379
385
if (child && child->_data_type == NodeDataType::array)
@@ -389,7 +395,7 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
389
395
return NULL ;
390
396
}
391
397
value = PyList_New (length);
392
- child = (TypeTreeNodeObject *)PyList_GetItem (child->m_Children , 1 );
398
+ child = (TypeTreeNodeObject *)PyList_GET_ITEM (child->m_Children , 1 );
393
399
for (int i = 0 ; i < length; i++)
394
400
{
395
401
PyObject *item = read_typetree_value<swap>(reader, child, config);
@@ -405,30 +411,27 @@ PyObject *read_typetree_value(ReaderT *reader, TypeTreeNodeObject *node, TypeTre
405
411
{
406
412
// class
407
413
value = PyDict_New ();
408
- if (config-> as_dict )
414
+ for ( int i = 0 ; i < PyList_GET_SIZE (node-> m_Children ); i++ )
409
415
{
410
- for (int i = 0 ; i < PyList_GET_SIZE (node->m_Children ); i++)
416
+ child = (TypeTreeNodeObject *)PyList_GET_ITEM (node->m_Children , i);
417
+ PyObject *child_value = read_typetree_value<swap>(reader, child, config);
418
+ if (!child_value)
411
419
{
412
- child = (TypeTreeNodeObject *)PyList_GetItem (node->m_Children , i);
413
- PyObject *child_value = read_typetree_value<swap>(reader, child, config);
414
- if (!child_value)
415
- {
416
- Py_DECREF (value);
417
- return NULL ;
418
- }
419
- if (PyDict_SetItem (value, child->m_Name , child_value))
420
- {
421
- Py_DECREF (value);
422
- Py_DECREF (child_value);
423
- return NULL ;
424
- }
425
- // dict increases ref count, so we need to decref here
420
+ Py_DECREF (value);
421
+ return NULL ;
422
+ }
423
+ if (PyDict_SetItem (value, child->m_Name , child_value))
424
+ {
425
+ Py_DECREF (value);
426
426
Py_DECREF (child_value);
427
+ return NULL ;
427
428
}
429
+ // dict increases ref count, so we need to decref here
430
+ Py_DECREF (child_value);
428
431
}
429
- else
432
+ if (!config-> as_dict )
430
433
{
431
- value = read_class <swap>(reader, node, config);
434
+ value = parse_class <swap>(reader, value , node, config);
432
435
}
433
436
}
434
437
}
@@ -481,6 +484,9 @@ PyObject *read_typetree(PyObject *self, PyObject *args, PyObject *kwargs)
481
484
return NULL ;
482
485
}
483
486
}
487
+ Py_INCREF (config.assetfile );
488
+ Py_INCREF (config.classes );
489
+ Py_INCREF (config.clean_name );
484
490
485
491
volatile uint16_t bint = 0x0100 ;
486
492
volatile bool is_big_endian = ((uint8_t *)&bint)[0 ] == 1 ;
@@ -626,14 +632,13 @@ static int TypeTreeNode_init(TypeTreeNodeObject *self, PyObject *args, PyObject
626
632
Py_XINCREF (self->m_Children );
627
633
}
628
634
629
- #define SET_NONE_IF_NULL (field ) \
630
- if (self->field == nullptr ) \
631
- { \
632
- self->field = Py_None; \
633
- } \
634
- else \
635
- { \
636
- Py_INCREF (self->field ); \
635
+ #define SET_NONE_IF_NULL (field ) \
636
+ { \
637
+ if (self->field == nullptr ) \
638
+ { \
639
+ self->field = Py_None; \
640
+ } \
641
+ Py_INCREF (self->field ); \
637
642
}
638
643
639
644
SET_NONE_IF_NULL (m_TypeFlags);
0 commit comments