bpo-36842: Implement PEP 578 (GH-12613)

Adds sys.audit, sys.addaudithook, io.open_code, and associated C APIs.
This commit is contained in:
Steve Dower 2019-05-23 08:45:22 -07:00 committed by GitHub
parent e788057a91
commit b82e17e626
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 3565 additions and 1816 deletions

View file

@ -2,6 +2,7 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_pystate.h"
#if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER)
/* clang MemorySanitizer doesn't yet understand getc_unlocked. */
@ -33,7 +34,8 @@ PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const c
PyObject *io, *stream;
_Py_IDENTIFIER(open);
io = PyImport_ImportModule("io");
/* import _io in case we are being used to open io.py */
io = PyImport_ImportModule("_io");
if (io == NULL)
return NULL;
stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
@ -514,6 +516,72 @@ PyTypeObject PyStdPrinter_Type = {
};
/* ************************** open_code hook ***************************
* The open_code hook allows embedders to override the method used to
* open files that are going to be used by the runtime to execute code
*/
int
PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) {
if (Py_IsInitialized() &&
PySys_Audit("setopencodehook", NULL) < 0) {
return -1;
}
if (_PyRuntime.open_code_hook) {
if (Py_IsInitialized()) {
PyErr_SetString(PyExc_SystemError,
"failed to change existing open_code hook");
}
return -1;
}
_PyRuntime.open_code_hook = hook;
_PyRuntime.open_code_userdata = userData;
return 0;
}
PyObject *
PyFile_OpenCodeObject(PyObject *path)
{
PyObject *iomod, *f = NULL;
_Py_IDENTIFIER(open);
if (!PyUnicode_Check(path)) {
PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'",
Py_TYPE(path)->tp_name);
return NULL;
}
Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook;
if (hook) {
f = hook(path, _PyRuntime.open_code_userdata);
} else {
iomod = PyImport_ImportModule("_io");
if (iomod) {
f = _PyObject_CallMethodId(iomod, &PyId_open, "Os",
path, "rb");
Py_DECREF(iomod);
}
}
return f;
}
PyObject *
PyFile_OpenCode(const char *utf8path)
{
PyObject *pathobj = PyUnicode_FromString(utf8path);
PyObject *f;
if (!pathobj) {
return NULL;
}
f = PyFile_OpenCodeObject(pathobj);
Py_DECREF(pathobj);
return f;
}
#ifdef __cplusplus
}
#endif