aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Doc/library/sys.rst2
-rw-r--r--Lib/test/audit-tests.py11
-rw-r--r--Lib/test/test_audit.py12
-rw-r--r--Python/sysmodule.c12
4 files changed, 31 insertions, 6 deletions
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index d9799f8358c..e10efb10ff5 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -774,7 +774,7 @@ always available.
that is deeper than the call stack, :exc:`ValueError` is raised. The default
for *depth* is zero, returning the frame at the top of the call stack.
- .. audit-event:: sys._getframe "" sys._getframe
+ .. audit-event:: sys._getframe frame sys._getframe
.. impl-detail::
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index ccec9fedc44..00333cc9036 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -408,6 +408,17 @@ def test_sqlite3():
raise RuntimeError("Expected sqlite3.load_extension to fail")
+def test_sys_getframe():
+ import sys
+
+ def hook(event, args):
+ if event.startswith("sys."):
+ print(event, args[0].f_code.co_name)
+
+ sys.addaudithook(hook)
+ sys._getframe()
+
+
if __name__ == "__main__":
from test.support import suppress_msvcrt_asserts
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index 0fa2d74835c..6a025f39912 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -176,5 +176,17 @@ class AuditTest(unittest.TestCase):
self.assertEqual(actual, expected)
+ def test_sys_getframe(self):
+ returncode, events, stderr = self.run_python("test_sys_getframe")
+ if returncode:
+ self.fail(stderr)
+
+ if support.verbose:
+ print(*events, sep='\n')
+ actual = [(ev[0], ev[2]) for ev in events]
+ expected = [("sys._getframe", "test_sys_getframe")]
+
+ self.assertEqual(actual, expected)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 93120071b40..a5fa551b957 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1772,10 +1772,6 @@ sys__getframe_impl(PyObject *module, int depth)
PyThreadState *tstate = _PyThreadState_GET();
_PyInterpreterFrame *frame = tstate->cframe->current_frame;
- if (_PySys_Audit(tstate, "sys._getframe", NULL) < 0) {
- return NULL;
- }
-
if (frame != NULL) {
while (depth > 0) {
frame = frame->previous;
@@ -1793,7 +1789,13 @@ sys__getframe_impl(PyObject *module, int depth)
"call stack is not deep enough");
return NULL;
}
- return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
+
+ PyObject *pyFrame = Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
+ if (pyFrame && _PySys_Audit(tstate, "sys._getframe", "(O)", pyFrame) < 0) {
+ Py_DECREF(pyFrame);
+ return NULL;
+ }
+ return pyFrame;
}
/*[clinic input]