[Python-Dev] PEP 246, redux (original) (raw)
James Y Knight foom at fuhm.net
Wed Jan 12 19:47:30 CET 2005
- Previous message: [Python-Dev] PEP 246, redux
- Next message: [Python-Dev] PEP 246, redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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:
- 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")
- 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
- Previous message: [Python-Dev] PEP 246, redux
- Next message: [Python-Dev] PEP 246, redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]