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

This commit is contained in:
Michael Seifert 2017-03-15 06:26:33 +01:00 committed by Serhiy Storchaka
parent 024b4fdc4a
commit 6c3d527468
4 changed files with 34 additions and 1 deletions

View File

@ -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

View File

@ -1374,6 +1374,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

View File

@ -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.

View File

@ -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;
} }