On 2005 Jan 11, at 23:58, Guido van Rossum wrote: ... >>> cls = type(x) >>> copier = _copy_dispatch.get(cls) >>> if copier: >>> return copier(x) ... >>> is this a bug, or a feature of the revised copy/pickle design? > > [Phillip] >> Looks like a bug to me; it breaks the behavior of classic classes, >> since >> type(classicInstance) returns InstanceType. > > I'm not so sure. I can't seem to break this for classic classes. You can't, _copy_dispatch deals with those. > The only thing this intends to break, and then only for new-style > classes, is the ability to have __copy__ be an instance variable > (whose value should be a callable without arguments) -- it must be a > method on the class. This is the same thing that I've done for all > built-in operations (__add__, __getitem__ etc.). And a wonderful idea it is. >> However, it also looks like it might have been introduced to fix the >> possibility that calling '__copy__' on a new-style class with a custom >> metaclass would result in ending up with an unbound method. (Similar >> to >> the "metaconfusion" issue being recently discussed for PEP 246.) > > Sorry, my head just exploded. :-( > > I think I did this change (for all slots) to make the operations more > efficient by avoiding dict lookups. It does have the desirable > property of not confusing a class's attributes with its metaclass's > attributes, but only as long as you use the operation's native syntax > (e.g. x[y]) rather than the nominally "equivalent" method call (e.g. > x.__getitem__(y)). Unfortunately, we do have a problem with the code in copy.py: class MetaCopyableClass(type): def __copy__(cls): """ code to copy CLASSES of this metaclass """ # etc, etc, snipped class CopyableClass: __metaclass__ = MetaCopyableClass # rest of class snipped x = CopyableClass() import copy y = copy.copy(x) kallisti:/tmp alex$ python x.py Traceback (most recent call last): File "x.py", line 14, in ? y = copy.copy(x) File "/usr/local/lib/python2.4/copy.py", line 79, in copy return copier(x) TypeError: __copy__() takes exactly 1 argument (2 given) kallisti:/tmp alex$ See? copy.copy(x) ends up using MetaCopyableClass.__copy__ -- because of a getattr on CopyableClass for '__copy__', which gets the BOUND-METHOD defined in the metaclass, with im_self being CopyableClass. I had exactly the same metabug in the pep 246 reference implementation, Armin Rigo showed how to fix it in his only recent post. Alex
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