@@ -217,6 +217,24 @@ def test_repr(self):
217217 ['{}({!r}, {}, {})' .format (name , capture , args_repr , kwargs_repr )
218218 for kwargs_repr in kwargs_reprs ])
219219
220+ def test_recursive_repr (self ):
221+ if self .partial is c_functools .partial :
222+ name = 'functools.partial'
223+ else :
224+ name = self .partial .__name__
225+
226+ f = self .partial (capture )
227+ f .__setstate__ ((f , (), {}, {}))
228+ self .assertEqual (repr (f ), '%s(%s(...))' % (name , name ))
229+
230+ f = self .partial (capture )
231+ f .__setstate__ ((capture , (f ,), {}, {}))
232+ self .assertEqual (repr (f ), '%s(%r, %s(...))' % (name , capture , name ))
233+
234+ f = self .partial (capture )
235+ f .__setstate__ ((capture , (), {'a' : f }, {}))
236+ self .assertEqual (repr (f ), '%s(%r, a=%s(...))' % (name , capture , name ))
237+
220238 def test_pickle (self ):
221239 f = self .partial (signature , ['asdf' ], bar = [True ])
222240 f .attr = []
@@ -297,6 +315,25 @@ def test_setstate_subclasses(self):
297315 self .assertEqual (r , ((1 , 2 ), {}))
298316 self .assertIs (type (r [0 ]), tuple )
299317
318+ def test_recursive_pickle (self ):
319+ f = self .partial (capture )
320+ f .__setstate__ ((f , (), {}, {}))
321+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
322+ with self .assertRaises (RecursionError ):
323+ pickle .dumps (f , proto )
324+
325+ f = self .partial (capture )
326+ f .__setstate__ ((capture , (f ,), {}, {}))
327+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
328+ f_copy = pickle .loads (pickle .dumps (f , proto ))
329+ self .assertIs (f_copy .args [0 ], f_copy )
330+
331+ f = self .partial (capture )
332+ f .__setstate__ ((capture , (), {'a' : f }, {}))
333+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
334+ f_copy = pickle .loads (pickle .dumps (f , proto ))
335+ self .assertIs (f_copy .keywords ['a' ], f_copy )
336+
300337 # Issue 6083: Reference counting bug
301338 def test_setstate_refcount (self ):
302339 class BadSequence :
0 commit comments