[3.5] bpo-29532: Altering a kwarg dictionary passed to functools.partial() no longer affects a partial object after creation. (#222)

This commit is contained in:
Serhiy Storchaka 2017-02-22 11:46:32 +02:00 committed by GitHub
parent 8fa7e22134
commit 5010a77a4d
3 changed files with 16 additions and 1 deletions

View file

@ -80,6 +80,15 @@ class TestPartial:
p(b=7) p(b=7)
self.assertEqual(d, {'a':3}) 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): def test_arg_combinations(self):
# exercise special code paths for zero args in either partial # exercise special code paths for zero args in either partial
# object or the caller # object or the caller

View file

@ -32,6 +32,9 @@ Extension Modules
Library 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, - Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap,
improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi,
Manuel Krebber, and Łukasz Langa. Manuel Krebber, and Łukasz Langa.

View file

@ -88,10 +88,13 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (kw == NULL) { if (kw == NULL) {
pto->kw = PyDict_New(); pto->kw = PyDict_New();
} }
else { else if (Py_REFCNT(kw) == 1) {
Py_INCREF(kw); Py_INCREF(kw);
pto->kw = kw; pto->kw = kw;
} }
else {
pto->kw = PyDict_Copy(kw);
}
} }
else { else {
pto->kw = PyDict_Copy(pkw); pto->kw = PyDict_Copy(pkw);