Re: [Python-Dev] Re: copy confusion

2005-01-12 Thread Alex Martelli
On 2005 Jan 12, at 00:30, Fredrik Lundh wrote:
Guido van Rossum wrote:
The only thing this intends to break /.../
it breaks classic C types:
True!!!  And it only breaks copy, NOT deepcopy, because of the 
following difference between the two functions in copy.py...:

def deepcopy(x, memo=None, _nil=[]):
   ...
cls = type(x)
copier = _deepcopy_dispatch.get(cls)
if copier:
y = copier(x, memo)
else:
try:
issc = issubclass(cls, type)
except TypeError: # cls is not a class (old Boost; see SF 
#502085)
issc = 0
if issc:
y = _deepcopy_atomic(x, memo)
else:
copier = getattr(x, __deepcopy__, None)

Now:
 x = cElementTree.Element(tag)
 cls = type(x)
 issubclass(cls, type)
False
therefore, copy.deepcopy ends up doing the getattr of '__deepcopy__' on 
x and live happily ever after.  Function copy.copy does NOT do that 
issubclass check, therefore it breaks Fredrik's code.


(and of course,  custom C types is the only case where I've ever used
__copy__; the default behavior has worked just fine for all other 
cases)

for cElementTree, I've worked around this with an ugly __reduce__ hack,
but that doesn't feel right...
I think you're entirely correct and that we SHOULD bugfix copy.py so 
that function copy, just like function deepcopy, does the getattr from 
the object when not issubclass(cls, type).

The comment suggests that check is there only for strange cases such as 
old Boost (presumably Boost Python in some previous incarnation) but 
it appears to me that it's working fine for your custom C type and that 
it would work just as well for __copy__ as is seems to do for 
__deepcopy__.

The fix, again, should be a tiny patch -- and it seems to me that we 
should have it for 2.3.5 as well as for 2.4.1 and the HEAD.

Alex
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: copy confusion

2005-01-11 Thread Fredrik Lundh
Guido van Rossum wrote:

 The only thing this intends to break /.../

it breaks classic C types:

 import cElementTree
 x = cElementTree.Element(tag)
 x
Element 'tag' at 00B4BA30
 x.__copy__
built-in method __copy__ of Element object at 0x00B4BA30
 x.__copy__()
Element 'tag' at 00B4BA68
 import copy
 y = copy.copy(x)
Traceback (most recent call last):
  File stdin, line 1, in ?
  File C:\python24\lib\copy.py, line 93, in copy
raise Error(un(shallow)copyable object of type %s % cls)
copy.Error: un(shallow)copyable object of type type 'Element'
 dir(x)
['__copy__', '__deepcopy__', 'append', 'clear', 'find', 'findall', 'findtext',
'get', 'getchildren', 'getiterator', 'insert', 'items', 'keys', 'makeelement', 
'set']
 dir(type(x))
['__class__', '__delattr__', '__delitem__', '__delslice__', '__doc__',
'__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__',
'__len__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__setitem__', '__setslice__', '__str__']

(and of course,  custom C types is the only case where I've ever used
__copy__; the default behavior has worked just fine for all other cases)

for cElementTree, I've worked around this with an ugly __reduce__ hack,
but that doesn't feel right...

/F 



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com