On Wed, Apr 30, 2008 at 07:12:42PM -0700, Robert Bradshaw wrote: > >From what I can see I'd be > >updating generate_getattro_function() to do a scope.lookup_here() on > >'__getattribute__' first, if that succeeds, output code to call it, > >otherwise go on to the existing code. > > Sounds like a good plan. Is __getattribute__ inherited?
Yes, and when inherited, it overrides __getattr__:
>>> class a(object):
... def __getattribute__(self,n):
... print 'a getattribute',n
... raise AttributeError
...
>>> class b(a):
... def __getattr__(self,n):
... print 'b getattr',n
... return None
...
>>> o = b()
>>> print o.asdf
a getattribute asdf
b getattr asdf
None
>>>
But note that b.__getattr__ is called in the end. If b defines __setattr__, it
is called for any setattr as well.
The Python C extension API docs also state that tp_getattro and tp_setattro are
"inherited by subtypes together with tp_getattr: a subtype inherits both
tp_getattr and tp_getattro from its base type when the subtype's tp_getattr and
tp_getattro are both NULL."
I think this will cause a conflict, in the following situation:
cdef class a:
def __getattribute__(self,n):
return n
cdef class b(a):
def __setattr__(self,n,v):
print 'b setattr',n,v
Evaluating b().asdf will not evaluate to 'asdf', rather an
AttributeError will be raised. Why? Because PyObject_GenericGetAttr()
doesn't look in the base class for attributes at all. And tp_getattro
will for type b will end up pointing to PyObject_GenericGetAttr due to
the above rule of only inhereting if *both* tp_getattro and tp_setattro
are not set. From what I can see in the slot_table definition
tp_getattro and tp_setattro are handled independently, and setting
setattr will leave getattro set to 0
> >
> >With the additional complication
> >that if __getattribute__ is defined, as well as __getattr__, the
> >latter
> >must be called if the former raises AttributeError.
>
> Yep, it should go onto the existing code (or call the super/default
> getattribute) on an error, even if __getattr__ is not defined, to
> match the specs.
Will do.
> >Another question is I noticed that the latest cython-devel code emits
> >warnings on usage of __new__, saying to use __cinit__ instead. I
> >take it
> >there is planned work to make __new__ more like Python's __new__ and
> >have it create the object as well? Again, that's another feature I
> >could
> >really use.
>
> Eventually we may implement this (I looked into it some, but it
> wasn't as straightforward as I had hoped), but using __cinit__ now is
> good to avoid the confusion.
Thanks, I'll take a look at it as well.
> >FWIW I'm writing a electrical design automation library called Tuke.
> >Currently I have some C extension API code written to wrap objects in
> >contexts, but would like to re-write that in Cython as well as
> >implement
> >a whole lot of other basic functionality.
> >
> >http://github.com/retep/tuke/tree/master
>
> Cool. Should I add this to http://wiki.cython.org/projects ?
Sure, although, it may still be another two or three weeks before they
is any actual Cython code in the above tree. ;)
--
http://petertodd.org 'peter'[:[EMAIL PROTECTED]
signature.asc
Description: Digital signature
_______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
