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] 

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to