diff -r 42bf74b90626 Include/object.h --- a/Include/object.h Wed Mar 20 14:26:33 2013 -0700 +++ b/Include/object.h Sat Mar 30 22:04:11 2013 -0700 @@ -809,6 +809,8 @@ * Python integers aren't currently weakly referencable. Best practice is * to use Py_CLEAR() even if you can't think of a reason for why you need to. */ + + #define Py_CLEAR(op) \ do { \ if (op) { \ @@ -819,8 +821,19 @@ } while (0) /* Macros to use in case the object pointer may be NULL: */ -#define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) -#define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) +#define Py_XINCREF(op) \ + do { \ + PyObject* _py_tmp=(PyObject*)(op); \ + if (_py_tmp != NULL) \ + Py_INCREF(_py_tmp); \ + } while (0) + +#define Py_XDECREF(op) \ + do { \ + PyObject* _py_tmp=(PyObject*)(op); \ + if (_py_tmp != NULL) \ + Py_DECREF(_py_tmp); \ + } while (0) /* These are provided as conveniences to Python runtime embedders, so that diff -r 42bf74b90626 Misc/ACKS --- a/Misc/ACKS Wed Mar 20 14:26:33 2013 -0700 +++ b/Misc/ACKS Sat Mar 30 22:04:11 2013 -0700 @@ -964,6 +964,7 @@ Remi Pointel Ariel Poliak Guilherme Polo +Illia Polosukhin Michael Pomraning Iustin Pop Claudiu Popa diff -r 42bf74b90626 Misc/NEWS --- a/Misc/NEWS Wed Mar 20 14:26:33 2013 -0700 +++ b/Misc/NEWS Sat Mar 30 22:04:11 2013 -0700 @@ -19,6 +19,9 @@ and kwarg and kwargannotation. Change the column offset of ast.Attribute to be at the attribute name. +- Issue #17206: Py_XDECREF() and Py_XINCREF() now expands their arguments once + instead of multiple times. Patch written by Illia Polosukhin. + - Issue #17434: Properly raise a SyntaxError when a string occurs between future imports. diff -r 42bf74b90626 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Wed Mar 20 14:26:33 2013 -0700 +++ b/Modules/_testcapimodule.c Sat Mar 30 22:04:11 2013 -0700 @@ -2468,6 +2468,17 @@ return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); } +static void +test_xdecref_doesnt_leak(PyObject* ob) +{ + Py_XDECREF(PyLong_FromLong(0)); +} + +static void +test_decref_doesnt_leak(PyObject* ob) +{ + Py_DECREF(PyLong_FromLong(0)); +} static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -2478,6 +2489,8 @@ {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, + {"test_xdecref_doesnt_leak", (PyCFunction)test_xdecref_doesnt_leak, METH_NOARGS}, + {"test_decref_doesnt_leak", (PyCFunction)test_decref_doesnt_leak, METH_NOARGS}, {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, METH_NOARGS}, {"test_long_as_double", (PyCFunction)test_long_as_double,METH_NOARGS},