[Python-Dev] PEP 246, redux
James Y Knight
foom at fuhm.net
Wed Jan 12 19:47:30 CET 2005
I'd just like to share a use case for transitive adaption that I've
just run into (I'm using Zope.Interface which does not support it).
Make of this what you will, I just thought an actual example where
transitive adaption is actually necessary might be useful to the
discussion.
I have a framework with an interface 'IResource'. A number of classes
implement this interface. I introduce a new version of the API, with an
'INewResource', so I register a wrapping adapter from
IResource->INewResource in the global adapter registry.
This all works fine as long as all the old code returns objects that
directly provide IResource. However, the issue is that code working
with the old API *doesn't* just do that, it may also have returned
something that is adaptable to IResource. Therefore, calling
INewResource(obj) will fail, because there is no direct adapter from
obj to INewResource, only obj->IResource and IResource->INewResource.
Now, I can't just add the extra adapters from obj->INewResource myself,
because the adapter from obj->IResource is in client code,
compatibility with which is needed. So, as far as I can tell, I have
two options:
1) everywhere I want to adapt to INewResource, do a dance:
resource = INewResource(result, None)
if resource is not None:
return resource
resource = IResource(result, None)
if resource is not None:
return INewResource(resource)
else:
raise TypeError("blah")
2) Make a custom __adapt__ on INewResource to do similar thing. This
seems somewhat difficult with zope.interface (need two classes) but
does work.
class INewResource(zope.interface.Interface):
pass
class SpecialAdaptInterfaceClass(zope.interface.InterfaceClass):
def __adapt__(self, result):
resource = zope.interface.InterfaceClass.__adapt__(self, other)
if resource is not None:
return resource
resource = IResource(result, None)
if resource is not None:
return INewResource(result)
INewResource.__class__ = SpecialAdaptInterfaceClass
I chose #2. In any case, it certainly looks doable, even with a
non-transitive adaptation system, but it's somewhat irritating.
Especially if you end up needing to do that kind of thing often.
James
More information about the Python-Dev
mailing list