From 8d4acf67131b9a1241bbda784905c5730c382d60 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Feb 2011 12:07:37 +0000 Subject: 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 8c709c419d16486b76126195864ed9376e8b849b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 20 Mar 2011 23:09:03 +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 d3c216b4c8eb33b04cff0f81e2233fb2d662df64 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 31 Mar 2011 01:31:06 +0200 Subject: Issue #11393: Add the new faulthandler module --- Python/pythonrun.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 38b2ab84fb..f787a4f8b3 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -70,6 +70,8 @@ extern void _PyUnicode_Init(void); extern void _PyUnicode_Fini(void); extern int _PyLong_Init(void); extern void PyLong_Fini(void); +extern int _PyFaulthandler_Init(void); +extern void _PyFaulthandler_Fini(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -286,6 +288,10 @@ Py_InitializeEx(int install_sigs) _PyImportHooks_Init(); + /* initialize the faulthandler module */ + if (_PyFaulthandler_Init()) + Py_FatalError("Py_Initialize: can't initialize faulthandler"); + /* Initialize _warnings. */ _PyWarnings_Init(); @@ -454,6 +460,9 @@ Py_Finalize(void) /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ _PyImport_Fini(); + /* unload faulthandler module */ + _PyFaulthandler_Fini(); + /* Debugging stuff */ #ifdef COUNT_ALLOCS dump_counts(stdout); @@ -2100,11 +2109,23 @@ cleanup: void Py_FatalError(const char *msg) { + const int fd = fileno(stderr); + PyThreadState *tstate; + fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { PyErr_PrintEx(0); } + else { + tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); + if (tstate != NULL) { + fputc('\n', stderr); + fflush(stderr); + _Py_DumpTraceback(fd, tstate); + } + } + #ifdef MS_WINDOWS { size_t len = strlen(msg); -- cgit v1.2.1 From eb92e63267528242069ef100470afec9147700ab Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 1 Apr 2011 12:13:55 +0200 Subject: Issue #11393: The fault handler handles also SIGABRT --- 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 f787a4f8b3..1c36e63ac4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2124,6 +2124,7 @@ Py_FatalError(const char *msg) fflush(stderr); _Py_DumpTraceback(fd, tstate); } + _PyFaulthandler_Fini(); } #ifdef MS_WINDOWS -- cgit v1.2.1 From 8136044f569744c1f5fbb37a093e2728db859ee0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 5 Apr 2011 00:39:01 +0200 Subject: Issue #10785: Store the filename as Unicode in the Python parser. --- Python/pythonrun.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1c36e63ac4..a6787c4fc7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -62,6 +62,7 @@ static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, PyCompilerFlags *); static void err_input(perrdetail *); +static void err_free(perrdetail *); static void initsigs(void); static void call_py_exitfuncs(void); static void wait_for_thread_shutdown(void); @@ -1887,12 +1888,13 @@ PyParser_ASTFromString(const char *s, const char *filename, int start, 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 = NULL; } + err_free(&err); + return mod; } mod_ty @@ -1917,14 +1919,15 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, 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; + mod = NULL; } + err_free(&err); + return mod; } /* Simplified interface to parsefile -- return node or set exception */ @@ -1938,6 +1941,7 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla start, NULL, NULL, &err, flags); if (n == NULL) err_input(&err); + err_free(&err); return n; } @@ -1952,6 +1956,7 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags) start, &err, flags); if (n == NULL) err_input(&err); + err_free(&err); return n; } @@ -1964,6 +1969,7 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, &_PyParser_Grammar, start, &err, flags); if (n == NULL) err_input(&err); + err_free(&err); return n; } @@ -1976,12 +1982,24 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st /* May want to move a more generalized form of this to parsetok.c or even parser modules. */ +void +PyParser_ClearError(perrdetail *err) +{ + err_free(err); +} + void PyParser_SetError(perrdetail *err) { err_input(err); } +static void +err_free(perrdetail *err) +{ + Py_CLEAR(err->filename); +} + /* Set the error appropriate to the given input error code (see errcode.h) */ static void @@ -1989,7 +2007,6 @@ err_input(perrdetail *err) { PyObject *v, *w, *errtype, *errtext; PyObject *msg_obj = NULL; - PyObject *filename; char *msg = NULL; errtype = PyExc_SyntaxError; @@ -2075,17 +2092,8 @@ err_input(perrdetail *err) errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), "replace"); } - 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); - else - v = NULL; + v = Py_BuildValue("(OiiN)", err->filename, + err->lineno, err->offset, errtext); if (v != NULL) { if (msg_obj) w = Py_BuildValue("(OO)", msg_obj, v); -- cgit v1.2.1 From db32b7ada2bd63927e2ecd2c32427baec6e44fda 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 a6787c4fc7..99bd66d7ad 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -632,7 +632,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 94efbe0ac4d55d812c49fa29accc75e135526975 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 99bd66d7ad..ad31613651 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); @@ -298,7 +298,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() */ @@ -618,6 +619,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"); @@ -730,8 +735,8 @@ initmain(void) } } -static void -initfsencoding(void) +static int +initfsencoding(PyInterpreterState *interp) { PyObject *codec; #if defined(HAVE_LANGINFO_H) && defined(CODESET) @@ -748,7 +753,8 @@ initfsencoding(void) Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; - return; + interp->fscodec_initialized = 1; + return 0; } #endif @@ -758,10 +764,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 ac8f9652916d3c88b8d08aaf32fa6942531cd712 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 7 May 2011 12:43:00 +0200 Subject: faulthandler: dump all threads by default * Set the default value of all_threads arguments to True * Py_FatalError() dumps all threads, instead of only the current thread Dump only the current thread is not reliable. In some cases, Python is unable to retrieve the state of the current thread and so is unable to dump the traceback. faulthandler keeps a reference to the interpreter and so is always able to dump the traceback of all threads. --- 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 ebc4f1cf17..6ebc823b80 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2144,7 +2144,7 @@ Py_FatalError(const char *msg) if (tstate != NULL) { fputc('\n', stderr); fflush(stderr); - _Py_DumpTraceback(fd, tstate); + _Py_DumpTracebackThreads(fd, tstate->interp, tstate); } _PyFaulthandler_Fini(); } -- cgit v1.2.1 From 48f7ac826a35230300859e8bfba3b7339efab679 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 26 May 2011 14:25:13 +0200 Subject: print_exception(): handle correctly PyObject_GetAttrString() failure Bug found by the Clang Static Analyzer. --- 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 b55dc5b201..232d7befa0 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1593,7 +1593,7 @@ print_exception(PyObject *f, PyObject *value) moduleName = PyObject_GetAttrString(type, "__module__"); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { - Py_DECREF(moduleName); + Py_XDECREF(moduleName); err = PyFile_WriteString("", f); } else { -- cgit v1.2.1 From 841e3742a787ea782d53c357b9894deff2ad363d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 4 Jul 2011 13:48:30 +0200 Subject: Issue #9642: Fix filesystem encoding initialization: use the ANSI code page on Windows if the mbcs codec is not available, and fail with a fatal error if we cannot get the locale encoding (if nl_langinfo(CODESET) is not available) instead of using UTF-8. --- Python/pythonrun.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 232d7befa0..5649e86c51 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -168,18 +168,25 @@ error: return NULL; } -#if defined(HAVE_LANGINFO_H) && defined(CODESET) static char* -get_codeset(void) +get_locale_encoding(void) { +#ifdef MS_WINDOWS + char codepage[100]; + PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); + return get_codec_name(codepage); +#elif defined(HAVE_LANGINFO_H) && defined(CODESET) 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); -} +#else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; #endif +} void Py_InitializeEx(int install_sigs) @@ -746,24 +753,17 @@ static int initfsencoding(PyInterpreterState *interp) { PyObject *codec; -#if defined(HAVE_LANGINFO_H) && defined(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. */ - codeset = get_codeset(); - if (codeset == NULL) + + if (Py_FileSystemDefaultEncoding == NULL) + { + Py_FileSystemDefaultEncoding = get_locale_encoding(); + if (Py_FileSystemDefaultEncoding == NULL) Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - Py_FileSystemDefaultEncoding = codeset; Py_HasFileSystemDefaultEncoding = 0; interp->fscodec_initialized = 1; return 0; } -#endif /* the encoding is mbcs, utf-8 or ascii */ codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); -- cgit v1.2.1