Commit 6c3d5274 authored by Michael Seifert's avatar Michael Seifert Committed by Serhiy Storchaka

bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords are not strings (#649)

parent 024b4fdc
...@@ -403,6 +403,32 @@ class TestPartialC(TestPartial, unittest.TestCase): ...@@ -403,6 +403,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
......
No preview for this file type
...@@ -281,6 +281,9 @@ Extension Modules ...@@ -281,6 +281,9 @@ Extension Modules
Library Library
------- -------
- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords
are not strings. Patch by Michael Seifert.
- bpo-8256: Fixed possible failing or crashing input() if attributes "encoding" - bpo-8256: Fixed possible failing or crashing input() if attributes "encoding"
or "errors" of sys.stdin or sys.stdout are not set or are not strings. or "errors" of sys.stdin or sys.stdout are not set or are not strings.
......
...@@ -297,8 +297,11 @@ partial_repr(partialobject *pto) ...@@ -297,8 +297,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