logo       

Re: pyrex functions to replace a method (Re: replace a method in class: how: msg#00051

python.pyrex

Subject: Re: pyrex functions to replace a method (Re: replace a method in class: how?)

On 28 Jun 2006 at 7:02, Brian Blais wrote:

> Greg Ewing wrote:
> > Brian Blais wrote:
> >> I have found a very similar problem trying to replace a method using a
> >> function defined in pyrex.
> >
> >
> > What *should* work is to define the method inside a
> > class in Pyrex (plain class, not extension type) and
> > extract it out of the class's __dict__. That's because
> > Pyrex pre-wraps a function defined in a class in an
> > unbound method object before putting it in the class.
> >
>
> So I tried:
>
> #---------------------------------------------------------------------------------
>
> #module_pyrex.pyx
>
> class update_funcs:
>
> def pyrex_update_within_class(self,val):
> print "pyrex module within class",val
>
>
> #---------------------------------------------------------------------------------
>
> #(adding to test_replace_method.py)
>
> This.update4=module_pyrex.update_funcs.__dict__['pyrex_update_within_class']
>
> t.update4('pyrex within class') # doesn't work
>
> #---------------------------------------------------------------------------------
>
> and get:
>
> TypeError: unbound method pyrex_update_within_class() must be called with
> update_funcs instance as first argument (got str instance instead)
>
>
> did I do this wrong?

Nothing. Python's method type is just too specialized to work as Greg
suggested. You will have to provide your own method descriptor. This
works:

#--------------------------------------------------------------------

#module_pyrex.pyx

cdef extern from "python.h":
object PyMethod_New(object func, object self, object cls)

# Yes, this has to be an extension type in Pyrex.
cdef class InstanceMethod:
cdef object fn
def __init__(self, fn):
self.fn = fn
def __get__(self, instance, owner):
return PyMethod_New(self.fn, instance, owner)

def pyrex_update_within_class(self,val):
print "pyrex module within class",val
pyrex_update_within_class = InstanceMethod(pyrex_update_within_class)

#--------------------------------------------------------------------

#(Make this replacement in main py module of original posting)

This.update3=module_pyrex.pyrex_update_within_class

#--------------------------------------------------------------------

InstanceMethod is minimal. Additions may be to make the fn attribute
readable and a __call__ method that calls fn directly.

Lenard Lindstrom
<len-l@xxxxxxxxx>


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise