Mercurial > cpython-lru_cache-weakref
diff Python/modsupport.c @ 32656:391937571065 legacy-trunk
This is Pete Shinners' patch from his bug report
[ 984722 ] Py_BuildValue loses reference counts on error
I'm ever-so-slightly uneasy at the amount of work this can do with an
exception pending, but I don't think that this can result in anything
more serious than a strange error message.
| author | Michael W. Hudson <mwh@python.net> |
|---|---|
| date | Wed, 14 Jul 2004 11:28:06 +0000 |
| parents | b6c139544c16 |
| children | fe4c627b2096 |
line wrap: on
line diff
--- a/Python/modsupport.c Wed Jul 14 00:48:58 2004 +0000 +++ b/Python/modsupport.c Wed Jul 14 11:28:06 2004 +0000 @@ -152,28 +152,32 @@ { PyObject *d; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((d = PyDict_New()) == NULL) return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ for (i = 0; i < n; i+= 2) { PyObject *k, *v; int err; k = do_mkvalue(p_format, p_va); if (k == NULL) { - Py_DECREF(d); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + k = Py_None; } v = do_mkvalue(p_format, p_va); if (v == NULL) { - Py_DECREF(k); - Py_DECREF(d); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + v = Py_None; } err = PyDict_SetItem(d, k, v); Py_DECREF(k); Py_DECREF(v); - if (err < 0) { + if (err < 0 || itemfailed) { Py_DECREF(d); return NULL; } @@ -194,15 +198,19 @@ { PyObject *v; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((v = PyList_New(n)) == NULL) return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ for (i = 0; i < n; i++) { PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - Py_DECREF(v); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + w = Py_None; } PyList_SetItem(v, i, w); } @@ -214,6 +222,10 @@ } else if (endchar) ++*p_format; + if (itemfailed) { + Py_DECREF(v); + v = NULL; + } return v; } @@ -233,15 +245,19 @@ { PyObject *v; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((v = PyTuple_New(n)) == NULL) return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ for (i = 0; i < n; i++) { PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - Py_DECREF(v); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + w = Py_None; } PyTuple_SetItem(v, i, w); } @@ -253,6 +269,10 @@ } else if (endchar) ++*p_format; + if (itemfailed) { + Py_DECREF(v); + v = NULL; + } return v; }
