Hi all -- looks like ExtensionClass doesn't recognize/implement the '__radd__()' protocol. Speculation below; first, a demonstration. Normal case: a regular class Number that knows how to add itself to other number-like things: class Number: def __init__ (self, n): self.n = n def __str__ (self): return str(self.n) def __add__ (self, other): return self.n + other __radd__ = __add__ n = Number(37) print n, n + 5, 5 + n The output of this is exactly what you'd expect: 37 42 42 (I have convinced myself that '__radd__()' is called in the "5 + n" case by writing a separate '__radd__()' with a print statement. Everything is sane!) Now the same thing as an ExtensionClass: from ExtensionClass import Base class ECNumber (Base): def __init__ (self, n): self.n = n def __str__ (self): return str(self.n) def __add__ (self, other): return self.n + other __radd__ = __add__ ecn = ECNumber(37) print ecn, ecn + 5, 5 + ecn The output of this is puzzling, to say the least: 37 42 134883149 IOW, "5 + ecn" evaluates to 134883149 -- that's a plain int, I checked with 'type()' on it. If I put this code: print id(ecn), id(5), id(ECNumber), id(Base), id(ExtensionClass) immediately after the last print, I get 135530536 135220848 135568720 1075195712 1075195488 ... which just tells me that the result of "5 + ecn" looks a lot like an id(), but isn't the id() of anything obvious. (Or 5 + any obvious id().) Happens the same with the ExtensionClass code from Zope 2.1.5 or 2.2beta1, and with Python 1.5.2 and the latest CVS Python. Speculation time: I'm guessing that this is similar to the problem with 'isinstance()' and ExtensionClass that I found several months ago, which was heroically debugged by Barry. To recap, it's a mutual finger-pointing bug: Python (Guido) can claim that it's up to ExtensionClass (Jim) to emulate the full semantics of Python classes/instances, but ExtensionClass can claim that Python should be more relaxed in what it accepts as a "class object" or "instance object". I think the relevant code in Python is in Objects/abstract.c, specifically 'PyNumber_Add()' and the BINOP macro: #define BINOP(v, w, opname, ropname, thisfunc) \ if (PyInstance_Check(v) || PyInstance_Check(w)) \ return PyInstance_DoBinOp(v, w, opname, ropname, thisfunc) [...] PyNumber_Add(v, w) PyObject *v, *w; { PySequenceMethods *m; BINOP(v, w, "__add__", "__radd__", PyNumber_Add); [...] My guess is that PyInstance_Check() returns false for ExtensionClass instances. Two possible fixes: loosen up PyInstance_Check(), or loosen up BINOP. Well, it's a nice theory. It doesn't explain why '__add__()' works for ExtensionClass while '__radd__()' does not; perhaps ExtensionClass implements that much of Python's class semantics, but doesn't go as far as '__radd__()'. Other opinions? Greg
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4