[ python-Feature Requests-558238 ] Pickling bound methods

SourceForge.net noreply at sourceforge.net
Thu Jan 1 07:48:53 EST 2004


Feature Requests item #558238, was opened at 2002-05-20 13:17
Message generated for change (Comment added) made by loewis
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=558238&group_id=5470

Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Konrad Hinsen (hinsen)
Assigned to: Martin v. Löwis (loewis)
Summary: Pickling bound methods

Initial Comment:
Last week I noticed that the pickle and cPickle modules
cannot handle bound methods. I found a solution that is
simple and (I think) general, so perhaps it should
become part of the standard library.

Here is my code:

import copy_reg

def pickle_bound_method(method):
    return getattr, (method.im_self, method.__name__)

class _Foo:
    def bar(self):
        pass

_foo = _Foo()

copy_reg.constructor(getattr)
copy_reg.pickle(type(_foo.bar), pickle_bound_method)



----------------------------------------------------------------------

>Comment By: Martin v. Löwis (loewis)
Date: 2004-01-01 13:48

Message:
Logged In: YES 
user_id=21627

There was some discussion on python-dev (initiated by
Christian) on whether bound methods should provide an
__reduce__. Apart from that, no progress.

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-01-01 08:17

Message:
Logged In: YES 
user_id=80475

Any progress on this one?

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-09-30 17:35

Message:
Logged In: YES 
user_id=21627

My concern is that the getattr call already creates a
danger, since you just have to find a 'suitable' object
whose __getattr__ does funny things. In the revised form,
this object would also have to appear as the __class__ of
some other object, so I guess this is pretty safe. I'll ask
python-dev.

----------------------------------------------------------------------

Comment By: Konrad Hinsen (hinsen)
Date: 2002-09-30 15:36

Message:
Logged In: YES 
user_id=11850

True. Would it be a security problem to use getattr inside a 
specialized constructor? For example,

def get_method(object, name):
    klass = object.__class__
    fn = getattr(klass, name)
    return new.instancemethod(fn, object, klass)

This would be difficult to abuse as a general getattr 
replacement, because new.instancemethod would fail in most 
cases other than the intended one.


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-09-30 12:03

Message:
Logged In: YES 
user_id=21627

Reconsidering: It fails to work in the presence of
inheritance, right?

>>> class B:
...   def foo(self):pass
... 
>>> class D(B):pass
... 
>>> d = D()
>>> m = d.foo
>>> m.im_self
<__main__.D instance at 0x1ccb28>
>>> m.__name__
'foo'
>>> D.__dict__['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
KeyError: foo
>>> 


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-09-24 20:12

Message:
Logged In: YES 
user_id=21627

That sounds good to me; I'm going to install it.

----------------------------------------------------------------------

Comment By: Konrad Hinsen (hinsen)
Date: 2002-09-24 19:54

Message:
Logged In: YES 
user_id=11850

Of course:

import copy_reg

def get_method(object, name):
    klass = object.__class__
    fn = klass.__dict__[name]
    return new.instancemethod(fn, object, klass)

def pickle_bound_method(method):
    return get_method, (method.im_self, method.__name__)

class _Foo:
    def bar(self):
        pass

_foo = _Foo()

copy_reg.constructor(get_method)
copy_reg.pickle(type(_foo.bar), pickle_bound_method)


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-09-22 15:08

Message:
Logged In: YES 
user_id=21627

Can you perhaps rewrite this to use new.instancemethod?

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-06-09 19:14

Message:
Logged In: YES 
user_id=21627

Making getattr a safe_constructor has security implictions
which make this approach dangerous. It seems that unpickling
might invoke arbitrary __getattr__ implementations. Adding a
protocol to declare classes as "safe for getattr" might help.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=558238&group_id=5470



More information about the Python-bugs-list mailing list