John Machin wrote: > 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 > >
John, Thank you very much for your suggestions. I followed them one by one and in the end found the cause of the problem to be a circular reference. Some species of contained Lists need a reference to the containing Time_Series and that circular reference trips up deepcopy. Supposedly I can define my own __deepcopy__, but didn't understand whose method it is supposed to be. Time_Series.__deepcopy__ () doesn't make sens, nor does it work. Time_Series should be the argument of the method not the owner. Anyway, I managed without deepcopy making a new instance and loading it as I would, if it were the first one. Thanks again Frederic -- http://mail.python.org/mailman/listinfo/python-list