Operator += works once, fails if called again

John Machin sjmachin at lexicon.net
Mon Oct 2 17:55:42 EDT 2006


Frederic Rentsch wrote:
> Hi all,
>
>    I have a class Time_Series derived from list. It lists days and
> contains a dictionary of various Lists also derived from list which
> contain values related to said days. (e.g. Stock quotes, volumes traded,
> etc.)
>    I defined an operator += which works just fine, but only once. If I
> repeat the operation, it fails and leaves me utterly mystified and crushed.
>
> Craving to be uncrushed by a superior intelligence.
>
> Frederic
>
>
> ---------------------------------------------------------------
>
> A test:
>
[perfection snipped]

>
> Perfect!
>
>  >>> TS1 += TS2    # Second call
>
> Traceback (most recent call last):
>   File "<pyshell#311>", line 1, in -toplevel-
>     TS += TS2
>   File "c:\i\sony\fre\src\python\TIME_SERIES_7.py", line 1314, in __iadd__
>     return self.__add__ (other)
>   File "c:\i\sony\fre\src\python\TIME_SERIES_7.py", line 1273, in __add__
>     Sum = copy.deepcopy (self)
>   File "C:\PYTHON24\lib\copy.py", line 188, in deepcopy
>     y = _reconstruct(x, rv, 1, memo)
>   File "C:\PYTHON24\lib\copy.py", line 335, in _reconstruct
>     state = deepcopy(state, memo)
>   File "C:\PYTHON24\lib\copy.py", line 161, in deepcopy
>     y = copier(x, memo)
>   File "C:\PYTHON24\lib\copy.py", line 252, in _deepcopy_dict
>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>   File "C:\PYTHON24\lib\copy.py", line 161, in deepcopy
>     y = copier(x, memo)
>   File "C:\PYTHON24\lib\copy.py", line 252, in _deepcopy_dict
>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>   File "C:\PYTHON24\lib\copy.py", line 188, in deepcopy
>     y = _reconstruct(x, rv, 1, memo)
>   File "C:\PYTHON24\lib\copy.py", line 335, in _reconstruct
>     state = deepcopy(state, memo)
>   File "C:\PYTHON24\lib\copy.py", line 161, in deepcopy
>     y = copier(x, memo)
>   File "C:\PYTHON24\lib\copy.py", line 252, in _deepcopy_dict
>     y[deepcopy(key, memo)] = deepcopy(value, memo)
>   File "C:\PYTHON24\lib\copy.py", line 188, in deepcopy
>     y = _reconstruct(x, rv, 1, memo)
>   File "C:\PYTHON24\lib\copy.py", line 320, in _reconstruct
>     y = callable(*args)
>   File "C:\PYTHON24\lib\copy_reg.py", line 92, in __newobj__

Oho! What's it doing there, in copy_reg.py?  Something has stashed away
a reference to copy_reg.__newobj__, and the stasher is *not* the copy
module ....

>     return cls.__new__(cls, *args)
> TypeError: instancemethod expected at least 2 arguments, got 0

>From a quick browse through the code for copy.py and copy_reg.py [Isn't
open source a wonderful thing?], I'm guessing:
(1) The "cls"  is *your* class. You can confirm that with a debugger
(or by hacking in a print statement!).
(2) You may need to read this in the copy docs:
"""
Classes can use the same interfaces to control copying that they use to
control pickling. See the description of module pickle for information
on these methods. The copy module does not use the copy_reg
registration module.
"""
(3) You may need to read this in the pickle docs:
"""
New-style types can provide a __getnewargs__() method that is used for
protocol 2. Implementing this method is needed if the type establishes
some internal invariants when the instance is created, or if the memory
allocation is affected by the values passed to the __new__() method for
the type (as it is for tuples and strings). Instances of a new-style
type C are created using
     obj = C.__new__(C, *args)
 where args is the result of calling __getnewargs__() on the original
object; if there is no __getnewargs__(), an empty tuple is assumed.
"""
(4) You may need to debug your pickling/unpickling before you debug
your deepcopying.
(5) Look at function _copy_inst at line 134 in copy.py -- work out what
it will do with your class instance, depending on what __magic__
method(s) you have implemented.

Hope some of this helps,
John




More information about the Python-list mailing list