Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7b16687

Browse files
committed
don't use a slot wrapper from a different special method (closes #14658)
This also alters the fix to #11603. Specifically, setting __repr__ to object.__str__ now raises a recursion RuntimeError when str() or repr() is called instead of silently bypassing the recursion. I believe this behavior is more correct.
1 parent 790e005 commit 7b16687

3 files changed

Lines changed: 18 additions & 3 deletions

File tree

Lib/test/test_descr.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4430,7 +4430,15 @@ class Foo:
44304430
pass
44314431
Foo.__repr__ = Foo.__str__
44324432
foo = Foo()
4433-
str(foo)
4433+
self.assertRaises(RuntimeError, str, foo)
4434+
self.assertRaises(RuntimeError, repr, foo)
4435+
4436+
def test_mixing_slot_wrappers(self):
4437+
class X(dict):
4438+
__setattr__ = dict.__setitem__
4439+
x = X()
4440+
x.y = 42
4441+
self.assertEqual(x["y"], 42)
44344442

44354443
def test_cycle_through_dict(self):
44364444
# See bug #1469629

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ What's New in Python 3.2.4
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #11603 (again): Setting __repr__ to __str__ now raises a RuntimeError
14+
when repr() or str() is called on such an object.
15+
16+
- Issue #14658: Fix binding a special method to a builtin implementation of a
17+
special method with a different name.
18+
1319
- Issue #14630: Fix a memory access bug for instances of a subclass of int
1420
with value 0.
1521

Objects/typeobject.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,7 +2928,7 @@ object_str(PyObject *self)
29282928
unaryfunc f;
29292929

29302930
f = Py_TYPE(self)->tp_repr;
2931-
if (f == NULL || f == object_str)
2931+
if (f == NULL)
29322932
f = object_repr;
29332933
return f(self);
29342934
}
@@ -5757,7 +5757,8 @@ update_one_slot(PyTypeObject *type, slotdef *p)
57575757
}
57585758
continue;
57595759
}
5760-
if (Py_TYPE(descr) == &PyWrapperDescr_Type) {
5760+
if (Py_TYPE(descr) == &PyWrapperDescr_Type &&
5761+
((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) {
57615762
void **tptr = resolve_slotdups(type, p->name_strobj);
57625763
if (tptr == NULL || tptr == ptr)
57635764
generic = p->function;

0 commit comments

Comments
 (0)