[Python-Dev] instancemethod_getattro seems to be partially wrong

Christian Tismer tismer at tismer.com
Wed Nov 19 22:18:46 EST 2003


Hi again, Guido,

>>No no no, I'm not fiddling around with any internals, here.
>>I just want to use the machinary as it is, and to be able to
>>pickle almost everything.

Sorry, this was a lie.
Sure I'm fiddling internaly, but simply by
installing some __reduce__ methids, hoping that
they work.
This worked most of the time, but I'm having problems
with bound methods.

> But how, I wonder, are you providing it?  You can't subclass
> instancemethod -- how do you manage to add a __reduce__ method to it
> without fiddling with any internals?

I added __reduce__ to the PyMethod type and tried to figure out
why it didn't take it.

>>My expectation is that C().x.__reduce__ gives me the bound
>>__reduce__ method of the bound x method of a C instance.
> 
> 
> Yes, unfortunately you get the __reduce__ method of the unbound
> function instead.
> 
> I think Martin is right: copy_reg may be your last hope.  (Or
> subclassing pickle to special-case instancemethod.)

Well, I see your point, but please let me explain mine, again:
If there is a class C which has a method x, then C().x is
a perfectly fine expression, yielding a bound method.

If I now like to pickle this expression, I would use the
__reduce__ protocol and ask C().x for its __reduce__ property.

Now, please see that __reduce__ has no parameters, i.e. it has
no other chance to do the right thing(TM) but by relying
on to be bound to the right thing.
So, doesn't it make sense to have __reduce__ to be always returned
as a method of some bound anything?

In other words, shouldn't things that are only useful as bound
things, always be bound?

> The pickling machinery wasn't intended to pickle bound methods or
> functions etc., and doesn't particularly go out of its way to allow
> you to add that functionality.

The pickling machinery gives me an __reduce__ interface, and I'm
expecting that this is able to pickle everything.

...

> And it would be except for the delegation of method attributes to
> function attributes.  It is a similar aliasing problem as you see when
> you try to access the __getattr__ implementation for classes as
> C.__getattr__ -- you get the __getattr__ for C instances instead.  So
> you have to use type(C).__getattr__ instead.  That would work for
> __reduce__ too I think: new.instancemethod.__reduce__(C().f).

I agree!
But I can't do this in this context, using __reduce__ only.
In other words, I'd have to add stuff to copyreg.py, which
I tried to circumvent.

...

> OK, so you *are* messing with internals after all (== changing C
> code), right?  Or else how do you accomplish this?

Yessir, I'm augmenting all things-to-be-pickled with __reduce__
methods. And this time is the first time that it doesn't work.

...

> I have a real job too, that's why I have little time to help you. :-(

I agree (and I didn't ask *you* in the first place), but still
I'd like to ask the general question:
Is this really the right way to handle bound objects?
Is the is_data criterion correct?
If I am asking for an attribute that makes *only* sense if it is
bound, like in the parameter-less __reduce__ case, wouldn't
it be the correct behavior to give me that bound object?

I have the strong impression that there is some difference
in methods which isn't dealt with, correctly, at the moment.
If a method wants to be bound to something, it should be
get bound to something.
Especially, if this method is useless without being bound.
Please, swallow this idea a little bit, before rejecting
it. I think that "is_data" is too rough and doesn't fit
the requirements, all the time.

sincerely -- chris

-- 
Christian Tismer             :^)   <mailto:tismer at tismer.com>
Mission Impossible 5oftware  :     Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a     :    *Starship* http://starship.python.net/
14109 Berlin                 :     PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34  home +49 30 802 86 56  mobile +49 173 24 18 776
PGP 0x57F3BF04       9064 F4E1 D754 C2FF 1619  305B C09C 5A3B 57F3 BF04
      whom do you want to sponsor today?   http://www.stackless.com/





More information about the Python-Dev mailing list