summaryrefslogtreecommitdiffstats
path: root/Objects/fileobject.c
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2019-05-23 15:45:22 (GMT)
committerGitHub <noreply@github.com>2019-05-23 15:45:22 (GMT)
commitb82e17e626f7b1cd98aada0b1ebb65cb9f8fb184 (patch)
tree5370a2a075707cb0b37ce135cad6ffe23da424c4 /Objects/fileobject.c
parente788057a9188ff37e232729815dfda2529079420 (diff)
downloadcpython-b82e17e626f7b1cd98aada0b1ebb65cb9f8fb184.zip
cpython-b82e17e626f7b1cd98aada0b1ebb65cb9f8fb184.tar.gz
cpython-b82e17e626f7b1cd98aada0b1ebb65cb9f8fb184.tar.bz2
bpo-36842: Implement PEP 578 (GH-12613)
Adds sys.audit, sys.addaudithook, io.open_code, and associated C APIs.
Diffstat (limited to 'Objects/fileobject.c')
-rw-r--r--Objects/fileobject.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 39c7c10..3b02633 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -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