Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9a2c2a9

Browse files
authored
bpo-42800: add audit hooks for f_code and tb_frame (GH-24182)
Accessing the following attributes will now fire PEP 578 style audit hooks as ("object.__getattr__", obj, name): * PyTracebackObject: tb_frame * PyFrameObject: f_code * PyGenObject: gi_code, gi_frame * PyCoroObject: cr_code, cr_frame * PyAsyncGenObject: ag_code, ag_frame Add an AUDIT_READ attribute flag aliased to READ_RESTRICTED. Update obsolete flag documentation.
1 parent 088a15c commit 9a2c2a9

11 files changed

Lines changed: 32 additions & 15 deletions

File tree

Doc/extending/newtypes.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,18 +287,23 @@ combined using bitwise-OR.
287287
+===========================+==============================================+
288288
| :const:`READONLY` | Never writable. |
289289
+---------------------------+----------------------------------------------+
290-
| :const:`READ_RESTRICTED` | Not readable in restricted mode. |
291-
+---------------------------+----------------------------------------------+
292-
| :const:`WRITE_RESTRICTED` | Not writable in restricted mode. |
293-
+---------------------------+----------------------------------------------+
294-
| :const:`RESTRICTED` | Not readable or writable in restricted mode. |
290+
| :const:`AUDIT_READ` | Emit an ``object.__getattr__`` |
291+
| | :ref:`audit events <audit-events>` before |
292+
| | reading. |
295293
+---------------------------+----------------------------------------------+
296294

295+
.. versionchanged:: 3.10
296+
:const:`RESTRICTED`, :const:`READ_RESTRICTED` and :const:`WRITE_RESTRICTED`
297+
are deprecated. However, :const:`READ_RESTRICTED` is an alias for
298+
:const:`AUDIT_READ`, so fields that specify either :const:`RESTRICTED` or
299+
:const:`READ_RESTRICTED` will also raise an audit event.
300+
297301
.. index::
298302
single: READONLY
299303
single: READ_RESTRICTED
300304
single: WRITE_RESTRICTED
301305
single: RESTRICTED
306+
single: AUDIT_READ
302307

303308
An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table to build
304309
descriptors that are used at runtime is that any attribute defined this way can

Doc/library/audit_events.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Audit events table
77

88
This table contains all events raised by :func:`sys.audit` or
99
:c:func:`PySys_Audit` calls throughout the CPython runtime and the
10-
standard library. These calls were added in 3.8.0 or later.
10+
standard library. These calls were added in 3.8.0 or later (see :pep:`578`).
1111

1212
See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for
1313
information on handling these events.

Doc/library/stdtypes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5195,6 +5195,9 @@ environment. Code objects are returned by the built-in :func:`compile` function
51955195
and can be extracted from function objects through their :attr:`__code__`
51965196
attribute. See also the :mod:`code` module.
51975197

5198+
Accessing ``__code__`` raises an :ref:`auditing event <auditing>`
5199+
``object.__getattr__`` with arguments ``obj`` and ``"__code__"``.
5200+
51985201
.. index::
51995202
builtin: exec
52005203
builtin: eval

Doc/reference/datamodel.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,9 @@ Internal types
10051005
:attr:`f_lasti` gives the precise instruction (this is an index into the
10061006
bytecode string of the code object).
10071007

1008+
Accessing ``f_code`` raises an :ref:`auditing event <auditing>`
1009+
``object.__getattr__`` with arguments ``obj`` and ``"f_code"``.
1010+
10081011
.. index::
10091012
single: f_trace (frame attribute)
10101013
single: f_trace_lines (frame attribute)
@@ -1089,6 +1092,9 @@ Internal types
10891092
:keyword:`try` statement with no matching except clause or with a
10901093
finally clause.
10911094

1095+
Accessing ``tb_frame`` raises an :ref:`auditing event <auditing>`
1096+
``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``.
1097+
10921098
.. index::
10931099
single: tb_next (traceback attribute)
10941100

Include/structmember.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef struct PyMemberDef {
6262
#define PY_WRITE_RESTRICTED 4
6363
#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED)
6464

65+
#define AUDIT_READ READ_RESTRICTED
6566

6667
/* Current API, use this */
6768
PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *);

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ Kevan Heydon
723723
Wouter van Heyst
724724
Kelsey Hightower
725725
Jason Hildebrand
726+
Ryan Hileman
726727
Aaron Hill
727728
Joel Hillacre
728729
Richie Hindle
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Audit hooks are now fired for frame.f_code, traceback.tb_frame, and generator code/frame attribute access.

Objects/descrobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
164164
if (descr_check((PyDescrObject *)descr, obj, &res))
165165
return res;
166166

167-
if (descr->d_member->flags & READ_RESTRICTED) {
167+
if (descr->d_member->flags & AUDIT_READ) {
168168
if (PySys_Audit("object.__getattr__", "Os",
169169
obj ? obj : Py_None, descr->d_member->name) < 0) {
170170
return NULL;

Objects/frameobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
static PyMemberDef frame_memberlist[] = {
1515
{"f_back", T_OBJECT, OFF(f_back), READONLY},
16-
{"f_code", T_OBJECT, OFF(f_code), READONLY},
16+
{"f_code", T_OBJECT, OFF(f_code), READONLY|AUDIT_READ},
1717
{"f_builtins", T_OBJECT, OFF(f_builtins), READONLY},
1818
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
1919
{"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0},

Objects/genobject.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,8 @@ static PyGetSetDef gen_getsetlist[] = {
741741
};
742742

743743
static PyMemberDef gen_memberlist[] = {
744-
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
745-
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY},
744+
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY|AUDIT_READ},
745+
{"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|AUDIT_READ},
746746
{NULL} /* Sentinel */
747747
};
748748

@@ -978,8 +978,8 @@ static PyGetSetDef coro_getsetlist[] = {
978978
};
979979

980980
static PyMemberDef coro_memberlist[] = {
981-
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY},
982-
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY},
981+
{"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY|AUDIT_READ},
982+
{"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|AUDIT_READ},
983983
{"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY},
984984
{NULL} /* Sentinel */
985985
};
@@ -1360,10 +1360,10 @@ static PyGetSetDef async_gen_getsetlist[] = {
13601360
};
13611361

13621362
static PyMemberDef async_gen_memberlist[] = {
1363-
{"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY},
1363+
{"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY|AUDIT_READ},
13641364
{"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async),
13651365
READONLY},
1366-
{"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY},
1366+
{"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|AUDIT_READ},
13671367
{NULL} /* Sentinel */
13681368
};
13691369

0 commit comments

Comments
 (0)