From f10b60500f32a7f9b014d5aa0df36edea83c210c Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 20 Oct 2009 21:52:47 +0000 Subject: Merged revisions 75570 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75570 | antoine.pitrou | 2009-10-20 23:29:37 +0200 (mar., 20 oct. 2009) | 6 lines Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which fixes the problem of some exceptions being thrown at shutdown when the interpreter is killed. Patch by Adam Olsen. ........ --- Python/pythonrun.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e7a051288d..875e44e99b 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -18,6 +18,7 @@ #include "eval.h" #include "marshal.h" #include "osdefs.h" +#include "abstract.h" #ifdef HAVE_SIGNAL_H #include @@ -66,6 +67,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, static void err_input(perrdetail *); static void initsigs(void); static void call_py_exitfuncs(void); +static void wait_for_thread_shutdown(void); static void call_ll_exitfuncs(void); extern void _PyUnicode_Init(void); extern void _PyUnicode_Fini(void); @@ -363,6 +365,8 @@ Py_Finalize(void) if (!initialized) return; + wait_for_thread_shutdown(); + /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread * or exit func is still waiting to do an import, the import machinery @@ -2059,6 +2063,34 @@ call_py_exitfuncs(void) PyErr_Clear(); } +/* Wait until threading._shutdown completes, provided + the threading module was imported in the first place. + The shutdown routine will wait until all non-daemon + "threading" threads have completed. */ +static void +wait_for_thread_shutdown(void) +{ +#ifdef WITH_THREAD + PyObject *result; + PyThreadState *tstate = PyThreadState_GET(); + PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, + "threading"); + if (threading == NULL) { + /* threading not imported */ + PyErr_Clear(); + return; + } + result = PyObject_CallMethod(threading, "_shutdown", ""); + if (result == NULL) { + PyErr_WriteUnraisable(threading); + } + else { + Py_DECREF(result); + } + Py_DECREF(threading); +#endif +} + #define NEXITFUNCS 32 static void (*exitfuncs[NEXITFUNCS])(void); static int nexitfuncs = 0; -- cgit v1.2.1 From a412ebff3dce42d46a21c7dded2e29c4243f4a8d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 28 Nov 2009 16:12:28 +0000 Subject: Issue #4486: When an exception has an explicit cause, do not print its implicit context too. --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 875e44e99b..3764740e81 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1576,7 +1576,7 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) cause_message, f); } } - if (context) { + else if (context) { res = PySet_Contains(seen, context); if (res == -1) PyErr_Clear(); -- cgit v1.2.1 From 7fc1caed37e14732a95513b5bc081dd5dcab65da Mon Sep 17 00:00:00 2001 From: "Andrew M. Kuchling" Date: Mon, 22 Feb 2010 23:26:10 +0000 Subject: #4532: fixes to make 3.x compile on QNX 6.3.2 (reported by Matt Kraai) --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3764740e81..b99a541d54 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -180,7 +180,7 @@ Py_InitializeEx(int install_sigs) return; initialized = 1; -#ifdef HAVE_SETLOCALE +#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) /* Set up the LC_CTYPE locale, so we can obtain the locale's charset without having to switch locales. */ -- cgit v1.2.1 From 4211cfd22a40b91fc7e2d12e10835bd02f99ae39 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 12 Mar 2010 14:45:56 +0000 Subject: Merged revisions 78826 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78826 | victor.stinner | 2010-03-10 23:30:19 +0100 (mer., 10 mars 2010) | 5 lines Issue #3137: Don't ignore errors at startup, especially a keyboard interrupt (SIGINT). If an error occurs while importing the site module, the error is printed and Python exits. Initialize the GIL before importing the site module. ........ --- Python/pythonrun.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index b99a541d54..cfa19b0708 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -296,13 +296,14 @@ Py_InitializeEx(int install_sigs) if (initstdio() < 0) Py_FatalError( "Py_Initialize: can't initialize sys standard streams"); - if (!Py_NoSiteFlag) - initsite(); /* Module site */ /* auto-thread-state API, if available */ #ifdef WITH_THREAD _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ + + if (!Py_NoSiteFlag) + initsite(); /* Module site */ } void @@ -711,22 +712,12 @@ initmain(void) static void initsite(void) { - PyObject *m, *f; + PyObject *m; m = PyImport_ImportModule("site"); if (m == NULL) { - f = PySys_GetObject("stderr"); - if (f == NULL || f == Py_None) - return; - if (Py_VerboseFlag) { - PyFile_WriteString( - "'import site' failed; traceback:\n", f); - PyErr_Print(); - } - else { - PyFile_WriteString( - "'import site' failed; use -v for traceback\n", f); - PyErr_Clear(); - } + PyErr_Print(); + Py_Finalize(); + exit(1); } else { Py_DECREF(m); @@ -1907,6 +1898,8 @@ err_input(perrdetail *err) char *msg = NULL; errtype = PyExc_SyntaxError; switch (err->error) { + case E_ERROR: + return; case E_SYNTAX: errtype = PyExc_IndentationError; if (err->expected == INDENT) -- cgit v1.2.1 From 227334cb2eacf4a9087140ef7726d6408b4798e5 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 14 Mar 2010 06:49:55 +0000 Subject: * Replaces the internals of the subprocess module from fork through exec on POSIX systems with a C extension module. This is required in order for the subprocess module to be made thread safe. The pure python implementation is retained so that it can continue to be used if for some reason the _posixsubprocess extension module is not available. The unittest executes tests on both code paths to guarantee compatibility. * Moves PyLong_FromPid and PyLong_AsPid from posixmodule.c into longobject.h. Code reviewed by jeffrey.yasskin at http://codereview.appspot.com/223077/show --- Python/pythonrun.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cfa19b0708..2bdef981ad 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2130,6 +2130,27 @@ initsigs(void) } +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. + * + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + */ +void +_Py_RestoreSignals(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_DFL); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_DFL); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_DFL); +#endif +} + + /* * The file descriptor fd is considered ``interactive'' if either * a) isatty(fd) is TRUE, or @@ -2223,6 +2244,11 @@ PyOS_getsig(int sig) #endif } +/* + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + */ PyOS_sighandler_t PyOS_setsig(int sig, PyOS_sighandler_t handler) { -- cgit v1.2.1 From 4bd6574097d2cbd2e779196837124380e2dbe9bb Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Sat, 17 Apr 2010 00:19:56 +0000 Subject: PEP 3147 --- Python/pythonrun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 2bdef981ad..cc617be4d1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1155,6 +1155,8 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, Py_DECREF(f); return -1; } + if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) + return -1; set_file_name = 1; Py_DECREF(f); } -- cgit v1.2.1 From 122aa3574de7e6b341502e5bfde280d2d47f7266 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 8 May 2010 00:07:07 +0000 Subject: err_input(): don't encode/decode the unicode message --- Python/pythonrun.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cc617be4d1..225d178986 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1896,7 +1896,7 @@ static void err_input(perrdetail *err) { PyObject *v, *w, *errtype, *errtext; - PyObject* u = NULL; + PyObject *msg_obj = NULL; char *msg = NULL; errtype = PyExc_SyntaxError; switch (err->error) { @@ -1952,14 +1952,9 @@ err_input(perrdetail *err) case E_DECODE: { PyObject *type, *value, *tb; PyErr_Fetch(&type, &value, &tb); - if (value != NULL) { - u = PyObject_Str(value); - if (u != NULL) { - msg = _PyUnicode_AsString(u); - } - } - if (msg == NULL) - msg = "unknown decode error"; + msg = "unknown decode error"; + if (value != NULL) + msg_obj = PyObject_Str(value); Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(tb); @@ -1988,14 +1983,18 @@ err_input(perrdetail *err) } v = Py_BuildValue("(ziiN)", err->filename, err->lineno, err->offset, errtext); - w = NULL; - if (v != NULL) - w = Py_BuildValue("(sO)", msg, v); - Py_XDECREF(u); + if (v != NULL) { + if (msg_obj) + w = Py_BuildValue("(OO)", msg_obj, v); + else + w = Py_BuildValue("(sO)", msg, v); + } else + w = NULL; Py_XDECREF(v); PyErr_SetObject(errtype, w); Py_XDECREF(w); cleanup: + Py_XDECREF(msg_obj); if (err->text != NULL) { PyObject_FREE(err->text); err->text = NULL; -- cgit v1.2.1 From 30dd43e9dcd124029da3b83ace652cbebea43c7e Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Sun, 9 May 2010 03:18:57 +0000 Subject: Merged revisions 81007 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81007 | jean-paul.calderone | 2010-05-08 16:06:02 -0400 (Sat, 08 May 2010) | 1 line Skip signal handler re-installation if it is not necessary. Issue 8354. ........ --- Python/pythonrun.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 225d178986..05a10c61c4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2254,6 +2254,10 @@ PyOS_sighandler_t PyOS_setsig(int sig, PyOS_sighandler_t handler) { #ifdef HAVE_SIGACTION + /* Some code in Modules/signalmodule.c depends on sigaction() being + * used here if HAVE_SIGACTION is defined. Fix that if this code + * changes to invalidate that assumption. + */ struct sigaction context, ocontext; context.sa_handler = handler; sigemptyset(&context.sa_mask); -- cgit v1.2.1 From 567b94adaaceb622c33f9be1998735dfb95f1707 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 May 2010 15:52:27 +0000 Subject: Recorded merge of revisions 81029 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........ --- Python/pythonrun.c | 3272 ++++++++++++++++++++++++++-------------------------- 1 file changed, 1636 insertions(+), 1636 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 05a10c61c4..e58b1c8ab9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -42,9 +42,9 @@ #ifndef Py_REF_DEBUG #define PRINT_TOTAL_REFS() #else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() fprintf(stderr, \ - "[%" PY_FORMAT_SIZE_T "d refs]\n", \ - _Py_GetRefTotal()) +#define PRINT_TOTAL_REFS() fprintf(stderr, \ + "[%" PY_FORMAT_SIZE_T "d refs]\n", \ + _Py_GetRefTotal()) #endif #ifdef __cplusplus @@ -61,9 +61,9 @@ static void initsite(void); static int initstdio(void); static void flush_io(void); static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, - PyCompilerFlags *, PyArena *); + PyCompilerFlags *, PyArena *); static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, - PyCompilerFlags *); + PyCompilerFlags *); static void err_input(perrdetail *); static void initsigs(void); static void call_py_exitfuncs(void); @@ -97,7 +97,7 @@ since _warnings is builtin. This API should not be used. */ PyObject * PyModule_GetWarningsModule(void) { - return PyImport_ImportModule("warnings"); + return PyImport_ImportModule("warnings"); } static int initialized = 0; @@ -107,7 +107,7 @@ static int initialized = 0; int Py_IsInitialized(void) { - return initialized; + return initialized; } /* Global initializations. Can be undone by Py_Finalize(). Don't @@ -125,191 +125,191 @@ Py_IsInitialized(void) static int add_flag(int flag, const char *envs) { - int env = atoi(envs); - if (flag < env) - flag = env; - if (flag < 1) - flag = 1; - return flag; + int env = atoi(envs); + if (flag < env) + flag = env; + if (flag < 1) + flag = 1; + return flag; } #if defined(HAVE_LANGINFO_H) && defined(CODESET) static char* get_codeset(void) { - char* codeset; - PyObject *codec, *name; + char* codeset; + PyObject *codec, *name; - codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') - return NULL; + codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') + return NULL; - codec = _PyCodec_Lookup(codeset); - if (!codec) - goto error; + codec = _PyCodec_Lookup(codeset); + if (!codec) + goto error; - name = PyObject_GetAttrString(codec, "name"); - Py_CLEAR(codec); - if (!name) - goto error; + name = PyObject_GetAttrString(codec, "name"); + Py_CLEAR(codec); + if (!name) + goto error; - codeset = strdup(_PyUnicode_AsString(name)); - Py_DECREF(name); - return codeset; + codeset = strdup(_PyUnicode_AsString(name)); + Py_DECREF(name); + return codeset; error: - Py_XDECREF(codec); - PyErr_Clear(); - return NULL; + Py_XDECREF(codec); + PyErr_Clear(); + return NULL; } #endif void Py_InitializeEx(int install_sigs) { - PyInterpreterState *interp; - PyThreadState *tstate; - PyObject *bimod, *sysmod, *pstderr; - char *p; + PyInterpreterState *interp; + PyThreadState *tstate; + PyObject *bimod, *sysmod, *pstderr; + char *p; #if defined(HAVE_LANGINFO_H) && defined(CODESET) - char *codeset; + char *codeset; #endif - extern void _Py_ReadyTypes(void); + extern void _Py_ReadyTypes(void); - if (initialized) - return; - initialized = 1; + if (initialized) + return; + initialized = 1; #if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) - /* Set up the LC_CTYPE locale, so we can obtain - the locale's charset without having to switch - locales. */ - setlocale(LC_CTYPE, ""); + /* Set up the LC_CTYPE locale, so we can obtain + the locale's charset without having to switch + locales. */ + setlocale(LC_CTYPE, ""); #endif - if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') - Py_DebugFlag = add_flag(Py_DebugFlag, p); - if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') - Py_VerboseFlag = add_flag(Py_VerboseFlag, p); - if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') - Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); - if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') - Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); - - interp = PyInterpreterState_New(); - if (interp == NULL) - Py_FatalError("Py_Initialize: can't make first interpreter"); - - tstate = PyThreadState_New(interp); - if (tstate == NULL) - Py_FatalError("Py_Initialize: can't make first thread"); - (void) PyThreadState_Swap(tstate); - - _Py_ReadyTypes(); - - if (!_PyFrame_Init()) - Py_FatalError("Py_Initialize: can't init frames"); - - if (!_PyLong_Init()) - Py_FatalError("Py_Initialize: can't init longs"); - - if (!PyByteArray_Init()) - Py_FatalError("Py_Initialize: can't init bytearray"); - - _PyFloat_Init(); - - interp->modules = PyDict_New(); - if (interp->modules == NULL) - Py_FatalError("Py_Initialize: can't make modules dictionary"); - interp->modules_reloading = PyDict_New(); - if (interp->modules_reloading == NULL) - Py_FatalError("Py_Initialize: can't make modules_reloading dictionary"); - - /* Init Unicode implementation; relies on the codec registry */ - _PyUnicode_Init(); - - bimod = _PyBuiltin_Init(); - if (bimod == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins modules"); - _PyImport_FixupExtension(bimod, "builtins", "builtins"); - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins dict"); - Py_INCREF(interp->builtins); - - /* initialize builtin exceptions */ - _PyExc_Init(); - - sysmod = _PySys_Init(); - if (sysmod == NULL) - Py_FatalError("Py_Initialize: can't initialize sys"); - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - Py_FatalError("Py_Initialize: can't initialize sys dict"); - Py_INCREF(interp->sysdict); - _PyImport_FixupExtension(sysmod, "sys", "sys"); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - PySys_SetObject("stderr", pstderr); - PySys_SetObject("__stderr__", pstderr); - - _PyImport_Init(); - - _PyImportHooks_Init(); + if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = add_flag(Py_DebugFlag, p); + if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') + Py_VerboseFlag = add_flag(Py_VerboseFlag, p); + if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') + Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); + if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') + Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); + + interp = PyInterpreterState_New(); + if (interp == NULL) + Py_FatalError("Py_Initialize: can't make first interpreter"); + + tstate = PyThreadState_New(interp); + if (tstate == NULL) + Py_FatalError("Py_Initialize: can't make first thread"); + (void) PyThreadState_Swap(tstate); + + _Py_ReadyTypes(); + + if (!_PyFrame_Init()) + Py_FatalError("Py_Initialize: can't init frames"); + + if (!_PyLong_Init()) + Py_FatalError("Py_Initialize: can't init longs"); + + if (!PyByteArray_Init()) + Py_FatalError("Py_Initialize: can't init bytearray"); + + _PyFloat_Init(); + + interp->modules = PyDict_New(); + if (interp->modules == NULL) + Py_FatalError("Py_Initialize: can't make modules dictionary"); + interp->modules_reloading = PyDict_New(); + if (interp->modules_reloading == NULL) + Py_FatalError("Py_Initialize: can't make modules_reloading dictionary"); + + /* Init Unicode implementation; relies on the codec registry */ + _PyUnicode_Init(); + + bimod = _PyBuiltin_Init(); + if (bimod == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins modules"); + _PyImport_FixupExtension(bimod, "builtins", "builtins"); + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins dict"); + Py_INCREF(interp->builtins); + + /* initialize builtin exceptions */ + _PyExc_Init(); + + sysmod = _PySys_Init(); + if (sysmod == NULL) + Py_FatalError("Py_Initialize: can't initialize sys"); + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + Py_FatalError("Py_Initialize: can't initialize sys dict"); + Py_INCREF(interp->sysdict); + _PyImport_FixupExtension(sysmod, "sys", "sys"); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + PySys_SetObject("stderr", pstderr); + PySys_SetObject("__stderr__", pstderr); + + _PyImport_Init(); + + _PyImportHooks_Init(); #if defined(HAVE_LANGINFO_H) && defined(CODESET) - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - - codeset = get_codeset(); - if (codeset) { - if (!Py_FileSystemDefaultEncoding) - Py_FileSystemDefaultEncoding = codeset; - else - free(codeset); - } + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + + codeset = get_codeset(); + if (codeset) { + if (!Py_FileSystemDefaultEncoding) + Py_FileSystemDefaultEncoding = codeset; + else + free(codeset); + } #endif - if (install_sigs) - initsigs(); /* Signal handling stuff, including initintr() */ - - /* Initialize warnings. */ - _PyWarnings_Init(); - if (PySys_HasWarnOptions()) { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (!warnings_module) - PyErr_Clear(); - Py_XDECREF(warnings_module); - } - - initmain(); /* Module __main__ */ - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - - /* auto-thread-state API, if available */ + if (install_sigs) + initsigs(); /* Signal handling stuff, including initintr() */ + + /* Initialize warnings. */ + _PyWarnings_Init(); + if (PySys_HasWarnOptions()) { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (!warnings_module) + PyErr_Clear(); + Py_XDECREF(warnings_module); + } + + initmain(); /* Module __main__ */ + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + + /* auto-thread-state API, if available */ #ifdef WITH_THREAD - _PyGILState_Init(interp, tstate); + _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ - if (!Py_NoSiteFlag) - initsite(); /* Module site */ + if (!Py_NoSiteFlag) + initsite(); /* Module site */ } void Py_Initialize(void) { - Py_InitializeEx(1); + Py_InitializeEx(1); } @@ -322,25 +322,25 @@ extern void dump_counts(FILE*); static void flush_std_files(void) { - PyObject *fout = PySys_GetObject("stdout"); - PyObject *ferr = PySys_GetObject("stderr"); - PyObject *tmp; + PyObject *fout = PySys_GetObject("stdout"); + PyObject *ferr = PySys_GetObject("stderr"); + PyObject *tmp; - if (fout != NULL && fout != Py_None) { - tmp = PyObject_CallMethod(fout, "flush", ""); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - } + if (fout != NULL && fout != Py_None) { + tmp = PyObject_CallMethod(fout, "flush", ""); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + } - if (ferr != NULL || ferr != Py_None) { - tmp = PyObject_CallMethod(ferr, "flush", ""); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - } + if (ferr != NULL || ferr != Py_None) { + tmp = PyObject_CallMethod(ferr, "flush", ""); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + } } /* Undo the effect of Py_Initialize(). @@ -360,169 +360,169 @@ flush_std_files(void) void Py_Finalize(void) { - PyInterpreterState *interp; - PyThreadState *tstate; - - if (!initialized) - return; - - wait_for_thread_shutdown(); - - /* The interpreter is still entirely intact at this point, and the - * exit funcs may be relying on that. In particular, if some thread - * or exit func is still waiting to do an import, the import machinery - * expects Py_IsInitialized() to return true. So don't say the - * interpreter is uninitialized until after the exit funcs have run. - * Note that Threading.py uses an exit func to do a join on all the - * threads created thru it, so this also protects pending imports in - * the threads created via Threading. - */ - call_py_exitfuncs(); - initialized = 0; - - /* Flush stdout+stderr */ - flush_std_files(); - - /* Get current thread state and interpreter pointer */ - tstate = PyThreadState_GET(); - interp = tstate->interp; - - /* Disable signal handling */ - PyOS_FiniInterrupts(); - - /* Clear type lookup cache */ - PyType_ClearCache(); - - /* Collect garbage. This may call finalizers; it's nice to call these - * before all modules are destroyed. - * XXX If a __del__ or weakref callback is triggered here, and tries to - * XXX import a module, bad things can happen, because Python no - * XXX longer believes it's initialized. - * XXX Fatal Python error: Interpreter not initialized (version mismatch?) - * XXX is easy to provoke that way. I've also seen, e.g., - * XXX Exception exceptions.ImportError: 'No module named sha' - * XXX in ignored - * XXX but I'm unclear on exactly how that one happens. In any case, - * XXX I haven't seen a real-life report of either of these. - */ - PyGC_Collect(); + PyInterpreterState *interp; + PyThreadState *tstate; + + if (!initialized) + return; + + wait_for_thread_shutdown(); + + /* The interpreter is still entirely intact at this point, and the + * exit funcs may be relying on that. In particular, if some thread + * or exit func is still waiting to do an import, the import machinery + * expects Py_IsInitialized() to return true. So don't say the + * interpreter is uninitialized until after the exit funcs have run. + * Note that Threading.py uses an exit func to do a join on all the + * threads created thru it, so this also protects pending imports in + * the threads created via Threading. + */ + call_py_exitfuncs(); + initialized = 0; + + /* Flush stdout+stderr */ + flush_std_files(); + + /* Get current thread state and interpreter pointer */ + tstate = PyThreadState_GET(); + interp = tstate->interp; + + /* Disable signal handling */ + PyOS_FiniInterrupts(); + + /* Clear type lookup cache */ + PyType_ClearCache(); + + /* Collect garbage. This may call finalizers; it's nice to call these + * before all modules are destroyed. + * XXX If a __del__ or weakref callback is triggered here, and tries to + * XXX import a module, bad things can happen, because Python no + * XXX longer believes it's initialized. + * XXX Fatal Python error: Interpreter not initialized (version mismatch?) + * XXX is easy to provoke that way. I've also seen, e.g., + * XXX Exception exceptions.ImportError: 'No module named sha' + * XXX in ignored + * XXX but I'm unclear on exactly how that one happens. In any case, + * XXX I haven't seen a real-life report of either of these. + */ + PyGC_Collect(); #ifdef COUNT_ALLOCS - /* With COUNT_ALLOCS, it helps to run GC multiple times: - each collection might release some types from the type - list, so they become garbage. */ - while (PyGC_Collect() > 0) - /* nothing */; + /* With COUNT_ALLOCS, it helps to run GC multiple times: + each collection might release some types from the type + list, so they become garbage. */ + while (PyGC_Collect() > 0) + /* nothing */; #endif - /* Destroy all modules */ - PyImport_Cleanup(); - - /* Flush stdout+stderr (again, in case more was printed) */ - flush_std_files(); - - /* Collect final garbage. This disposes of cycles created by - * new-style class definitions, for example. - * XXX This is disabled because it caused too many problems. If - * XXX a __del__ or weakref callback triggers here, Python code has - * XXX a hard time running, because even the sys module has been - * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). - * XXX One symptom is a sequence of information-free messages - * XXX coming from threads (if a __del__ or callback is invoked, - * XXX other threads can execute too, and any exception they encounter - * XXX triggers a comedy of errors as subsystem after subsystem - * XXX fails to find what it *expects* to find in sys to help report - * XXX the exception and consequent unexpected failures). I've also - * XXX seen segfaults then, after adding print statements to the - * XXX Python code getting called. - */ + /* Destroy all modules */ + PyImport_Cleanup(); + + /* Flush stdout+stderr (again, in case more was printed) */ + flush_std_files(); + + /* Collect final garbage. This disposes of cycles created by + * new-style class definitions, for example. + * XXX This is disabled because it caused too many problems. If + * XXX a __del__ or weakref callback triggers here, Python code has + * XXX a hard time running, because even the sys module has been + * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). + * XXX One symptom is a sequence of information-free messages + * XXX coming from threads (if a __del__ or callback is invoked, + * XXX other threads can execute too, and any exception they encounter + * XXX triggers a comedy of errors as subsystem after subsystem + * XXX fails to find what it *expects* to find in sys to help report + * XXX the exception and consequent unexpected failures). I've also + * XXX seen segfaults then, after adding print statements to the + * XXX Python code getting called. + */ #if 0 - PyGC_Collect(); + PyGC_Collect(); #endif - /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ - _PyImport_Fini(); + /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + _PyImport_Fini(); - /* Debugging stuff */ + /* Debugging stuff */ #ifdef COUNT_ALLOCS - dump_counts(stdout); + dump_counts(stdout); #endif - PRINT_TOTAL_REFS(); + PRINT_TOTAL_REFS(); #ifdef Py_TRACE_REFS - /* Display all objects still alive -- this can invoke arbitrary - * __repr__ overrides, so requires a mostly-intact interpreter. - * Alas, a lot of stuff may still be alive now that will be cleaned - * up later. - */ - if (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferences(stderr); + /* Display all objects still alive -- this can invoke arbitrary + * __repr__ overrides, so requires a mostly-intact interpreter. + * Alas, a lot of stuff may still be alive now that will be cleaned + * up later. + */ + if (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferences(stderr); #endif /* Py_TRACE_REFS */ - /* Clear interpreter state */ - PyInterpreterState_Clear(interp); + /* Clear interpreter state */ + PyInterpreterState_Clear(interp); - /* Now we decref the exception classes. After this point nothing - can raise an exception. That's okay, because each Fini() method - below has been checked to make sure no exceptions are ever - raised. - */ + /* Now we decref the exception classes. After this point nothing + can raise an exception. That's okay, because each Fini() method + below has been checked to make sure no exceptions are ever + raised. + */ - _PyExc_Fini(); + _PyExc_Fini(); - /* Cleanup auto-thread-state */ + /* Cleanup auto-thread-state */ #ifdef WITH_THREAD - _PyGILState_Fini(); + _PyGILState_Fini(); #endif /* WITH_THREAD */ - /* Delete current thread */ - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); - - /* Sundry finalizers */ - PyMethod_Fini(); - PyFrame_Fini(); - PyCFunction_Fini(); - PyTuple_Fini(); - PyList_Fini(); - PySet_Fini(); - PyBytes_Fini(); - PyByteArray_Fini(); - PyLong_Fini(); - PyFloat_Fini(); - PyDict_Fini(); - - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(); - - /* reset file system default encoding */ - if (!Py_HasFileSystemDefaultEncoding) { - free((char*)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = NULL; - } - - /* XXX Still allocated: - - various static ad-hoc pointers to interned strings - - int and float free list blocks - - whatever various modules and libraries allocate - */ - - PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + /* Delete current thread */ + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); + + /* Sundry finalizers */ + PyMethod_Fini(); + PyFrame_Fini(); + PyCFunction_Fini(); + PyTuple_Fini(); + PyList_Fini(); + PySet_Fini(); + PyBytes_Fini(); + PyByteArray_Fini(); + PyLong_Fini(); + PyFloat_Fini(); + PyDict_Fini(); + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(); + + /* reset file system default encoding */ + if (!Py_HasFileSystemDefaultEncoding) { + free((char*)Py_FileSystemDefaultEncoding); + Py_FileSystemDefaultEncoding = NULL; + } + + /* XXX Still allocated: + - various static ad-hoc pointers to interned strings + - int and float free list blocks + - whatever various modules and libraries allocate + */ + + PyGrammar_RemoveAccelerators(&_PyParser_Grammar); #ifdef Py_TRACE_REFS - /* Display addresses (& refcnts) of all objects still alive. - * An address can be used to find the repr of the object, printed - * above by _Py_PrintReferences. - */ - if (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferenceAddresses(stderr); + /* Display addresses (& refcnts) of all objects still alive. + * An address can be used to find the repr of the object, printed + * above by _Py_PrintReferences. + */ + if (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferenceAddresses(stderr); #endif /* Py_TRACE_REFS */ #ifdef PYMALLOC_DEBUG - if (Py_GETENV("PYTHONMALLOCSTATS")) - _PyObject_DebugMallocStats(); + if (Py_GETENV("PYTHONMALLOCSTATS")) + _PyObject_DebugMallocStats(); #endif - call_ll_exitfuncs(); + call_ll_exitfuncs(); } /* Create and initialize a new interpreter and thread, and return the @@ -541,81 +541,81 @@ Py_Finalize(void) PyThreadState * Py_NewInterpreter(void) { - PyInterpreterState *interp; - PyThreadState *tstate, *save_tstate; - PyObject *bimod, *sysmod; - - if (!initialized) - Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); - - interp = PyInterpreterState_New(); - if (interp == NULL) - return NULL; - - tstate = PyThreadState_New(interp); - if (tstate == NULL) { - PyInterpreterState_Delete(interp); - return NULL; - } - - save_tstate = PyThreadState_Swap(tstate); - - /* XXX The following is lax in error checking */ - - interp->modules = PyDict_New(); - interp->modules_reloading = PyDict_New(); - - bimod = _PyImport_FindExtension("builtins", "builtins"); - if (bimod != NULL) { - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - goto handle_error; - Py_INCREF(interp->builtins); - } - - /* initialize builtin exceptions */ - _PyExc_Init(); - - sysmod = _PyImport_FindExtension("sys", "sys"); - if (bimod != NULL && sysmod != NULL) { - PyObject *pstderr; - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - goto handle_error; - Py_INCREF(interp->sysdict); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - PySys_SetObject("stderr", pstderr); - PySys_SetObject("__stderr__", pstderr); - - _PyImportHooks_Init(); - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - initmain(); - if (!Py_NoSiteFlag) - initsite(); - } - - if (!PyErr_Occurred()) - return tstate; + PyInterpreterState *interp; + PyThreadState *tstate, *save_tstate; + PyObject *bimod, *sysmod; + + if (!initialized) + Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); + + interp = PyInterpreterState_New(); + if (interp == NULL) + return NULL; + + tstate = PyThreadState_New(interp); + if (tstate == NULL) { + PyInterpreterState_Delete(interp); + return NULL; + } + + save_tstate = PyThreadState_Swap(tstate); + + /* XXX The following is lax in error checking */ + + interp->modules = PyDict_New(); + interp->modules_reloading = PyDict_New(); + + bimod = _PyImport_FindExtension("builtins", "builtins"); + if (bimod != NULL) { + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + goto handle_error; + Py_INCREF(interp->builtins); + } + + /* initialize builtin exceptions */ + _PyExc_Init(); + + sysmod = _PyImport_FindExtension("sys", "sys"); + if (bimod != NULL && sysmod != NULL) { + PyObject *pstderr; + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + goto handle_error; + Py_INCREF(interp->sysdict); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + PySys_SetObject("stderr", pstderr); + PySys_SetObject("__stderr__", pstderr); + + _PyImportHooks_Init(); + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + initmain(); + if (!Py_NoSiteFlag) + initsite(); + } + + if (!PyErr_Occurred()) + return tstate; handle_error: - /* Oops, it didn't work. Undo it all. */ + /* Oops, it didn't work. Undo it all. */ - PyErr_Print(); - PyThreadState_Clear(tstate); - PyThreadState_Swap(save_tstate); - PyThreadState_Delete(tstate); - PyInterpreterState_Delete(interp); + PyErr_Print(); + PyThreadState_Clear(tstate); + PyThreadState_Swap(save_tstate); + PyThreadState_Delete(tstate); + PyInterpreterState_Delete(interp); - return NULL; + return NULL; } /* Delete an interpreter and its last thread. This requires that the @@ -633,19 +633,19 @@ handle_error: void Py_EndInterpreter(PyThreadState *tstate) { - PyInterpreterState *interp = tstate->interp; + PyInterpreterState *interp = tstate->interp; - if (tstate != PyThreadState_GET()) - Py_FatalError("Py_EndInterpreter: thread is not current"); - if (tstate->frame != NULL) - Py_FatalError("Py_EndInterpreter: thread still has a frame"); - if (tstate != interp->tstate_head || tstate->next != NULL) - Py_FatalError("Py_EndInterpreter: not the last thread"); + if (tstate != PyThreadState_GET()) + Py_FatalError("Py_EndInterpreter: thread is not current"); + if (tstate->frame != NULL) + Py_FatalError("Py_EndInterpreter: thread still has a frame"); + if (tstate != interp->tstate_head || tstate->next != NULL) + Py_FatalError("Py_EndInterpreter: not the last thread"); - PyImport_Cleanup(); - PyInterpreterState_Clear(interp); - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); + PyImport_Cleanup(); + PyInterpreterState_Clear(interp); + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); } static wchar_t *progname = L"python"; @@ -653,14 +653,14 @@ static wchar_t *progname = L"python"; void Py_SetProgramName(wchar_t *pn) { - if (pn && *pn) - progname = pn; + if (pn && *pn) + progname = pn; } wchar_t * Py_GetProgramName(void) { - return progname; + return progname; } static wchar_t *default_home = NULL; @@ -669,23 +669,23 @@ static wchar_t env_home[PATH_MAX+1]; void Py_SetPythonHome(wchar_t *home) { - default_home = home; + default_home = home; } wchar_t * Py_GetPythonHome(void) { - wchar_t *home = default_home; - if (home == NULL && !Py_IgnoreEnvironmentFlag) { - char* chome = Py_GETENV("PYTHONHOME"); - if (chome) { - size_t r = mbstowcs(env_home, chome, PATH_MAX+1); - if (r != (size_t)-1 && r <= PATH_MAX) - home = env_home; - } + wchar_t *home = default_home; + if (home == NULL && !Py_IgnoreEnvironmentFlag) { + char* chome = Py_GETENV("PYTHONHOME"); + if (chome) { + size_t r = mbstowcs(env_home, chome, PATH_MAX+1); + if (r != (size_t)-1 && r <= PATH_MAX) + home = env_home; + } - } - return home; + } + return home; } /* Create __main__ module */ @@ -693,18 +693,18 @@ Py_GetPythonHome(void) static void initmain(void) { - PyObject *m, *d; - m = PyImport_AddModule("__main__"); - if (m == NULL) - Py_FatalError("can't create __main__ module"); - d = PyModule_GetDict(m); - if (PyDict_GetItemString(d, "__builtins__") == NULL) { - PyObject *bimod = PyImport_ImportModule("builtins"); - if (bimod == NULL || - PyDict_SetItemString(d, "__builtins__", bimod) != 0) - Py_FatalError("can't add __builtins__ to __main__"); - Py_DECREF(bimod); - } + PyObject *m, *d; + m = PyImport_AddModule("__main__"); + if (m == NULL) + Py_FatalError("can't create __main__ module"); + d = PyModule_GetDict(m); + if (PyDict_GetItemString(d, "__builtins__") == NULL) { + PyObject *bimod = PyImport_ImportModule("builtins"); + if (bimod == NULL || + PyDict_SetItemString(d, "__builtins__", bimod) != 0) + Py_FatalError("can't add __builtins__ to __main__"); + Py_DECREF(bimod); + } } /* Import the site module (not into __main__ though) */ @@ -712,386 +712,386 @@ initmain(void) static void initsite(void) { - PyObject *m; - m = PyImport_ImportModule("site"); - if (m == NULL) { - PyErr_Print(); - Py_Finalize(); - exit(1); - } - else { - Py_DECREF(m); - } + PyObject *m; + m = PyImport_ImportModule("site"); + if (m == NULL) { + PyErr_Print(); + Py_Finalize(); + exit(1); + } + else { + Py_DECREF(m); + } } static PyObject* create_stdio(PyObject* io, - int fd, int write_mode, char* name, - char* encoding, char* errors) -{ - PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; - const char* mode; - PyObject *line_buffering; - int buffering, isatty; - - /* stdin is always opened in buffered mode, first because it shouldn't - make a difference in common use cases, second because TextIOWrapper - depends on the presence of a read1() method which only exists on - buffered streams. - */ - if (Py_UnbufferedStdioFlag && write_mode) - buffering = 0; - else - buffering = -1; - if (write_mode) - mode = "wb"; - else - mode = "rb"; - buf = PyObject_CallMethod(io, "open", "isiOOOi", - fd, mode, buffering, - Py_None, Py_None, Py_None, 0); - if (buf == NULL) - goto error; - - if (buffering) { - raw = PyObject_GetAttrString(buf, "raw"); - if (raw == NULL) - goto error; - } - else { - raw = buf; - Py_INCREF(raw); - } - - text = PyUnicode_FromString(name); - if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0) - goto error; - res = PyObject_CallMethod(raw, "isatty", ""); - if (res == NULL) - goto error; - isatty = PyObject_IsTrue(res); - Py_DECREF(res); - if (isatty == -1) - goto error; - if (isatty || Py_UnbufferedStdioFlag) - line_buffering = Py_True; - else - line_buffering = Py_False; - - Py_CLEAR(raw); - Py_CLEAR(text); - - stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", - buf, encoding, errors, - "\n", line_buffering); - Py_CLEAR(buf); - if (stream == NULL) - goto error; - - if (write_mode) - mode = "w"; - else - mode = "r"; - text = PyUnicode_FromString(mode); - if (!text || PyObject_SetAttrString(stream, "mode", text) < 0) - goto error; - Py_CLEAR(text); - return stream; + int fd, int write_mode, char* name, + char* encoding, char* errors) +{ + PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; + const char* mode; + PyObject *line_buffering; + int buffering, isatty; + + /* stdin is always opened in buffered mode, first because it shouldn't + make a difference in common use cases, second because TextIOWrapper + depends on the presence of a read1() method which only exists on + buffered streams. + */ + if (Py_UnbufferedStdioFlag && write_mode) + buffering = 0; + else + buffering = -1; + if (write_mode) + mode = "wb"; + else + mode = "rb"; + buf = PyObject_CallMethod(io, "open", "isiOOOi", + fd, mode, buffering, + Py_None, Py_None, Py_None, 0); + if (buf == NULL) + goto error; + + if (buffering) { + raw = PyObject_GetAttrString(buf, "raw"); + if (raw == NULL) + goto error; + } + else { + raw = buf; + Py_INCREF(raw); + } + + text = PyUnicode_FromString(name); + if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0) + goto error; + res = PyObject_CallMethod(raw, "isatty", ""); + if (res == NULL) + goto error; + isatty = PyObject_IsTrue(res); + Py_DECREF(res); + if (isatty == -1) + goto error; + if (isatty || Py_UnbufferedStdioFlag) + line_buffering = Py_True; + else + line_buffering = Py_False; + + Py_CLEAR(raw); + Py_CLEAR(text); + + stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", + buf, encoding, errors, + "\n", line_buffering); + Py_CLEAR(buf); + if (stream == NULL) + goto error; + + if (write_mode) + mode = "w"; + else + mode = "r"; + text = PyUnicode_FromString(mode); + if (!text || PyObject_SetAttrString(stream, "mode", text) < 0) + goto error; + Py_CLEAR(text); + return stream; error: - Py_XDECREF(buf); - Py_XDECREF(stream); - Py_XDECREF(text); - Py_XDECREF(raw); - return NULL; + Py_XDECREF(buf); + Py_XDECREF(stream); + Py_XDECREF(text); + Py_XDECREF(raw); + return NULL; } /* Initialize sys.stdin, stdout, stderr and builtins.open */ static int initstdio(void) { - PyObject *iomod = NULL, *wrapper; - PyObject *bimod = NULL; - PyObject *m; - PyObject *std = NULL; - int status = 0, fd; - PyObject * encoding_attr; - char *encoding = NULL, *errors; - - /* Hack to avoid a nasty recursion issue when Python is invoked - in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ - if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { - goto error; - } - Py_DECREF(m); - - if (!(m = PyImport_ImportModule("encodings.latin_1"))) { - goto error; - } - Py_DECREF(m); - - if (!(bimod = PyImport_ImportModule("builtins"))) { - goto error; - } - - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { - goto error; - } - - /* Set builtins.open */ - if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { - goto error; - } - - encoding = Py_GETENV("PYTHONIOENCODING"); - errors = NULL; - if (encoding) { - encoding = strdup(encoding); - errors = strchr(encoding, ':'); - if (errors) { - *errors = '\0'; - errors++; - } - } - - /* Set sys.stdin */ - fd = fileno(stdin); - /* Under some conditions stdin, stdout and stderr may not be connected - * and fileno() may point to an invalid file descriptor. For example - * GUI apps don't have valid standard streams by default. - */ - if (fd < 0) { + PyObject *iomod = NULL, *wrapper; + PyObject *bimod = NULL; + PyObject *m; + PyObject *std = NULL; + int status = 0, fd; + PyObject * encoding_attr; + char *encoding = NULL, *errors; + + /* Hack to avoid a nasty recursion issue when Python is invoked + in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ + if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { + goto error; + } + Py_DECREF(m); + + if (!(m = PyImport_ImportModule("encodings.latin_1"))) { + goto error; + } + Py_DECREF(m); + + if (!(bimod = PyImport_ImportModule("builtins"))) { + goto error; + } + + if (!(iomod = PyImport_ImportModule("io"))) { + goto error; + } + if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { + goto error; + } + + /* Set builtins.open */ + if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { + goto error; + } + + encoding = Py_GETENV("PYTHONIOENCODING"); + errors = NULL; + if (encoding) { + encoding = strdup(encoding); + errors = strchr(encoding, ':'); + if (errors) { + *errors = '\0'; + errors++; + } + } + + /* Set sys.stdin */ + fd = fileno(stdin); + /* Under some conditions stdin, stdout and stderr may not be connected + * and fileno() may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + */ + if (fd < 0) { #ifdef MS_WINDOWS - std = Py_None; - Py_INCREF(std); + std = Py_None; + Py_INCREF(std); #else - goto error; + goto error; #endif - } - else { - std = create_stdio(iomod, fd, 0, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - PySys_SetObject("__stdin__", std); - PySys_SetObject("stdin", std); - Py_DECREF(std); - - /* Set sys.stdout */ - fd = fileno(stdout); - if (fd < 0) { + } + else { + std = create_stdio(iomod, fd, 0, "", encoding, errors); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + PySys_SetObject("__stdin__", std); + PySys_SetObject("stdin", std); + Py_DECREF(std); + + /* Set sys.stdout */ + fd = fileno(stdout); + if (fd < 0) { #ifdef MS_WINDOWS - std = Py_None; - Py_INCREF(std); + std = Py_None; + Py_INCREF(std); #else - goto error; + goto error; #endif - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - PySys_SetObject("__stdout__", std); - PySys_SetObject("stdout", std); - Py_DECREF(std); + } + else { + std = create_stdio(iomod, fd, 1, "", encoding, errors); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + PySys_SetObject("__stdout__", std); + PySys_SetObject("stdout", std); + Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ - /* Set sys.stderr, replaces the preliminary stderr */ - fd = fileno(stderr); - if (fd < 0) { + /* Set sys.stderr, replaces the preliminary stderr */ + fd = fileno(stderr); + if (fd < 0) { #ifdef MS_WINDOWS - std = Py_None; - Py_INCREF(std); + std = Py_None; + Py_INCREF(std); #else - goto error; + goto error; #endif - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - - /* Same as hack above, pre-import stderr's codec to avoid recursion - when import.c tries to write to stderr in verbose mode. */ - encoding_attr = PyObject_GetAttrString(std, "encoding"); - if (encoding_attr != NULL) { - const char * encoding; - encoding = _PyUnicode_AsString(encoding_attr); - if (encoding != NULL) { - _PyCodec_Lookup(encoding); - } - } - PyErr_Clear(); /* Not a fatal error if codec isn't available */ - - PySys_SetObject("__stderr__", std); - PySys_SetObject("stderr", std); - Py_DECREF(std); + } + else { + std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + + /* Same as hack above, pre-import stderr's codec to avoid recursion + when import.c tries to write to stderr in verbose mode. */ + encoding_attr = PyObject_GetAttrString(std, "encoding"); + if (encoding_attr != NULL) { + const char * encoding; + encoding = _PyUnicode_AsString(encoding_attr); + if (encoding != NULL) { + _PyCodec_Lookup(encoding); + } + } + PyErr_Clear(); /* Not a fatal error if codec isn't available */ + + PySys_SetObject("__stderr__", std); + PySys_SetObject("stderr", std); + Py_DECREF(std); #endif - if (0) { + if (0) { error: - status = -1; - } + status = -1; + } - if (encoding) - free(encoding); - Py_XDECREF(bimod); - Py_XDECREF(iomod); - return status; + if (encoding) + free(encoding); + Py_XDECREF(bimod); + Py_XDECREF(iomod); + return status; } /* Parse input from a file and execute it */ int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, - PyCompilerFlags *flags) + PyCompilerFlags *flags) { - if (filename == NULL) - filename = "???"; - if (Py_FdIsInteractive(fp, filename)) { - int err = PyRun_InteractiveLoopFlags(fp, filename, flags); - if (closeit) - fclose(fp); - return err; - } - else - return PyRun_SimpleFileExFlags(fp, filename, closeit, flags); + if (filename == NULL) + filename = "???"; + if (Py_FdIsInteractive(fp, filename)) { + int err = PyRun_InteractiveLoopFlags(fp, filename, flags); + if (closeit) + fclose(fp); + return err; + } + else + return PyRun_SimpleFileExFlags(fp, filename, closeit, flags); } int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) { - PyObject *v; - int ret; - PyCompilerFlags local_flags; - - if (flags == NULL) { - flags = &local_flags; - local_flags.cf_flags = 0; - } - v = PySys_GetObject("ps1"); - if (v == NULL) { - PySys_SetObject("ps1", v = PyUnicode_FromString(">>> ")); - Py_XDECREF(v); - } - v = PySys_GetObject("ps2"); - if (v == NULL) { - PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); - Py_XDECREF(v); - } - for (;;) { - ret = PyRun_InteractiveOneFlags(fp, filename, flags); - PRINT_TOTAL_REFS(); - if (ret == E_EOF) - return 0; - /* - if (ret == E_NOMEM) - return -1; - */ - } + PyObject *v; + int ret; + PyCompilerFlags local_flags; + + if (flags == NULL) { + flags = &local_flags; + local_flags.cf_flags = 0; + } + v = PySys_GetObject("ps1"); + if (v == NULL) { + PySys_SetObject("ps1", v = PyUnicode_FromString(">>> ")); + Py_XDECREF(v); + } + v = PySys_GetObject("ps2"); + if (v == NULL) { + PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); + Py_XDECREF(v); + } + for (;;) { + ret = PyRun_InteractiveOneFlags(fp, filename, flags); + PRINT_TOTAL_REFS(); + if (ret == E_EOF) + return 0; + /* + if (ret == E_NOMEM) + return -1; + */ + } } /* compute parser flags based on compiler flags */ static int PARSER_FLAGS(PyCompilerFlags *flags) { - int parser_flags = 0; - if (!flags) - return 0; - if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) - parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; - if (flags->cf_flags & PyCF_IGNORE_COOKIE) - parser_flags |= PyPARSE_IGNORE_COOKIE; - if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) - parser_flags |= PyPARSE_BARRY_AS_BDFL; - return parser_flags; + int parser_flags = 0; + if (!flags) + return 0; + if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) + parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; + if (flags->cf_flags & PyCF_IGNORE_COOKIE) + parser_flags |= PyPARSE_IGNORE_COOKIE; + if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) + parser_flags |= PyPARSE_BARRY_AS_BDFL; + return parser_flags; } #if 0 /* Keep an example of flags with future keyword support. */ #define PARSER_FLAGS(flags) \ - ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ - PyPARSE_DONT_IMPLY_DEDENT : 0) \ - | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \ - PyPARSE_WITH_IS_KEYWORD : 0)) : 0) + ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ + PyPARSE_DONT_IMPLY_DEDENT : 0) \ + | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \ + PyPARSE_WITH_IS_KEYWORD : 0)) : 0) #endif int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) { - PyObject *m, *d, *v, *w, *oenc = NULL; - mod_ty mod; - PyArena *arena; - char *ps1 = "", *ps2 = "", *enc = NULL; - int errcode = 0; - - if (fp == stdin) { - /* Fetch encoding from sys.stdin */ - v = PySys_GetObject("stdin"); - if (v == NULL || v == Py_None) - return -1; - oenc = PyObject_GetAttrString(v, "encoding"); - if (!oenc) - return -1; - enc = _PyUnicode_AsString(oenc); - } - v = PySys_GetObject("ps1"); - if (v != NULL) { - v = PyObject_Str(v); - if (v == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(v)) - ps1 = _PyUnicode_AsString(v); - } - w = PySys_GetObject("ps2"); - if (w != NULL) { - w = PyObject_Str(w); - if (w == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(w)) - ps2 = _PyUnicode_AsString(w); - } - arena = PyArena_New(); - if (arena == NULL) { - Py_XDECREF(v); - Py_XDECREF(w); - Py_XDECREF(oenc); - return -1; - } - mod = PyParser_ASTFromFile(fp, filename, enc, - Py_single_input, ps1, ps2, - flags, &errcode, arena); - Py_XDECREF(v); - Py_XDECREF(w); - Py_XDECREF(oenc); - if (mod == NULL) { - PyArena_Free(arena); - if (errcode == E_EOF) { - PyErr_Clear(); - return E_EOF; - } - PyErr_Print(); - return -1; - } - m = PyImport_AddModule("__main__"); - if (m == NULL) { - PyArena_Free(arena); - return -1; - } - d = PyModule_GetDict(m); - v = run_mod(mod, filename, d, d, flags, arena); - PyArena_Free(arena); - flush_io(); - if (v == NULL) { - PyErr_Print(); - return -1; - } - Py_DECREF(v); - return 0; + PyObject *m, *d, *v, *w, *oenc = NULL; + mod_ty mod; + PyArena *arena; + char *ps1 = "", *ps2 = "", *enc = NULL; + int errcode = 0; + + if (fp == stdin) { + /* Fetch encoding from sys.stdin */ + v = PySys_GetObject("stdin"); + if (v == NULL || v == Py_None) + return -1; + oenc = PyObject_GetAttrString(v, "encoding"); + if (!oenc) + return -1; + enc = _PyUnicode_AsString(oenc); + } + v = PySys_GetObject("ps1"); + if (v != NULL) { + v = PyObject_Str(v); + if (v == NULL) + PyErr_Clear(); + else if (PyUnicode_Check(v)) + ps1 = _PyUnicode_AsString(v); + } + w = PySys_GetObject("ps2"); + if (w != NULL) { + w = PyObject_Str(w); + if (w == NULL) + PyErr_Clear(); + else if (PyUnicode_Check(w)) + ps2 = _PyUnicode_AsString(w); + } + arena = PyArena_New(); + if (arena == NULL) { + Py_XDECREF(v); + Py_XDECREF(w); + Py_XDECREF(oenc); + return -1; + } + mod = PyParser_ASTFromFile(fp, filename, enc, + Py_single_input, ps1, ps2, + flags, &errcode, arena); + Py_XDECREF(v); + Py_XDECREF(w); + Py_XDECREF(oenc); + if (mod == NULL) { + PyArena_Free(arena); + if (errcode == E_EOF) { + PyErr_Clear(); + return E_EOF; + } + PyErr_Print(); + return -1; + } + m = PyImport_AddModule("__main__"); + if (m == NULL) { + PyArena_Free(arena); + return -1; + } + d = PyModule_GetDict(m); + v = run_mod(mod, filename, d, d, flags, arena); + PyArena_Free(arena); + flush_io(); + if (v == NULL) { + PyErr_Print(); + return -1; + } + Py_DECREF(v); + return 0; } /* Check whether a file maybe a pyc file: Look at the extension, @@ -1100,739 +1100,739 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags static int maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit) { - if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) - return 1; - - /* Only look into the file if we are allowed to close it, since - it then should also be seekable. */ - if (closeit) { - /* Read only two bytes of the magic. If the file was opened in - text mode, the bytes 3 and 4 of the magic (\r\n) might not - be read as they are on disk. */ - unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; - unsigned char buf[2]; - /* Mess: In case of -x, the stream is NOT at its start now, - and ungetc() was used to push back the first newline, - which makes the current stream position formally undefined, - and a x-platform nightmare. - Unfortunately, we have no direct way to know whether -x - was specified. So we use a terrible hack: if the current - stream position is not 0, we assume -x was specified, and - give up. Bug 132850 on SourceForge spells out the - hopelessness of trying anything else (fseek and ftell - don't work predictably x-platform for text-mode files). - */ - int ispyc = 0; - if (ftell(fp) == 0) { - if (fread(buf, 1, 2, fp) == 2 && - ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) - ispyc = 1; - rewind(fp); - } - return ispyc; - } - return 0; + if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) + return 1; + + /* Only look into the file if we are allowed to close it, since + it then should also be seekable. */ + if (closeit) { + /* Read only two bytes of the magic. If the file was opened in + text mode, the bytes 3 and 4 of the magic (\r\n) might not + be read as they are on disk. */ + unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; + unsigned char buf[2]; + /* Mess: In case of -x, the stream is NOT at its start now, + and ungetc() was used to push back the first newline, + which makes the current stream position formally undefined, + and a x-platform nightmare. + Unfortunately, we have no direct way to know whether -x + was specified. So we use a terrible hack: if the current + stream position is not 0, we assume -x was specified, and + give up. Bug 132850 on SourceForge spells out the + hopelessness of trying anything else (fseek and ftell + don't work predictably x-platform for text-mode files). + */ + int ispyc = 0; + if (ftell(fp) == 0) { + if (fread(buf, 1, 2, fp) == 2 && + ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) + ispyc = 1; + rewind(fp); + } + return ispyc; + } + return 0; } int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, - PyCompilerFlags *flags) -{ - PyObject *m, *d, *v; - const char *ext; - int set_file_name = 0, ret, len; - - m = PyImport_AddModule("__main__"); - if (m == NULL) - return -1; - d = PyModule_GetDict(m); - if (PyDict_GetItemString(d, "__file__") == NULL) { - PyObject *f; - f = PyUnicode_DecodeFSDefault(filename); - if (f == NULL) - return -1; - if (PyDict_SetItemString(d, "__file__", f) < 0) { - Py_DECREF(f); - return -1; - } - if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) - return -1; - set_file_name = 1; - Py_DECREF(f); - } - len = strlen(filename); - ext = filename + len - (len > 4 ? 4 : 0); - if (maybe_pyc_file(fp, filename, ext, closeit)) { - /* Try to run a pyc file. First, re-open in binary */ - if (closeit) - fclose(fp); - if ((fp = fopen(filename, "rb")) == NULL) { - fprintf(stderr, "python: Can't reopen .pyc file\n"); - ret = -1; - goto done; - } - /* Turn on optimization if a .pyo file is given */ - if (strcmp(ext, ".pyo") == 0) - Py_OptimizeFlag = 1; - v = run_pyc_file(fp, filename, d, d, flags); - } else { - v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d, - closeit, flags); - } - flush_io(); - if (v == NULL) { - PyErr_Print(); - ret = -1; - goto done; - } - Py_DECREF(v); - ret = 0; + PyCompilerFlags *flags) +{ + PyObject *m, *d, *v; + const char *ext; + int set_file_name = 0, ret, len; + + m = PyImport_AddModule("__main__"); + if (m == NULL) + return -1; + d = PyModule_GetDict(m); + if (PyDict_GetItemString(d, "__file__") == NULL) { + PyObject *f; + f = PyUnicode_DecodeFSDefault(filename); + if (f == NULL) + return -1; + if (PyDict_SetItemString(d, "__file__", f) < 0) { + Py_DECREF(f); + return -1; + } + if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) + return -1; + set_file_name = 1; + Py_DECREF(f); + } + len = strlen(filename); + ext = filename + len - (len > 4 ? 4 : 0); + if (maybe_pyc_file(fp, filename, ext, closeit)) { + /* Try to run a pyc file. First, re-open in binary */ + if (closeit) + fclose(fp); + if ((fp = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "python: Can't reopen .pyc file\n"); + ret = -1; + goto done; + } + /* Turn on optimization if a .pyo file is given */ + if (strcmp(ext, ".pyo") == 0) + Py_OptimizeFlag = 1; + v = run_pyc_file(fp, filename, d, d, flags); + } else { + v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d, + closeit, flags); + } + flush_io(); + if (v == NULL) { + PyErr_Print(); + ret = -1; + goto done; + } + Py_DECREF(v); + ret = 0; done: - if (set_file_name && PyDict_DelItemString(d, "__file__")) - PyErr_Clear(); - return ret; + if (set_file_name && PyDict_DelItemString(d, "__file__")) + PyErr_Clear(); + return ret; } int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) { - PyObject *m, *d, *v; - m = PyImport_AddModule("__main__"); - if (m == NULL) - return -1; - d = PyModule_GetDict(m); - v = PyRun_StringFlags(command, Py_file_input, d, d, flags); - if (v == NULL) { - PyErr_Print(); - return -1; - } - Py_DECREF(v); - return 0; + PyObject *m, *d, *v; + m = PyImport_AddModule("__main__"); + if (m == NULL) + return -1; + d = PyModule_GetDict(m); + v = PyRun_StringFlags(command, Py_file_input, d, d, flags); + if (v == NULL) { + PyErr_Print(); + return -1; + } + Py_DECREF(v); + return 0; } static int parse_syntax_error(PyObject *err, PyObject **message, const char **filename, - int *lineno, int *offset, const char **text) -{ - long hold; - PyObject *v; - - /* old style errors */ - if (PyTuple_Check(err)) - return PyArg_ParseTuple(err, "O(ziiz)", message, filename, - lineno, offset, text); - - /* new style errors. `err' is an instance */ - - if (! (v = PyObject_GetAttrString(err, "msg"))) - goto finally; - *message = v; - - if (!(v = PyObject_GetAttrString(err, "filename"))) - goto finally; - if (v == Py_None) - *filename = NULL; - else if (! (*filename = _PyUnicode_AsString(v))) - goto finally; - - Py_DECREF(v); - if (!(v = PyObject_GetAttrString(err, "lineno"))) - goto finally; - hold = PyLong_AsLong(v); - Py_DECREF(v); - v = NULL; - if (hold < 0 && PyErr_Occurred()) - goto finally; - *lineno = (int)hold; - - if (!(v = PyObject_GetAttrString(err, "offset"))) - goto finally; - if (v == Py_None) { - *offset = -1; - Py_DECREF(v); - v = NULL; - } else { - hold = PyLong_AsLong(v); - Py_DECREF(v); - v = NULL; - if (hold < 0 && PyErr_Occurred()) - goto finally; - *offset = (int)hold; - } - - if (!(v = PyObject_GetAttrString(err, "text"))) - goto finally; - if (v == Py_None) - *text = NULL; - else if (!PyUnicode_Check(v) || - !(*text = _PyUnicode_AsString(v))) - goto finally; - Py_DECREF(v); - return 1; + int *lineno, int *offset, const char **text) +{ + long hold; + PyObject *v; + + /* old style errors */ + if (PyTuple_Check(err)) + return PyArg_ParseTuple(err, "O(ziiz)", message, filename, + lineno, offset, text); + + /* new style errors. `err' is an instance */ + + if (! (v = PyObject_GetAttrString(err, "msg"))) + goto finally; + *message = v; + + if (!(v = PyObject_GetAttrString(err, "filename"))) + goto finally; + if (v == Py_None) + *filename = NULL; + else if (! (*filename = _PyUnicode_AsString(v))) + goto finally; + + Py_DECREF(v); + if (!(v = PyObject_GetAttrString(err, "lineno"))) + goto finally; + hold = PyLong_AsLong(v); + Py_DECREF(v); + v = NULL; + if (hold < 0 && PyErr_Occurred()) + goto finally; + *lineno = (int)hold; + + if (!(v = PyObject_GetAttrString(err, "offset"))) + goto finally; + if (v == Py_None) { + *offset = -1; + Py_DECREF(v); + v = NULL; + } else { + hold = PyLong_AsLong(v); + Py_DECREF(v); + v = NULL; + if (hold < 0 && PyErr_Occurred()) + goto finally; + *offset = (int)hold; + } + + if (!(v = PyObject_GetAttrString(err, "text"))) + goto finally; + if (v == Py_None) + *text = NULL; + else if (!PyUnicode_Check(v) || + !(*text = _PyUnicode_AsString(v))) + goto finally; + Py_DECREF(v); + return 1; finally: - Py_XDECREF(v); - return 0; + Py_XDECREF(v); + return 0; } void PyErr_Print(void) { - PyErr_PrintEx(1); + PyErr_PrintEx(1); } static void print_error_text(PyObject *f, int offset, const char *text) { - char *nl; - if (offset >= 0) { - if (offset > 0 && offset == (int)strlen(text)) - offset--; - for (;;) { - nl = strchr(text, '\n'); - if (nl == NULL || nl-text >= offset) - break; - offset -= (int)(nl+1-text); - text = nl+1; - } - while (*text == ' ' || *text == '\t') { - text++; - offset--; - } - } - PyFile_WriteString(" ", f); - PyFile_WriteString(text, f); - if (*text == '\0' || text[strlen(text)-1] != '\n') - PyFile_WriteString("\n", f); - if (offset == -1) - return; - PyFile_WriteString(" ", f); - offset--; - while (offset > 0) { - PyFile_WriteString(" ", f); - offset--; - } - PyFile_WriteString("^\n", f); + char *nl; + if (offset >= 0) { + if (offset > 0 && offset == (int)strlen(text)) + offset--; + for (;;) { + nl = strchr(text, '\n'); + if (nl == NULL || nl-text >= offset) + break; + offset -= (int)(nl+1-text); + text = nl+1; + } + while (*text == ' ' || *text == '\t') { + text++; + offset--; + } + } + PyFile_WriteString(" ", f); + PyFile_WriteString(text, f); + if (*text == '\0' || text[strlen(text)-1] != '\n') + PyFile_WriteString("\n", f); + if (offset == -1) + return; + PyFile_WriteString(" ", f); + offset--; + while (offset > 0) { + PyFile_WriteString(" ", f); + offset--; + } + PyFile_WriteString("^\n", f); } static void handle_system_exit(void) { - PyObject *exception, *value, *tb; - int exitcode = 0; - - if (Py_InspectFlag) - /* Don't exit if -i flag was given. This flag is set to 0 - * when entering interactive mode for inspecting. */ - return; - - PyErr_Fetch(&exception, &value, &tb); - fflush(stdout); - if (value == NULL || value == Py_None) - goto done; - if (PyExceptionInstance_Check(value)) { - /* The error code should be in the `code' attribute. */ - PyObject *code = PyObject_GetAttrString(value, "code"); - if (code) { - Py_DECREF(value); - value = code; - if (value == Py_None) - goto done; - } - /* If we failed to dig out the 'code' attribute, - just let the else clause below print the error. */ - } - if (PyLong_Check(value)) - exitcode = (int)PyLong_AsLong(value); - else { - PyObject_Print(value, stderr, Py_PRINT_RAW); - PySys_WriteStderr("\n"); - exitcode = 1; - } + PyObject *exception, *value, *tb; + int exitcode = 0; + + if (Py_InspectFlag) + /* Don't exit if -i flag was given. This flag is set to 0 + * when entering interactive mode for inspecting. */ + return; + + PyErr_Fetch(&exception, &value, &tb); + fflush(stdout); + if (value == NULL || value == Py_None) + goto done; + if (PyExceptionInstance_Check(value)) { + /* The error code should be in the `code' attribute. */ + PyObject *code = PyObject_GetAttrString(value, "code"); + if (code) { + Py_DECREF(value); + value = code; + if (value == Py_None) + goto done; + } + /* If we failed to dig out the 'code' attribute, + just let the else clause below print the error. */ + } + if (PyLong_Check(value)) + exitcode = (int)PyLong_AsLong(value); + else { + PyObject_Print(value, stderr, Py_PRINT_RAW); + PySys_WriteStderr("\n"); + exitcode = 1; + } done: - /* Restore and clear the exception info, in order to properly decref - * the exception, value, and traceback. If we just exit instead, - * these leak, which confuses PYTHONDUMPREFS output, and may prevent - * some finalizers from running. - */ - PyErr_Restore(exception, value, tb); - PyErr_Clear(); - Py_Exit(exitcode); - /* NOTREACHED */ + /* Restore and clear the exception info, in order to properly decref + * the exception, value, and traceback. If we just exit instead, + * these leak, which confuses PYTHONDUMPREFS output, and may prevent + * some finalizers from running. + */ + PyErr_Restore(exception, value, tb); + PyErr_Clear(); + Py_Exit(exitcode); + /* NOTREACHED */ } void PyErr_PrintEx(int set_sys_last_vars) { - PyObject *exception, *v, *tb, *hook; - - if (PyErr_ExceptionMatches(PyExc_SystemExit)) { - handle_system_exit(); - } - PyErr_Fetch(&exception, &v, &tb); - if (exception == NULL) - return; - PyErr_NormalizeException(&exception, &v, &tb); - if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); - } - PyException_SetTraceback(v, tb); - if (exception == NULL) - return; - /* Now we know v != NULL too */ - if (set_sys_last_vars) { - PySys_SetObject("last_type", exception); - PySys_SetObject("last_value", v); - PySys_SetObject("last_traceback", tb); - } - hook = PySys_GetObject("excepthook"); - if (hook) { - PyObject *args = PyTuple_Pack(3, exception, v, tb); - PyObject *result = PyEval_CallObject(hook, args); - if (result == NULL) { - PyObject *exception2, *v2, *tb2; - if (PyErr_ExceptionMatches(PyExc_SystemExit)) { - handle_system_exit(); - } - PyErr_Fetch(&exception2, &v2, &tb2); - PyErr_NormalizeException(&exception2, &v2, &tb2); - /* It should not be possible for exception2 or v2 - to be NULL. However PyErr_Display() can't - tolerate NULLs, so just be safe. */ - if (exception2 == NULL) { - exception2 = Py_None; - Py_INCREF(exception2); - } - if (v2 == NULL) { - v2 = Py_None; - Py_INCREF(v2); - } - fflush(stdout); - PySys_WriteStderr("Error in sys.excepthook:\n"); - PyErr_Display(exception2, v2, tb2); - PySys_WriteStderr("\nOriginal exception was:\n"); - PyErr_Display(exception, v, tb); - Py_DECREF(exception2); - Py_DECREF(v2); - Py_XDECREF(tb2); - } - Py_XDECREF(result); - Py_XDECREF(args); - } else { - PySys_WriteStderr("sys.excepthook is missing\n"); - PyErr_Display(exception, v, tb); - } - Py_XDECREF(exception); - Py_XDECREF(v); - Py_XDECREF(tb); + PyObject *exception, *v, *tb, *hook; + + if (PyErr_ExceptionMatches(PyExc_SystemExit)) { + handle_system_exit(); + } + PyErr_Fetch(&exception, &v, &tb); + if (exception == NULL) + return; + PyErr_NormalizeException(&exception, &v, &tb); + if (tb == NULL) { + tb = Py_None; + Py_INCREF(tb); + } + PyException_SetTraceback(v, tb); + if (exception == NULL) + return; + /* Now we know v != NULL too */ + if (set_sys_last_vars) { + PySys_SetObject("last_type", exception); + PySys_SetObject("last_value", v); + PySys_SetObject("last_traceback", tb); + } + hook = PySys_GetObject("excepthook"); + if (hook) { + PyObject *args = PyTuple_Pack(3, exception, v, tb); + PyObject *result = PyEval_CallObject(hook, args); + if (result == NULL) { + PyObject *exception2, *v2, *tb2; + if (PyErr_ExceptionMatches(PyExc_SystemExit)) { + handle_system_exit(); + } + PyErr_Fetch(&exception2, &v2, &tb2); + PyErr_NormalizeException(&exception2, &v2, &tb2); + /* It should not be possible for exception2 or v2 + to be NULL. However PyErr_Display() can't + tolerate NULLs, so just be safe. */ + if (exception2 == NULL) { + exception2 = Py_None; + Py_INCREF(exception2); + } + if (v2 == NULL) { + v2 = Py_None; + Py_INCREF(v2); + } + fflush(stdout); + PySys_WriteStderr("Error in sys.excepthook:\n"); + PyErr_Display(exception2, v2, tb2); + PySys_WriteStderr("\nOriginal exception was:\n"); + PyErr_Display(exception, v, tb); + Py_DECREF(exception2); + Py_DECREF(v2); + Py_XDECREF(tb2); + } + Py_XDECREF(result); + Py_XDECREF(args); + } else { + PySys_WriteStderr("sys.excepthook is missing\n"); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); } static void print_exception(PyObject *f, PyObject *value) { - int err = 0; - PyObject *type, *tb; - - if (!PyExceptionInstance_Check(value)) { - PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); - PyFile_WriteString(Py_TYPE(value)->tp_name, f); - PyFile_WriteString(" found\n", f); - return; - } - - Py_INCREF(value); - fflush(stdout); - type = (PyObject *) Py_TYPE(value); - tb = PyException_GetTraceback(value); - if (tb && tb != Py_None) - err = PyTraceBack_Print(tb, f); - if (err == 0 && - PyObject_HasAttrString(value, "print_file_and_line")) - { - PyObject *message; - const char *filename, *text; - int lineno, offset; - if (!parse_syntax_error(value, &message, &filename, - &lineno, &offset, &text)) - PyErr_Clear(); - else { - char buf[10]; - PyFile_WriteString(" File \"", f); - if (filename == NULL) - PyFile_WriteString("", f); - else - PyFile_WriteString(filename, f); - PyFile_WriteString("\", line ", f); - PyOS_snprintf(buf, sizeof(buf), "%d", lineno); - PyFile_WriteString(buf, f); - PyFile_WriteString("\n", f); - if (text != NULL) - print_error_text(f, offset, text); - Py_DECREF(value); - value = message; - /* Can't be bothered to check all those - PyFile_WriteString() calls */ - if (PyErr_Occurred()) - err = -1; - } - } - if (err) { - /* Don't do anything else */ - } - else { - PyObject* moduleName; - char* className; - assert(PyExceptionClass_Check(type)); - className = PyExceptionClass_Name(type); - if (className != NULL) { - char *dot = strrchr(className, '.'); - if (dot != NULL) - className = dot+1; - } - - moduleName = PyObject_GetAttrString(type, "__module__"); - if (moduleName == NULL || !PyUnicode_Check(moduleName)) - { - Py_DECREF(moduleName); - err = PyFile_WriteString("", f); - } - else { - char* modstr = _PyUnicode_AsString(moduleName); - if (modstr && strcmp(modstr, "builtins")) - { - err = PyFile_WriteString(modstr, f); - err += PyFile_WriteString(".", f); - } - Py_DECREF(moduleName); - } - if (err == 0) { - if (className == NULL) - err = PyFile_WriteString("", f); - else - err = PyFile_WriteString(className, f); - } - } - if (err == 0 && (value != Py_None)) { - PyObject *s = PyObject_Str(value); - /* only print colon if the str() of the - object is not the empty string - */ - if (s == NULL) - err = -1; - else if (!PyUnicode_Check(s) || - PyUnicode_GetSize(s) != 0) - err = PyFile_WriteString(": ", f); - if (err == 0) - err = PyFile_WriteObject(s, f, Py_PRINT_RAW); - Py_XDECREF(s); - } - /* try to write a newline in any case */ - err += PyFile_WriteString("\n", f); - Py_XDECREF(tb); - Py_DECREF(value); - /* If an error happened here, don't show it. - XXX This is wrong, but too many callers rely on this behavior. */ - if (err != 0) - PyErr_Clear(); + int err = 0; + PyObject *type, *tb; + + if (!PyExceptionInstance_Check(value)) { + PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); + PyFile_WriteString(Py_TYPE(value)->tp_name, f); + PyFile_WriteString(" found\n", f); + return; + } + + Py_INCREF(value); + fflush(stdout); + type = (PyObject *) Py_TYPE(value); + tb = PyException_GetTraceback(value); + if (tb && tb != Py_None) + err = PyTraceBack_Print(tb, f); + if (err == 0 && + PyObject_HasAttrString(value, "print_file_and_line")) + { + PyObject *message; + const char *filename, *text; + int lineno, offset; + if (!parse_syntax_error(value, &message, &filename, + &lineno, &offset, &text)) + PyErr_Clear(); + else { + char buf[10]; + PyFile_WriteString(" File \"", f); + if (filename == NULL) + PyFile_WriteString("", f); + else + PyFile_WriteString(filename, f); + PyFile_WriteString("\", line ", f); + PyOS_snprintf(buf, sizeof(buf), "%d", lineno); + PyFile_WriteString(buf, f); + PyFile_WriteString("\n", f); + if (text != NULL) + print_error_text(f, offset, text); + Py_DECREF(value); + value = message; + /* Can't be bothered to check all those + PyFile_WriteString() calls */ + if (PyErr_Occurred()) + err = -1; + } + } + if (err) { + /* Don't do anything else */ + } + else { + PyObject* moduleName; + char* className; + assert(PyExceptionClass_Check(type)); + className = PyExceptionClass_Name(type); + if (className != NULL) { + char *dot = strrchr(className, '.'); + if (dot != NULL) + className = dot+1; + } + + moduleName = PyObject_GetAttrString(type, "__module__"); + if (moduleName == NULL || !PyUnicode_Check(moduleName)) + { + Py_DECREF(moduleName); + err = PyFile_WriteString("", f); + } + else { + char* modstr = _PyUnicode_AsString(moduleName); + if (modstr && strcmp(modstr, "builtins")) + { + err = PyFile_WriteString(modstr, f); + err += PyFile_WriteString(".", f); + } + Py_DECREF(moduleName); + } + if (err == 0) { + if (className == NULL) + err = PyFile_WriteString("", f); + else + err = PyFile_WriteString(className, f); + } + } + if (err == 0 && (value != Py_None)) { + PyObject *s = PyObject_Str(value); + /* only print colon if the str() of the + object is not the empty string + */ + if (s == NULL) + err = -1; + else if (!PyUnicode_Check(s) || + PyUnicode_GetSize(s) != 0) + err = PyFile_WriteString(": ", f); + if (err == 0) + err = PyFile_WriteObject(s, f, Py_PRINT_RAW); + Py_XDECREF(s); + } + /* try to write a newline in any case */ + err += PyFile_WriteString("\n", f); + Py_XDECREF(tb); + Py_DECREF(value); + /* If an error happened here, don't show it. + XXX This is wrong, but too many callers rely on this behavior. */ + if (err != 0) + PyErr_Clear(); } static const char *cause_message = - "\nThe above exception was the direct cause " - "of the following exception:\n\n"; + "\nThe above exception was the direct cause " + "of the following exception:\n\n"; static const char *context_message = - "\nDuring handling of the above exception, " - "another exception occurred:\n\n"; + "\nDuring handling of the above exception, " + "another exception occurred:\n\n"; static void print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) { - int err = 0, res; - PyObject *cause, *context; - - if (seen != NULL) { - /* Exception chaining */ - if (PySet_Add(seen, value) == -1) - PyErr_Clear(); - else if (PyExceptionInstance_Check(value)) { - cause = PyException_GetCause(value); - context = PyException_GetContext(value); - if (cause) { - res = PySet_Contains(seen, cause); - if (res == -1) - PyErr_Clear(); - if (res == 0) { - print_exception_recursive( - f, cause, seen); - err |= PyFile_WriteString( - cause_message, f); - } - } - else if (context) { - res = PySet_Contains(seen, context); - if (res == -1) - PyErr_Clear(); - if (res == 0) { - print_exception_recursive( - f, context, seen); - err |= PyFile_WriteString( - context_message, f); - } - } - Py_XDECREF(context); - Py_XDECREF(cause); - } - } - print_exception(f, value); - if (err != 0) - PyErr_Clear(); + int err = 0, res; + PyObject *cause, *context; + + if (seen != NULL) { + /* Exception chaining */ + if (PySet_Add(seen, value) == -1) + PyErr_Clear(); + else if (PyExceptionInstance_Check(value)) { + cause = PyException_GetCause(value); + context = PyException_GetContext(value); + if (cause) { + res = PySet_Contains(seen, cause); + if (res == -1) + PyErr_Clear(); + if (res == 0) { + print_exception_recursive( + f, cause, seen); + err |= PyFile_WriteString( + cause_message, f); + } + } + else if (context) { + res = PySet_Contains(seen, context); + if (res == -1) + PyErr_Clear(); + if (res == 0) { + print_exception_recursive( + f, context, seen); + err |= PyFile_WriteString( + context_message, f); + } + } + Py_XDECREF(context); + Py_XDECREF(cause); + } + } + print_exception(f, value); + if (err != 0) + PyErr_Clear(); } void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { - PyObject *seen; - PyObject *f = PySys_GetObject("stderr"); - if (f == Py_None) { - /* pass */ - } - else if (f == NULL) { - _PyObject_Dump(value); - fprintf(stderr, "lost sys.stderr\n"); - } - else { - /* We choose to ignore seen being possibly NULL, and report - at least the main exception (it could be a MemoryError). - */ - seen = PySet_New(NULL); - if (seen == NULL) - PyErr_Clear(); - print_exception_recursive(f, value, seen); - Py_XDECREF(seen); - } + PyObject *seen; + PyObject *f = PySys_GetObject("stderr"); + if (f == Py_None) { + /* pass */ + } + else if (f == NULL) { + _PyObject_Dump(value); + fprintf(stderr, "lost sys.stderr\n"); + } + else { + /* We choose to ignore seen being possibly NULL, and report + at least the main exception (it could be a MemoryError). + */ + seen = PySet_New(NULL); + if (seen == NULL) + PyErr_Clear(); + print_exception_recursive(f, value, seen); + Py_XDECREF(seen); + } } PyObject * PyRun_StringFlags(const char *str, int start, PyObject *globals, - PyObject *locals, PyCompilerFlags *flags) + PyObject *locals, PyCompilerFlags *flags) { - PyObject *ret = NULL; - mod_ty mod; - PyArena *arena = PyArena_New(); - if (arena == NULL) - return NULL; + PyObject *ret = NULL; + mod_ty mod; + PyArena *arena = PyArena_New(); + if (arena == NULL) + return NULL; - mod = PyParser_ASTFromString(str, "", start, flags, arena); - if (mod != NULL) - ret = run_mod(mod, "", globals, locals, flags, arena); - PyArena_Free(arena); - return ret; + mod = PyParser_ASTFromString(str, "", start, flags, arena); + if (mod != NULL) + ret = run_mod(mod, "", globals, locals, flags, arena); + PyArena_Free(arena); + return ret; } PyObject * PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, - PyObject *locals, int closeit, PyCompilerFlags *flags) -{ - PyObject *ret; - mod_ty mod; - PyArena *arena = PyArena_New(); - if (arena == NULL) - return NULL; - - mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, - flags, NULL, arena); - if (closeit) - fclose(fp); - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - ret = run_mod(mod, filename, globals, locals, flags, arena); - PyArena_Free(arena); - return ret; + PyObject *locals, int closeit, PyCompilerFlags *flags) +{ + PyObject *ret; + mod_ty mod; + PyArena *arena = PyArena_New(); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, + flags, NULL, arena); + if (closeit) + fclose(fp); + if (mod == NULL) { + PyArena_Free(arena); + return NULL; + } + ret = run_mod(mod, filename, globals, locals, flags, arena); + PyArena_Free(arena); + return ret; } static void flush_io(void) { - PyObject *f, *r; - PyObject *type, *value, *traceback; + PyObject *f, *r; + PyObject *type, *value, *traceback; - /* Save the current exception */ - PyErr_Fetch(&type, &value, &traceback); + /* Save the current exception */ + PyErr_Fetch(&type, &value, &traceback); - f = PySys_GetObject("stderr"); - if (f != NULL) { - r = PyObject_CallMethod(f, "flush", ""); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - f = PySys_GetObject("stdout"); - if (f != NULL) { - r = PyObject_CallMethod(f, "flush", ""); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } + f = PySys_GetObject("stderr"); + if (f != NULL) { + r = PyObject_CallMethod(f, "flush", ""); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + f = PySys_GetObject("stdout"); + if (f != NULL) { + r = PyObject_CallMethod(f, "flush", ""); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } - PyErr_Restore(type, value, traceback); + PyErr_Restore(type, value, traceback); } static PyObject * run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags, PyArena *arena) + PyCompilerFlags *flags, PyArena *arena) { - PyCodeObject *co; - PyObject *v; - co = PyAST_Compile(mod, filename, flags, arena); - if (co == NULL) - return NULL; - v = PyEval_EvalCode(co, globals, locals); - Py_DECREF(co); - return v; + PyCodeObject *co; + PyObject *v; + co = PyAST_Compile(mod, filename, flags, arena); + if (co == NULL) + return NULL; + v = PyEval_EvalCode(co, globals, locals); + Py_DECREF(co); + return v; } static PyObject * run_pyc_file(FILE *fp, const char *filename, PyObject *globals, - PyObject *locals, PyCompilerFlags *flags) -{ - PyCodeObject *co; - PyObject *v; - long magic; - long PyImport_GetMagicNumber(void); - - magic = PyMarshal_ReadLongFromFile(fp); - if (magic != PyImport_GetMagicNumber()) { - PyErr_SetString(PyExc_RuntimeError, - "Bad magic number in .pyc file"); - return NULL; - } - (void) PyMarshal_ReadLongFromFile(fp); - v = PyMarshal_ReadLastObjectFromFile(fp); - fclose(fp); - if (v == NULL || !PyCode_Check(v)) { - Py_XDECREF(v); - PyErr_SetString(PyExc_RuntimeError, - "Bad code object in .pyc file"); - return NULL; - } - co = (PyCodeObject *)v; - v = PyEval_EvalCode(co, globals, locals); - if (v && flags) - flags->cf_flags |= (co->co_flags & PyCF_MASK); - Py_DECREF(co); - return v; + PyObject *locals, PyCompilerFlags *flags) +{ + PyCodeObject *co; + PyObject *v; + long magic; + long PyImport_GetMagicNumber(void); + + magic = PyMarshal_ReadLongFromFile(fp); + if (magic != PyImport_GetMagicNumber()) { + PyErr_SetString(PyExc_RuntimeError, + "Bad magic number in .pyc file"); + return NULL; + } + (void) PyMarshal_ReadLongFromFile(fp); + v = PyMarshal_ReadLastObjectFromFile(fp); + fclose(fp); + if (v == NULL || !PyCode_Check(v)) { + Py_XDECREF(v); + PyErr_SetString(PyExc_RuntimeError, + "Bad code object in .pyc file"); + return NULL; + } + co = (PyCodeObject *)v; + v = PyEval_EvalCode(co, globals, locals); + if (v && flags) + flags->cf_flags |= (co->co_flags & PyCF_MASK); + Py_DECREF(co); + return v; } PyObject * Py_CompileStringFlags(const char *str, const char *filename, int start, - PyCompilerFlags *flags) -{ - PyCodeObject *co; - mod_ty mod; - PyArena *arena = PyArena_New(); - if (arena == NULL) - return NULL; - - mod = PyParser_ASTFromString(str, filename, start, flags, arena); - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { - PyObject *result = PyAST_mod2obj(mod); - PyArena_Free(arena); - return result; - } - co = PyAST_Compile(mod, filename, flags, arena); - PyArena_Free(arena); - return (PyObject *)co; + PyCompilerFlags *flags) +{ + PyCodeObject *co; + mod_ty mod; + PyArena *arena = PyArena_New(); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromString(str, filename, start, flags, arena); + if (mod == NULL) { + PyArena_Free(arena); + return NULL; + } + if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { + PyObject *result = PyAST_mod2obj(mod); + PyArena_Free(arena); + return result; + } + co = PyAST_Compile(mod, filename, flags, arena); + PyArena_Free(arena); + return (PyObject *)co; } struct symtable * Py_SymtableString(const char *str, const char *filename, int start) { - struct symtable *st; - mod_ty mod; - PyCompilerFlags flags; - PyArena *arena = PyArena_New(); - if (arena == NULL) - return NULL; + struct symtable *st; + mod_ty mod; + PyCompilerFlags flags; + PyArena *arena = PyArena_New(); + if (arena == NULL) + return NULL; - flags.cf_flags = 0; - mod = PyParser_ASTFromString(str, filename, start, &flags, arena); - if (mod == NULL) { - PyArena_Free(arena); - return NULL; - } - st = PySymtable_Build(mod, filename, 0); - PyArena_Free(arena); - return st; + flags.cf_flags = 0; + mod = PyParser_ASTFromString(str, filename, start, &flags, arena); + if (mod == NULL) { + PyArena_Free(arena); + return NULL; + } + st = PySymtable_Build(mod, filename, 0); + PyArena_Free(arena); + return st; } /* Preferred access to parser is through AST. */ mod_ty PyParser_ASTFromString(const char *s, const char *filename, int start, - PyCompilerFlags *flags, PyArena *arena) -{ - mod_ty mod; - PyCompilerFlags localflags; - perrdetail err; - int iflags = PARSER_FLAGS(flags); - - node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, - &_PyParser_Grammar, start, &err, - &iflags); - if (flags == NULL) { - localflags.cf_flags = 0; - flags = &localflags; - } - if (n) { - flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNode(n, flags, filename, arena); - PyNode_Free(n); - return mod; - } - else { - err_input(&err); - return NULL; - } + PyCompilerFlags *flags, PyArena *arena) +{ + mod_ty mod; + PyCompilerFlags localflags; + perrdetail err; + int iflags = PARSER_FLAGS(flags); + + node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, + &_PyParser_Grammar, start, &err, + &iflags); + if (flags == NULL) { + localflags.cf_flags = 0; + flags = &localflags; + } + if (n) { + flags->cf_flags |= iflags & PyCF_MASK; + mod = PyAST_FromNode(n, flags, filename, arena); + PyNode_Free(n); + return mod; + } + else { + err_input(&err); + return NULL; + } } mod_ty PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, - int start, char *ps1, - char *ps2, PyCompilerFlags *flags, int *errcode, - PyArena *arena) -{ - mod_ty mod; - PyCompilerFlags localflags; - perrdetail err; - int iflags = PARSER_FLAGS(flags); - - node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, - &_PyParser_Grammar, - start, ps1, ps2, &err, &iflags); - if (flags == NULL) { - localflags.cf_flags = 0; - flags = &localflags; - } - if (n) { - flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNode(n, flags, filename, arena); - PyNode_Free(n); - return mod; - } - else { - err_input(&err); - if (errcode) - *errcode = err.error; - return NULL; - } + int start, char *ps1, + char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) +{ + mod_ty mod; + PyCompilerFlags localflags; + perrdetail err; + int iflags = PARSER_FLAGS(flags); + + node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, + &_PyParser_Grammar, + start, ps1, ps2, &err, &iflags); + if (flags == NULL) { + localflags.cf_flags = 0; + flags = &localflags; + } + if (n) { + flags->cf_flags |= iflags & PyCF_MASK; + mod = PyAST_FromNode(n, flags, filename, arena); + PyNode_Free(n); + return mod; + } + else { + err_input(&err); + if (errcode) + *errcode = err.error; + return NULL; + } } /* Simplified interface to parsefile -- return node or set exception */ @@ -1840,14 +1840,14 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, node * PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) { - perrdetail err; - node *n = PyParser_ParseFileFlags(fp, filename, NULL, - &_PyParser_Grammar, - start, NULL, NULL, &err, flags); - if (n == NULL) - err_input(&err); + perrdetail err; + node *n = PyParser_ParseFileFlags(fp, filename, NULL, + &_PyParser_Grammar, + start, NULL, NULL, &err, flags); + if (n == NULL) + err_input(&err); - return n; + return n; } /* Simplified interface to parsestring -- return node or set exception */ @@ -1855,30 +1855,30 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla node * PyParser_SimpleParseStringFlags(const char *str, int start, int flags) { - perrdetail err; - node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, - start, &err, flags); - if (n == NULL) - err_input(&err); - return n; + perrdetail err; + node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, + start, &err, flags); + if (n == NULL) + err_input(&err); + return n; } node * PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, - int start, int flags) + int start, int flags) { - perrdetail err; - node *n = PyParser_ParseStringFlagsFilename(str, filename, - &_PyParser_Grammar, start, &err, flags); - if (n == NULL) - err_input(&err); - return n; + perrdetail err; + node *n = PyParser_ParseStringFlagsFilename(str, filename, + &_PyParser_Grammar, start, &err, flags); + if (n == NULL) + err_input(&err); + return n; } node * PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start) { - return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0); + return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0); } /* May want to move a more generalized form of this to parsetok.c or @@ -1887,7 +1887,7 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st void PyParser_SetError(perrdetail *err) { - err_input(err); + err_input(err); } /* Set the error appropriate to the given input error code (see errcode.h) */ @@ -1895,110 +1895,110 @@ PyParser_SetError(perrdetail *err) static void err_input(perrdetail *err) { - PyObject *v, *w, *errtype, *errtext; - PyObject *msg_obj = NULL; - char *msg = NULL; - errtype = PyExc_SyntaxError; - switch (err->error) { - case E_ERROR: - return; - case E_SYNTAX: - errtype = PyExc_IndentationError; - if (err->expected == INDENT) - msg = "expected an indented block"; - else if (err->token == INDENT) - msg = "unexpected indent"; - else if (err->token == DEDENT) - msg = "unexpected unindent"; - else { - errtype = PyExc_SyntaxError; - msg = "invalid syntax"; - } - break; - case E_TOKEN: - msg = "invalid token"; - break; - case E_EOFS: - msg = "EOF while scanning triple-quoted string literal"; - break; - case E_EOLS: - msg = "EOL while scanning string literal"; - break; - case E_INTR: - if (!PyErr_Occurred()) - PyErr_SetNone(PyExc_KeyboardInterrupt); - goto cleanup; - case E_NOMEM: - PyErr_NoMemory(); - goto cleanup; - case E_EOF: - msg = "unexpected EOF while parsing"; - break; - case E_TABSPACE: - errtype = PyExc_TabError; - msg = "inconsistent use of tabs and spaces in indentation"; - break; - case E_OVERFLOW: - msg = "expression too long"; - break; - case E_DEDENT: - errtype = PyExc_IndentationError; - msg = "unindent does not match any outer indentation level"; - break; - case E_TOODEEP: - errtype = PyExc_IndentationError; - msg = "too many levels of indentation"; - break; - case E_DECODE: { - PyObject *type, *value, *tb; - PyErr_Fetch(&type, &value, &tb); - msg = "unknown decode error"; - if (value != NULL) - msg_obj = PyObject_Str(value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tb); - break; - } - case E_LINECONT: - msg = "unexpected character after line continuation character"; - break; - - case E_IDENTIFIER: - msg = "invalid character in identifier"; - break; - default: - fprintf(stderr, "error=%d\n", err->error); - msg = "unknown parsing error"; - break; - } - /* err->text may not be UTF-8 in case of decoding errors. - Explicitly convert to an object. */ - if (!err->text) { - errtext = Py_None; - Py_INCREF(Py_None); - } else { - errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), - "replace"); - } - v = Py_BuildValue("(ziiN)", err->filename, - err->lineno, err->offset, errtext); - if (v != NULL) { - if (msg_obj) - w = Py_BuildValue("(OO)", msg_obj, v); - else - w = Py_BuildValue("(sO)", msg, v); - } else - w = NULL; - Py_XDECREF(v); - PyErr_SetObject(errtype, w); - Py_XDECREF(w); + PyObject *v, *w, *errtype, *errtext; + PyObject *msg_obj = NULL; + char *msg = NULL; + errtype = PyExc_SyntaxError; + switch (err->error) { + case E_ERROR: + return; + case E_SYNTAX: + errtype = PyExc_IndentationError; + if (err->expected == INDENT) + msg = "expected an indented block"; + else if (err->token == INDENT) + msg = "unexpected indent"; + else if (err->token == DEDENT) + msg = "unexpected unindent"; + else { + errtype = PyExc_SyntaxError; + msg = "invalid syntax"; + } + break; + case E_TOKEN: + msg = "invalid token"; + break; + case E_EOFS: + msg = "EOF while scanning triple-quoted string literal"; + break; + case E_EOLS: + msg = "EOL while scanning string literal"; + break; + case E_INTR: + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_KeyboardInterrupt); + goto cleanup; + case E_NOMEM: + PyErr_NoMemory(); + goto cleanup; + case E_EOF: + msg = "unexpected EOF while parsing"; + break; + case E_TABSPACE: + errtype = PyExc_TabError; + msg = "inconsistent use of tabs and spaces in indentation"; + break; + case E_OVERFLOW: + msg = "expression too long"; + break; + case E_DEDENT: + errtype = PyExc_IndentationError; + msg = "unindent does not match any outer indentation level"; + break; + case E_TOODEEP: + errtype = PyExc_IndentationError; + msg = "too many levels of indentation"; + break; + case E_DECODE: { + PyObject *type, *value, *tb; + PyErr_Fetch(&type, &value, &tb); + msg = "unknown decode error"; + if (value != NULL) + msg_obj = PyObject_Str(value); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tb); + break; + } + case E_LINECONT: + msg = "unexpected character after line continuation character"; + break; + + case E_IDENTIFIER: + msg = "invalid character in identifier"; + break; + default: + fprintf(stderr, "error=%d\n", err->error); + msg = "unknown parsing error"; + break; + } + /* err->text may not be UTF-8 in case of decoding errors. + Explicitly convert to an object. */ + if (!err->text) { + errtext = Py_None; + Py_INCREF(Py_None); + } else { + errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), + "replace"); + } + v = Py_BuildValue("(ziiN)", err->filename, + err->lineno, err->offset, errtext); + if (v != NULL) { + if (msg_obj) + w = Py_BuildValue("(OO)", msg_obj, v); + else + w = Py_BuildValue("(sO)", msg, v); + } else + w = NULL; + Py_XDECREF(v); + PyErr_SetObject(errtype, w); + Py_XDECREF(w); cleanup: - Py_XDECREF(msg_obj); - if (err->text != NULL) { - PyObject_FREE(err->text); - err->text = NULL; - } + Py_XDECREF(msg_obj); + if (err->text != NULL) { + PyObject_FREE(err->text); + err->text = NULL; + } } /* Print fatal error message and abort */ @@ -2006,32 +2006,32 @@ cleanup: void Py_FatalError(const char *msg) { - fprintf(stderr, "Fatal Python error: %s\n", msg); - fflush(stderr); /* it helps in Windows debug build */ - if (PyErr_Occurred()) { - PyErr_Print(); - } + fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ + if (PyErr_Occurred()) { + PyErr_Print(); + } #ifdef MS_WINDOWS - { - size_t len = strlen(msg); - WCHAR* buffer; - size_t i; - - /* Convert the message to wchar_t. This uses a simple one-to-one - conversion, assuming that the this error message actually uses ASCII - only. If this ceases to be true, we will have to convert. */ - buffer = alloca( (len+1) * (sizeof *buffer)); - for( i=0; i<=len; ++i) - buffer[i] = msg[i]; - OutputDebugStringW(L"Fatal Python error: "); - OutputDebugStringW(buffer); - OutputDebugStringW(L"\n"); - } + { + size_t len = strlen(msg); + WCHAR* buffer; + size_t i; + + /* Convert the message to wchar_t. This uses a simple one-to-one + conversion, assuming that the this error message actually uses ASCII + only. If this ceases to be true, we will have to convert. */ + buffer = alloca( (len+1) * (sizeof *buffer)); + for( i=0; i<=len; ++i) + buffer[i] = msg[i]; + OutputDebugStringW(L"Fatal Python error: "); + OutputDebugStringW(buffer); + OutputDebugStringW(L"\n"); + } #ifdef _DEBUG - DebugBreak(); + DebugBreak(); #endif #endif /* MS_WINDOWS */ - abort(); + abort(); } /* Clean up and exit */ @@ -2044,17 +2044,17 @@ static void (*pyexitfunc)(void) = NULL; /* For the atexit module. */ void _Py_PyAtExit(void (*func)(void)) { - pyexitfunc = func; + pyexitfunc = func; } static void call_py_exitfuncs(void) { - if (pyexitfunc == NULL) - return; + if (pyexitfunc == NULL) + return; - (*pyexitfunc)(); - PyErr_Clear(); + (*pyexitfunc)(); + PyErr_Clear(); } /* Wait until threading._shutdown completes, provided @@ -2065,23 +2065,23 @@ static void wait_for_thread_shutdown(void) { #ifdef WITH_THREAD - PyObject *result; - PyThreadState *tstate = PyThreadState_GET(); - PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, - "threading"); - if (threading == NULL) { - /* threading not imported */ - PyErr_Clear(); - return; - } - result = PyObject_CallMethod(threading, "_shutdown", ""); - if (result == NULL) { - PyErr_WriteUnraisable(threading); - } - else { - Py_DECREF(result); - } - Py_DECREF(threading); + PyObject *result; + PyThreadState *tstate = PyThreadState_GET(); + PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, + "threading"); + if (threading == NULL) { + /* threading not imported */ + PyErr_Clear(); + return; + } + result = PyObject_CallMethod(threading, "_shutdown", ""); + if (result == NULL) { + PyErr_WriteUnraisable(threading); + } + else { + Py_DECREF(result); + } + Py_DECREF(threading); #endif } @@ -2091,43 +2091,43 @@ static int nexitfuncs = 0; int Py_AtExit(void (*func)(void)) { - if (nexitfuncs >= NEXITFUNCS) - return -1; - exitfuncs[nexitfuncs++] = func; - return 0; + if (nexitfuncs >= NEXITFUNCS) + return -1; + exitfuncs[nexitfuncs++] = func; + return 0; } static void call_ll_exitfuncs(void) { - while (nexitfuncs > 0) - (*exitfuncs[--nexitfuncs])(); + while (nexitfuncs > 0) + (*exitfuncs[--nexitfuncs])(); - fflush(stdout); - fflush(stderr); + fflush(stdout); + fflush(stderr); } void Py_Exit(int sts) { - Py_Finalize(); + Py_Finalize(); - exit(sts); + exit(sts); } static void initsigs(void) { #ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_IGN); + PyOS_setsig(SIGPIPE, SIG_IGN); #endif #ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_IGN); + PyOS_setsig(SIGXFZ, SIG_IGN); #endif #ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_IGN); + PyOS_setsig(SIGXFSZ, SIG_IGN); #endif - PyOS_InitInterrupts(); /* May imply initsignal() */ + PyOS_InitInterrupts(); /* May imply initsignal() */ } @@ -2141,13 +2141,13 @@ void _Py_RestoreSignals(void) { #ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_DFL); + PyOS_setsig(SIGPIPE, SIG_DFL); #endif #ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_DFL); + PyOS_setsig(SIGXFZ, SIG_DFL); #endif #ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_DFL); + PyOS_setsig(SIGXFSZ, SIG_DFL); #endif } @@ -2161,13 +2161,13 @@ _Py_RestoreSignals(void) int Py_FdIsInteractive(FILE *fp, const char *filename) { - if (isatty((int)fileno(fp))) - return 1; - if (!Py_InteractiveFlag) - return 0; - return (filename == NULL) || - (strcmp(filename, "") == 0) || - (strcmp(filename, "???") == 0); + if (isatty((int)fileno(fp))) + return 1; + if (!Py_InteractiveFlag) + return 0; + return (filename == NULL) || + (strcmp(filename, "") == 0) || + (strcmp(filename, "???") == 0); } @@ -2185,21 +2185,21 @@ Py_FdIsInteractive(FILE *fp, const char *filename) int PyOS_CheckStack(void) { - __try { - /* alloca throws a stack overflow exception if there's - not enough space left on the stack */ - alloca(PYOS_STACK_MARGIN * sizeof(void*)); - return 0; - } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH) { - int errcode = _resetstkoflw(); - if (errcode == 0) - { - Py_FatalError("Could not reset the stack!"); - } - } - return 1; + __try { + /* alloca throws a stack overflow exception if there's + not enough space left on the stack */ + alloca(PYOS_STACK_MARGIN * sizeof(void*)); + return 0; + } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) { + int errcode = _resetstkoflw(); + if (errcode == 0) + { + Py_FatalError("Could not reset the stack!"); + } + } + return 1; } #endif /* WIN32 && _MSC_VER */ @@ -2215,33 +2215,33 @@ PyOS_sighandler_t PyOS_getsig(int sig) { #ifdef HAVE_SIGACTION - struct sigaction context; - if (sigaction(sig, NULL, &context) == -1) - return SIG_ERR; - return context.sa_handler; + struct sigaction context; + if (sigaction(sig, NULL, &context) == -1) + return SIG_ERR; + return context.sa_handler; #else - PyOS_sighandler_t handler; + PyOS_sighandler_t handler; /* Special signal handling for the secure CRT in Visual Studio 2005 */ #if defined(_MSC_VER) && _MSC_VER >= 1400 - switch (sig) { - /* Only these signals are valid */ - case SIGINT: - case SIGILL: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGBREAK: - case SIGABRT: - break; - /* Don't call signal() with other values or it will assert */ - default: - return SIG_ERR; - } + switch (sig) { + /* Only these signals are valid */ + case SIGINT: + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + break; + /* Don't call signal() with other values or it will assert */ + default: + return SIG_ERR; + } #endif /* _MSC_VER && _MSC_VER >= 1400 */ - handler = signal(sig, SIG_IGN); - if (handler != SIG_ERR) - signal(sig, handler); - return handler; + handler = signal(sig, SIG_IGN); + if (handler != SIG_ERR) + signal(sig, handler); + return handler; #endif } @@ -2254,24 +2254,24 @@ PyOS_sighandler_t PyOS_setsig(int sig, PyOS_sighandler_t handler) { #ifdef HAVE_SIGACTION - /* Some code in Modules/signalmodule.c depends on sigaction() being - * used here if HAVE_SIGACTION is defined. Fix that if this code - * changes to invalidate that assumption. - */ - struct sigaction context, ocontext; - context.sa_handler = handler; - sigemptyset(&context.sa_mask); - context.sa_flags = 0; - if (sigaction(sig, &context, &ocontext) == -1) - return SIG_ERR; - return ocontext.sa_handler; + /* Some code in Modules/signalmodule.c depends on sigaction() being + * used here if HAVE_SIGACTION is defined. Fix that if this code + * changes to invalidate that assumption. + */ + struct sigaction context, ocontext; + context.sa_handler = handler; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + if (sigaction(sig, &context, &ocontext) == -1) + return SIG_ERR; + return ocontext.sa_handler; #else - PyOS_sighandler_t oldhandler; - oldhandler = signal(sig, handler); + PyOS_sighandler_t oldhandler; + oldhandler = signal(sig, handler); #ifdef HAVE_SIGINTERRUPT - siginterrupt(sig, 1); + siginterrupt(sig, 1); #endif - return oldhandler; + return oldhandler; #endif } @@ -2281,71 +2281,71 @@ PyOS_setsig(int sig, PyOS_sighandler_t handler) PyAPI_FUNC(node *) PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) { - return PyParser_SimpleParseFileFlags(fp, filename, start, 0); + return PyParser_SimpleParseFileFlags(fp, filename, start, 0); } #undef PyParser_SimpleParseString PyAPI_FUNC(node *) PyParser_SimpleParseString(const char *str, int start) { - return PyParser_SimpleParseStringFlags(str, start, 0); + return PyParser_SimpleParseStringFlags(str, start, 0); } #undef PyRun_AnyFile PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name) { - return PyRun_AnyFileExFlags(fp, name, 0, NULL); + return PyRun_AnyFileExFlags(fp, name, 0, NULL); } #undef PyRun_AnyFileEx PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit) { - return PyRun_AnyFileExFlags(fp, name, closeit, NULL); + return PyRun_AnyFileExFlags(fp, name, closeit, NULL); } #undef PyRun_AnyFileFlags PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags) { - return PyRun_AnyFileExFlags(fp, name, 0, flags); + return PyRun_AnyFileExFlags(fp, name, 0, flags); } #undef PyRun_File PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l) { - return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); + return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); } #undef PyRun_FileEx PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c) { - return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); + return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); } #undef PyRun_FileFlags PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, - PyCompilerFlags *flags) + PyCompilerFlags *flags) { - return PyRun_FileExFlags(fp, p, s, g, l, 0, flags); + return PyRun_FileExFlags(fp, p, s, g, l, 0, flags); } #undef PyRun_SimpleFile PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p) { - return PyRun_SimpleFileExFlags(f, p, 0, NULL); + return PyRun_SimpleFileExFlags(f, p, 0, NULL); } #undef PyRun_SimpleFileEx PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c) { - return PyRun_SimpleFileExFlags(f, p, c, NULL); + return PyRun_SimpleFileExFlags(f, p, c, NULL); } @@ -2353,35 +2353,35 @@ PyRun_SimpleFileEx(FILE *f, const char *p, int c) PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l) { - return PyRun_StringFlags(str, s, g, l, NULL); + return PyRun_StringFlags(str, s, g, l, NULL); } #undef PyRun_SimpleString PyAPI_FUNC(int) PyRun_SimpleString(const char *s) { - return PyRun_SimpleStringFlags(s, NULL); + return PyRun_SimpleStringFlags(s, NULL); } #undef Py_CompileString PyAPI_FUNC(PyObject *) Py_CompileString(const char *str, const char *p, int s) { - return Py_CompileStringFlags(str, p, s, NULL); + return Py_CompileStringFlags(str, p, s, NULL); } #undef PyRun_InteractiveOne PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p) { - return PyRun_InteractiveOneFlags(f, p, NULL); + return PyRun_InteractiveOneFlags(f, p, NULL); } #undef PyRun_InteractiveLoop PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p) { - return PyRun_InteractiveLoopFlags(f, p, NULL); + return PyRun_InteractiveLoopFlags(f, p, NULL); } #ifdef __cplusplus -- cgit v1.2.1 From 5266e4236ff854c931fb0f6b958539e243da015f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 May 2010 00:59:09 +0000 Subject: Issue #4653: fix typo in flush_std_files() Don't call sys.stderr.flush() if sys has no stderr attribute or if sys.stderr==None. --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e58b1c8ab9..3031aef5f2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -334,7 +334,7 @@ flush_std_files(void) Py_DECREF(tmp); } - if (ferr != NULL || ferr != Py_None) { + if (ferr != NULL && ferr != Py_None) { tmp = PyObject_CallMethod(ferr, "flush", ""); if (tmp == NULL) PyErr_Clear(); -- cgit v1.2.1 From f9dbe155860b82bbc704f46258ad998e2b018e59 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 15 May 2010 12:27:16 +0000 Subject: Issue #8610: Load file system codec at startup, and display a fatal error on failure. Set the file system encoding to utf-8 (instead of None) if getting the locale encoding failed, or if nl_langinfo(CODESET) function is missing. --- Python/pythonrun.c | 62 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3031aef5f2..4932c4ad4c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -57,6 +57,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ static void initmain(void); +static void initfsencoding(void); static void initsite(void); static int initstdio(void); static void flush_io(void); @@ -159,7 +160,6 @@ get_codeset(void) error: Py_XDECREF(codec); - PyErr_Clear(); return NULL; } #endif @@ -171,9 +171,6 @@ Py_InitializeEx(int install_sigs) PyThreadState *tstate; PyObject *bimod, *sysmod, *pstderr; char *p; -#if defined(HAVE_LANGINFO_H) && defined(CODESET) - char *codeset; -#endif extern void _Py_ReadyTypes(void); if (initialized) @@ -264,21 +261,7 @@ Py_InitializeEx(int install_sigs) _PyImportHooks_Init(); -#if defined(HAVE_LANGINFO_H) && defined(CODESET) - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - - codeset = get_codeset(); - if (codeset) { - if (!Py_FileSystemDefaultEncoding) - Py_FileSystemDefaultEncoding = codeset; - else - free(codeset); - } -#endif + initfsencoding(); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ @@ -496,7 +479,7 @@ Py_Finalize(void) _PyUnicode_Fini(); /* reset file system default encoding */ - if (!Py_HasFileSystemDefaultEncoding) { + if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { free((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; } @@ -707,6 +690,45 @@ initmain(void) } } +static void +initfsencoding(void) +{ + PyObject *codec; +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + char *codeset; + + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + if (codeset != NULL) { + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; + } + + PyErr_Clear(); + fprintf(stderr, + "Unable to get the locale encoding: " + "fallback to utf-8\n"); + Py_FileSystemDefaultEncoding = "utf-8"; + Py_HasFileSystemDefaultEncoding = 1; +#endif + + /* the encoding is mbcs, utf-8 or ascii */ + codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); + if (!codec) { + /* Such error can only occurs in critical situations: no more + * memory, import a module of the standard library failed, + * etc. */ + Py_FatalError("Py_Initialize: unable to load the file system codec"); + } else { + Py_DECREF(codec); + } +} + /* Import the site module (not into __main__ though) */ static void -- cgit v1.2.1 From 737239f6f90fe530a0e75462a3bf6b4679abe49f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 17 May 2010 08:58:51 +0000 Subject: handle_system_exit() flushs files to warranty the output order PyObject_Print() writes into the C object stderr, whereas PySys_WriteStderr() writes into the Python object sys.stderr. Each object has its own buffer, so call sys.stderr.flush() and fflush(stderr). --- Python/pythonrun.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 4932c4ad4c..d3981961ee 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1367,7 +1367,11 @@ handle_system_exit(void) if (PyLong_Check(value)) exitcode = (int)PyLong_AsLong(value); else { + PyObject *sys_stderr = PySys_GetObject("stderr"); + if (sys_stderr != NULL) + PyObject_CallMethod(sys_stderr, "flush", NULL); PyObject_Print(value, stderr, Py_PRINT_RAW); + fflush(stderr); PySys_WriteStderr("\n"); exitcode = 1; } -- cgit v1.2.1 From f6e4e2c2fa3e76a272ca41f744f0cc4e68b193e7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 May 2010 00:34:15 +0000 Subject: Issue #6697: Check that _PyUnicode_AsString() result is not NULL --- Python/pythonrun.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index d3981961ee..58388c22d9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -138,8 +138,8 @@ add_flag(int flag, const char *envs) static char* get_codeset(void) { - char* codeset; - PyObject *codec, *name; + char* codeset, *name_str; + PyObject *codec, *name = NULL; codeset = nl_langinfo(CODESET); if (!codeset || codeset[0] == '\0') @@ -154,12 +154,16 @@ get_codeset(void) if (!name) goto error; - codeset = strdup(_PyUnicode_AsString(name)); + name_str = _PyUnicode_AsString(name); + if (name == NULL) + goto error; + codeset = strdup(name_str); Py_DECREF(name); return codeset; error: Py_XDECREF(codec); + Py_XDECREF(name); return NULL; } #endif @@ -1060,22 +1064,34 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags if (!oenc) return -1; enc = _PyUnicode_AsString(oenc); + if (enc == NULL) + return -1; } v = PySys_GetObject("ps1"); if (v != NULL) { v = PyObject_Str(v); if (v == NULL) PyErr_Clear(); - else if (PyUnicode_Check(v)) + else if (PyUnicode_Check(v)) { ps1 = _PyUnicode_AsString(v); + if (ps1 == NULL) { + PyErr_Clear(); + ps1 = ""; + } + } } w = PySys_GetObject("ps2"); if (w != NULL) { w = PyObject_Str(w); if (w == NULL) PyErr_Clear(); - else if (PyUnicode_Check(w)) + else if (PyUnicode_Check(w)) { ps2 = _PyUnicode_AsString(w); + if (ps2 == NULL) { + PyErr_Clear(); + ps2 = ""; + } + } } arena = PyArena_New(); if (arena == NULL) { -- cgit v1.2.1 From c0e3f0787e625295074aee19d585f02b9b5a209a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 May 2010 20:40:50 +0000 Subject: Issue #8766: Initialize _warnings module before importing the first module. Fix a crash if an empty directory called "encodings" exists in sys.path. --- Python/pythonrun.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 58388c22d9..b469c4a625 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -265,13 +265,15 @@ Py_InitializeEx(int install_sigs) _PyImportHooks_Init(); + /* Initialize _warnings. */ + _PyWarnings_Init(); + initfsencoding(); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ /* Initialize warnings. */ - _PyWarnings_Init(); if (PySys_HasWarnOptions()) { PyObject *warnings_module = PyImport_ImportModule("warnings"); if (!warnings_module) -- cgit v1.2.1 From 17b0f141ce9882104863d5a7914759a43843de29 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 21 May 2010 23:45:42 +0000 Subject: Issue #3798: sys.exit(message) writes the message to sys.stderr file, instead of the C file stderr, to use stderr encoding and error handler --- Python/pythonrun.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index b469c4a625..1581c90fb3 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1386,10 +1386,12 @@ handle_system_exit(void) exitcode = (int)PyLong_AsLong(value); else { PyObject *sys_stderr = PySys_GetObject("stderr"); - if (sys_stderr != NULL) - PyObject_CallMethod(sys_stderr, "flush", NULL); - PyObject_Print(value, stderr, Py_PRINT_RAW); - fflush(stderr); + if (sys_stderr != NULL && sys_stderr != Py_None) { + PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); + } else { + PyObject_Print(value, stderr, Py_PRINT_RAW); + fflush(stderr); + } PySys_WriteStderr("\n"); exitcode = 1; } -- cgit v1.2.1 From bb4e6d2cdb19b9ad4d8439844127032223299b8f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 8 Jun 2010 21:00:13 +0000 Subject: Py_FatalError(): don't sys sys.last_xxx variables Call PyErr_PrintEx(0) instead of PyErr_Print() to avoid a crash if Py_FatalError() is called in an early stage of Python initialization (if PySys is not yet initialized). --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1581c90fb3..05a980085d 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2055,7 +2055,7 @@ Py_FatalError(const char *msg) fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { - PyErr_Print(); + PyErr_PrintEx(0); } #ifdef MS_WINDOWS { -- cgit v1.2.1 From 24e0c93aebd29160d263fb92dfdca097342fcd5f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 11 Jun 2010 00:36:33 +0000 Subject: Issue #8965: initfsencoding() doesn't change the encoding on Mac OS X File system encoding have to be hardcoded to "utf-8" on Mac OS X. r81190 introduced a regression: the encoding was changed depending on the locale. --- Python/pythonrun.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 05a980085d..5b7cd20251 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -703,24 +703,26 @@ initfsencoding(void) #if defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); - if (codeset != NULL) { - Py_FileSystemDefaultEncoding = codeset; - Py_HasFileSystemDefaultEncoding = 0; - return; - } + if (Py_FileSystemDefaultEncoding == NULL) { + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + if (codeset != NULL) { + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; + } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); - Py_FileSystemDefaultEncoding = "utf-8"; - Py_HasFileSystemDefaultEncoding = 1; + PyErr_Clear(); + fprintf(stderr, + "Unable to get the locale encoding: " + "fallback to utf-8\n"); + Py_FileSystemDefaultEncoding = "utf-8"; + Py_HasFileSystemDefaultEncoding = 1; + } #endif /* the encoding is mbcs, utf-8 or ascii */ -- cgit v1.2.1 From 86ae93c37f42628dac90832d2194e39afa157539 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 17 Jun 2010 23:08:50 +0000 Subject: Issue #6543: Write the traceback in the terminal encoding instead of utf-8. Fix the encoding of the modules filename. Reindent also traceback.h, just because I hate tabs :-) --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 5b7cd20251..f45d7dc9fa 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1190,7 +1190,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__file__") == NULL) { PyObject *f; - f = PyUnicode_DecodeFSDefault(filename); + f = PyUnicode_FromString(filename); if (f == NULL) return -1; if (PyDict_SetItemString(d, "__file__", f) < 0) { -- cgit v1.2.1 From 3d274b327dd0211aae4b809de8f4eaf524c68e26 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Thu, 5 Aug 2010 17:34:27 +0000 Subject: Issue #9079: Added _PyTime_gettimeofday(_PyTime_timeval *tp) to C API exposed in Python.h. This function is similar to POSIX gettimeofday(struct timeval *tp), but available on platforms without gettimeofday(). --- Python/pythonrun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f45d7dc9fa..79a19f8dd7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -268,6 +268,8 @@ Py_InitializeEx(int install_sigs) /* Initialize _warnings. */ _PyWarnings_Init(); + _PyTime_Init(); + initfsencoding(); if (install_sigs) -- cgit v1.2.1 From 9847d74fb7da263e9d1943d6c635656d54f44de6 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 8 Aug 2010 20:46:42 +0000 Subject: Issue #5319: Print an error if flushing stdout fails at interpreter shutdown. --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 79a19f8dd7..233fc16ea1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -320,7 +320,7 @@ flush_std_files(void) if (fout != NULL && fout != Py_None) { tmp = PyObject_CallMethod(fout, "flush", ""); if (tmp == NULL) - PyErr_Clear(); + PyErr_WriteUnraisable(fout); else Py_DECREF(tmp); } -- cgit v1.2.1 From 258aa419f44f3c3b45a9ac1db3f6f02519f3d91b Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 8 Aug 2010 22:18:46 +0000 Subject: Issue #477863: Print a warning at shutdown if gc.garbage is not empty. --- Python/pythonrun.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 233fc16ea1..a7a54ba710 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -404,6 +404,9 @@ Py_Finalize(void) while (PyGC_Collect() > 0) /* nothing */; #endif + /* We run this while most interpreter state is still alive, so that + debug information can be printed out */ + _PyGC_Fini(); /* Destroy all modules */ PyImport_Cleanup(); -- cgit v1.2.1 From 32765cc90a223dc7c1434b716a9ee46e57a67f17 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Aug 2010 22:26:51 +0000 Subject: Issue #8063: Call _PyGILState_Init() earlier in Py_InitializeEx(). --- Python/pythonrun.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index a7a54ba710..76a8eef2df 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -206,6 +206,11 @@ Py_InitializeEx(int install_sigs) Py_FatalError("Py_Initialize: can't make first thread"); (void) PyThreadState_Swap(tstate); + /* auto-thread-state API, if available */ +#ifdef WITH_THREAD + _PyGILState_Init(interp, tstate); +#endif /* WITH_THREAD */ + _Py_ReadyTypes(); if (!_PyFrame_Init()) @@ -288,11 +293,6 @@ Py_InitializeEx(int install_sigs) Py_FatalError( "Py_Initialize: can't initialize sys standard streams"); - /* auto-thread-state API, if available */ -#ifdef WITH_THREAD - _PyGILState_Init(interp, tstate); -#endif /* WITH_THREAD */ - if (!Py_NoSiteFlag) initsite(); /* Module site */ } -- cgit v1.2.1 From eed5e45dca43ab6cf3424e21b30e2c775d292e77 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Aug 2010 21:23:25 +0000 Subject: Issue #8622: Add PYTHONFSENCODING environment variable to override the filesystem encoding. initfsencoding() displays also a better error message if get_codeset() failed. --- Python/pythonrun.c | 65 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 76a8eef2df..fd31974cb8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -134,18 +134,13 @@ add_flag(int flag, const char *envs) return flag; } -#if defined(HAVE_LANGINFO_H) && defined(CODESET) static char* -get_codeset(void) +get_codec_name(const char *encoding) { - char* codeset, *name_str; + char *name_utf8, *name_str; PyObject *codec, *name = NULL; - codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') - return NULL; - - codec = _PyCodec_Lookup(codeset); + codec = _PyCodec_Lookup(encoding); if (!codec) goto error; @@ -154,18 +149,34 @@ get_codeset(void) if (!name) goto error; - name_str = _PyUnicode_AsString(name); + name_utf8 = _PyUnicode_AsString(name); if (name == NULL) goto error; - codeset = strdup(name_str); + name_str = strdup(name_utf8); Py_DECREF(name); - return codeset; + if (name_str == NULL) { + PyErr_NoMemory(); + return NULL; + } + return name_str; error: Py_XDECREF(codec); Py_XDECREF(name); return NULL; } + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) +static char* +get_codeset(void) +{ + char* codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); + return NULL; + } + return get_codec_name(codeset); +} #endif void @@ -706,25 +717,35 @@ initfsencoding(void) { PyObject *codec; #if defined(HAVE_LANGINFO_H) && defined(CODESET) - char *codeset; + char *codeset = NULL; if (Py_FileSystemDefaultEncoding == NULL) { - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); + const char *env_encoding = Py_GETENV("PYTHONFSENCODING"); + if (env_encoding != NULL) { + codeset = get_codec_name(env_encoding); + if (!codeset) { + fprintf(stderr, "PYTHONFSENCODING is not a valid encoding:\n"); + PyErr_Print(); + } + } + if (!codeset) { + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + } if (codeset != NULL) { Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; return; + } else { + fprintf(stderr, "Unable to get the locale encoding:\n"); + PyErr_Print(); } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); + fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n"); Py_FileSystemDefaultEncoding = "utf-8"; Py_HasFileSystemDefaultEncoding = 1; } -- cgit v1.2.1 From 64b32a2e48eecce58447ae9f0c678464720eb960 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 13 Sep 2010 14:16:46 +0000 Subject: Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly re-created on a subsequent call to Py_Initialize(). The problem (a crash) wouldn't appear in 3.1 or 2.7 where the GIL's structure is more trivial. --- Python/pythonrun.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index fd31974cb8..8f4e9f18f7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -514,6 +514,10 @@ Py_Finalize(void) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); +#ifdef WITH_THREAD + _PyEval_FiniThreads(); +#endif + #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed -- cgit v1.2.1 From a6001dfe413068f5a425f062d62f2038a72b013d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 20 Sep 2010 20:13:48 +0000 Subject: Issue #9901: Destroying the GIL in Py_Finalize() can fail if some other threads are still running. Instead, reinitialize the GIL on a second call to Py_Initialize(). --- Python/pythonrun.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8f4e9f18f7..a3f5d2b667 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -217,8 +217,15 @@ Py_InitializeEx(int install_sigs) Py_FatalError("Py_Initialize: can't make first thread"); (void) PyThreadState_Swap(tstate); - /* auto-thread-state API, if available */ #ifdef WITH_THREAD + /* We can't call _PyEval_FiniThreads() in Py_Finalize because + destroying the GIL might fail when it is being referenced from + another running thread (see issue #9901). + Instead we destroy the previously created GIL here, which ensures + that we can call Py_Initialize / Py_Finalize multiple times. */ + _PyEval_FiniThreads(); + + /* Auto-thread-state API */ _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ @@ -514,10 +521,6 @@ Py_Finalize(void) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); -#ifdef WITH_THREAD - _PyEval_FiniThreads(); -#endif - #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed -- cgit v1.2.1 From 82deba1f06f5dedc64fab78febbed063b4b8f85d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 Sep 2010 16:35:47 +0000 Subject: Issue #9630: Redecode filenames when setting the filesystem encoding Redecode the filenames of: - all modules: __file__ and __path__ attributes - all code objects: co_filename attribute - sys.path - sys.meta_path - sys.executable - sys.path_importer_cache (keys) Keep weak references to all code objects until initfsencoding() is called, to be able to redecode co_filename attribute of all code objects. --- Python/pythonrun.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index a3f5d2b667..a888a19f20 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -719,6 +719,259 @@ initmain(void) } } +/* Redecode a filename from the default filesystem encoding (utf-8) to + 'new_encoding' encoding with 'errors' error handler */ +static PyObject* +redecode_filename(PyObject *file, const char *new_encoding, + const char *errors) +{ + PyObject *file_bytes = NULL, *new_file = NULL; + + file_bytes = PyUnicode_EncodeFSDefault(file); + if (file_bytes == NULL) + return NULL; + new_file = PyUnicode_Decode( + PyBytes_AsString(file_bytes), + PyBytes_GET_SIZE(file_bytes), + new_encoding, + errors); + Py_DECREF(file_bytes); + return new_file; +} + +/* Redecode a path list */ +static int +redecode_path_list(PyObject *paths, + const char *new_encoding, const char *errors) +{ + PyObject *filename, *new_filename; + Py_ssize_t i, size; + + size = PyList_Size(paths); + for (i=0; i < size; i++) { + filename = PyList_GetItem(paths, i); + if (filename == NULL) + return -1; + + new_filename = redecode_filename(filename, new_encoding, errors); + if (new_filename == NULL) + return -1; + if (PyList_SetItem(paths, i, new_filename)) { + Py_DECREF(new_filename); + return -1; + } + } + return 0; +} + +/* Redecode __file__ and __path__ attributes of sys.modules */ +static int +redecode_sys_modules(const char *new_encoding, const char *errors) +{ + PyInterpreterState *interp; + PyObject *modules, *values, *file, *new_file, *paths; + PyObject *iter = NULL, *module = NULL; + + interp = PyThreadState_GET()->interp; + modules = interp->modules; + + values = PyObject_CallMethod(modules, "values", ""); + if (values == NULL) + goto error; + + iter = PyObject_GetIter(values); + Py_DECREF(values); + if (iter == NULL) + goto error; + + while (1) + { + module = PyIter_Next(iter); + if (module == NULL) { + if (PyErr_Occurred()) + goto error; + else + break; + } + + file = PyModule_GetFilenameObject(module); + if (file != NULL) { + new_file = redecode_filename(file, new_encoding, errors); + Py_DECREF(file); + if (new_file == NULL) + goto error; + if (PyObject_SetAttrString(module, "__file__", new_file)) { + Py_DECREF(new_file); + goto error; + } + Py_DECREF(new_file); + } + else + PyErr_Clear(); + + paths = PyObject_GetAttrString(module, "__path__"); + if (paths != NULL) { + if (redecode_path_list(paths, new_encoding, errors)) + goto error; + } + else + PyErr_Clear(); + + Py_CLEAR(module); + } + Py_CLEAR(iter); + return 0; + +error: + Py_XDECREF(iter); + Py_XDECREF(module); + return -1; +} + +/* Redecode sys.path_importer_cache keys */ +static int +redecode_sys_path_importer_cache(const char *new_encoding, const char *errors) +{ + PyObject *path_importer_cache, *items, *item, *path, *importer, *new_path; + PyObject *new_cache = NULL, *iter = NULL; + + path_importer_cache = PySys_GetObject("path_importer_cache"); + if (path_importer_cache == NULL) + goto error; + + items = PyObject_CallMethod(path_importer_cache, "items", ""); + if (items == NULL) + goto error; + + iter = PyObject_GetIter(items); + Py_DECREF(items); + if (iter == NULL) + goto error; + + new_cache = PyDict_New(); + if (new_cache == NULL) + goto error; + + while (1) + { + item = PyIter_Next(iter); + if (item == NULL) { + if (PyErr_Occurred()) + goto error; + else + break; + } + path = PyTuple_GET_ITEM(item, 0); + importer = PyTuple_GET_ITEM(item, 1); + + new_path = redecode_filename(path, new_encoding, errors); + if (new_path == NULL) + goto error; + if (PyDict_SetItem(new_cache, new_path, importer)) { + Py_DECREF(new_path); + goto error; + } + Py_DECREF(new_path); + } + Py_CLEAR(iter); + if (PySys_SetObject("path_importer_cache", new_cache)) + goto error; + Py_CLEAR(new_cache); + return 0; + +error: + Py_XDECREF(iter); + Py_XDECREF(new_cache); + return -1; +} + +/* Redecode co_filename attribute of all code objects */ +static int +redecode_code_objects(const char *new_encoding, const char *errors) +{ + Py_ssize_t i, len; + PyCodeObject *co; + PyObject *ref, *new_file; + + len = Py_SIZE(_Py_code_object_list); + for (i=0; i < len; i++) { + ref = PyList_GET_ITEM(_Py_code_object_list, i); + co = (PyCodeObject *)PyWeakref_GetObject(ref); + if ((PyObject*)co == Py_None) + continue; + if (co == NULL) + return -1; + + new_file = redecode_filename(co->co_filename, new_encoding, errors); + if (new_file == NULL) + return -1; + Py_DECREF(co->co_filename); + co->co_filename = new_file; + } + Py_CLEAR(_Py_code_object_list); + return 0; +} + +/* Redecode the filenames of all modules (__file__ and __path__ attributes), + all code objects (co_filename attribute), sys.path, sys.meta_path, + sys.executable and sys.path_importer_cache (keys) when the filesystem + encoding changes from the default encoding (utf-8) to new_encoding */ +static int +redecode_filenames(const char *new_encoding) +{ + char *errors; + PyObject *paths, *executable, *new_executable; + + /* PyUnicode_DecodeFSDefault() and PyUnicode_EncodeFSDefault() do already + use utf-8 if Py_FileSystemDefaultEncoding is NULL */ + if (strcmp(new_encoding, "utf-8") == 0) + return 0; + + if (strcmp(new_encoding, "mbcs") != 0) + errors = "surrogateescape"; + else + errors = NULL; + + /* sys.modules */ + if (redecode_sys_modules(new_encoding, errors)) + return -1; + + /* sys.path and sys.meta_path */ + paths = PySys_GetObject("path"); + if (paths != NULL) { + if (redecode_path_list(paths, new_encoding, errors)) + return -1; + } + paths = PySys_GetObject("meta_path"); + if (paths != NULL) { + if (redecode_path_list(paths, new_encoding, errors)) + return -1; + } + + /* sys.executable */ + executable = PySys_GetObject("executable"); + if (executable == NULL) + return -1; + new_executable = redecode_filename(executable, new_encoding, errors); + if (new_executable == NULL) + return -1; + if (PySys_SetObject("executable", new_executable)) { + Py_DECREF(new_executable); + return -1; + } + Py_DECREF(new_executable); + + /* sys.path_importer_cache */ + if (redecode_sys_path_importer_cache(new_encoding, errors)) + return -1; + + /* code objects */ + if (redecode_code_objects(new_encoding, errors)) + return -1; + + return 0; +} + static void initfsencoding(void) { @@ -744,8 +997,11 @@ initfsencoding(void) codeset = get_codeset(); } if (codeset != NULL) { + if (redecode_filenames(codeset)) + Py_FatalError("Py_Initialize: can't redecode filenames"); Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; + Py_CLEAR(_Py_code_object_list); return; } else { fprintf(stderr, "Unable to get the locale encoding:\n"); @@ -758,6 +1014,8 @@ initfsencoding(void) } #endif + Py_CLEAR(_Py_code_object_list); + /* the encoding is mbcs, utf-8 or ascii */ codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); if (!codec) { -- cgit v1.2.1 From e27a5e8d1136800ee4395e2172fc51c1dd44d271 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 13 Oct 2010 22:02:27 +0000 Subject: Issue #9992: Remove PYTHONFSENCODING environment variable. --- Python/pythonrun.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index a888a19f20..012c1b85f2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -980,22 +980,12 @@ initfsencoding(void) char *codeset = NULL; if (Py_FileSystemDefaultEncoding == NULL) { - const char *env_encoding = Py_GETENV("PYTHONFSENCODING"); - if (env_encoding != NULL) { - codeset = get_codec_name(env_encoding); - if (!codeset) { - fprintf(stderr, "PYTHONFSENCODING is not a valid encoding:\n"); - PyErr_Print(); - } - } - if (!codeset) { - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); - } + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); if (codeset != NULL) { if (redecode_filenames(codeset)) Py_FatalError("Py_Initialize: can't redecode filenames"); -- cgit v1.2.1 From 9add3cda9de8882b78ac036ab30a3ed068ec1a73 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 15 Oct 2010 11:16:59 +0000 Subject: redecode_filename(): don't need to initialize variables --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 012c1b85f2..026fcfa8ce 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -725,7 +725,7 @@ static PyObject* redecode_filename(PyObject *file, const char *new_encoding, const char *errors) { - PyObject *file_bytes = NULL, *new_file = NULL; + PyObject *file_bytes, *new_file; file_bytes = PyUnicode_EncodeFSDefault(file); if (file_bytes == NULL) -- cgit v1.2.1 From a47a00d4de1dba7e27eb086e9843d0e1592663ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 15 Oct 2010 12:04:23 +0000 Subject: Use locale encoding if Py_FileSystemDefaultEncoding is not set * PyUnicode_EncodeFSDefault(), PyUnicode_DecodeFSDefaultAndSize() and PyUnicode_DecodeFSDefault() use the locale encoding instead of UTF-8 if Py_FileSystemDefaultEncoding is NULL * redecode_filenames() functions and _Py_code_object_list (issue #9630) are no more needed: remove them --- Python/pythonrun.c | 258 ----------------------------------------------------- 1 file changed, 258 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 026fcfa8ce..73fef75602 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -719,259 +719,6 @@ initmain(void) } } -/* Redecode a filename from the default filesystem encoding (utf-8) to - 'new_encoding' encoding with 'errors' error handler */ -static PyObject* -redecode_filename(PyObject *file, const char *new_encoding, - const char *errors) -{ - PyObject *file_bytes, *new_file; - - file_bytes = PyUnicode_EncodeFSDefault(file); - if (file_bytes == NULL) - return NULL; - new_file = PyUnicode_Decode( - PyBytes_AsString(file_bytes), - PyBytes_GET_SIZE(file_bytes), - new_encoding, - errors); - Py_DECREF(file_bytes); - return new_file; -} - -/* Redecode a path list */ -static int -redecode_path_list(PyObject *paths, - const char *new_encoding, const char *errors) -{ - PyObject *filename, *new_filename; - Py_ssize_t i, size; - - size = PyList_Size(paths); - for (i=0; i < size; i++) { - filename = PyList_GetItem(paths, i); - if (filename == NULL) - return -1; - - new_filename = redecode_filename(filename, new_encoding, errors); - if (new_filename == NULL) - return -1; - if (PyList_SetItem(paths, i, new_filename)) { - Py_DECREF(new_filename); - return -1; - } - } - return 0; -} - -/* Redecode __file__ and __path__ attributes of sys.modules */ -static int -redecode_sys_modules(const char *new_encoding, const char *errors) -{ - PyInterpreterState *interp; - PyObject *modules, *values, *file, *new_file, *paths; - PyObject *iter = NULL, *module = NULL; - - interp = PyThreadState_GET()->interp; - modules = interp->modules; - - values = PyObject_CallMethod(modules, "values", ""); - if (values == NULL) - goto error; - - iter = PyObject_GetIter(values); - Py_DECREF(values); - if (iter == NULL) - goto error; - - while (1) - { - module = PyIter_Next(iter); - if (module == NULL) { - if (PyErr_Occurred()) - goto error; - else - break; - } - - file = PyModule_GetFilenameObject(module); - if (file != NULL) { - new_file = redecode_filename(file, new_encoding, errors); - Py_DECREF(file); - if (new_file == NULL) - goto error; - if (PyObject_SetAttrString(module, "__file__", new_file)) { - Py_DECREF(new_file); - goto error; - } - Py_DECREF(new_file); - } - else - PyErr_Clear(); - - paths = PyObject_GetAttrString(module, "__path__"); - if (paths != NULL) { - if (redecode_path_list(paths, new_encoding, errors)) - goto error; - } - else - PyErr_Clear(); - - Py_CLEAR(module); - } - Py_CLEAR(iter); - return 0; - -error: - Py_XDECREF(iter); - Py_XDECREF(module); - return -1; -} - -/* Redecode sys.path_importer_cache keys */ -static int -redecode_sys_path_importer_cache(const char *new_encoding, const char *errors) -{ - PyObject *path_importer_cache, *items, *item, *path, *importer, *new_path; - PyObject *new_cache = NULL, *iter = NULL; - - path_importer_cache = PySys_GetObject("path_importer_cache"); - if (path_importer_cache == NULL) - goto error; - - items = PyObject_CallMethod(path_importer_cache, "items", ""); - if (items == NULL) - goto error; - - iter = PyObject_GetIter(items); - Py_DECREF(items); - if (iter == NULL) - goto error; - - new_cache = PyDict_New(); - if (new_cache == NULL) - goto error; - - while (1) - { - item = PyIter_Next(iter); - if (item == NULL) { - if (PyErr_Occurred()) - goto error; - else - break; - } - path = PyTuple_GET_ITEM(item, 0); - importer = PyTuple_GET_ITEM(item, 1); - - new_path = redecode_filename(path, new_encoding, errors); - if (new_path == NULL) - goto error; - if (PyDict_SetItem(new_cache, new_path, importer)) { - Py_DECREF(new_path); - goto error; - } - Py_DECREF(new_path); - } - Py_CLEAR(iter); - if (PySys_SetObject("path_importer_cache", new_cache)) - goto error; - Py_CLEAR(new_cache); - return 0; - -error: - Py_XDECREF(iter); - Py_XDECREF(new_cache); - return -1; -} - -/* Redecode co_filename attribute of all code objects */ -static int -redecode_code_objects(const char *new_encoding, const char *errors) -{ - Py_ssize_t i, len; - PyCodeObject *co; - PyObject *ref, *new_file; - - len = Py_SIZE(_Py_code_object_list); - for (i=0; i < len; i++) { - ref = PyList_GET_ITEM(_Py_code_object_list, i); - co = (PyCodeObject *)PyWeakref_GetObject(ref); - if ((PyObject*)co == Py_None) - continue; - if (co == NULL) - return -1; - - new_file = redecode_filename(co->co_filename, new_encoding, errors); - if (new_file == NULL) - return -1; - Py_DECREF(co->co_filename); - co->co_filename = new_file; - } - Py_CLEAR(_Py_code_object_list); - return 0; -} - -/* Redecode the filenames of all modules (__file__ and __path__ attributes), - all code objects (co_filename attribute), sys.path, sys.meta_path, - sys.executable and sys.path_importer_cache (keys) when the filesystem - encoding changes from the default encoding (utf-8) to new_encoding */ -static int -redecode_filenames(const char *new_encoding) -{ - char *errors; - PyObject *paths, *executable, *new_executable; - - /* PyUnicode_DecodeFSDefault() and PyUnicode_EncodeFSDefault() do already - use utf-8 if Py_FileSystemDefaultEncoding is NULL */ - if (strcmp(new_encoding, "utf-8") == 0) - return 0; - - if (strcmp(new_encoding, "mbcs") != 0) - errors = "surrogateescape"; - else - errors = NULL; - - /* sys.modules */ - if (redecode_sys_modules(new_encoding, errors)) - return -1; - - /* sys.path and sys.meta_path */ - paths = PySys_GetObject("path"); - if (paths != NULL) { - if (redecode_path_list(paths, new_encoding, errors)) - return -1; - } - paths = PySys_GetObject("meta_path"); - if (paths != NULL) { - if (redecode_path_list(paths, new_encoding, errors)) - return -1; - } - - /* sys.executable */ - executable = PySys_GetObject("executable"); - if (executable == NULL) - return -1; - new_executable = redecode_filename(executable, new_encoding, errors); - if (new_executable == NULL) - return -1; - if (PySys_SetObject("executable", new_executable)) { - Py_DECREF(new_executable); - return -1; - } - Py_DECREF(new_executable); - - /* sys.path_importer_cache */ - if (redecode_sys_path_importer_cache(new_encoding, errors)) - return -1; - - /* code objects */ - if (redecode_code_objects(new_encoding, errors)) - return -1; - - return 0; -} - static void initfsencoding(void) { @@ -987,11 +734,8 @@ initfsencoding(void) stdin and stdout if these are terminals. */ codeset = get_codeset(); if (codeset != NULL) { - if (redecode_filenames(codeset)) - Py_FatalError("Py_Initialize: can't redecode filenames"); Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; - Py_CLEAR(_Py_code_object_list); return; } else { fprintf(stderr, "Unable to get the locale encoding:\n"); @@ -1004,8 +748,6 @@ initfsencoding(void) } #endif - Py_CLEAR(_Py_code_object_list); - /* the encoding is mbcs, utf-8 or ascii */ codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); if (!codec) { -- cgit v1.2.1 From 24c7fa3b4d2daf8a3b9d1b3c143e6a55b5b2b4d5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Oct 2010 13:14:10 +0000 Subject: Issue #9713, #10114: Parser functions (eg. PyParser_ASTFromFile) expects filenames encoded to the filesystem encoding with surrogateescape error handler (to support undecodable bytes), instead of UTF-8 in strict mode. --- Python/pythonrun.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 73fef75602..8c535fd8a6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1213,7 +1213,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__file__") == NULL) { PyObject *f; - f = PyUnicode_FromString(filename); + f = PyUnicode_DecodeFSDefault(filename); if (f == NULL) return -1; if (PyDict_SetItemString(d, "__file__", f) < 0) { @@ -1968,7 +1968,9 @@ err_input(perrdetail *err) { PyObject *v, *w, *errtype, *errtext; PyObject *msg_obj = NULL; + PyObject *filename; char *msg = NULL; + errtype = PyExc_SyntaxError; switch (err->error) { case E_ERROR: @@ -2052,8 +2054,12 @@ err_input(perrdetail *err) errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), "replace"); } - v = Py_BuildValue("(ziiN)", err->filename, - err->lineno, err->offset, errtext); + filename = PyUnicode_DecodeFSDefault(err->filename); + if (filename != NULL) + v = Py_BuildValue("(NiiN)", filename, + err->lineno, err->offset, errtext); + else + v = NULL; if (v != NULL) { if (msg_obj) w = Py_BuildValue("(OO)", msg_obj, v); -- cgit v1.2.1 From a92ba0800250ece57c8b4cfa5f8d8fc1558fd024 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Oct 2010 13:42:53 +0000 Subject: Fix ast_error_finish() and err_input(): filename can be NULL Fix my previous commit (r85569). --- Python/pythonrun.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8c535fd8a6..f72c9d705a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2054,7 +2054,12 @@ err_input(perrdetail *err) errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), "replace"); } - filename = PyUnicode_DecodeFSDefault(err->filename); + if (err->filename != NULL) + filename = PyUnicode_DecodeFSDefault(err->filename); + else { + Py_INCREF(Py_None); + filename = Py_None; + } if (filename != NULL) v = Py_BuildValue("(NiiN)", filename, err->lineno, err->offset, errtext); -- cgit v1.2.1 From fd287a210024b8e10ed205fba01ece1fbcabc5ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 17 Oct 2010 01:24:53 +0000 Subject: _PyImport_FixupExtension() and _PyImport_FindExtension() uses FS encoding * Rename _PyImport_FindExtension() to _PyImport_FindExtensionUnicode(): the filename becomes a Unicode object instead of byte string * Rename _PyImport_FixupExtension() to _PyImport_FixupExtensionUnicode(): the filename becomes a Unicode object instead of byte string --- Python/pythonrun.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f72c9d705a..fe99fd23f4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -255,7 +255,7 @@ Py_InitializeEx(int install_sigs) bimod = _PyBuiltin_Init(); if (bimod == NULL) Py_FatalError("Py_Initialize: can't initialize builtins modules"); - _PyImport_FixupExtension(bimod, "builtins", "builtins"); + _PyImport_FixupBuiltin(bimod, "builtins"); interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) Py_FatalError("Py_Initialize: can't initialize builtins dict"); @@ -271,7 +271,7 @@ Py_InitializeEx(int install_sigs) if (interp->sysdict == NULL) Py_FatalError("Py_Initialize: can't initialize sys dict"); Py_INCREF(interp->sysdict); - _PyImport_FixupExtension(sysmod, "sys", "sys"); + _PyImport_FixupBuiltin(sysmod, "sys"); PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); @@ -577,7 +577,7 @@ Py_NewInterpreter(void) interp->modules = PyDict_New(); interp->modules_reloading = PyDict_New(); - bimod = _PyImport_FindExtension("builtins", "builtins"); + bimod = _PyImport_FindBuiltin("builtins"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) @@ -588,7 +588,7 @@ Py_NewInterpreter(void) /* initialize builtin exceptions */ _PyExc_Init(); - sysmod = _PyImport_FindExtension("sys", "sys"); + sysmod = _PyImport_FindBuiltin("sys"); if (bimod != NULL && sysmod != NULL) { PyObject *pstderr; interp->sysdict = PyModule_GetDict(sysmod); -- cgit v1.2.1 From 69ad491c3243b85456e2b60a4b47fd7a8a15a55c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Oct 2010 00:05:51 +0000 Subject: initfsencoding(): get_codeset() failure is now a fatal error Don't fallback to utf-8 anymore to avoid mojibake. I never got any error from his function. --- Python/pythonrun.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index fe99fd23f4..f755d117ff 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -730,21 +730,14 @@ initfsencoding(void) /* On Unix, set the file system encoding according to the user's preference, if the CODESET names a well-known Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ + initialized by other means. */ codeset = get_codeset(); - if (codeset != NULL) { - Py_FileSystemDefaultEncoding = codeset; - Py_HasFileSystemDefaultEncoding = 0; - return; - } else { - fprintf(stderr, "Unable to get the locale encoding:\n"); - PyErr_Print(); - } + if (codeset == NULL) + Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n"); - Py_FileSystemDefaultEncoding = "utf-8"; - Py_HasFileSystemDefaultEncoding = 1; + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; } #endif -- cgit v1.2.1 From f26d99263a6433201f1f5b751a3f113f67359961 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 24 Oct 2010 02:52:05 +0000 Subject: remove broken code accounting an offset the size of the line #10186 --- Python/pythonrun.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f755d117ff..cf8f7bf2a7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1344,8 +1344,6 @@ print_error_text(PyObject *f, int offset, const char *text) { char *nl; if (offset >= 0) { - if (offset > 0 && offset == (int)strlen(text)) - offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) -- cgit v1.2.1 From 09e4cb55cdc2cc460b0c3cac7620bdf3bb3d103b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 24 Oct 2010 03:41:46 +0000 Subject: tighten loop --- Python/pythonrun.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cf8f7bf2a7..1b0a84bd65 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1363,11 +1363,8 @@ print_error_text(PyObject *f, int offset, const char *text) if (offset == -1) return; PyFile_WriteString(" ", f); - offset--; - while (offset > 0) { + while (--offset) PyFile_WriteString(" ", f); - offset--; - } PyFile_WriteString("^\n", f); } -- cgit v1.2.1 From d83461f3fbb6225b8b24dfcbd4c8cba26de8f263 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 29 Oct 2010 03:28:14 +0000 Subject: decrement offset when it points to a newline (#10186 followup) --- Python/pythonrun.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1b0a84bd65..33dd11bc88 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1344,6 +1344,8 @@ print_error_text(PyObject *f, int offset, const char *text) { char *nl; if (offset >= 0) { + if (offset > 0 && offset == strlen(text) && text[offset - 1] == '\n') + offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) @@ -1363,7 +1365,7 @@ print_error_text(PyObject *f, int offset, const char *text) if (offset == -1) return; PyFile_WriteString(" ", f); - while (--offset) + while (--offset > 0) PyFile_WriteString(" ", f); PyFile_WriteString("^\n", f); } -- cgit v1.2.1 From e0040b2197ac9d233f6c2a359c5968711bec7555 Mon Sep 17 00:00:00 2001 From: Hirokazu Yamamoto Date: Sat, 30 Oct 2010 15:08:15 +0000 Subject: Issue #10157: Fixed refleaks in pythonrun.c. Patch by Stefan Krah. --- Python/pythonrun.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 33dd11bc88..8b1e61a1c9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -283,6 +283,7 @@ Py_InitializeEx(int install_sigs) Py_FatalError("Py_Initialize: can't set preliminary stderr"); PySys_SetObject("stderr", pstderr); PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); _PyImport_Init(); @@ -605,6 +606,7 @@ Py_NewInterpreter(void) Py_FatalError("Py_Initialize: can't set preliminary stderr"); PySys_SetObject("stderr", pstderr); PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); _PyImportHooks_Init(); if (initstdio() < 0) @@ -971,6 +973,7 @@ initstdio(void) if (encoding != NULL) { _PyCodec_Lookup(encoding); } + Py_DECREF(encoding_attr); } PyErr_Clear(); /* Not a fatal error if codec isn't available */ -- cgit v1.2.1 From 4461ae12ac9eb6467106e6a9184180066599b8c4 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 10 Nov 2010 13:55:25 +0000 Subject: Issue #10372: Import the warnings module only after the IO library is initialized, so as to avoid bootstrap issues with the '-W' option. --- Python/pythonrun.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8b1e61a1c9..784558c119 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -299,19 +299,21 @@ Py_InitializeEx(int install_sigs) if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ + initmain(); /* Module __main__ */ + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + /* Initialize warnings. */ if (PySys_HasWarnOptions()) { PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (!warnings_module) - PyErr_Clear(); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + PyErr_Print(); + } Py_XDECREF(warnings_module); } - initmain(); /* Module __main__ */ - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - if (!Py_NoSiteFlag) initsite(); /* Module site */ } -- cgit v1.2.1 From 75596c7d735b7520f34bb96e70effcb6b0d1cb24 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 20 Nov 2010 19:50:57 +0000 Subject: Issue #10255: Fix reference leak in Py_InitializeEx(). Patch by Neil Schemenauer. --- Python/pythonrun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 784558c119..37c1f1197a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -893,8 +893,10 @@ initstdio(void) /* Set builtins.open */ if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { + Py_DECREF(wrapper); goto error; } + Py_DECREF(wrapper); encoding = Py_GETENV("PYTHONIOENCODING"); errors = NULL; -- cgit v1.2.1 From c16ad2eeb23a20667e832e09ad88e012952d8988 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 30 Nov 2010 09:41:01 +0000 Subject: Remove redundant includes of headers that are already included by Python.h. --- Python/pythonrun.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 37c1f1197a..de8e9da4b6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -11,14 +11,10 @@ #include "parsetok.h" #include "errcode.h" #include "code.h" -#include "compile.h" #include "symtable.h" -#include "pyarena.h" #include "ast.h" -#include "eval.h" #include "marshal.h" #include "osdefs.h" -#include "abstract.h" #ifdef HAVE_SIGNAL_H #include -- cgit v1.2.1 From bbbb00332d45ae20db0b9032efcb3bf397e2df3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Fri, 3 Dec 2010 20:14:31 +0000 Subject: Merge branches/pep-0384. --- Python/pythonrun.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index de8e9da4b6..3f6385d455 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1755,7 +1755,7 @@ run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, co = PyAST_Compile(mod, filename, flags, arena); if (co == NULL) return NULL; - v = PyEval_EvalCode(co, globals, locals); + v = PyEval_EvalCode((PyObject*)co, globals, locals); Py_DECREF(co); return v; } @@ -1785,7 +1785,7 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, return NULL; } co = (PyCodeObject *)v; - v = PyEval_EvalCode(co, globals, locals); + v = PyEval_EvalCode((PyObject*)co, globals, locals); if (v && flags) flags->cf_flags |= (co->co_flags & PyCF_MASK); Py_DECREF(co); @@ -1817,6 +1817,14 @@ Py_CompileStringFlags(const char *str, const char *filename, int start, return (PyObject *)co; } +/* For use in Py_LIMITED_API */ +#undef Py_CompileString +PyObject * +PyCompileString(const char *str, const char *filename, int start) +{ + return Py_CompileStringFlags(str, filename, start, NULL); +} + struct symtable * Py_SymtableString(const char *str, const char *filename, int start) { -- cgit v1.2.1 From e652f1b1b4166521e134d6312eebe9b761ea78e5 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 4 Dec 2010 10:26:46 +0000 Subject: Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile. --- Python/pythonrun.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3f6385d455..f7335a2b21 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1793,8 +1793,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, } PyObject * -Py_CompileStringFlags(const char *str, const char *filename, int start, - PyCompilerFlags *flags) +Py_CompileStringExFlags(const char *str, const char *filename, int start, + PyCompilerFlags *flags, int optimize) { PyCodeObject *co; mod_ty mod; @@ -1812,7 +1812,7 @@ Py_CompileStringFlags(const char *str, const char *filename, int start, PyArena_Free(arena); return result; } - co = PyAST_Compile(mod, filename, flags, arena); + co = PyAST_CompileEx(mod, filename, flags, optimize, arena); PyArena_Free(arena); return (PyObject *)co; } @@ -2450,7 +2450,15 @@ PyRun_SimpleString(const char *s) PyAPI_FUNC(PyObject *) Py_CompileString(const char *str, const char *p, int s) { - return Py_CompileStringFlags(str, p, s, NULL); + return Py_CompileStringExFlags(str, p, s, NULL, -1); +} + +#undef Py_CompileStringFlags +PyAPI_FUNC(PyObject *) +Py_CompileStringFlags(const char *str, const char *p, int s, + PyCompilerFlags *flags) +{ + return Py_CompileStringExFlags(str, p, s, flags, -1); } #undef PyRun_InteractiveOne -- cgit v1.2.1 From 37eff4f6fb0628592d5d39b6cec49ccd8ce4a333 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 28 Dec 2010 18:30:18 +0000 Subject: Add sys.flags.quiet attribute for the new -q option, as noted missing by Eric in #1772833. --- Python/pythonrun.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f7335a2b21..e3836b8b7c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -78,6 +78,7 @@ extern void _PyGILState_Fini(void); int Py_DebugFlag; /* Needed by parser.c */ int Py_VerboseFlag; /* Needed by import.c */ +int Py_QuietFlag; /* Needed by sysmodule.c */ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */ int Py_NoSiteFlag; /* Suppress 'import site' */ -- cgit v1.2.1 From d4a9fa435abe536522fb0343710feac61914ce00 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jan 2011 12:59:15 +0000 Subject: Issue #9566: use Py_ssize_t instead of int --- Python/pythonrun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e3836b8b7c..33f187386a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1202,7 +1202,8 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, ret, len; + int set_file_name = 0, ret; + size_t len; m = PyImport_AddModule("__main__"); if (m == NULL) -- cgit v1.2.1 From a73a92af0473a634b74becf20fd96bd612fc35e0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Feb 2011 12:10:23 +0000 Subject: Merged revisions 88530 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r88530 | victor.stinner | 2011-02-23 13:07:37 +0100 (mer., 23 févr. 2011) | 4 lines Issue #11272: Fix input() and sys.stdin for Windows newline On Windows, input() strips '\r' (and not only '\n'), and sys.stdin uses universal newline (replace '\r\n' by '\n'). ........ --- Python/pythonrun.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 33f187386a..8e97d7fc24 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -778,6 +778,7 @@ create_stdio(PyObject* io, { PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; const char* mode; + const char* newline; PyObject *line_buffering; int buffering, isatty; @@ -828,9 +829,17 @@ create_stdio(PyObject* io, Py_CLEAR(raw); Py_CLEAR(text); + newline = "\n"; +#ifdef MS_WINDOWS + if (!write_mode) { + /* translate \r\n to \n for sys.stdin on Windows */ + newline = NULL; + } +#endif + stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", buf, encoding, errors, - "\n", line_buffering); + newline, line_buffering); Py_CLEAR(buf); if (stream == NULL) goto error; -- cgit v1.2.1 From 496f14b82b0a34082d0987ceaae21e4e226628dd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 20 Mar 2011 23:23:22 +0100 Subject: Fix #11586: typo in initfsencoding() Patch written by Ray Allen. --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8e97d7fc24..38b2ab84fb 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -147,7 +147,7 @@ get_codec_name(const char *encoding) goto error; name_utf8 = _PyUnicode_AsString(name); - if (name == NULL) + if (name_utf8 == NULL) goto error; name_str = strdup(name_utf8); Py_DECREF(name); -- cgit v1.2.1 From 0ed611ee5df5214a93916fed71b8804b966570c5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 27 Apr 2011 00:20:27 +0200 Subject: Issue #10914: Py_NewInterpreter() uses PyErr_PrintEx(0) ... instead of PyErr_Print() because we don't need to set sys attributes, the sys module is destroyed just after printing the error. --- Python/pythonrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 38b2ab84fb..6251e30a34 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -622,7 +622,7 @@ Py_NewInterpreter(void) handle_error: /* Oops, it didn't work. Undo it all. */ - PyErr_Print(); + PyErr_PrintEx(0); PyThreadState_Clear(tstate); PyThreadState_Swap(save_tstate); PyThreadState_Delete(tstate); -- cgit v1.2.1 From aa039cee1babca74cc172aae2886c7c2da30ea8d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 27 Apr 2011 00:24:21 +0200 Subject: Issue #10914: Initialize correctly the filesystem codec when creating a new subinterpreter to fix a bootstrap issue with codecs implemented in Python, as the ISO-8859-15 codec. Add fscodec_initialized attribute to the PyInterpreterState structure. --- Python/pythonrun.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 6251e30a34..faaf54a0a6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -53,7 +53,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ static void initmain(void); -static void initfsencoding(void); +static int initfsencoding(PyInterpreterState *interp); static void initsite(void); static int initstdio(void); static void flush_io(void); @@ -291,7 +291,8 @@ Py_InitializeEx(int install_sigs) _PyTime_Init(); - initfsencoding(); + if (initfsencoding(interp) < 0) + Py_FatalError("Py_Initialize: unable to load the file system codec"); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ @@ -608,6 +609,10 @@ Py_NewInterpreter(void) Py_DECREF(pstderr); _PyImportHooks_Init(); + + if (initfsencoding(interp) < 0) + goto handle_error; + if (initstdio() < 0) Py_FatalError( "Py_Initialize: can't initialize sys standard streams"); @@ -720,8 +725,8 @@ initmain(void) } } -static void -initfsencoding(void) +static int +initfsencoding(PyInterpreterState *interp) { PyObject *codec; #if defined(HAVE_LANGINFO_H) && defined(CODESET) @@ -738,7 +743,8 @@ initfsencoding(void) Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; - return; + interp->fscodec_initialized = 1; + return 0; } #endif @@ -748,10 +754,11 @@ initfsencoding(void) /* Such error can only occurs in critical situations: no more * memory, import a module of the standard library failed, * etc. */ - Py_FatalError("Py_Initialize: unable to load the file system codec"); - } else { - Py_DECREF(codec); + return -1; } + Py_DECREF(codec); + interp->fscodec_initialized = 1; + return 0; } /* Import the site module (not into __main__ though) */ -- cgit v1.2.1 From 89ae6ab2a2cfece70bf55c2a314376093e6a1a41 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 4 May 2011 20:02:30 +0200 Subject: Issue #1856: Avoid crashes and lockups when daemon threads run while the interpreter is shutting down; instead, these threads are now killed when they try to take the GIL. --- Python/pythonrun.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index faaf54a0a6..1e2dd586b4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -90,6 +90,8 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ +PyThreadState *_Py_Finalizing = NULL; + /* PyModule_GetWarningsModule is no longer necessary as of 2.6 since _warnings is builtin. This API should not be used. */ PyObject * @@ -188,6 +190,7 @@ Py_InitializeEx(int install_sigs) if (initialized) return; initialized = 1; + _Py_Finalizing = NULL; #if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) /* Set up the LC_CTYPE locale, so we can obtain @@ -388,15 +391,19 @@ Py_Finalize(void) * the threads created via Threading. */ call_py_exitfuncs(); - initialized = 0; - - /* Flush stdout+stderr */ - flush_std_files(); /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp; + /* Remaining threads (e.g. daemon threads) will automatically exit + after taking the GIL (in PyEval_RestoreThread()). */ + _Py_Finalizing = tstate; + initialized = 0; + + /* Flush stdout+stderr */ + flush_std_files(); + /* Disable signal handling */ PyOS_FiniInterrupts(); -- cgit v1.2.1 From 98292273d840a24a366ab585f907da593c0726e0 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 20 Sep 2011 14:45:44 -0400 Subject: - Issue #13021: Missing decref on an error path. Thanks to Suman Saha for finding the bug and providing a patch. --- Python/pythonrun.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 084db12f63..bea7fe1544 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1241,8 +1241,10 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, Py_DECREF(f); return -1; } - if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) + if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) { + Py_DECREF(f); return -1; + } set_file_name = 1; Py_DECREF(f); } -- cgit v1.2.1 From 28e55082c3f1c64621bf2a3de150e51a94815d3d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 26 Nov 2011 21:59:36 +0100 Subject: Issue #13444: When stdout has been closed explicitly, we should not attempt to flush it at shutdown and print an error. This also adds a test for issue #5319, whose resolution introduced the issue. --- Python/pythonrun.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index bea7fe1544..fe92d303c8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -332,6 +332,22 @@ extern void dump_counts(FILE*); /* Flush stdout and stderr */ +static int +file_is_closed(PyObject *fobj) +{ + int r; + PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); + if (tmp == NULL) { + PyErr_Clear(); + return 0; + } + r = PyObject_IsTrue(tmp); + Py_DECREF(tmp); + if (r < 0) + PyErr_Clear(); + return r > 0; +} + static void flush_std_files(void) { @@ -339,7 +355,7 @@ flush_std_files(void) PyObject *ferr = PySys_GetObject("stderr"); PyObject *tmp; - if (fout != NULL && fout != Py_None) { + if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { tmp = PyObject_CallMethod(fout, "flush", ""); if (tmp == NULL) PyErr_WriteUnraisable(fout); @@ -347,7 +363,7 @@ flush_std_files(void) Py_DECREF(tmp); } - if (ferr != NULL && ferr != Py_None) { + if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { tmp = PyObject_CallMethod(ferr, "flush", ""); if (tmp == NULL) PyErr_Clear(); -- cgit v1.2.1 From 07ee349b41ca8f94aadaf39be3ec9ca5aca692f9 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 28 Nov 2011 19:08:36 +0100 Subject: Issue #7111: Python can now be run without a stdin, stdout or stderr stream. It was already the case with Python 2. However, the corresponding sys module entries are now set to None (instead of an unusable file object). --- Python/pythonrun.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index fe92d303c8..4b0ac139a2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -892,6 +892,19 @@ error: return NULL; } +static int +is_valid_fd(int fd) +{ + int dummy_fd; + if (fd < 0 || !_PyVerify_fd(fd)) + return 0; + dummy_fd = dup(fd); + if (dummy_fd < 0) + return 0; + close(dummy_fd); + return 1; +} + /* Initialize sys.stdin, stdout, stderr and builtins.open */ static int initstdio(void) @@ -951,13 +964,9 @@ initstdio(void) * and fileno() may point to an invalid file descriptor. For example * GUI apps don't have valid standard streams by default. */ - if (fd < 0) { -#ifdef MS_WINDOWS + if (!is_valid_fd(fd)) { std = Py_None; Py_INCREF(std); -#else - goto error; -#endif } else { std = create_stdio(iomod, fd, 0, "", encoding, errors); @@ -970,13 +979,9 @@ initstdio(void) /* Set sys.stdout */ fd = fileno(stdout); - if (fd < 0) { -#ifdef MS_WINDOWS + if (!is_valid_fd(fd)) { std = Py_None; Py_INCREF(std); -#else - goto error; -#endif } else { std = create_stdio(iomod, fd, 1, "", encoding, errors); @@ -990,13 +995,9 @@ initstdio(void) #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ /* Set sys.stderr, replaces the preliminary stderr */ fd = fileno(stderr); - if (fd < 0) { -#ifdef MS_WINDOWS + if (!is_valid_fd(fd)) { std = Py_None; Py_INCREF(std); -#else - goto error; -#endif } else { std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); -- cgit v1.2.1 From d7a1b71b34af52ecbc6f22544f0bc4eb1e7198f7 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 18 Jan 2012 15:14:46 +0100 Subject: Fix a memory leak when initializing the standard I/O streams. --- Python/pythonrun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 4b0ac139a2..ec69bcba8f 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1012,7 +1012,8 @@ initstdio(void) const char * encoding; encoding = _PyUnicode_AsString(encoding_attr); if (encoding != NULL) { - _PyCodec_Lookup(encoding); + PyObject *codec_info = _PyCodec_Lookup(encoding); + Py_XDECREF(codec_info); } Py_DECREF(encoding_attr); } -- cgit v1.2.1