On 20 Nov 2011, at 16:35, Guido van Rossum wrote: > Um, what?! __class__ *already* has a special meaning. Those examples > violate that meaning. No wonder they get garbage results. > > The correct way to override isinstance is explained here: > http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass > . >
Proxy classes have been using __class__ as a descriptor for this purpose for years before ABCs were introduced. This worked fine up until Python 3 where the compiler magic broke it when super is used. That is now fixed anyway. If I understand correctly, ABCs are great for allowing classes of objects to pass isinstance checks (etc) - what proxy, lazy and mock objects need is to be able to allow individual instances to pass different isinstance checks. All the best, Michael Foord > --Guido > > On Sat, Nov 19, 2011 at 6:13 PM, Michael Foord > <fuzzy...@voidspace.org.uk> wrote: >> >> >> On 19 November 2011 23:11, Vinay Sajip <vinay_sa...@yahoo.co.uk> wrote: >>> >>> Michael Foord <fuzzyman <at> voidspace.org.uk> writes: >>> >>>> That works fine in Python 3 (mock.Mock does it): >>>> >>>> >>> class Foo(object): >>>> ... @property >>>> ... def __class__(self): >>>> ... return int >>>> ... >>>> >>> a = Foo() >>>> >>> isinstance(a, int) >>>> True >>>> >>> a.__class__ >>>> <class 'int'> >>>> >>>> There must be something else going on here. >>>> >>> >>> Michael, thanks for the quick response. Okay, I'll dig in a bit further: >>> the >>> definition in SimpleLazyObject is >>> >>> __class__ = property(new_method_proxy(operator.attrgetter("__class__"))) >>> >>> so perhaps the problem is something related to the specifics of the >>> definition. >>> Here's what I found in initial exploration: >>> >>> -------------------------------------------------------------------------- >>> Python 2.7.2+ (default, Oct 4 2011, 20:06:09) >>> [GCC 4.6.1] on linux2 >>> Type "help", "copyright", "credits" or "license" for more information. >>>>>> from django.utils.functional import SimpleLazyObject >>>>>> fake_bool = SimpleLazyObject(lambda: True) >>>>>> fake_bool.__class__ >>> <type 'bool'> >>>>>> fake_bool.__dict__ >>> {'_setupfunc': <function <lambda> at 0xca9ed8>, '_wrapped': True} >>>>>> SimpleLazyObject.__dict__ >>> dict_proxy({ >>> '__module__': 'django.utils.functional', >>> '__nonzero__': <function inner at 0xca9de8>, >>> '__deepcopy__': <function __deepcopy__ at 0xca9c08>, >>> '__str__': <function inner at 0xca9b18>, >>> '_setup': <function _setup at 0xca9aa0>, >>> '__class__': <property object at 0xca5730>, >>> '__hash__': <function inner at 0xca9d70>, >>> '__unicode__': <function inner at 0xca9b90>, >>> '__bool__': <function inner at 0xca9de8>, >>> '__eq__': <function inner at 0xca9cf8>, >>> '__doc__': '\n A lazy object initialised from any function.\n\n >>> Designed for compound objects of unknown type. For builtins or >>> objects of\n known type, use django.utils.functional.lazy.\n ', >>> '__init__': <function __init__ at 0xca9a28> >>> }) >>> -------------------------------------------------------------------------- >>> Python 3.2.2 (default, Sep 5 2011, 21:17:14) >>> [GCC 4.6.1] on linux2 >>> Type "help", "copyright", "credits" or "license" for more information. >>>>>> from django.utils.functional import SimpleLazyObject >>>>>> fake_bool = SimpleLazyObject(lambda : True) >>>>>> fake_bool.__class__ >>> <class 'django.utils.functional.SimpleLazyObject'> >>>>>> fake_bool.__dict__ >>> { >>> '_setupfunc': <function <lambda> at 0x1c36ea8>, >>> '_wrapped': <object object at 0x1d88b70> >>> } >>>>>> SimpleLazyObject.__dict__ >>> dict_proxy({ >>> '__module__': 'django.utils.functional', >>> '__nonzero__': <function inner at 0x1f56490>, >>> '__deepcopy__': <function __deepcopy__ at 0x1f562f8>, >>> '__str__': <function inner at 0x1f561e8>, >>> '_setup': <function _setup at 0x1f56160>, >>> '__hash__': <function inner at 0x1f56408>, >>> '__unicode__': <function inner at 0x1f56270>, >>> '__bool__': <function inner at 0x1f56490>, >>> '__eq__': <function inner at 0x1f56380>, >>> '__doc__': '\n A lazy object initialised from any function.\n\n >>> Designed for compound objects of unknown type. For builtins or >>> objects of\n known type, use django.utils.functional.lazy.\n ', >>> '__init__': <function __init__ at 0x1f560d8> >>> }) >>> -------------------------------------------------------------------------- >>> >>> In Python 3, there's no __class__ property as there is in Python 2, >>> the fake_bool's type isn't bool, and the callable to set up the wrapped >>> object never gets called (which is why _wrapped is not set to True, but to >>> an anonymous object - this is set in SimpleLazyObject.__init__). >>> >> >> The Python compiler can do strange things with assignment to __class__ in >> the presence of super. This issue has now been fixed, but it may be what is >> biting you: >> >> http://bugs.python.org/issue12370 >> >> If this *is* the problem, then see the workaround suggested in the issue. >> (alias super to _super in the module scope and use the old style super >> calling convention.) >> >> Michael >> >> >>> >>> Puzzling! >>> >>> Regards, >>> >>> Vinay Sajip >>> >>> _______________________________________________ >>> 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/fuzzyman%40voidspace.org.uk >>> >> >> >> >> -- >> >> http://www.voidspace.org.uk/ >> >> May you do good and not evil >> May you find forgiveness for yourself and forgive others >> >> May you share freely, never taking more than you give. >> -- the sqlite blessing http://www.sqlite.org/different.html >> >> _______________________________________________ >> 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/guido%40python.org >> >> > > > > -- > --Guido van Rossum (python.org/~guido) > -- http://www.voidspace.org.uk/ May you do good and not evil May you find forgiveness for yourself and forgive others May you share freely, never taking more than you give. -- the sqlite blessing http://www.sqlite.org/different.html _______________________________________________ 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