Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0ca0240

Browse files
committed
gh-85283: Add PySys_AuditTuple() function
sys.audit() now has assertions to check that the event argument isnot NULL and that the format argument does not use the "N" format.Add tests on PySys_AuditTuple().
1 parentfb6c4ed commit0ca0240

File tree

7 files changed

+109
-9
lines changed

7 files changed

+109
-9
lines changed

‎Doc/c-api/sys.rst

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,19 +291,24 @@ accessible to C code. They all work with the current interpreter thread's
291291
Raise an auditing event with any active hooks. Return zero for success
292292
and non-zero with an exception set on failure.
293293
294+
The *event* string argument must not be *NULL*.
295+
294296
If any hooks have been added, *format* and other arguments will be used
295297
to construct a tuple to pass. Apart from ``N``, the same format characters
296298
as used in:c:func:`Py_BuildValue` are available. If the built value is not
297-
a tuple, it will be added into a single-element tuple. (The ``N`` format
298-
option consumes a reference, but since there is no way to know whether
299-
arguments to this function will be consumed, using it may cause reference
300-
leaks.)
299+
a tuple, it will be added into a single-element tuple.
300+
301+
The ``N`` format option must not be used. It consumes a reference, but since
302+
there is no way to know whether arguments to this function will be consumed,
303+
using it may cause reference leaks.
301304
302305
Note that ``#`` format characters should always be treated as
303306
:c:type:`Py_ssize_t`, regardless of whether ``PY_SSIZE_T_CLEAN`` was defined.
304307
305308
:func:`sys.audit` performs the same function from Python code.
306309
310+
See also:c:func:`PySys_AuditTuple`.
311+
307312
..versionadded::3.8
308313
309314
..versionchanged::3.8.2
@@ -312,6 +317,14 @@ accessible to C code. They all work with the current interpreter thread's
312317
unavoidable deprecation warning was raised.
313318
314319
320+
..c:function::intPySys_AuditTuple(const char *event, PyObject *args)
321+
322+
Similar to:c:func:`PySys_Audit`, but pass arguments as a Python object.
323+
*args* must be a:class:`tuple`. To pass no arguments, *args* can be *NULL*.
324+
325+
..versionadded::3.13
326+
327+
315328
..c:function::intPySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
316329
317330
Append the callable *hook* to the list of active auditing hooks.

‎Doc/whatsnew/3.13.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,10 @@ New Features
10131013
``_PyThreadState_UncheckedGet()``.
10141014
(Contributed by Victor Stinner in:gh:`108867`.)
10151015

1016+
* Add:c:func:`PySys_AuditTuple` function: similar to:c:func:`PySys_Audit`,
1017+
but pass event arguments as a Python:class:`tuple` object.
1018+
(Contributed by Victor Stinner in:gh:`85283`.)
1019+
10161020
Porting to Python 3.13
10171021
----------------------
10181022

‎Include/cpython/sysmodule.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
66

77
PyAPI_FUNC(int)PySys_Audit(
88
constchar*event,
9-
constchar*argFormat,
9+
constchar*format,
1010
...);
1111
PyAPI_FUNC(int)PySys_AddAuditHook(Py_AuditHookFunction,void*);
12+
13+
PyAPI_FUNC(int)PySys_AuditTuple(
14+
constchar*event,
15+
PyObject*args);

‎Lib/test/test_embed.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,6 +1716,9 @@ def test_open_code_hook(self):
17161716
deftest_audit(self):
17171717
self.run_embedded_interpreter("test_audit")
17181718

1719+
deftest_audit_tuple(self):
1720+
self.run_embedded_interpreter("test_audit_tuple")
1721+
17191722
deftest_audit_subinterpreter(self):
17201723
self.run_embedded_interpreter("test_audit_subinterpreter")
17211724

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add:c:func:`PySys_AuditTuple` function: similar to:c:func:`PySys_Audit`,
2+
but pass event arguments as a Python:class:`tuple` object. Patch by Victor
3+
Stinner.

‎Programs/_testembed.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,11 +1278,16 @@ static int _test_audit(Py_ssize_t setValue)
12781278
printf("Set event failed");
12791279
return4;
12801280
}
1281+
if (PyErr_Occurred()) {
1282+
printf("Exception raised");
1283+
return5;
1284+
}
12811285

12821286
if (sawSet!=42) {
12831287
printf("Failed to see *userData change\n");
1284-
return5;
1288+
return6;
12851289
}
1290+
12861291
return0;
12871292
}
12881293

@@ -1296,6 +1301,57 @@ static int test_audit(void)
12961301
returnresult;
12971302
}
12981303

1304+
staticinttest_audit_tuple(void)
1305+
{
1306+
#defineASSERT(TEST,EXITCODE) \
1307+
if (!(TEST)) { \
1308+
printf("ERROR test failed at %s:%i\n", __FILE__, __LINE__); \
1309+
return (EXITCODE); \
1310+
}
1311+
1312+
Py_ssize_tsawSet=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+
gotoerror;
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+
gotoerror;
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+
return0;
1347+
1348+
error:
1349+
PyErr_Print();
1350+
return1;
1351+
1352+
#undef ASSERT
1353+
}
1354+
12991355
staticvolatileint_audit_subinterpreter_interpreter_count=0;
13001356

13011357
staticint_audit_subinterpreter_hook(constchar*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},

‎Python/sysmodule.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,7 @@ static int
191191
sys_audit_tstate(PyThreadState*ts,constchar*event,
192192
constchar*argFormat,va_listvargs)
193193
{
194-
/* N format is inappropriate, because you do not know
195-
whether the reference is consumed by the call.
196-
Assert rather than exception for perf reasons */
194+
assert(event!=NULL);
197195
assert(!argFormat|| !strchr(argFormat,'N'));
198196

199197
if (!ts) {
@@ -338,6 +336,21 @@ PySys_Audit(const char *event, const char *argFormat, ...)
338336
returnres;
339337
}
340338

339+
int
340+
PySys_AuditTuple(constchar*event,PyObject*args)
341+
{
342+
if (args==NULL) {
343+
returnPySys_Audit(event,NULL);
344+
}
345+
346+
if (!PyTuple_Check(args)) {
347+
PyErr_Format(PyExc_TypeError,"args must be tuple, got %s",
348+
Py_TYPE(args)->tp_name);
349+
return-1;
350+
}
351+
returnPySys_Audit(event,"O",args);
352+
}
353+
341354
/* We expose this function primarily for our own cleanup during
342355
* finalization. In general, it should not need to be called,
343356
* and as such the function is not exported.
@@ -509,6 +522,9 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
509522
returnNULL;
510523
}
511524

525+
assert(args[0]!=NULL);
526+
assert(PyUnicode_Check(args[0]));
527+
512528
if (!should_audit(tstate->interp)) {
513529
Py_RETURN_NONE;
514530
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp