Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc20c97f

Browse files
bennorthserhiy-storchaka
authored andcommitted
bpo-18533: Avoid RuntimeError from repr() of recursive dictview (python#4823) (python#5357)
(cherry picked from commitd7773d9)
1 parentecaa372 commitc20c97f

File tree

4 files changed

+46
-7
lines changed

4 files changed

+46
-7
lines changed

‎Lib/test/test_dictviews.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
importcopy
22
importpickle
3+
importsys
34
importunittest
45
importcollections
56
fromtestimporttest_support
@@ -169,6 +170,20 @@ def test_items_set_operations(self):
169170
deftest_recursive_repr(self):
170171
d= {}
171172
d[42]=d.viewvalues()
173+
r=repr(d)
174+
# Cannot perform a stronger test, as the contents of the repr
175+
# are implementation-dependent. All we can say is that we
176+
# want a str result, not an exception of any sort.
177+
self.assertIsInstance(r,str)
178+
d[42]=d.viewitems()
179+
r=repr(d)
180+
# Again.
181+
self.assertIsInstance(r,str)
182+
183+
deftest_deeply_nested_repr(self):
184+
d= {}
185+
foriinrange(sys.getrecursionlimit()+100):
186+
d= {42:d.viewvalues()}
172187
self.assertRaises(RuntimeError,repr,d)
173188

174189
deftest_abc_registry(self):

‎Lib/test/test_ordered_dict.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@ def test_repr_recursive(self):
220220
self.assertEqual(repr(od),
221221
"OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
222222

223+
deftest_repr_recursive_values(self):
224+
od=OrderedDict()
225+
od[42]=od.viewvalues()
226+
r=repr(od)
227+
# Cannot perform a stronger test, as the contents of the repr
228+
# are implementation-dependent. All we can say is that we
229+
# want a str result, not an exception of any sort.
230+
self.assertIsInstance(r,str)
231+
od[42]=od.viewitems()
232+
r=repr(od)
233+
# Again.
234+
self.assertIsInstance(r,str)
235+
223236
deftest_setdefault(self):
224237
pairs= [('c',1), ('b',2), ('a',3), ('d',4), ('e',5), ('f',6)]
225238
shuffle(pairs)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
``repr()`` on a dict containing its own ``viewvalues()`` or
2+
``viewitems()`` no longer raises ``RuntimeError``. Instead, use
3+
``...``, as for other recursive structures. Patch by Ben North.

‎Objects/dictobject.c‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,21 +3005,29 @@ dictview_repr(dictviewobject *dv)
30053005
{
30063006
PyObject*seq;
30073007
PyObject*seq_str;
3008-
PyObject*result;
3008+
PyObject*result=NULL;
3009+
Py_ssize_trc;
30093010

3011+
rc=Py_ReprEnter((PyObject*)dv);
3012+
if (rc!=0) {
3013+
returnrc>0 ?PyString_FromString("...") :NULL;
3014+
}
30103015
seq=PySequence_List((PyObject*)dv);
3011-
if (seq==NULL)
3012-
returnNULL;
3013-
3016+
if (seq==NULL) {
3017+
gotoDone;
3018+
}
30143019
seq_str=PyObject_Repr(seq);
3020+
Py_DECREF(seq);
3021+
30153022
if (seq_str==NULL) {
3016-
Py_DECREF(seq);
3017-
returnNULL;
3023+
gotoDone;
30183024
}
30193025
result=PyString_FromFormat("%s(%s)",Py_TYPE(dv)->tp_name,
30203026
PyString_AS_STRING(seq_str));
30213027
Py_DECREF(seq_str);
3022-
Py_DECREF(seq);
3028+
3029+
Done:
3030+
Py_ReprLeave((PyObject*)dv);
30233031
returnresult;
30243032
}
30253033

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp