diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 8c85b1498f4..56cb00c293c 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2441,6 +2441,12 @@ Changes in the Python API module and the :func:`help` function. (Contributed by Serhiy Storchaka in :issue:`15582`.) +* Nested :func:`functools.partial` calls are now flattened. If you were + relying on the previous behavior, you can now either add an attribute to a + :func:`functools.partial` object or you can create a subclass of + :func:`functools.partial`. + (Contributed by Alexander Belopolsky in :issue:`7830`.) + Changes in the C API -------------------- diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index ae929eca99f..7ecf877b11d 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -139,14 +139,23 @@ class TestPartial: def test_nested_optimization(self): partial = self.partial - # Only "true" partial is optimized - if partial.__name__ != 'partial': - return inner = partial(signature, 'asdf') nested = partial(inner, bar=True) flat = partial(signature, 'asdf', bar=True) self.assertEqual(signature(nested), signature(flat)) + def test_nested_partial_with_attribute(self): + # see issue 25137 + partial = self.partial + + def foo(bar): + return bar + + p = partial(foo, 'first') + p2 = partial(p, 'second') + p2.new_attr = 'spam' + self.assertEqual(p2.new_attr, 'spam') + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): @@ -238,6 +247,9 @@ class TestPartialCSubclass(TestPartialC): if c_functools: partial = PartialSubclass + # partial subclasses are not optimized for nested calls + test_nested_optimization = None + class TestPartialMethod(unittest.TestCase):