From 350e0ff264038e3790d0182134de7959965dea7d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 Dec 2012 14:28:26 +0100 Subject: Issue #13390: New function :func:`sys.getallocatedblocks()` returns the number of memory blocks currently allocated. Also, the ``-R`` option to regrtest uses this function to guard against memory allocation leaks. --- Python/pythonrun.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index dd32017574..f0d8550773 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -38,9 +38,10 @@ #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, " \ + "%" PY_FORMAT_SIZE_T "d blocks]\n", \ + _Py_GetRefTotal(), _Py_GetAllocatedBlocks()) #endif #ifdef __cplusplus -- cgit v1.2.1 From b66f6b5c73f6eda0d24bea66059da1fa7f651aa4 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Tue, 26 Mar 2013 01:59:56 +0200 Subject: #17323: The "[X refs, Y blocks]" printed by debug builds has been disabled by default. It can be re-enabled with the `-X showrefcount` option. --- Python/pythonrun.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f0d8550773..751008ac30 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -35,13 +35,29 @@ #define PATH_MAX MAXPATHLEN #endif +#ifdef Py_REF_DEBUG +void _print_total_refs() { + PyObject *xoptions, *key, *value; + xoptions = PySys_GetXOptions(); + if (xoptions == NULL) + return; + key = PyUnicode_FromString("showrefcount"); + if (key == NULL) + return; + value = PyDict_GetItem(xoptions, key); + Py_DECREF(key); + if (value == Py_True) + fprintf(stderr, + "[%" PY_FORMAT_SIZE_T "d refs, " + "%" PY_FORMAT_SIZE_T "d blocks]\n", + _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); +} +#endif + #ifndef Py_REF_DEBUG #define PRINT_TOTAL_REFS() #else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() fprintf(stderr, \ - "[%" PY_FORMAT_SIZE_T "d refs, " \ - "%" PY_FORMAT_SIZE_T "d blocks]\n", \ - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()) +#define PRINT_TOTAL_REFS() _print_total_refs() #endif #ifdef __cplusplus -- cgit v1.2.1 From 77fee69c3d917426c31557ec45eec4f72a51877f Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 24 Apr 2013 20:17:53 +0200 Subject: Issue #17832: fix a compilation warning about a function prototype. Also, make the private function static. --- 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 751008ac30..0cd695f36e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -36,7 +36,8 @@ #endif #ifdef Py_REF_DEBUG -void _print_total_refs() { +static +void _print_total_refs(void) { PyObject *xoptions, *key, *value; xoptions = PySys_GetXOptions(); if (xoptions == NULL) -- cgit v1.2.1 From 0010471202cc1a3eff955f556a247c78e7e2c34b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 4 May 2013 13:56:58 -0400 Subject: #17115,17116: Have modules initialize the __package__ and __loader__ attributes to None. The long-term goal is for people to be able to rely on these attributes existing and checking for None to see if they have been set. Since import itself sets these attributes when a loader does not the only instances when the attributes are None are from someone overloading __import__() and not using a loader or someone creating a module from scratch. This patch also unifies module initialization. Before you could have different attributes with default values depending on how the module object was created. Now the only way to not get the same default set of attributes is to circumvent initialization by calling ModuleType.__new__() directly. --- 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 b92a8bd9b4..40f6ab4cee 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -866,7 +866,8 @@ initmain(PyInterpreterState *interp) * be set if __main__ gets further initialized later in the startup * process. */ - if (PyDict_GetItemString(d, "__loader__") == NULL) { + PyObject *loader = PyDict_GetItemString(d, "__loader__"); + if (loader == NULL || loader == Py_None) { PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); if (loader == NULL) { -- cgit v1.2.1 From 39da2cb53bcacdaeb61d98d5511dbd44b423f080 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 4 May 2013 17:37:09 -0400 Subject: #17115: I hate you MS for not supporting C99. --- Python/pythonrun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 75f1ef6a26..cf2ecf1cb1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -843,7 +843,7 @@ Py_GetPythonHome(void) static void initmain(PyInterpreterState *interp) { - PyObject *m, *d; + PyObject *m, *d, *loader; m = PyImport_AddModule("__main__"); if (m == NULL) Py_FatalError("can't create __main__ module"); @@ -864,7 +864,7 @@ initmain(PyInterpreterState *interp) * be set if __main__ gets further initialized later in the startup * process. */ - PyObject *loader = PyDict_GetItemString(d, "__loader__"); + loader = PyDict_GetItemString(d, "__loader__"); if (loader == NULL || loader == Py_None) { PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); -- cgit v1.2.1 From 5756d7dace379752116766907b63ac77ffc4bc98 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2013 21:15:57 +0200 Subject: Issue #1545463: Global variables caught in reference cycles are now garbage-collected at shutdown. --- 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 96b0988ec7..02a4329950 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -544,10 +544,6 @@ 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(); @@ -628,6 +624,7 @@ Py_Finalize(void) PyFloat_Fini(); PyDict_Fini(); PySlice_Fini(); + _PyGC_Fini(); /* Cleanup Unicode implementation */ _PyUnicode_Fini(); -- cgit v1.2.1 From 37c223a89b1cd652ae397b07915c2dad168d3a0a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Jul 2013 15:50:49 +0200 Subject: Issue #18203: Fix Py_Finalize(): destroy the GIL after the last call to PyMem_Malloc() or PyObject_Malloc(). For example, PyCFunction_Fini() calls PyObject_GC_Del() which calls PyObject_FREE(). --- Python/pythonrun.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 02a4329950..94175be87e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -606,11 +606,6 @@ Py_Finalize(void) _PyExc_Fini(); - /* Cleanup auto-thread-state */ -#ifdef WITH_THREAD - _PyGILState_Fini(); -#endif /* WITH_THREAD */ - /* Sundry finalizers */ PyMethod_Fini(); PyFrame_Fini(); @@ -629,10 +624,6 @@ Py_Finalize(void) /* Cleanup Unicode implementation */ _PyUnicode_Fini(); - /* Delete current thread. After this, many C API calls become crashy. */ - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); - /* reset file system default encoding */ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { free((char*)Py_FileSystemDefaultEncoding); @@ -647,6 +638,15 @@ Py_Finalize(void) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + /* Cleanup auto-thread-state */ +#ifdef WITH_THREAD + _PyGILState_Fini(); +#endif /* WITH_THREAD */ + + /* Delete current thread. After this, many C API calls become crashy. */ + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); + #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 28ee3a69061fefad791404c84825222db9c7d0f2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Jul 2013 23:30:24 +0200 Subject: Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup() Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the GIL is held or not. --- Python/pythonrun.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 94175be87e..d95a09d4a7 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -174,7 +174,7 @@ get_codec_name(const char *encoding) name_utf8 = _PyUnicode_AsString(name); if (name_utf8 == NULL) goto error; - name_str = strdup(name_utf8); + name_str = _PyMem_RawStrdup(name_utf8); Py_DECREF(name); if (name_str == NULL) { PyErr_NoMemory(); @@ -626,7 +626,7 @@ Py_Finalize(void) /* reset file system default encoding */ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - free((char*)Py_FileSystemDefaultEncoding); + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; } @@ -1081,7 +1081,11 @@ initstdio(void) encoding = Py_GETENV("PYTHONIOENCODING"); errors = NULL; if (encoding) { - encoding = strdup(encoding); + encoding = _PyMem_Strdup(encoding); + if (encoding == NULL) { + PyErr_NoMemory(); + goto error; + } errors = strchr(encoding, ':'); if (errors) { *errors = '\0'; @@ -1140,10 +1144,10 @@ initstdio(void) 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) { - PyObject *codec_info = _PyCodec_Lookup(encoding); + const char * std_encoding; + std_encoding = _PyUnicode_AsString(encoding_attr); + if (std_encoding != NULL) { + PyObject *codec_info = _PyCodec_Lookup(std_encoding); Py_XDECREF(codec_info); } Py_DECREF(encoding_attr); @@ -1160,8 +1164,7 @@ initstdio(void) status = -1; } - if (encoding) - free(encoding); + PyMem_Free(encoding); Py_XDECREF(bimod); Py_XDECREF(iomod); return status; -- cgit v1.2.1 From 485316200dd2089a50ed5b41f2041bd1a8603622 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 17 Jul 2013 01:22:45 +0200 Subject: Close #18469: Replace PyDict_GetItemString() with _PyDict_GetItemId() in structseq.c _PyDict_GetItemId() is more efficient: it only builds the Unicode string once. Identifiers (dictionary keys) are now created at Python initialization, and if the creation failed, Python does exit with a fatal error. Before, PyDict_GetItemString() failure was not handled: structseq_new() could call PyObject_GC_NewVar() with a negative size, and structseq_dealloc() could also crash. --- 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 d95a09d4a7..814220b40e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -86,6 +86,7 @@ static void call_py_exitfuncs(void); static void wait_for_thread_shutdown(void); static void call_ll_exitfuncs(void); extern int _PyUnicode_Init(void); +extern int _PyStructSequence_Init(void); extern void _PyUnicode_Fini(void); extern int _PyLong_Init(void); extern void PyLong_Fini(void); @@ -336,6 +337,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) /* Init Unicode implementation; relies on the codec registry */ if (_PyUnicode_Init() < 0) Py_FatalError("Py_Initialize: can't initialize unicode"); + if (_PyStructSequence_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize structseq"); bimod = _PyBuiltin_Init(); if (bimod == NULL) -- cgit v1.2.1 From 7b7c6fa589acf72320bf1e20d7928e0b3934bd38 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 21 Jul 2013 13:25:51 +0200 Subject: Issue #18520: Fix initsigs(), handle PyOS_InitInterrupts() error PyOS_InitInterrupts() can raise error when importing the signal module --- 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 814220b40e..040172bb3d 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2481,6 +2481,9 @@ initsigs(void) PyOS_setsig(SIGXFSZ, SIG_IGN); #endif PyOS_InitInterrupts(); /* May imply initsignal() */ + if (PyErr_Occurred()) { + Py_FatalError("Py_Initialize: can't import signal"); + } } -- cgit v1.2.1 From 92d3e3cf6bfe7320aea27780a6525e6075624935 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 22:24:54 +0200 Subject: Issue #18520: Add a new PyStructSequence_InitType2() function, same than PyStructSequence_InitType() except that it has a return value (0 on success, -1 on error). * PyStructSequence_InitType2() now raises MemoryError on memory allocation failure * Fix also some calls to PyDict_SetItemString(): handle error --- 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 040172bb3d..edf9b6b542 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -328,7 +328,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) if (!PyByteArray_Init()) Py_FatalError("Py_Initialize: can't init bytearray"); - _PyFloat_Init(); + if (!_PyFloat_Init()) + Py_FatalError("Py_Initialize: can't init float"); interp->modules = PyDict_New(); if (interp->modules == NULL) -- cgit v1.2.1 From ba92a0f1543b48abeccafc1ecf5d1246bd6bf27d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 22:53:28 +0200 Subject: Issue #18520: initsite() is a little bit more verbose when import site fails --- 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 edf9b6b542..30e5e6f0c3 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -918,6 +918,7 @@ initsite(void) PyObject *m; m = PyImport_ImportModule("site"); if (m == NULL) { + fprintf(stderr, "Failed to import the site module\n"); PyErr_Print(); Py_Finalize(); exit(1); -- cgit v1.2.1 From 7196af1e77661d5981f36256a627831392e8c220 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Jul 2013 23:55:19 +0200 Subject: Issue #18520: Fix initstdio(), handle PySys_SetObject() failure --- Python/pythonrun.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 30e5e6f0c3..18c2baa656 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1159,8 +1159,14 @@ initstdio(void) } PyErr_Clear(); /* Not a fatal error if codec isn't available */ - PySys_SetObject("__stderr__", std); - PySys_SetObject("stderr", std); + if (PySys_SetObject("__stderr__", std) < 0) { + Py_DECREF(std); + goto error; + } + if (PySys_SetObject("stderr", std) < 0) { + Py_DECREF(std); + goto error; + } Py_DECREF(std); #endif -- cgit v1.2.1 From 3a7cb33cf3decec1dafe3aa8bea15e2044ae00e7 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 30 Jul 2013 21:01:23 +0200 Subject: Fix style --- Python/pythonrun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 18c2baa656..86c3206829 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1382,8 +1382,8 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit) return 0; } -int -static set_main_loader(PyObject *d, const char *filename, const char *loader_name) +static int +set_main_loader(PyObject *d, const char *filename, const char *loader_name) { PyInterpreterState *interp; PyThreadState *tstate; -- cgit v1.2.1 From 011ede87bdf36ab2e4cbb24825eb6425d9d72184 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sat, 10 Aug 2013 16:36:18 +0200 Subject: Issue #16400: Add command line option for isolated mode. -I Run Python in isolated mode. This also implies -E and -s. In isolated mode sys.path contains neither the script?s directory nor the user?s site-packages directory. All PYTHON* environment variables are ignored, too. Further restrictions may be imposed to prevent the user from injecting malicious code. --- 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 86c3206829..b0bc549647 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -112,6 +112,7 @@ 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} */ int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ PyThreadState *_Py_Finalizing = NULL; -- cgit v1.2.1 From 457ae56f001adc89839c41d0de3155a1bd8578fd Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 25 Aug 2013 19:48:18 +0200 Subject: Issue #18808: Non-daemon threads are now automatically joined when a sub-interpreter is shutdown (it would previously dump a fatal error). --- 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 b0bc549647..37dc3b8dc8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -789,6 +789,9 @@ Py_EndInterpreter(PyThreadState *tstate) Py_FatalError("Py_EndInterpreter: thread is not current"); if (tstate->frame != NULL) Py_FatalError("Py_EndInterpreter: thread still has a frame"); + + wait_for_thread_shutdown(); + if (tstate != interp->tstate_head || tstate->next != NULL) Py_FatalError("Py_EndInterpreter: not the last thread"); -- cgit v1.2.1 From c36bfc1c99c6dffff8cb89c723001902d721ff97 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 26 Aug 2013 22:28:21 +0200 Subject: Close #11619: The parser and the import machinery do not encode Unicode filenames anymore on Windows. --- Python/pythonrun.c | 104 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 22 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 37dc3b8dc8..dc8f412cb4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -2051,8 +2051,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, } PyObject * -Py_CompileStringExFlags(const char *str, const char *filename, int start, - PyCompilerFlags *flags, int optimize) +Py_CompileStringObject(const char *str, PyObject *filename, int start, + PyCompilerFlags *flags, int optimize) { PyCodeObject *co; mod_ty mod; @@ -2060,7 +2060,7 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start, if (arena == NULL) return NULL; - mod = PyParser_ASTFromString(str, filename, start, flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; @@ -2070,11 +2070,24 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start, PyArena_Free(arena); return result; } - co = PyAST_CompileEx(mod, filename, flags, optimize, arena); + co = PyAST_CompileObject(mod, filename, flags, optimize, arena); PyArena_Free(arena); return (PyObject *)co; } +PyObject * +Py_CompileStringExFlags(const char *str, const char *filename_str, int start, + PyCompilerFlags *flags, int optimize) +{ + PyObject *filename, *co; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + co = Py_CompileStringObject(str, filename, start, flags, optimize); + Py_DECREF(filename); + return co; +} + /* For use in Py_LIMITED_API */ #undef Py_CompileString PyObject * @@ -2084,46 +2097,62 @@ PyCompileString(const char *str, const char *filename, int start) } struct symtable * -Py_SymtableString(const char *str, const char *filename, int start) +Py_SymtableStringObject(const char *str, PyObject *filename, int start) { struct symtable *st; mod_ty mod; PyCompilerFlags flags; - PyArena *arena = PyArena_New(); + PyArena *arena; + + arena = PyArena_New(); if (arena == NULL) return NULL; flags.cf_flags = 0; - mod = PyParser_ASTFromString(str, filename, start, &flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, &flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; } - st = PySymtable_Build(mod, filename, 0); + st = PySymtable_BuildObject(mod, filename, 0); PyArena_Free(arena); return st; } +struct symtable * +Py_SymtableString(const char *str, const char *filename_str, int start) +{ + PyObject *filename; + struct symtable *st; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + st = Py_SymtableStringObject(str, filename, start); + Py_DECREF(filename); + 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) +PyParser_ASTFromStringObject(const char *s, PyObject *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); + node *n = PyParser_ParseStringObject(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); + mod = PyAST_FromNodeObject(n, flags, filename, arena); PyNode_Free(n); } else { @@ -2135,26 +2164,40 @@ PyParser_ASTFromString(const char *s, const char *filename, int start, } mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, - int start, char *ps1, - char *ps2, PyCompilerFlags *flags, int *errcode, - PyArena *arena) +PyParser_ASTFromString(const char *s, const char *filename_str, int start, + PyCompilerFlags *flags, PyArena *arena) +{ + PyObject *filename; + mod_ty mod; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena); + Py_DECREF(filename); + return mod; +} + +mod_ty +PyParser_ASTFromFileObject(FILE *fp, PyObject *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); + node *n = PyParser_ParseFileObject(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); + mod = PyAST_FromNodeObject(n, flags, filename, arena); PyNode_Free(n); } else { @@ -2167,6 +2210,23 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, return mod; } +mod_ty +PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc, + int start, char *ps1, + char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) +{ + mod_ty mod; + PyObject *filename; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2, + flags, errcode, arena); + Py_DECREF(filename); + return mod; +} + /* Simplified interface to parsefile -- return node or set exception */ node * -- cgit v1.2.1 From e5883d6d95989121670eca012dd5bde1721747e7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 28 Aug 2013 00:53:59 +0200 Subject: Issue #18571: Implementation of the PEP 446: file descriptors and file handles are now created non-inheritable; add functions os.get/set_inheritable(), os.get/set_handle_inheritable() and socket.socket.get/set_inheritable(). --- 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 dc8f412cb4..522a05d8b4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1454,7 +1454,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, /* Try to run a pyc file. First, re-open in binary */ if (closeit) fclose(fp); - if ((pyc_fp = fopen(filename, "rb")) == NULL) { + if ((pyc_fp = _Py_fopen(filename, "rb")) == NULL) { fprintf(stderr, "python: Can't reopen .pyc file\n"); goto done; } -- cgit v1.2.1 From 7016935cc4f10f296c9fe5a4b45592fed4992528 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 28 Aug 2013 01:47:46 +0200 Subject: pythonrun.c: use MAXPATHLEN instead of PATH_MAX PATH_MAX is not available on "MIPS IRIX 6.5.30 [SB] 3.x" buildbot --- 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 522a05d8b4..375bf34c82 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -821,7 +821,7 @@ Py_GetProgramName(void) } static wchar_t *default_home = NULL; -static wchar_t env_home[PATH_MAX+1]; +static wchar_t env_home[MAXPATHLEN+1]; void Py_SetPythonHome(wchar_t *home) -- cgit v1.2.1 From a7b94565928a47b36f01c932aad076cc093a9db5 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 31 Aug 2013 00:26:02 +0200 Subject: Issue #18756: os.urandom() now uses a lazily-opened persistent file descriptor, so as to avoid using many file descriptors when run in parallel from multiple threads. --- 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 375bf34c82..cbd62aa056 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -625,6 +625,7 @@ Py_Finalize(void) PyDict_Fini(); PySlice_Fini(); _PyGC_Fini(); + _PyRandom_Fini(); /* Cleanup Unicode implementation */ _PyUnicode_Fini(); -- cgit v1.2.1 From 4fcb46d2e3fb9972e2bf232295394404489e2489 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 13 Sep 2013 11:46:24 +0300 Subject: Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional. --- Python/pythonrun.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cbd62aa056..c2ca563d1a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1056,7 +1056,7 @@ initstdio(void) PyObject *std = NULL; int status = 0, fd; PyObject * encoding_attr; - char *encoding = NULL, *errors; + char *pythonioencoding = NULL, *encoding, *errors; /* Hack to avoid a nasty recursion issue when Python is invoked in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ @@ -1088,19 +1088,23 @@ initstdio(void) } Py_DECREF(wrapper); - encoding = Py_GETENV("PYTHONIOENCODING"); - errors = NULL; - if (encoding) { - encoding = _PyMem_Strdup(encoding); - if (encoding == NULL) { + pythonioencoding = Py_GETENV("PYTHONIOENCODING"); + encoding = errors = NULL; + if (pythonioencoding) { + pythonioencoding = _PyMem_Strdup(pythonioencoding); + if (pythonioencoding == NULL) { PyErr_NoMemory(); goto error; } - errors = strchr(encoding, ':'); + errors = strchr(pythonioencoding, ':'); if (errors) { *errors = '\0'; errors++; + if (!*errors) + errors = NULL; } + if (*pythonioencoding) + encoding = pythonioencoding; } /* Set sys.stdin */ @@ -1180,7 +1184,7 @@ initstdio(void) status = -1; } - PyMem_Free(encoding); + PyMem_Free(pythonioencoding); Py_XDECREF(bimod); Py_XDECREF(iomod); return status; -- cgit v1.2.1 From 54fa1af4e71e74b44edb29fba10bcde115779113 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Thu, 17 Oct 2013 22:35:35 +1000 Subject: Issue #16129: Add `Py_SetStandardStreamEncoding` This new pre-initialization API allows embedding applications like Blender to force a particular encoding and error handler for the standard IO streams. Also refactors Modules/_testembed.c to let us start testing multiple embedding scenarios. (Initial patch by Bastien Montagne) --- Python/pythonrun.c | 81 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 16 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 06f30b0f40..3bcc4742d1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -134,6 +134,40 @@ Py_IsInitialized(void) return initialized; } +/* Helper to allow an embedding application to override the normal + * mechanism that attempts to figure out an appropriate IO encoding + */ + +static char *_Py_StandardStreamEncoding = NULL; +static char *_Py_StandardStreamErrors = NULL; + +int +Py_SetStandardStreamEncoding(const char *encoding, const char *errors) +{ + if (Py_IsInitialized()) { + /* This is too late to have any effect */ + return -1; + } + if (encoding) { + _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); + if (!_Py_StandardStreamEncoding) { + PyErr_NoMemory(); + return -1; + } + } + if (errors) { + _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); + if (!_Py_StandardStreamErrors) { + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + } + PyErr_NoMemory(); + return -1; + } + } + return 0; +} + /* Global initializations. Can be undone by Py_Finalize(). Don't call this twice without an intervening Py_Finalize() call. When initializations fail, a fatal error is issued and the function does @@ -1088,23 +1122,29 @@ initstdio(void) } Py_DECREF(wrapper); - pythonioencoding = Py_GETENV("PYTHONIOENCODING"); - encoding = errors = NULL; - if (pythonioencoding) { - pythonioencoding = _PyMem_Strdup(pythonioencoding); - if (pythonioencoding == NULL) { - PyErr_NoMemory(); - goto error; - } - errors = strchr(pythonioencoding, ':'); - if (errors) { - *errors = '\0'; - errors++; - if (!*errors) - errors = NULL; + encoding = _Py_StandardStreamEncoding; + errors = _Py_StandardStreamErrors; + if (!encoding || !errors) { + pythonioencoding = Py_GETENV("PYTHONIOENCODING"); + if (pythonioencoding) { + char *err; + pythonioencoding = _PyMem_Strdup(pythonioencoding); + if (pythonioencoding == NULL) { + PyErr_NoMemory(); + goto error; + } + err = strchr(pythonioencoding, ':'); + if (err) { + *err = '\0'; + err++; + if (*err && !errors) { + errors = err; + } + } + if (*pythonioencoding && !encoding) { + encoding = pythonioencoding; + } } - if (*pythonioencoding) - encoding = pythonioencoding; } /* Set sys.stdin */ @@ -1184,6 +1224,15 @@ initstdio(void) status = -1; } + /* We won't need them anymore. */ + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = NULL; + } + if (_Py_StandardStreamErrors) { + PyMem_RawFree(_Py_StandardStreamErrors); + _Py_StandardStreamErrors = NULL; + } PyMem_Free(pythonioencoding); Py_XDECREF(bimod); Py_XDECREF(iomod); -- cgit v1.2.1 From 595d11f97b0cb5fb5242835f3a4f5db2e4ce08c1 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Fri, 18 Oct 2013 23:11:47 +1000 Subject: Issue #16129: Py_SetStandardStreamEncoding cleanups - don't call PyErr_NoMemory with interpreter is not initialised - note that it's OK to call _PyMem_RawStrDup here - don't include this in the limited API - capitalise "IO" - be explicit that a non-zero return indicates an error - include versionadded marker in docs --- Python/pythonrun.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3bcc4742d1..b963ce1132 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -148,11 +148,17 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) /* This is too late to have any effect */ return -1; } + /* Can't call PyErr_NoMemory() on errors, as Python hasn't been + * initialised yet. + * + * However, the raw memory allocators are initialised appropriately + * as C static variables, so _PyMem_RawStrdup is OK even though + * Py_Initialize hasn't been called yet. + */ if (encoding) { _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); if (!_Py_StandardStreamEncoding) { - PyErr_NoMemory(); - return -1; + return -2; } } if (errors) { @@ -161,8 +167,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) if (_Py_StandardStreamEncoding) { PyMem_RawFree(_Py_StandardStreamEncoding); } - PyErr_NoMemory(); - return -1; + return -3; } } return 0; -- cgit v1.2.1 From 43d34bd80f869e7121089a0e4d3b4b1e58453bb8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Nov 2013 18:28:21 +0100 Subject: Issue #19512: _print_total_refs() now uses an identifier to get "showrefcount" key from sys._xoptions --- Python/pythonrun.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 15a48f9947..dcd3664d14 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -38,15 +38,13 @@ #ifdef Py_REF_DEBUG static void _print_total_refs(void) { - PyObject *xoptions, *key, *value; + PyObject *xoptions, *value; + _Py_IDENTIFIER(showrefcount); + xoptions = PySys_GetXOptions(); if (xoptions == NULL) return; - key = PyUnicode_FromString("showrefcount"); - if (key == NULL) - return; - value = PyDict_GetItem(xoptions, key); - Py_DECREF(key); + value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); if (value == Py_True) fprintf(stderr, "[%" PY_FORMAT_SIZE_T "d refs, " -- cgit v1.2.1 From 66cb4b750939e85ca23732e63996f27135b7c334 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Nov 2013 18:41:07 +0100 Subject: Issue #19512: Add PyRun_InteractiveOneObject() function Only decode the filename once. PyRun_InteractiveOneObject() uses an identifier for "" string, so the byte string is only decoded once. --- Python/pythonrun.c | 111 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 29 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index dcd3664d14..61d03521e8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -73,7 +73,7 @@ static int initfsencoding(PyInterpreterState *interp); static void initsite(void); static int initstdio(void); static void flush_io(void); -static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, +static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, PyCompilerFlags *, PyArena *); static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, PyCompilerFlags *); @@ -1265,12 +1265,18 @@ PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, } int -PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) +PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) { - PyObject *v; - int ret; + PyObject *filename, *v; + int ret, err; PyCompilerFlags local_flags; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + if (flags == NULL) { flags = &local_flags; local_flags.cf_flags = 0; @@ -1285,16 +1291,21 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); Py_XDECREF(v); } + err = -1; for (;;) { - ret = PyRun_InteractiveOneFlags(fp, filename, flags); + ret = PyRun_InteractiveOneObject(fp, filename, flags); PRINT_TOTAL_REFS(); - if (ret == E_EOF) - return 0; + if (ret == E_EOF) { + err = 0; + break; + } /* if (ret == E_NOMEM) - return -1; + break; */ } + Py_DECREF(filename); + return err; } /* compute parser flags based on compiler flags */ @@ -1322,14 +1333,21 @@ static int PARSER_FLAGS(PyCompilerFlags *flags) #endif int -PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) +PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) { - PyObject *m, *d, *v, *w, *oenc = NULL; + PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name; mod_ty mod; PyArena *arena; char *ps1 = "", *ps2 = "", *enc = NULL; int errcode = 0; _Py_IDENTIFIER(encoding); + _Py_IDENTIFIER(__main__); + + mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */ + if (mod_name == NULL) { + PyErr_Print(); + return -1; + } if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ @@ -1375,9 +1393,9 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags Py_XDECREF(oenc); return -1; } - mod = PyParser_ASTFromFile(fp, filename, enc, - Py_single_input, ps1, ps2, - flags, &errcode, arena); + mod = PyParser_ASTFromFileObject(fp, filename, enc, + Py_single_input, ps1, ps2, + flags, &errcode, arena); Py_XDECREF(v); Py_XDECREF(w); Py_XDECREF(oenc); @@ -1390,7 +1408,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags PyErr_Print(); return -1; } - m = PyImport_AddModule("__main__"); + m = PyImport_AddModuleObject(mod_name); if (m == NULL) { PyArena_Free(arena); return -1; @@ -1407,6 +1425,23 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags return 0; } +int +PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) +{ + PyObject *filename; + int res; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + res = PyRun_InteractiveOneObject(fp, filename, flags); + Py_DECREF(filename); + return res; +} + + /* Check whether a file maybe a pyc file: Look at the extension, the file type, and, if we may close it, at the first few bytes. */ @@ -2010,37 +2045,55 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, { PyObject *ret = NULL; mod_ty mod; - PyArena *arena = PyArena_New(); + PyArena *arena; + _Py_static_string(PyId_string, ""); + PyObject *filename; + + filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ + if (filename == NULL) + return NULL; + + arena = PyArena_New(); if (arena == NULL) return NULL; - mod = PyParser_ASTFromString(str, "", start, flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); if (mod != NULL) - ret = run_mod(mod, "", globals, locals, flags, arena); + ret = run_mod(mod, filename, globals, locals, flags, arena); PyArena_Free(arena); return ret; } PyObject * -PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, +PyRun_FileExFlags(FILE *fp, const char *filename_str, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) { - PyObject *ret; + PyObject *ret = NULL; mod_ty mod; - PyArena *arena = PyArena_New(); + PyArena *arena = NULL; + PyObject *filename; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + goto exit; + + arena = PyArena_New(); if (arena == NULL) - return NULL; + goto exit; - mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0, - flags, NULL, arena); + mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0, + flags, NULL, arena); if (closeit) fclose(fp); if (mod == NULL) { - PyArena_Free(arena); - return NULL; + goto exit; } ret = run_mod(mod, filename, globals, locals, flags, arena); - PyArena_Free(arena); + +exit: + Py_XDECREF(filename); + if (arena != NULL) + PyArena_Free(arena); return ret; } @@ -2075,12 +2128,12 @@ flush_io(void) } static PyObject * -run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags, PyArena *arena) +run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, + PyCompilerFlags *flags, PyArena *arena) { PyCodeObject *co; PyObject *v; - co = PyAST_Compile(mod, filename, flags, arena); + co = PyAST_CompileObject(mod, filename, flags, -1, arena); if (co == NULL) return NULL; v = PyEval_EvalCode((PyObject*)co, globals, locals); -- cgit v1.2.1 From abe98ac333cb6792ed82b144822738e50e38d443 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Nov 2013 22:41:44 +0100 Subject: Issue #19512: add some common identifiers to only create common strings once, instead of creating temporary Unicode string objects Add also more identifiers in pythonrun.c to avoid temporary Unicode string objets for the interactive interpreter. --- Python/pythonrun.c | 59 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 61d03521e8..e510e6f78a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -35,6 +35,21 @@ #define PATH_MAX MAXPATHLEN #endif +/* Common identifiers */ +_Py_Identifier _PyId_argv = _Py_static_string_init("argv"); +_Py_Identifier _PyId_path = _Py_static_string_init("path"); +_Py_Identifier _PyId_stdin = _Py_static_string_init("stdin"); +_Py_Identifier _PyId_stdout = _Py_static_string_init("stdout"); +_Py_Identifier _PyId_stderr = _Py_static_string_init("stderr"); + +/* local identifiers */ +_Py_IDENTIFIER(excepthook); +_Py_IDENTIFIER(ps1); +_Py_IDENTIFIER(ps2); +_Py_IDENTIFIER(last_type); +_Py_IDENTIFIER(last_value); +_Py_IDENTIFIER(last_traceback); + #ifdef Py_REF_DEBUG static void _print_total_refs(void) { @@ -412,7 +427,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); - PySys_SetObject("stderr", pstderr); + _PySys_SetObjectId(&_PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); @@ -497,8 +512,8 @@ file_is_closed(PyObject *fobj) static void flush_std_files(void) { - PyObject *fout = PySys_GetObject("stdout"); - PyObject *ferr = PySys_GetObject("stderr"); + PyObject *fout = _PySys_GetObjectId(&_PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&_PyId_stderr); PyObject *tmp; _Py_IDENTIFIER(flush); @@ -776,7 +791,7 @@ Py_NewInterpreter(void) pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); - PySys_SetObject("stderr", pstderr); + _PySys_SetObjectId(&_PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); @@ -1170,7 +1185,7 @@ initstdio(void) goto error; } /* if (fd < 0) */ PySys_SetObject("__stdin__", std); - PySys_SetObject("stdin", std); + _PySys_SetObjectId(&_PyId_stdin, std); Py_DECREF(std); /* Set sys.stdout */ @@ -1185,7 +1200,7 @@ initstdio(void) goto error; } /* if (fd < 0) */ PySys_SetObject("__stdout__", std); - PySys_SetObject("stdout", std); + _PySys_SetObjectId(&_PyId_stdout, std); Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ @@ -1219,7 +1234,7 @@ initstdio(void) Py_DECREF(std); goto error; } - if (PySys_SetObject("stderr", std) < 0) { + if (_PySys_SetObjectId(&_PyId_stderr, std) < 0) { Py_DECREF(std); goto error; } @@ -1281,14 +1296,14 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * flags = &local_flags; local_flags.cf_flags = 0; } - v = PySys_GetObject("ps1"); + v = _PySys_GetObjectId(&PyId_ps1); if (v == NULL) { - PySys_SetObject("ps1", v = PyUnicode_FromString(">>> ")); + _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> ")); Py_XDECREF(v); } - v = PySys_GetObject("ps2"); + v = _PySys_GetObjectId(&PyId_ps2); if (v == NULL) { - PySys_SetObject("ps2", v = PyUnicode_FromString("... ")); + _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... ")); Py_XDECREF(v); } err = -1; @@ -1351,7 +1366,7 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ - v = PySys_GetObject("stdin"); + v = _PySys_GetObjectId(&_PyId_stdin); if (v && v != Py_None) { oenc = _PyObject_GetAttrId(v, &PyId_encoding); if (oenc) @@ -1360,7 +1375,7 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) PyErr_Clear(); } } - v = PySys_GetObject("ps1"); + v = _PySys_GetObjectId(&PyId_ps1); if (v != NULL) { v = PyObject_Str(v); if (v == NULL) @@ -1373,7 +1388,7 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) } } } - w = PySys_GetObject("ps2"); + w = _PySys_GetObjectId(&PyId_ps2); if (w != NULL) { w = PyObject_Str(w); if (w == NULL) @@ -1752,7 +1767,7 @@ handle_system_exit(void) if (PyLong_Check(value)) exitcode = (int)PyLong_AsLong(value); else { - PyObject *sys_stderr = PySys_GetObject("stderr"); + PyObject *sys_stderr = _PySys_GetObjectId(&_PyId_stderr); if (sys_stderr != NULL && sys_stderr != Py_None) { PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); } else { @@ -1795,11 +1810,11 @@ PyErr_PrintEx(int set_sys_last_vars) 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); + _PySys_SetObjectId(&PyId_last_type, exception); + _PySys_SetObjectId(&PyId_last_value, v); + _PySys_SetObjectId(&PyId_last_traceback, tb); } - hook = PySys_GetObject("excepthook"); + hook = _PySys_GetObjectId(&PyId_excepthook); if (hook) { PyObject *args = PyTuple_Pack(3, exception, v, tb); PyObject *result = PyEval_CallObject(hook, args); @@ -2009,7 +2024,7 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { PyObject *seen; - PyObject *f = PySys_GetObject("stderr"); + PyObject *f = _PySys_GetObjectId(&_PyId_stderr); if (PyExceptionInstance_Check(value) && tb != NULL && PyTraceBack_Check(tb)) { /* Put the traceback on the exception, otherwise it won't get @@ -2107,7 +2122,7 @@ flush_io(void) /* Save the current exception */ PyErr_Fetch(&type, &value, &traceback); - f = PySys_GetObject("stderr"); + f = _PySys_GetObjectId(&_PyId_stderr); if (f != NULL) { r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) @@ -2115,7 +2130,7 @@ flush_io(void) else PyErr_Clear(); } - f = PySys_GetObject("stdout"); + f = _PySys_GetObjectId(&_PyId_stdout); if (f != NULL) { r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) -- cgit v1.2.1 From 05bfe3160e622f7d33904a12c89fe0a155222fff Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 00:12:30 +0100 Subject: print_exception(): don't encode the module name to UTF-8 Replace _PyUnicode_AsString()+strcmp() with PyUnicode_CompareWithASCIIString(). --- Python/pythonrun.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e510e6f78a..e0c863811a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1928,10 +1928,9 @@ print_exception(PyObject *f, PyObject *value) err = PyFile_WriteString("", f); } else { - char* modstr = _PyUnicode_AsString(moduleName); - if (modstr && strcmp(modstr, "builtins")) + if (PyUnicode_CompareWithASCIIString(moduleName, "builtins") != 0) { - err = PyFile_WriteString(modstr, f); + err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); -- cgit v1.2.1 From 36fcb30e4fb853c47112a363d46b9e77f3c5e97d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 00:46:04 +0100 Subject: Issue #19512: add _PyUnicode_CompareWithId() function _PyUnicode_CompareWithId() is faster than PyUnicode_CompareWithASCIIString() when both strings are equal and interned. Add also _PyId_builtins identifier for "builtins" common string. --- 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 e0c863811a..be41de67f2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -37,6 +37,7 @@ /* Common identifiers */ _Py_Identifier _PyId_argv = _Py_static_string_init("argv"); +_Py_Identifier _PyId_builtins = _Py_static_string_init("builtins"); _Py_Identifier _PyId_path = _Py_static_string_init("path"); _Py_Identifier _PyId_stdin = _Py_static_string_init("stdin"); _Py_Identifier _PyId_stdout = _Py_static_string_init("stdout"); @@ -1928,7 +1929,7 @@ print_exception(PyObject *f, PyObject *value) err = PyFile_WriteString("", f); } else { - if (PyUnicode_CompareWithASCIIString(moduleName, "builtins") != 0) + if (_PyUnicode_CompareWithId(moduleName, &_PyId_builtins) != 0) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); -- cgit v1.2.1 From f8a141c2766dbd2eadcb245e207f4242295710c8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 12:37:56 +0100 Subject: print_error_text() doesn't encode the filename anymore Use aslo PyUnicode_FromFormat() to format the line so only one call to PyFile_WriteObject() is needed. tb_displayline() of Python/traceback.c has similar implementation. --- Python/pythonrun.c | 62 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index be41de67f2..5115c5724c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -50,6 +50,7 @@ _Py_IDENTIFIER(ps2); _Py_IDENTIFIER(last_type); _Py_IDENTIFIER(last_value); _Py_IDENTIFIER(last_traceback); +_Py_static_string(PyId_string, ""); #ifdef Py_REF_DEBUG static @@ -1625,8 +1626,8 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) } static int -parse_syntax_error(PyObject *err, PyObject **message, const char **filename, - int *lineno, int *offset, const char **text) +parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, + int *lineno, int *offset, PyObject **text) { long hold; PyObject *v; @@ -1637,6 +1638,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename, _Py_IDENTIFIER(text); *message = NULL; + *filename = NULL; /* new style errors. `err' is an instance */ *message = _PyObject_GetAttrId(err, &PyId_msg); @@ -1648,13 +1650,13 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename, goto finally; if (v == Py_None) { Py_DECREF(v); - *filename = NULL; + *filename = _PyUnicode_FromId(&PyId_string); + if (*filename == NULL) + goto finally; + Py_INCREF(*filename); } else { - *filename = _PyUnicode_AsString(v); - Py_DECREF(v); - if (!*filename) - goto finally; + *filename = v; } v = _PyObject_GetAttrId(err, &PyId_lineno); @@ -1688,15 +1690,13 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename, *text = NULL; } else { - *text = _PyUnicode_AsString(v); - Py_DECREF(v); - if (!*text) - goto finally; + *text = v; } return 1; finally: Py_XDECREF(*message); + Py_XDECREF(*filename); return 0; } @@ -1707,9 +1707,15 @@ PyErr_Print(void) } static void -print_error_text(PyObject *f, int offset, const char *text) +print_error_text(PyObject *f, int offset, PyObject *text_obj) { + char *text; char *nl; + + text = _PyUnicode_AsString(text_obj); + if (text == NULL) + return; + if (offset >= 0) { if (offset > 0 && offset == strlen(text) && text[offset - 1] == '\n') offset--; @@ -1880,27 +1886,30 @@ print_exception(PyObject *f, PyObject *value) if (err == 0 && _PyObject_HasAttrId(value, &PyId_print_file_and_line)) { - PyObject *message; - const char *filename, *text; + PyObject *message, *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); + PyObject *line; + Py_DECREF(value); value = message; + + line = PyUnicode_FromFormat(" File \"%U\", line %d\n", + filename, lineno); + Py_DECREF(filename); + if (line != NULL) { + PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + } + + if (text != NULL) { + print_error_text(f, offset, text); + Py_DECREF(text); + } + /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) @@ -2061,7 +2070,6 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *ret = NULL; mod_ty mod; PyArena *arena; - _Py_static_string(PyId_string, ""); PyObject *filename; filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ -- cgit v1.2.1 From 359ed22ea49d63923b451351ebf80decaaa7b79e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 23:07:29 +0100 Subject: Issue #19512, #19515: remove shared identifiers, move identifiers where they are used. Move also _Py_IDENTIFIER() defintions to the top in modified files to remove identifiers duplicated in the same file. --- Python/pythonrun.c | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 5115c5724c..922446ecf6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -35,21 +35,16 @@ #define PATH_MAX MAXPATHLEN #endif -/* Common identifiers */ -_Py_Identifier _PyId_argv = _Py_static_string_init("argv"); -_Py_Identifier _PyId_builtins = _Py_static_string_init("builtins"); -_Py_Identifier _PyId_path = _Py_static_string_init("path"); -_Py_Identifier _PyId_stdin = _Py_static_string_init("stdin"); -_Py_Identifier _PyId_stdout = _Py_static_string_init("stdout"); -_Py_Identifier _PyId_stderr = _Py_static_string_init("stderr"); - -/* local identifiers */ +_Py_IDENTIFIER(builtins); _Py_IDENTIFIER(excepthook); -_Py_IDENTIFIER(ps1); -_Py_IDENTIFIER(ps2); +_Py_IDENTIFIER(last_traceback); _Py_IDENTIFIER(last_type); _Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(last_traceback); +_Py_IDENTIFIER(ps1); +_Py_IDENTIFIER(ps2); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); _Py_static_string(PyId_string, ""); #ifdef Py_REF_DEBUG @@ -429,7 +424,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&_PyId_stderr, pstderr); + _PySys_SetObjectId(&PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); @@ -514,8 +509,8 @@ file_is_closed(PyObject *fobj) static void flush_std_files(void) { - PyObject *fout = _PySys_GetObjectId(&_PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&_PyId_stderr); + PyObject *fout = _PySys_GetObjectId(&PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); PyObject *tmp; _Py_IDENTIFIER(flush); @@ -793,7 +788,7 @@ Py_NewInterpreter(void) pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&_PyId_stderr, pstderr); + _PySys_SetObjectId(&PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); @@ -1187,7 +1182,7 @@ initstdio(void) goto error; } /* if (fd < 0) */ PySys_SetObject("__stdin__", std); - _PySys_SetObjectId(&_PyId_stdin, std); + _PySys_SetObjectId(&PyId_stdin, std); Py_DECREF(std); /* Set sys.stdout */ @@ -1202,7 +1197,7 @@ initstdio(void) goto error; } /* if (fd < 0) */ PySys_SetObject("__stdout__", std); - _PySys_SetObjectId(&_PyId_stdout, std); + _PySys_SetObjectId(&PyId_stdout, std); Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ @@ -1236,7 +1231,7 @@ initstdio(void) Py_DECREF(std); goto error; } - if (_PySys_SetObjectId(&_PyId_stderr, std) < 0) { + if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { Py_DECREF(std); goto error; } @@ -1368,7 +1363,7 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ - v = _PySys_GetObjectId(&_PyId_stdin); + v = _PySys_GetObjectId(&PyId_stdin); if (v && v != Py_None) { oenc = _PyObject_GetAttrId(v, &PyId_encoding); if (oenc) @@ -1774,7 +1769,7 @@ handle_system_exit(void) if (PyLong_Check(value)) exitcode = (int)PyLong_AsLong(value); else { - PyObject *sys_stderr = _PySys_GetObjectId(&_PyId_stderr); + PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); if (sys_stderr != NULL && sys_stderr != Py_None) { PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); } else { @@ -1938,7 +1933,7 @@ print_exception(PyObject *f, PyObject *value) err = PyFile_WriteString("", f); } else { - if (_PyUnicode_CompareWithId(moduleName, &_PyId_builtins) != 0) + if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); @@ -2033,7 +2028,7 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { PyObject *seen; - PyObject *f = _PySys_GetObjectId(&_PyId_stderr); + PyObject *f = _PySys_GetObjectId(&PyId_stderr); if (PyExceptionInstance_Check(value) && tb != NULL && PyTraceBack_Check(tb)) { /* Put the traceback on the exception, otherwise it won't get @@ -2130,7 +2125,7 @@ flush_io(void) /* Save the current exception */ PyErr_Fetch(&type, &value, &traceback); - f = _PySys_GetObjectId(&_PyId_stderr); + f = _PySys_GetObjectId(&PyId_stderr); if (f != NULL) { r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) @@ -2138,7 +2133,7 @@ flush_io(void) else PyErr_Clear(); } - f = _PySys_GetObjectId(&_PyId_stdout); + f = _PySys_GetObjectId(&PyId_stdout); if (f != NULL) { r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) -- cgit v1.2.1 From 355e6272737a813c3db93acf944cc25a5c93aaa1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 12 Nov 2013 16:37:55 +0100 Subject: Close #19466: Clear the frames of daemon threads earlier during the Python shutdown to call objects destructors. So "unclosed file" resource warnings are now corretly emitted for daemon threads. --- Python/pythonrun.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 922446ecf6..78942880e4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -576,11 +576,13 @@ Py_Finalize(void) _Py_Finalizing = tstate; initialized = 0; - /* Flush stdout+stderr */ - flush_std_files(); - - /* Disable signal handling */ - PyOS_FiniInterrupts(); + /* Destroy the state of all threads except of the current thread: in + practice, only daemon threads should still be alive. Clear frames of + other threads to call objects destructor. Destructors will be called in + the current Python thread. Since _Py_Finalizing has been set, no other + Python threads can lock the GIL at this point (if they try, they will + exit immediatly). */ + _PyThreadState_DeleteExcept(tstate); /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. @@ -595,6 +597,7 @@ Py_Finalize(void) * 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 @@ -602,6 +605,13 @@ Py_Finalize(void) while (PyGC_Collect() > 0) /* nothing */; #endif + + /* Flush stdout+stderr */ + flush_std_files(); + + /* Disable signal handling */ + PyOS_FiniInterrupts(); + /* Destroy all modules */ PyImport_Cleanup(); -- cgit v1.2.1 From 24d2bc62d4f65e830305258cd3b4e8b31e4f4634 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 12 Nov 2013 17:18:51 +0100 Subject: Issue #19466: Fix typo. Patch written by Vajrasky Kok. --- 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 78942880e4..8a59169d4f 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -581,7 +581,7 @@ Py_Finalize(void) other threads to call objects destructor. Destructors will be called in the current Python thread. Since _Py_Finalizing has been set, no other Python threads can lock the GIL at this point (if they try, they will - exit immediatly). */ + exit immediately). */ _PyThreadState_DeleteExcept(tstate); /* Collect garbage. This may call finalizers; it's nice to call these -- cgit v1.2.1 From fb9987791e8c7266ae19cf54761130808e66538b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 12 Nov 2013 21:39:02 +0100 Subject: Issue #19515: Remove identifiers duplicated in the same file. Patch written by Andrei Dorian Duma. --- Python/pythonrun.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8a59169d4f..8ccf70dea9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -37,9 +37,11 @@ _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(excepthook); +_Py_IDENTIFIER(flush); _Py_IDENTIFIER(last_traceback); _Py_IDENTIFIER(last_type); _Py_IDENTIFIER(last_value); +_Py_IDENTIFIER(name); _Py_IDENTIFIER(ps1); _Py_IDENTIFIER(ps2); _Py_IDENTIFIER(stdin); @@ -215,7 +217,6 @@ get_codec_name(const char *encoding) { char *name_utf8, *name_str; PyObject *codec, *name = NULL; - _Py_IDENTIFIER(name); codec = _PyCodec_Lookup(encoding); if (!codec) @@ -512,7 +513,6 @@ flush_std_files(void) PyObject *fout = _PySys_GetObjectId(&PyId_stdout); PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); PyObject *tmp; - _Py_IDENTIFIER(flush); if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); @@ -1009,7 +1009,6 @@ create_stdio(PyObject* io, _Py_IDENTIFIER(open); _Py_IDENTIFIER(isatty); _Py_IDENTIFIER(TextIOWrapper); - _Py_IDENTIFIER(name); _Py_IDENTIFIER(mode); /* stdin is always opened in buffered mode, first because it shouldn't @@ -2130,7 +2129,6 @@ flush_io(void) { PyObject *f, *r; PyObject *type, *value, *traceback; - _Py_IDENTIFIER(flush); /* Save the current exception */ PyErr_Fetch(&type, &value, &traceback); -- cgit v1.2.1 From 1f4288b872047826fa7bc66ab5fe785e61a095b1 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 20 Nov 2013 11:46:18 +0100 Subject: ssue #19183: Implement PEP 456 'secure and interchangeable hash algorithm'. Python now uses SipHash24 on all major platforms. --- 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 e427be3174..b5d57dfcbf 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -104,6 +104,7 @@ extern int _PyLong_Init(void); extern void PyLong_Fini(void); extern int _PyFaulthandler_Init(void); extern void _PyFaulthandler_Fini(void); +extern void _PyHash_Fini(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -650,6 +651,8 @@ Py_Finalize(void) #ifdef COUNT_ALLOCS dump_counts(stdout); #endif + /* dump hash stats */ + _PyHash_Fini(); PRINT_TOTAL_REFS(); -- cgit v1.2.1 From ccdf7c7327a9087370fd0b419eff377807a1070b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 23 Nov 2013 12:27:24 +0100 Subject: Issue #18874: Implement the PEP 454 (tracemalloc) --- 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 b5d57dfcbf..3adbbd7373 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -105,6 +105,7 @@ extern void PyLong_Fini(void); extern int _PyFaulthandler_Init(void); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); +extern int _PyTraceMalloc_Init(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -454,6 +455,9 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ + if (_PyTraceMalloc_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize tracemalloc"); + initmain(interp); /* Module __main__ */ if (initstdio() < 0) Py_FatalError( -- cgit v1.2.1 From 7049e92e939bfdb1d9e34a8d3a5d1611d8fd1a4a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 1 Dec 2013 10:03:26 +0100 Subject: Closes #19831: Stop tracemalloc later at Python shutdown to be able to use tracemalloc in objects destructor Replace atexit handler with an harcoded C function _PyTraceMalloc_Fini(). --- Python/pythonrun.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3adbbd7373..ccf82af36b 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -106,6 +106,7 @@ extern int _PyFaulthandler_Init(void); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Init(void); +extern int _PyTraceMalloc_Fini(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -642,6 +643,10 @@ Py_Finalize(void) PyGC_Collect(); #endif + /* Disable tracemalloc after all Python objects have been destroyed, + so it is possible to use tracemalloc in objects destructor. */ + _PyTraceMalloc_Fini(); + /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ _PyImport_Fini(); -- cgit v1.2.1 From 88f29f787daaf77dfe602476cb4707a593709945 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 9 Dec 2013 02:10:08 +0100 Subject: Issue #19817: Fix print_exception(), clear the exception on error --- Python/pythonrun.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Python/pythonrun.c') diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ccf82af36b..97daecc205 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1888,9 +1888,11 @@ print_exception(PyObject *f, PyObject *value) _Py_IDENTIFIER(print_file_and_line); 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); + err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); + err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); + err += PyFile_WriteString(" found\n", f); + if (err) + PyErr_Clear(); return; } -- cgit v1.2.1