@@ -386,6 +386,23 @@ test_gc(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
386
386
}
387
387
388
388
389
+ static int
390
+ check_module_attr (PyObject * module , const char * name , PyObject * expected )
391
+ {
392
+ PyObject * attr = PyObject_GetAttrString (module , name );
393
+ if (attr == _Py_NULL ) {
394
+ return -1 ;
395
+ }
396
+ assert (attr == expected );
397
+ Py_DECREF (attr );
398
+
399
+ if (PyObject_DelAttrString (module , name ) < 0 ) {
400
+ return -1 ;
401
+ }
402
+ return 0 ;
403
+ }
404
+
405
+
389
406
// test PyModule_AddType()
390
407
static int
391
408
test_module_add_type (PyObject * module )
@@ -407,14 +424,7 @@ test_module_add_type(PyObject *module)
407
424
ASSERT_REFCNT (Py_REFCNT (type ) == refcnt + 1 );
408
425
#endif
409
426
410
- PyObject * attr = PyObject_GetAttrString (module , type_name );
411
- if (attr == _Py_NULL ) {
412
- return -1 ;
413
- }
414
- assert (attr == _Py_CAST (PyObject * , type ));
415
- Py_DECREF (attr );
416
-
417
- if (PyObject_DelAttrString (module , type_name ) < 0 ) {
427
+ if (check_module_attr (module , type_name , _Py_CAST (PyObject * , type )) < 0 ) {
418
428
return -1 ;
419
429
}
420
430
ASSERT_REFCNT (Py_REFCNT (type ) == refcnt );
@@ -426,30 +436,70 @@ test_module_add_type(PyObject *module)
426
436
static int
427
437
test_module_addobjectref (PyObject * module )
428
438
{
429
- PyObject * obj = Py_True ;
430
439
const char * name = "test_module_addobjectref" ;
440
+ PyObject * obj = PyUnicode_FromString (name );
441
+ assert (obj != NULL );
431
442
#ifdef CHECK_REFCNT
432
443
Py_ssize_t refcnt = Py_REFCNT (obj );
433
444
#endif
434
445
435
446
if (PyModule_AddObjectRef (module , name , obj ) < 0 ) {
436
447
ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt );
448
+ Py_DECREF (obj );
437
449
return -1 ;
438
450
}
439
- #ifndef IMMORTAL_OBJS
440
451
ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt + 1 );
441
- #endif
442
452
443
- if (PyObject_DelAttrString (module , name ) < 0 ) {
453
+ if (check_module_attr (module , name , obj ) < 0 ) {
454
+ Py_DECREF (obj );
444
455
return -1 ;
445
456
}
446
457
ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt );
447
458
448
459
// PyModule_AddObjectRef() with value=NULL must not crash
460
+ assert (!PyErr_Occurred ());
449
461
int res = PyModule_AddObjectRef (module , name , _Py_NULL );
450
462
assert (res < 0 );
463
+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
464
+ PyErr_Clear ();
465
+
466
+ Py_DECREF (obj );
467
+ return 0 ;
468
+ }
469
+
470
+
471
+ // test PyModule_Add()
472
+ static int
473
+ test_module_add (PyObject * module )
474
+ {
475
+ const char * name = "test_module_add" ;
476
+ PyObject * obj = PyUnicode_FromString (name );
477
+ assert (obj != NULL );
478
+ #ifdef CHECK_REFCNT
479
+ Py_ssize_t refcnt = Py_REFCNT (obj );
480
+ #endif
481
+
482
+ if (PyModule_Add (module , name , Py_NewRef (obj )) < 0 ) {
483
+ ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt );
484
+ Py_DECREF (obj );
485
+ return -1 ;
486
+ }
487
+ ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt + 1 );
488
+
489
+ if (check_module_attr (module , name , obj ) < 0 ) {
490
+ Py_DECREF (obj );
491
+ return -1 ;
492
+ }
493
+ ASSERT_REFCNT (Py_REFCNT (obj ) == refcnt );
494
+
495
+ // PyModule_Add() with value=NULL must not crash
496
+ assert (!PyErr_Occurred ());
497
+ int res = PyModule_Add (module , name , _Py_NULL );
498
+ assert (res < 0 );
499
+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
451
500
PyErr_Clear ();
452
501
502
+ Py_DECREF (obj );
453
503
return 0 ;
454
504
}
455
505
@@ -458,18 +508,20 @@ static PyObject *
458
508
test_module (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (ignored ))
459
509
{
460
510
PyObject * module = PyImport_ImportModule ("sys" );
461
- if (module == _Py_NULL ) {
462
- return _Py_NULL ;
511
+ if (module == NULL ) {
512
+ return NULL ;
463
513
}
464
514
assert (PyModule_Check (module ));
465
515
466
516
if (test_module_add_type (module ) < 0 ) {
467
517
goto error ;
468
518
}
469
-
470
519
if (test_module_addobjectref (module ) < 0 ) {
471
520
goto error ;
472
521
}
522
+ if (test_module_add (module ) < 0 ) {
523
+ goto error ;
524
+ }
473
525
474
526
Py_DECREF (module );
475
527
Py_RETURN_NONE ;
0 commit comments