From: Serhiy Storchaka Date: Wed, 22 Feb 2017 09:46:32 +0000 (+0200) Subject: [3.5] bpo-29532: Altering a kwarg dictionary passed to functools.partial() no longer... X-Git-Tag: v3.5.4rc1~332 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5010a77a4da76d8d3fd861a63a7f1ce8f0e9c520;p=python [3.5] bpo-29532: Altering a kwarg dictionary passed to functools.partial() no longer affects a partial object after creation. (#222) --- diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 9ccd0cafc4..a82ca7ab88 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -80,6 +80,15 @@ class TestPartial: p(b=7) self.assertEqual(d, {'a':3}) + def test_kwargs_copy(self): + # Issue #29532: Altering a kwarg dictionary passed to a constructor + # should not affect a partial object after creation + d = {'a': 3} + p = self.partial(capture, **d) + self.assertEqual(p(), ((), {'a': 3})) + d['a'] = 5 + self.assertEqual(p(), ((), {'a': 3})) + def test_arg_combinations(self): # exercise special code paths for zero args in either partial # object or the caller diff --git a/Misc/NEWS b/Misc/NEWS index 038233735f..a01d454ab7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,9 @@ Extension Modules Library ------- +- bpo-29532: Altering a kwarg dictionary passed to functools.partial() + no longer affects a partial object after creation. + - Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap, improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, Manuel Krebber, and Łukasz Langa. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index be0f5f9e65..0471d665e6 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -88,10 +88,13 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (kw == NULL) { pto->kw = PyDict_New(); } - else { + else if (Py_REFCNT(kw) == 1) { Py_INCREF(kw); pto->kw = kw; } + else { + pto->kw = PyDict_Copy(kw); + } } else { pto->kw = PyDict_Copy(pkw);