Re: [Zope-dev] ExtensionClass and __radd__()?

2000-07-06 Thread Pavlos Christoforou

On Wed, 5 Jul 2000, Greg Ward wrote:

 
 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__()'.
 

A quick note which you probably already know:

grep add ExtensionClass.c gives:

static PyObject *py__add__, *py__sub__, *py__mul__, *py__div__,
  INIT_PY_NAME(__add__); BINOP(add,Add)
  FILLENTRY(nm-nb, add, add, METH_VARARGS, "Add to another");
  FILLENTRY(sm-sq, concat, add, METH_VARARGS,
  SET_SPECIAL(add,add); subclass_add(PyObject *self, PyObject *v)
  UNLESS(m=subclass_getspecial(self,py__add__)) return NULL;
   AsCMethod(m)-meth==(PyCFunction)add_by_name
ASSIGN(m,AsCMethod(m)-type-tp_as_number-nb_add(self,v));
  (binaryfunc)subclass_add, /*nb_add*/
(binaryfunc)subclass_add, /*sq_concat*/
  return; /* we added a reference; don't delete now */ 

whereas grep radd ExtensionClass.c returns nothing


Pavlos


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] ExtensionClass and __radd__()?

2000-07-06 Thread Greg Ward

On 06 July 2000, Pavlos Christoforou said:
 A quick note which you probably already know:
 
 grep add ExtensionClass.c gives:
[...lots...]
 whereas grep radd ExtensionClass.c returns nothing

Yep, did the same myself shortly after posting.  It's not really clear
what 'py__add__' is and how it works, though, so it's not obvious if
'py__radd__' is the right thing to add, and if so how to add it.

Greg


If it's just a matter
of adding radd (and rsub, rmul, and rdiv) in all those places
-- 
Greg Ward - software developer[EMAIL PROTECTED]
MEMS Exchange / CNRI   voice: +1-703-262-5376
Reston, Virginia, USAfax: +1-703-262-5367

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




[Zope-dev] ExtensionClass and __radd__()?

2000-07-05 Thread Greg Ward

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

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )