diff -r 284b3de802b7 Lib/test/test_capi.py --- a/Lib/test/test_capi.py Sat Jan 30 04:45:02 2016 +0000 +++ b/Lib/test/test_capi.py Fri Jan 29 13:08:15 2016 +0200 @@ -236,6 +236,20 @@ class CAPITest(unittest.TestCase): 'return_result_with_error.* ' 'returned a result with an error set') + def test_buildvalue_N(self): + getrefcount = support.get_attribute(sys, 'getrefcount') + obj = object() + cnt = getrefcount(obj) + res = _testcapi.buildvalue_cN(65, obj) + self.assertIs(res[1], obj) + self.assertEqual(getrefcount(obj), cnt + 1) + # test that the 'N' argument is decrefed in case of error + obj = object() + cnt = getrefcount(obj) + with self.assertRaises((OverflowError, ValueError)): + res = _testcapi.buildvalue_cN(2**32, obj) + self.assertEqual(getrefcount(obj), cnt) + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): diff -r 284b3de802b7 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Sat Jan 30 04:45:02 2016 +0000 +++ b/Modules/_testcapimodule.c Fri Jan 29 13:08:15 2016 +0200 @@ -872,6 +872,18 @@ test_L_code(PyObject *self) #endif /* ifdef HAVE_LONG_LONG */ +static PyObject * +buildvalue_cN(PyObject *self, PyObject *args) +{ + int i; + PyObject *o; + if (!PyArg_ParseTuple(args, "iO", &i, &o)) + return NULL; + Py_INCREF(o); + return Py_BuildValue("cN", i, o); +} + + /* Test tuple argument processing */ static PyObject * getargs_tuple(PyObject *self, PyObject *args) @@ -3653,6 +3665,7 @@ static PyMethodDef TestMethods[] = { {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, #endif {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, + {"buildvalue_cN", buildvalue_cN, METH_VARARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_keywords", (PyCFunction)getargs_keywords, METH_VARARGS|METH_KEYWORDS}, diff -r 284b3de802b7 Python/modsupport.c --- a/Python/modsupport.c Sat Jan 30 04:45:02 2016 +0000 +++ b/Python/modsupport.c Fri Jan 29 13:08:15 2016 +0200 @@ -156,10 +156,11 @@ do_mktuple(const char **p_format, va_lis 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. */ + if ((v = PyTuple_New(n)) == NULL) { + itemfailed = 1; + } for (i = 0; i < n; i++) { PyObject *w; @@ -168,20 +169,19 @@ do_mktuple(const char **p_format, va_lis PyErr_Fetch(&exception, &value, &tb); w = do_mkvalue(p_format, p_va, flags); PyErr_Restore(exception, value, tb); + Py_XDECREF(w); } else { w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + itemfailed = 1; + } + PyTuple_SET_ITEM(v, i, w); } - if (w == NULL) { - itemfailed = 1; - Py_INCREF(Py_None); - w = Py_None; - } - PyTuple_SET_ITEM(v, i, w); } if (itemfailed) { /* do_mkvalue() should have already set an error */ - Py_DECREF(v); + Py_XDECREF(v); return NULL; } if (**p_format != endchar) {