[Python-checkins] bpo-32381: Add _PyRun_AnyFileObject() (GH-23723)
vstinner
webhook-mailer at python.org
Wed Dec 9 16:37:56 EST 2020
https://github.com/python/cpython/commit/a82f63f5af027a0eab0f0812d750b804368cbd25
commit: a82f63f5af027a0eab0f0812d750b804368cbd25
branch: master
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2020-12-09T22:37:27+01:00
summary:
bpo-32381: Add _PyRun_AnyFileObject() (GH-23723)
pymain_run_file() no longer encodes the filename: pass the filename
as an object to the new _PyRun_AnyFileObject() function.
Add new private functions:
* _PyRun_AnyFileObject()
* _PyRun_InteractiveLoopObject()
* _Py_FdIsInteractive()
files:
M Include/cpython/pylifecycle.h
M Include/cpython/pythonrun.h
M Modules/main.c
M Python/pylifecycle.c
M Python/pythonrun.c
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index f38ec5a4ae399..b4e2c8a8427c8 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -44,6 +44,7 @@ PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *);
PyAPI_FUNC(void) _Py_RestoreSignals(void);
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
+PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename);
PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
diff --git a/Include/cpython/pythonrun.h b/Include/cpython/pythonrun.h
index febda73f3ec6c..e396a674bc468 100644
--- a/Include/cpython/pythonrun.h
+++ b/Include/cpython/pythonrun.h
@@ -13,6 +13,11 @@ PyAPI_FUNC(int) PyRun_AnyFileExFlags(
const char *filename, /* decoded from the filesystem encoding */
int closeit,
PyCompilerFlags *flags);
+PyAPI_FUNC(int) _PyRun_AnyFileObject(
+ FILE *fp,
+ PyObject *filename,
+ int closeit,
+ PyCompilerFlags *flags);
PyAPI_FUNC(int) PyRun_SimpleFileExFlags(
FILE *fp,
const char *filename, /* decoded from the filesystem encoding */
@@ -30,6 +35,10 @@ PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(
FILE *fp,
const char *filename, /* decoded from the filesystem encoding */
PyCompilerFlags *flags);
+PyAPI_FUNC(int) _PyRun_InteractiveLoopObject(
+ FILE *fp,
+ PyObject *filename,
+ PyCompilerFlags *flags);
PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *,
diff --git a/Modules/main.c b/Modules/main.c
index 3aa4d91c9a3cd..7ffcb07a7fd4b 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -313,17 +313,8 @@ pymain_run_file(const PyConfig *config, PyCompilerFlags *cf)
}
FILE *fp = _Py_wfopen(filename, L"rb");
if (fp == NULL) {
- char *cfilename_buffer;
- const char *cfilename;
- int err = errno;
- cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL);
- if (cfilename_buffer != NULL)
- cfilename = cfilename_buffer;
- else
- cfilename = "<unprintable file name>";
- fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
- config->program_name, cfilename, err, strerror(err));
- PyMem_RawFree(cfilename_buffer);
+ fprintf(stderr, "%ls: can't open file '%ls': [Errno %d] %s\n",
+ config->program_name, filename, errno, strerror(errno));
return 2;
}
@@ -353,25 +344,15 @@ pymain_run_file(const PyConfig *config, PyCompilerFlags *cf)
return pymain_exit_err_print();
}
- PyObject *unicode, *bytes = NULL;
- const char *filename_str;
-
- unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
- if (unicode != NULL) {
- bytes = PyUnicode_EncodeFSDefault(unicode);
- Py_DECREF(unicode);
- }
- if (bytes != NULL) {
- filename_str = PyBytes_AsString(bytes);
- }
- else {
- PyErr_Clear();
- filename_str = "<filename encoding error>";
+ PyObject *filename_obj = PyUnicode_FromWideChar(filename, -1);
+ if (filename_obj == NULL) {
+ PyErr_Print();
+ return -1;
}
/* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */
- int run = PyRun_AnyFileExFlags(fp, filename_str, 1, cf);
- Py_XDECREF(bytes);
+ int run = _PyRun_AnyFileObject(fp, filename_obj, 1, cf);
+ Py_XDECREF(filename_obj);
return (run != 0);
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 70824ff674129..6a705b4d2b4b9 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -2739,6 +2739,21 @@ Py_FdIsInteractive(FILE *fp, const char *filename)
}
+int
+_Py_FdIsInteractive(FILE *fp, PyObject *filename)
+{
+ if (isatty((int)fileno(fp))) {
+ return 1;
+ }
+ if (!Py_InteractiveFlag) {
+ return 0;
+ }
+ return (filename == NULL) ||
+ (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) ||
+ (PyUnicode_CompareWithASCIIString(filename, "???") == 0);
+}
+
+
/* Wrappers around sigaction() or signal(). */
PyOS_sighandler_t
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 15e407d9195c0..dacf1a647106f 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -67,44 +67,69 @@ static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
PyCompilerFlags *flags);
-/* Parse input from a file and execute it */
int
-PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+_PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit,
PyCompilerFlags *flags)
{
- if (filename == NULL)
- filename = "???";
- if (Py_FdIsInteractive(fp, filename)) {
- int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
- if (closeit)
+ int decref_filename = 0;
+ if (filename == NULL) {
+ filename = PyUnicode_FromString("???");
+ if (filename == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+ decref_filename = 1;
+ }
+
+ int res;
+ if (_Py_FdIsInteractive(fp, filename)) {
+ res = _PyRun_InteractiveLoopObject(fp, filename, flags);
+ if (closeit) {
fclose(fp);
- return err;
+ }
+ }
+ else {
+ res = _PyRun_SimpleFileObject(fp, filename, closeit, flags);
+ }
+
+ if (decref_filename) {
+ Py_DECREF(filename);
}
- else
- return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
+ return res;
}
+
+/* Parse input from a file and execute it */
int
-PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
+PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+ PyCompilerFlags *flags)
{
- PyObject *filename, *v;
- int ret, err;
- PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
- int nomem_count = 0;
-#ifdef Py_REF_DEBUG
- int show_ref_count = _Py_GetConfig()->show_ref_count;
-#endif
-
- filename = PyUnicode_DecodeFSDefault(filename_str);
- if (filename == NULL) {
- PyErr_Print();
- return -1;
+ PyObject *filename_obj;
+ if (filename != NULL) {
+ filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ PyErr_Print();
+ return -1;
+ }
}
+ else {
+ filename_obj = NULL;
+ }
+ int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags);
+ Py_XDECREF(filename_obj);
+ return res;
+}
+
+int
+_PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
+{
+ PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
if (flags == NULL) {
flags = &local_flags;
}
- v = _PySys_GetObjectId(&PyId_ps1);
+
+ PyObject *v = _PySys_GetObjectId(&PyId_ps1);
if (v == NULL) {
_PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> "));
Py_XDECREF(v);
@@ -114,7 +139,13 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
_PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... "));
Py_XDECREF(v);
}
- err = 0;
+
+#ifdef Py_REF_DEBUG
+ int show_ref_count = _Py_GetConfig()->show_ref_count;
+#endif
+ int err = 0;
+ int ret;
+ int nomem_count = 0;
do {
ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
if (ret == -1 && PyErr_Occurred()) {
@@ -141,10 +172,26 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
}
#endif
} while (ret != E_EOF);
- Py_DECREF(filename);
return err;
}
+
+int
+PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
+{
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+
+ int err = _PyRun_InteractiveLoopObject(fp, filename_obj, flags);
+ Py_DECREF(filename_obj);
+ return err;
+
+}
+
+
/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
* error on failure. */
static int
More information about the Python-checkins
mailing list