deepcopy chokes with TypeError on dynamically assigned instance method
Nick Coghlan
ncoghlan at iinet.net.au
Fri Feb 11 06:22:35 EST 2005
Kanenas wrote:
> On Thu, 10 Feb 2005 00:54:04 -0800, Kanenas <kanenas @t comcast d.t
> net> wrote:
>
>
>>When an instance has a dynamically assigned instance method, deepcopy
>>throws a TypeError with the message "TypeError: instancemethod
>>expected at least 2 arguments, got 0".
>
>
> I forgot to mention that the TypeError is thrown only when
> constructing an instance from another instance in the same class, e.g.
> Foo('bar') is fine but Foo(Foo('bar')) will fail.
Interesting. The problem appears to be that bound methods are not copyable:
>>> x = Foo('bar')
>>> x
Foo([b,a,r])
>>> x.bar
<bound method Foo.bar of Foo([b,a,r])>
>>> copy(x.bar)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\lib\copy.py", line 95, in copy
return _reconstruct(x, rv, 0)
File "C:\Python24\lib\copy.py", line 320, in _reconstruct
y = callable(*args)
File "C:\Python24\lib\copy_reg.py", line 92, in __newobj__
return cls.__new__(cls, *args)
TypeError: instancemethod expected at least 2 arguments, got 0
>>> x.__repr__
<bound method Foo.__repr__ of Foo([b,a,r])>
>>> copy(x.__repr__)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\lib\copy.py", line 95, in copy
return _reconstruct(x, rv, 0)
File "C:\Python24\lib\copy.py", line 320, in _reconstruct
y = callable(*args)
File "C:\Python24\lib\copy_reg.py", line 92, in __newobj__
return cls.__new__(cls, *args)
TypeError: instancemethod expected at least 2 arguments, got 0
Normally, the methods live in the class dictionary, so they don't cause a
problem with copying the instance.
It turns out this exception actually makes sense, since you *don't* want to copy
these atributes to the new instance. If you actually copied them, they'd be
bound to the *old* instance, rather than the new one.
So I expect you'll need to provide a __deepcopy__ in order to correctly generate
the instancemethods bound to the new instance.
I also realised that the reason the use of a mutable default is OK here is
because you're deepcopying it.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
More information about the Python-list
mailing list