diff options
author | Armin Rigo <arigo@tunes.org> | 2005-12-29 15:59:19 (GMT) |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2005-12-29 15:59:19 (GMT) |
commit | fd163f92cee2aa8189879bd43670782f4cfd2cf8 (patch) | |
tree | 9bd3785dde016396b17a006059c68b3e4b60023e /Objects/typeobject.c | |
parent | c4308d5be64a622ee7be685c5eb05f90782711c1 (diff) | |
download | cpython-fd163f92cee2aa8189879bd43670782f4cfd2cf8.zip cpython-fd163f92cee2aa8189879bd43670782f4cfd2cf8.tar.gz cpython-fd163f92cee2aa8189879bd43670782f4cfd2cf8.tar.bz2 |
SF patch #1390657:
* set sq_repeat and sq_concat to NULL for user-defined new-style
classes, as a way to fix a number of related problems. See
test_descr.notimplemented()). One of these problems was fixed
in r25556 and r25557 but many more existed; this is a general
fix and thus reverts r25556-r25557.
* to avoid having PySequence_Repeat()/PySequence_Concat() failing
on user-defined classes, they now fall back to nb_add/nb_mul if
sq_concat/sq_repeat are not defined and the arguments appear to
be sequences.
* added tests.
Backport candidate.
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r-- | Objects/typeobject.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7c36ba4..b74fa1a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4095,9 +4095,6 @@ slot_sq_length(PyObject *self) return len; } -SLOT1(slot_sq_concat, "__add__", PyObject *, "O") -SLOT1(slot_sq_repeat, "__mul__", int, "i") - /* Super-optimized version of slot_sq_item. Other slots could do the same... */ static PyObject * @@ -4211,9 +4208,6 @@ slot_sq_contains(PyObject *self, PyObject *value) return result; } -SLOT1(slot_sq_inplace_concat, "__iadd__", PyObject *, "O") -SLOT1(slot_sq_inplace_repeat, "__imul__", int, "i") - #define slot_mp_length slot_sq_length SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O") @@ -4926,12 +4920,17 @@ typedef struct wrapperbase slotdef; static slotdef slotdefs[] = { SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry, "x.__len__() <==> len(x)"), - SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc, - "x.__add__(y) <==> x+y"), - SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc, - "x.__mul__(n) <==> x*n"), - SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc, - "x.__rmul__(n) <==> n*x"), + /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. + The logic in abstract.c always falls back to nb_add/nb_multiply in + this case. Defining both the nb_* and the sq_* slots to call the + user-defined methods has unexpected side-effects, as shown by + test_descr.notimplemented() */ + SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + "x.__add__(y) <==> x+y"), + SQSLOT("__mul__", sq_repeat, NULL, wrap_intargfunc, + "x.__mul__(n) <==> x*n"), + SQSLOT("__rmul__", sq_repeat, NULL, wrap_intargfunc, + "x.__rmul__(n) <==> n*x"), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, "x.__getitem__(y) <==> x[y]"), SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc, @@ -4953,10 +4952,10 @@ static slotdef slotdefs[] = { Use of negative indices is not supported."), SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, "x.__contains__(y) <==> y in x"), - SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat, - wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), - SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat, - wrap_intargfunc, "x.__imul__(y) <==> x*=y"), + SQSLOT("__iadd__", sq_inplace_concat, NULL, + wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), + SQSLOT("__imul__", sq_inplace_repeat, NULL, + wrap_intargfunc, "x.__imul__(y) <==> x*=y"), MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry, "x.__len__() <==> len(x)"), |