[pypy-commit] pypy default: for consistency, the in-place operators need the same bug compatibility hack as the regular operators
arigo
noreply at buildbot.pypy.org
Tue May 19 16:25:02 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r77389:5acade5a80c5
Date: 2015-05-19 16:25 +0200
http://bitbucket.org/pypy/pypy/changeset/5acade5a80c5/
Log: for consistency, the in-place operators need the same bug
compatibility hack as the regular operators
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -759,9 +759,26 @@
noninplacespacemethod = specialname[3:-2]
if noninplacespacemethod in ['or', 'and']:
noninplacespacemethod += '_' # not too clean
+ seq_bug_compat = (symbol == '+=' or symbol == '*=')
+ rhs_method = '__r' + specialname[3:]
+
def inplace_impl(space, w_lhs, w_rhs):
w_impl = space.lookup(w_lhs, specialname)
if w_impl is not None:
+ # 'seq_bug_compat' is for cpython bug-to-bug compatibility:
+ # see objspace/test/test_descrobject.*rmul_overrides.
+ # For cases like "list += object-overriding-__radd__".
+ if (seq_bug_compat and space.type(w_lhs).flag_sequence_bug_compat
+ and not space.type(w_rhs).flag_sequence_bug_compat):
+ w_res = _invoke_binop(space, space.lookup(w_rhs, rhs_method),
+ w_rhs, w_lhs)
+ if w_res is not None:
+ return w_res
+ # xxx if __radd__ is defined but returns NotImplemented,
+ # then it might be called again below. Oh well, too bad.
+ # Anyway that's a case where we're likely to end up in
+ # a TypeError.
+ #
w_res = space.get_and_call_function(w_impl, w_lhs, w_rhs)
if _check_notimplemented(space, w_res):
return w_res
diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -759,6 +759,12 @@
assert bytearray('2') * oops() == 42
assert 1000 * oops() == 42
assert '2'.__mul__(oops()) == '222'
+ x = '2'
+ x *= oops()
+ assert x == 42
+ x = [2]
+ x *= oops()
+ assert x == 42
def test_sequence_rmul_overrides_oldstyle(self):
class oops:
@@ -783,6 +789,12 @@
assert [2] + A1([3]) == [2, 3]
assert type([2] + A1([3])) is list
assert [2] + A2([3]) == 42
+ x = "2"
+ x += A2([3])
+ assert x == 42
+ x = [2]
+ x += A2([3])
+ assert x == 42
def test_data_descriptor_without_delete(self):
class D(object):
More information about the pypy-commit
mailing list