Core and Builtins
-----------------
+ - Issue #24096: Make warnings.warn_explicit more robust against mutation of the
+ warnings.filters list.
+
+- Issue #23996: Avoid a crash when a delegated generator raises an
+ unnormalized StopIteration exception. Patch by Stefan Behnel.
+
+- Issue #24022: Fix tokenizer crash when processing undecodable source code.
+
+- Issue #23309: Avoid a deadlock at shutdown if a daemon thread is aborted
+ while it is holding a lock to a buffered I/O object, and the main thread
+ tries to use the same I/O object (typically stdout or stderr). A fatal
+ error is emitted instead.
+
+- Issue #22977: Fixed formatting Windows error messages on Wine.
+ Patch by Martin Panter.
+
+- Issue #23803: Fixed str.partition() and str.rpartition() when a separator
+ is wider then partitioned string.
+
+- Issue #23192: Fixed generator lambdas. Patch by Bruno Cauet.
+
+- Issue #23629: Fix the default __sizeof__ implementation for variable-sized
+ objects.
+
- Issue #24044: Fix possible null pointer dereference in list.sort in out of
memory conditions.
}
- /* The item is a borrowed reference. */
+ /* The item is a new reference. */
-static const char *
+static PyObject*
get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
PyObject *module, PyObject **item)
{
ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
good_msg = check_matched(msg, text);
- if (good_msg == -1)
++ if (good_msg == -1) {
++ Py_DECREF(tmp_item);
+ return NULL;
++ }
+
good_mod = check_matched(mod, module);
- if (good_mod == -1)
++ if (good_mod == -1) {
++ Py_DECREF(tmp_item);
+ return NULL;
++ }
+
is_subclass = PyObject_IsSubclass(category, cat);
- if (is_subclass == -1)
++ if (is_subclass == -1) {
++ Py_DECREF(tmp_item);
+ return NULL;
++ }
+
ln = PyLong_AsSsize_t(ln_obj);
- if (ln == -1 && PyErr_Occurred())
- if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
- (ln == -1 && PyErr_Occurred())) {
++ if (ln == -1 && PyErr_Occurred()) {
+ Py_DECREF(tmp_item);
return NULL;
+ }
- if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
+ if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
+ *item = tmp_item;
- return _PyUnicode_AsString(action);
+ return action;
+ }
+
+ Py_DECREF(tmp_item);
}
action = get_default_action();
- if (action != NULL)
+ if (action != NULL) {
+ Py_INCREF(Py_None);
+ *item = Py_None;
- return _PyUnicode_AsString(action);
+ return action;
+ }
PyErr_SetString(PyExc_ValueError,
MODULE_NAME ".defaultaction not found");
PyObject *module, PyObject *registry, PyObject *sourceline)
{
PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
- PyObject *item = Py_None;
+ PyObject *item = NULL;
- const char *action;
+ PyObject *action;
int rc;
+ /* module can be None if a warning is emitted late during Python shutdown.
+ In this case, the Python warnings module was probably unloaded, filters
+ are no more available to choose as action. It is safer to ignore the
+ warning and do nothing. */
+ if (module == Py_None)
+ Py_RETURN_NONE;
+
if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
return NULL;