[Zope3-dev] Interface.Implements module still broken for
2.2 metaclasses
Phillip J. Eby
pje@telecommunity.com
Sun, 07 Jul 2002 16:54:42 -0400
At 09:20 PM 7/7/02 +0100, Steve Alexander wrote:
>Phillip J. Eby wrote:
>>The Interface.Implements module's getImplements() and
>>getImplementsOfInstances() do not yield correct results for Python 2.2
>>metaclass instances; that is, objects which inherit from 'type'. The
>>correction is straightforward, they need to use 'isinstance()'-based
>>checks rather than 'type()' checks. (And I have verified that they
>>operate correctly with such a change.) Unfortunately, I'm not sure that
>>this can be properly backported to Python 2.1.
>
>I think that if they are changed to use isinstance(), they will no longer
>work with context wrappers and security proxies.
>The solution is that isinstance in python 2.3 will take into account the
>__class__ attribute of the object, so a semi-transparent proxy can publish
>its inner object's __class__ attribute.
I'm not really sure what you're talking about, but I'm pretty sure it has
nothing to do with what I'm talking about. :) I'm talking about these
functions:
def getImplements(object):
t = type(object)
if t in ClassTypes:
if hasattr(object, '__class_implements__'):
return object.__class_implements__
elif hasattr(object, '__implements__'):
return object.__implements__
return _typeImplements.get(t, None)
def getImplementsOfInstances(klass, tiget=_typeImplements.get):
if type(klass) in ClassTypes:
if hasattr(klass, '__implements__'):
return klass.__implements__
else:
return None
else:
return tiget(klass, None)
I believe they should read as follows:
def getImplements(object):
if isinstance(object,ClassTypes):
if hasattr(object, '__class_implements__'):
return object.__class_implements__
elif hasattr(object, '__implements__'):
return object.__implements__
return _typeImplements.get(type(object), None)
def getImplementsOfInstances(klass, tiget=_typeImplements.get):
if isinstance(klass,ClassTypes):
if hasattr(klass, '__implements__'):
return klass.__implements__
else:
return None
else:
return tiget(klass, None)
This change would only affect proxies which happened to be around classes
-- and the change would simply make them *work* on such proxies once
isinstance() uses __class__! I can't see how making this change could
possibly affect the current security proxies, since they don't subclass 'type'.
All of the Interface package unit tests run correctly with the change, and
it also correctly handles the following situation:
from IFoo import IFoo
class myMeta(type):
pass
class myClass(object):
__metaclass__ = myMeta
__implements__ = IFoo
# this line fails with unpatched code:
assert getImplementsOfInstances(myClass) is IFoo