Kaydet (Commit) 53b2667d authored tarafından Michael Seifert's avatar Michael Seifert Kaydeden (comit) Serhiy Storchaka

bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords are…

bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords are not strings (#649) (#671)
üst faa2cc63
...@@ -402,6 +402,32 @@ class TestPartialC(TestPartial, unittest.TestCase): ...@@ -402,6 +402,32 @@ class TestPartialC(TestPartial, unittest.TestCase):
else: else:
self.fail('partial object allowed __dict__ to be deleted') self.fail('partial object allowed __dict__ to be deleted')
def test_manually_adding_non_string_keyword(self):
p = self.partial(capture)
# Adding a non-string/unicode keyword to partial kwargs
p.keywords[1234] = 'value'
r = repr(p)
self.assertIn('1234', r)
self.assertIn("'value'", r)
with self.assertRaises(TypeError):
p()
def test_keystr_replaces_value(self):
p = self.partial(capture)
class MutatesYourDict(object):
def __str__(self):
p.keywords[self] = ['sth2']
return 'astr'
# Raplacing the value during key formatting should keep the original
# value alive (at least long enough).
p.keywords[MutatesYourDict()] = ['sth']
r = repr(p)
self.assertIn('astr', r)
self.assertIn("['sth']", r)
class TestPartialPy(TestPartial, unittest.TestCase): class TestPartialPy(TestPartial, unittest.TestCase):
partial = py_functools.partial partial = py_functools.partial
......
...@@ -1371,6 +1371,7 @@ Federico Schwindt ...@@ -1371,6 +1371,7 @@ Federico Schwindt
Barry Scott Barry Scott
Steven Scott Steven Scott
Nick Seidenman Nick Seidenman
Michael Seifert
Žiga Seilnacht Žiga Seilnacht
Yury Selivanov Yury Selivanov
Fred Sells Fred Sells
......
...@@ -29,6 +29,9 @@ Core and Builtins ...@@ -29,6 +29,9 @@ Core and Builtins
Library Library
------- -------
- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords
are not strings. Patch by Michael Seifert.
- bpo-29742: get_extra_info() raises exception if get called on closed ssl transport. - bpo-29742: get_extra_info() raises exception if get called on closed ssl transport.
Patch by Nikolay Kim. Patch by Nikolay Kim.
......
...@@ -250,8 +250,11 @@ partial_repr(partialobject *pto) ...@@ -250,8 +250,11 @@ partial_repr(partialobject *pto)
/* Pack keyword arguments */ /* Pack keyword arguments */
assert (PyDict_Check(pto->kw)); assert (PyDict_Check(pto->kw));
for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) {
Py_SETREF(arglist, PyUnicode_FromFormat("%U, %U=%R", arglist, /* Prevent key.__str__ from deleting the value. */
Py_INCREF(value);
Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist,
key, value)); key, value));
Py_DECREF(value);
if (arglist == NULL) if (arglist == NULL)
goto done; goto done;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment