gh-101446: Change `repr` of `collections.OrderedDict` (#101661)

This commit is contained in:
Nikita Sobolev 2023-02-08 05:01:10 +03:00 committed by GitHub
parent b2b85b5db9
commit 790ff6bc6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 11 additions and 50 deletions

View File

@ -267,7 +267,7 @@ class OrderedDict(dict):
'od.__repr__() <==> repr(od)' 'od.__repr__() <==> repr(od)'
if not self: if not self:
return '%s()' % (self.__class__.__name__,) return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, list(self.items())) return '%s(%r)' % (self.__class__.__name__, dict(self.items()))
def __reduce__(self): def __reduce__(self):
'Return state information for pickling' 'Return state information for pickling'

View File

@ -362,7 +362,7 @@ class OrderedDictTests:
OrderedDict = self.OrderedDict OrderedDict = self.OrderedDict
od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
self.assertEqual(repr(od), self.assertEqual(repr(od),
"OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") "OrderedDict({'c': 1, 'b': 2, 'a': 3, 'd': 4, 'e': 5, 'f': 6})")
self.assertEqual(eval(repr(od)), od) self.assertEqual(eval(repr(od)), od)
self.assertEqual(repr(OrderedDict()), "OrderedDict()") self.assertEqual(repr(OrderedDict()), "OrderedDict()")
@ -372,7 +372,7 @@ class OrderedDictTests:
od = OrderedDict.fromkeys('abc') od = OrderedDict.fromkeys('abc')
od['x'] = od od['x'] = od
self.assertEqual(repr(od), self.assertEqual(repr(od),
"OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") "OrderedDict({'a': None, 'b': None, 'c': None, 'x': ...})")
def test_repr_recursive_values(self): def test_repr_recursive_values(self):
OrderedDict = self.OrderedDict OrderedDict = self.OrderedDict

View File

@ -0,0 +1,2 @@
Change repr of :class:`collections.OrderedDict` to use regular dictionary
formating instead of pairs of keys and values.

View File

@ -1367,7 +1367,7 @@ static PyObject *
odict_repr(PyODictObject *self) odict_repr(PyODictObject *self)
{ {
int i; int i;
PyObject *pieces = NULL, *result = NULL; PyObject *result = NULL, *dcopy = NULL;
if (PyODict_SIZE(self) == 0) if (PyODict_SIZE(self) == 0)
return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self))); return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));
@ -1377,57 +1377,16 @@ odict_repr(PyODictObject *self)
return i > 0 ? PyUnicode_FromString("...") : NULL; return i > 0 ? PyUnicode_FromString("...") : NULL;
} }
if (PyODict_CheckExact(self)) { dcopy = PyDict_Copy((PyObject *)self);
Py_ssize_t count = 0; if (dcopy == NULL) {
_ODictNode *node; goto Done;
pieces = PyList_New(PyODict_SIZE(self));
if (pieces == NULL)
goto Done;
_odict_FOREACH(self, node) {
PyObject *pair;
PyObject *key = _odictnode_KEY(node);
PyObject *value = _odictnode_VALUE(node, self);
if (value == NULL) {
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
goto Done;
}
pair = PyTuple_Pack(2, key, value);
if (pair == NULL)
goto Done;
if (count < PyList_GET_SIZE(pieces))
PyList_SET_ITEM(pieces, count, pair); /* steals reference */
else {
if (PyList_Append(pieces, pair) < 0) {
Py_DECREF(pair);
goto Done;
}
Py_DECREF(pair);
}
count++;
}
if (count < PyList_GET_SIZE(pieces)) {
Py_SET_SIZE(pieces, count);
}
}
else {
PyObject *items = PyObject_CallMethodNoArgs(
(PyObject *)self, &_Py_ID(items));
if (items == NULL)
goto Done;
pieces = PySequence_List(items);
Py_DECREF(items);
if (pieces == NULL)
goto Done;
} }
result = PyUnicode_FromFormat("%s(%R)", result = PyUnicode_FromFormat("%s(%R)",
_PyType_Name(Py_TYPE(self)), pieces); _PyType_Name(Py_TYPE(self)),
dcopy);
Done: Done:
Py_XDECREF(pieces);
Py_ReprLeave((PyObject *)self); Py_ReprLeave((PyObject *)self);
return result; return result;
} }