Commit 57c9d8ed authored by Kevin Modzelewski's avatar Kevin Modzelewski

Change str.add type-checking behavior

In CPython, str.add directly throws a TypeError since it is implemented
as a sq_concat.  sqlalchemy relies on being able to do str()+MyStr() and
use MyStr.__radd__ to handle the addition.  We were throwing a TypeError
but not implementing it in sq_concat.

So instead, return NotImplemented instead of directly throwing a TypeError.
This makes '+' more compatible but str.__add__ a bit less compatible.
parent 2442b5f3
......@@ -346,10 +346,10 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
checkAndThrowCAPIException();
return rtn;
} else {
// Note: this is deliberately not returning NotImplemented, even though
// that would be more usual. I assume this behavior of CPython's is
// for backwards compatibility.
raiseExcHelper(TypeError, "cannot concatenate 'str' and '%s' objects", getTypeName(_rhs));
// This is a compatibility break with CPython, which has their sq_concat method
// directly throw a TypeError. Since we're not implementing this as a sq_concat,
// return NotImplemented for now.
return NotImplemented;
}
}
......
......@@ -10,7 +10,7 @@ def f():
i += IntLike()
print i
try:
i + 1
1 + i
except TypeError, e:
print e
f()
# expected: fail
# str has some weird adding behavior that cannot be replicated with Python code.
# Usually, if an __add__ throws an error, then __radd__ isn't tried.
# But string addition is defined in sq_concat, which is tried after __add__ and
......@@ -13,10 +11,8 @@ class D(object):
def __radd__(self, lhs):
return 3.14
try:
print "".__add__(D())
except TypeError as e:
print e
print "" + D()
try:
print C() + D()
except TypeError as e:
......
# expected: fail
# CPython's str.__add__ directly throws a TypeError.
# Ours (and PyPy's) returns NotImplemented.
try:
print "".__add__(1)
except TypeError as e:
print e
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment