bpo-36842: Implement PEP 578 by zooba · Pull Request #12613 · python/cpython (original) (raw)
Patch to use METH_FASTCALL:
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index f987bb2016..fd1408c748 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -22,6 +22,7 @@ Data members:
#include "pycore_pymem.h"
#include "pycore_pathconfig.h"
#include "pycore_pystate.h"
+#include "pycore_tupleobject.h"
#include "pythread.h"
#include "pydtrace.h"
@@ -360,20 +361,14 @@ PyDoc_STRVAR(audit_doc,
Passes the event to any audit hooks that are attached.");
static PyObject *
-sys_audit(PyObject *self, PyObject *args)
+sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
{
- if (!PyTuple_Check(args)) {
- PyErr_Format(PyExc_TypeError, "expected tuple, not %.200s", Py_TYPE(args)->tp_name);
- return NULL;
- }
-
- Py_ssize_t argc = PyTuple_GET_SIZE(args);
if (argc == 0) {
PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'");
return NULL;
}
- PyObject *auditEvent = PyTuple_GET_ITEM(args, 0);
+ PyObject *auditEvent = args[0];
if (!auditEvent) {
PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'");
return NULL;
@@ -388,16 +383,10 @@ sys_audit(PyObject *self, PyObject *args)
return NULL;
}
- PyObject *auditArgs = PyTuple_New(argc - 1);
+ PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
if (!auditArgs) {
return NULL;
}
- for (int i = 0; i < argc - 1; ++i) {
- PyObject *o = PyTuple_GET_ITEM(args, i + 1);
- Py_INCREF(o);
- PyTuple_SET_ITEM(auditArgs, i, o);
- }
-
int res = PySys_Audit(event, "O", auditArgs);
Py_DECREF(auditArgs);
@@ -1924,7 +1913,7 @@ sys_getandroidapilevel_impl(PyObject *module)
static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */
SYS_ADDAUDITHOOK_METHODDEF
- {"audit", sys_audit, METH_VARARGS, audit_doc },
+ {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc },
{"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook,
METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
SYS_CALLSTATS_METHODDEF
By the way, I might be useful to extract the code from PySys_Audit() to decide if audit is used or not: create a subfunction, and call it from sys_audit() to do nothing if audit is not used (common case).
Calling PyUnicode_AsUTF8() and _PyTuple_FromArray() is not free :-) (I know that they are fast, but many function calls take less than 100 ns overall.)