| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,6 +25,12 @@ PyAPI_FUNC(int) PyErr_WarnExplicit( | |||
| 25 | 25 | const char *module, /* UTF-8 encoded string */ | |
| 26 | 26 | PyObject *registry); | |
| 27 | 27 | ||
| 28 | + PyAPI_FUNC(int) | ||
| 29 | + PyErr_WarnExplicitFormat(PyObject *category, | ||
| 30 | + const char *filename, int lineno, | ||
| 31 | + const char *module, PyObject *registry, | ||
| 32 | + const char *format, ...); | ||
| 33 | + | ||
| 28 | 34 | /* DEPRECATED: Use PyErr_WarnEx() instead. */ | |
| 29 | 35 | #ifndef Py_LIMITED_API | |
| 30 | 36 | #define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1? | |||
| 10 | 10 | Core and Builtins | |
| 11 | 11 | ----------------- | |
| 12 | 12 | ||
| 13 | + - Issue #1545463: At shutdown, defer finalization of codec modules so | ||
| 14 | + that stderr remains usable. | ||
| 15 | + | ||
| 13 | 16 | - Issue #7330: Implement width and precision (ex: "%5.3s") for the format | |
| 14 | 17 | string of PyUnicode_FromFormat() function, original patch written by Ysj Ray. | |
| 15 | 18 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1557,8 +1557,12 @@ _PyGC_DumpShutdownStats(void) | |||
| 1557 | 1557 | else | |
| 1558 | 1558 | message = "gc: %zd uncollectable objects at " \ | |
| 1559 | 1559 | "shutdown; use gc.set_debug(gc.DEBUG_UNCOLLECTABLE) to list them"; | |
| 1560 | - if (PyErr_WarnFormat(PyExc_ResourceWarning, 0, message, | ||
| 1561 | - PyList_GET_SIZE(garbage)) < 0) | ||
| 1560 | + /* PyErr_WarnFormat does too many things and we are at shutdown, | ||
| 1561 | + the warnings module's dependencies (e.g. linecache) may be gone | ||
| 1562 | + already. */ | ||
| 1563 | + if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, | ||
| 1564 | + "gc", NULL, message, | ||
| 1565 | + PyList_GET_SIZE(garbage))) | ||
| 1562 | 1566 | PyErr_WriteUnraisable(NULL); | |
| 1563 | 1567 | if (debug & DEBUG_UNCOLLECTABLE) { | |
| 1564 | 1568 | PyObject *repr = NULL, *bytes = NULL; | |
@@ -1567,7 +1571,7 @@ _PyGC_DumpShutdownStats(void) | |||
| 1567 | 1571 | PyErr_WriteUnraisable(garbage); | |
| 1568 | 1572 | else { | |
| 1569 | 1573 | PySys_WriteStderr( | |
| 1570 | - " %s\n", | ||
| 1574 | + " %s\n", | ||
| 1571 | 1575 | PyBytes_AS_STRING(bytes) | |
| 1572 | 1576 | ); | |
| 1573 | 1577 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -800,8 +800,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text, | |||
| 800 | 800 | goto exit; | |
| 801 | 801 | if (module_str != NULL) { | |
| 802 | 802 | module = PyUnicode_FromString(module_str); | |
| 803 | - if (module == NULL) | ||
| 804 | - goto exit; | ||
| 803 | + if (module == NULL) | ||
| 804 | + goto exit; | ||
| 805 | 805 | } | |
| 806 | 806 | ||
| 807 | 807 | if (category == NULL) | |
@@ -820,6 +820,49 @@ PyErr_WarnExplicit(PyObject *category, const char *text, | |||
| 820 | 820 | return ret; | |
| 821 | 821 | } | |
| 822 | 822 | ||
| 823 | + int | ||
| 824 | + PyErr_WarnExplicitFormat(PyObject *category, | ||
| 825 | + const char *filename_str, int lineno, | ||
| 826 | + const char *module_str, PyObject *registry, | ||
| 827 | + const char *format, ...) | ||
| 828 | + { | ||
| 829 | + PyObject *message; | ||
| 830 | + PyObject *module = NULL; | ||
| 831 | + PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); | ||
| 832 | + int ret = -1; | ||
| 833 | + va_list vargs; | ||
| 834 | + | ||
| 835 | + if (filename == NULL) | ||
| 836 | + goto exit; | ||
| 837 | + if (module_str != NULL) { | ||
| 838 | + module = PyUnicode_FromString(module_str); | ||
| 839 | + if (module == NULL) | ||
| 840 | + goto exit; | ||
| 841 | + } | ||
| 842 | + | ||
| 843 | + #ifdef HAVE_STDARG_PROTOTYPES | ||
| 844 | + va_start(vargs, format); | ||
| 845 | + #else | ||
| 846 | + va_start(vargs); | ||
| 847 | + #endif | ||
| 848 | + message = PyUnicode_FromFormatV(format, vargs); | ||
| 849 | + if (message != NULL) { | ||
| 850 | + PyObject *res; | ||
| 851 | + res = warn_explicit(category, message, filename, lineno, | ||
| 852 | + module, registry, NULL); | ||
| 853 | + Py_DECREF(message); | ||
| 854 | + if (res != NULL) { | ||
| 855 | + Py_DECREF(res); | ||
| 856 | + ret = 0; | ||
| 857 | + } | ||
| 858 | + } | ||
| 859 | + va_end(vargs); | ||
| 860 | + exit: | ||
| 861 | + Py_XDECREF(module); | ||
| 862 | + Py_XDECREF(filename); | ||
| 863 | + return ret; | ||
| 864 | + } | ||
| 865 | + | ||
| 823 | 866 | ||
| 824 | 867 | PyDoc_STRVAR(warn_doc, | |
| 825 | 868 | "Issue a warning, or maybe ignore it or raise an exception."); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -295,6 +295,30 @@ static char* sys_files[] = { | |||
| 295 | 295 | NULL | |
| 296 | 296 | }; | |
| 297 | 297 | ||
| 298 | + static int | ||
| 299 | + is_essential_module(PyObject *name) | ||
| 300 | + { | ||
| 301 | + Py_ssize_t name_len; | ||
| 302 | + char *name_str = PyUnicode_AsUTF8AndSize(name, &name_len); | ||
| 303 | + | ||
| 304 | + if (name_str == NULL) { | ||
| 305 | + PyErr_Clear(); | ||
| 306 | + return 0; | ||
| 307 | + } | ||
| 308 | + if (strcmp(name_str, "builtins") == 0) | ||
| 309 | + return 1; | ||
| 310 | + if (strcmp(name_str, "sys") == 0) | ||
| 311 | + return 1; | ||
| 312 | + /* These are all needed for stderr to still function */ | ||
| 313 | + if (strcmp(name_str, "codecs") == 0) | ||
| 314 | + return 1; | ||
| 315 | + if (strcmp(name_str, "_codecs") == 0) | ||
| 316 | + return 1; | ||
| 317 | + if (strncmp(name_str, "encodings.", 10) == 0) | ||
| 318 | + return 1; | ||
| 319 | + return 0; | ||
| 320 | + } | ||
| 321 | + | ||
| 298 | 322 | ||
| 299 | 323 | /* Un-initialize things, as good as we can */ | |
| 300 | 324 | ||
@@ -374,9 +398,7 @@ PyImport_Cleanup(void) | |||
| 374 | 398 | if (value->ob_refcnt != 1) | |
| 375 | 399 | continue; | |
| 376 | 400 | if (PyUnicode_Check(key) && PyModule_Check(value)) { | |
| 377 | - if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) | ||
| 378 | - continue; | ||
| 379 | - if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) | ||
| 401 | + if (is_essential_module(key)) | ||
| 380 | 402 | continue; | |
| 381 | 403 | if (Py_VerboseFlag) | |
| 382 | 404 | PySys_FormatStderr( | |
@@ -392,9 +414,7 @@ PyImport_Cleanup(void) | |||
| 392 | 414 | pos = 0; | |
| 393 | 415 | while (PyDict_Next(modules, &pos, &key, &value)) { | |
| 394 | 416 | if (PyUnicode_Check(key) && PyModule_Check(value)) { | |
| 395 | - if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) | ||
| 396 | - continue; | ||
| 397 | - if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) | ||
| 417 | + if (is_essential_module(key)) | ||
| 398 | 418 | continue; | |
| 399 | 419 | if (Py_VerboseFlag) | |
| 400 | 420 | PySys_FormatStderr("# cleanup[2] %U\n", key); | |
@@ -411,20 +431,15 @@ PyImport_Cleanup(void) | |||
| 411 | 431 | machinery. */ | |
| 412 | 432 | _PyGC_DumpShutdownStats(); | |
| 413 | 433 | ||
| 414 | - /* Next, delete sys and builtins (in that order) */ | ||
| 415 | - value = PyDict_GetItemString(modules, "sys"); | ||
| 416 | - if (value != NULL && PyModule_Check(value)) { | ||
| 417 | - if (Py_VerboseFlag) | ||
| 418 | - PySys_WriteStderr("# cleanup sys\n"); | ||
| 419 | - _PyModule_Clear(value); | ||
| 420 | - PyDict_SetItemString(modules, "sys", Py_None); | ||
| 421 | - } | ||
| 422 | - value = PyDict_GetItemString(modules, "builtins"); | ||
| 423 | - if (value != NULL && PyModule_Check(value)) { | ||
| 424 | - if (Py_VerboseFlag) | ||
| 425 | - PySys_WriteStderr("# cleanup builtins\n"); | ||
| 426 | - _PyModule_Clear(value); | ||
| 427 | - PyDict_SetItemString(modules, "builtins", Py_None); | ||
| 434 | + /* Next, delete all remaining modules */ | ||
| 435 | + pos = 0; | ||
| 436 | + while (PyDict_Next(modules, &pos, &key, &value)) { | ||
| 437 | + if (PyUnicode_Check(key) && PyModule_Check(value)) { | ||
| 438 | + if (Py_VerboseFlag) | ||
| 439 | + PySys_FormatStderr("# cleanup[3] %U\n", key); | ||
| 440 | + _PyModule_Clear(value); | ||
| 441 | + PyDict_SetItem(modules, key, Py_None); | ||
| 442 | + } | ||
| 428 | 443 | } | |
| 429 | 444 | ||
| 430 | 445 | /* Finally, clear and delete the modules directory */ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments