@@ -1278,11 +1278,16 @@ static int _test_audit(Py_ssize_t setValue)
12781278 printf ("Set event failed" );
12791279 return 4 ;
12801280 }
1281+ if (PyErr_Occurred ()) {
1282+ printf ("Exception raised" );
1283+ return 5 ;
1284+ }
12811285
12821286 if (sawSet != 42 ) {
12831287 printf ("Failed to see *userData change\n" );
1284- return 5 ;
1288+ return 6 ;
12851289 }
1290+
12861291 return 0 ;
12871292}
12881293
@@ -1296,6 +1301,57 @@ static int test_audit(void)
12961301 return result ;
12971302}
12981303
1304+ static int test_audit_tuple (void )
1305+ {
1306+ #define ASSERT (TEST , EXITCODE ) \
1307+ if (!(TEST)) { \
1308+ printf("ERROR test failed at %s:%i\n", __FILE__, __LINE__); \
1309+ return (EXITCODE); \
1310+ }
1311+
1312+ Py_ssize_t sawSet = 0 ;
1313+
1314+ // we need at least one hook, otherwise code checking for
1315+ // PySys_AuditTuple() is skipped.
1316+ PySys_AddAuditHook (_audit_hook , & sawSet );
1317+ _testembed_Py_InitializeFromConfig ();
1318+
1319+ ASSERT (!PyErr_Occurred (), 0 );
1320+
1321+ // pass Python tuple object
1322+ PyObject * tuple = Py_BuildValue ("(i)" , 444 );
1323+ if (tuple == NULL ) {
1324+ goto error ;
1325+ }
1326+ ASSERT (PySys_AuditTuple ("_testembed.set" , tuple ) == 0 , 10 );
1327+ ASSERT (!PyErr_Occurred (), 11 );
1328+ ASSERT (sawSet == 444 , 12 );
1329+ Py_DECREF (tuple );
1330+
1331+ // pass Python int object
1332+ PyObject * int_arg = PyLong_FromLong (555 );
1333+ if (int_arg == NULL ) {
1334+ goto error ;
1335+ }
1336+ ASSERT (PySys_AuditTuple ("_testembed.set" , int_arg ) == -1 , 20 );
1337+ ASSERT (PyErr_ExceptionMatches (PyExc_TypeError ), 21 );
1338+ PyErr_Clear ();
1339+ Py_DECREF (int_arg );
1340+
1341+ // NULL is accepted and means "no arguments"
1342+ ASSERT (PySys_AuditTuple ("_testembed.test_audit_tuple" , NULL ) == 0 , 30 );
1343+ ASSERT (!PyErr_Occurred (), 31 );
1344+
1345+ Py_Finalize ();
1346+ return 0 ;
1347+
1348+ error :
1349+ PyErr_Print ();
1350+ return 1 ;
1351+
1352+ #undef ASSERT
1353+ }
1354+
12991355static volatile int _audit_subinterpreter_interpreter_count = 0 ;
13001356
13011357static int _audit_subinterpreter_hook (const char * event , PyObject * args , void * userdata )
@@ -2140,6 +2196,7 @@ static struct TestCase TestCases[] = {
21402196 // Audit
21412197 {"test_open_code_hook" , test_open_code_hook },
21422198 {"test_audit" , test_audit },
2199+ {"test_audit_tuple" , test_audit_tuple },
21432200 {"test_audit_subinterpreter" , test_audit_subinterpreter },
21442201 {"test_audit_run_command" , test_audit_run_command },
21452202 {"test_audit_run_file" , test_audit_run_file },
0 commit comments