On 4/1/2010 7:20 PM, Andrew Svetlov wrote: > using of copy.copy for simple iterators is forbidden > >>>> import copy >>>> copy.copy(iter([1, 2, 3])) > Traceback (most recent call last): > File "<stdin>", line 1, in<module> > File "/home/andrew/projects/py3k/Lib/copy.py", line 96, in copy > return _reconstruct(x, rv, 0) > File "/home/andrew/projects/py3k/Lib/copy.py", line 284, in _reconstruct > y = callable(*args) > File "/home/andrew/projects/py3k/Lib/copyreg.py", line 88, in __newobj__ > return cls.__new__(cls, *args) > TypeError: object.__new__(list_iterator) is not safe, use > list_iterator.__new__() The same happens for the iterators of other builtin classes: tuples, sets, and dicts (that I tried). In the other hand, >>> copy.copy(iter(range(1,3,1))) # 3.1 Traceback (most recent call last): ... TypeError: rangeiter() requires 3 int arguments and similar for filter and map. I do not know whether the former group is detected by rule or explicit hard-coded list, but I suspect the latter. > That behavior is safe and clean. > But it's possible to copy iterator objects returned by itertools functions: > >>>> i = itertools.chain([1, 2], [3, 4, 5]) >>>> i.__next__() > 1 >>>> j = copy.copy(i) This works because itertools.chain() is legal >>>> j.__next__() > Traceback (most recent call last): > File "<stdin>", line 1, in<module> > StopIteration Because itertools.chain() is empty. >>>> i.__next__() > 2 > > Looks like itertools object should be protected from usage like that. I suspect only those for which itertools.xxx() works rather than raising an exception. > Folks, what are you think about? Why privilige the itertools module? A possible rule would be to not copy anything with both .__iter__ and .__next__. Terry Jan Reedy
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4