Re: PyProtocols: TypeError: Ambiguous adapter choice
luper rouch <[email protected]> Fri, 10 Jul 2009 21:26:51 +0200
| Newsgroups | gmane.comp.python.peak |
|---|---|
| Message-ID | <[email protected]> |
2009/7/10 Sergey Schetinin <[email protected]>: > 2009/7/10 luper rouch <[email protected]>: >> 2009/7/10 Sergey Schetinin <[email protected]>: >>> 2009/7/10 luper rouch <[email protected]>: >>>> 2009/7/10 Sergey Schetinin <[email protected]>: >>>>> 2009/7/10 luper rouch <[email protected]>: >>>>>> The following code produces an error: >>>>>> >>>>>> TypeError: ('Ambiguous adapter choice', <class >>>>>> '__main__.FooOneAsFoo'>, <class '__main__.FooTwoAsFoo'>, 2, 2) >>>>>> >>>>>> --- code begins --- >>>>>> >>>>>> from protocols import Interface, advise >>>>>> >>>>>> class IFoo(Interface): >>>>>> pass >>>>>> >>>>>> class IFooOne(Interface): >>>>>> pass >>>>>> >>>>>> class IFooTwo(Interface): >>>>>> pass >>>>>> >>>>>> class FooOneAsFoo(object): >>>>>> advise( >>>>>> instancesProvide=[IFoo], >>>>>> asAdapterForProtocols=[IFooOne] >>>>>> ) >>>>>> >>>>>> class FooTwoAsFoo(object): >>>>>> advise( >>>>>> instancesProvide=[IFoo], >>>>>> asAdapterForProtocols=[IFooTwo] >>>>>> ) >>>>>> >>>>>> class ComposedFoo(object): >>>>>> advise( >>>>>> instancesProvide=[IFooOne, IFooTwo] >>>>>> ) >>>>>> >>>>>> --- code ends --- >>>>>> >>>>>> Why is it ambiguous to write for example: >>>>>> >>>>>> foo = FooOneAsFoo(ComposedFoo()) >>>>>> >>>>>> foo has an IFoo interface, adapted from the IFooOne interface of ComposedFoo. >>>>>> >>>>> >>>>> Are you sure it's the "foo = FooOneAsFoo(ComposedFoo())" producing the >>>>> error? Could it actually be IFoo(ComposedFoo()) ? >>>>> >>>> >>>> Actually it's the ComposedFoo definition that triggers the error. >>>> >>> >>> I guess I'm wrong, but I remember adapter graph being checked for >>> ambiguity when used, not on declarations. PEAK-Rules rebuilds indexes >>> when first used, so maybe that's what I'm confusing it with. >>> >>> Anyway, the adaptation graph is ambiguous, because there are two >>> adapters from ComposedFoo type to IFoo protocol with the same weight. >>> I'm still not sure why you get the error if not trying to do that >>> adaptation. >>> >> >> Here is the full traceback: >> >> Traceback (most recent call last): >> File "beuh.py", line 43, in <module> >> class ComposedFoo(object): >> File "/var/lib/python-support/python2.6/peak/util/decorators.py", >> line 435, in advise >> return decorator(newClass) >> File "/var/lib/python-support/python2.6/protocols/api.py", line 225, >> in callback >> instancesDoNotProvide=instancesDoNotProvide >> File "/var/lib/python-support/python2.6/protocols/api.py", line 149, >> in declareImplementation >> declareAdapterForType(proto, NO_ADAPTER_NEEDED, typ) >> File "/var/lib/python-support/python2.6/protocols/api.py", line 95, >> in declareAdapterForType >> typ, adapter, depth >> File "/var/lib/python-support/python2.6/protocols/interfaces.py", >> line 144, in registerImplementation >> proto, composeAdapters(adapter,self,extender), klass, depth+d >> File "/var/lib/python-support/python2.6/protocols/api.py", line 95, >> in declareAdapterForType >> typ, adapter, depth >> File "/var/lib/python-support/python2.6/protocols/interfaces.py", >> line 129, in registerImplementation >> self.__adapters,klass,adapter,depth >> File "/var/lib/python-support/python2.6/protocols/adapters.py", line >> 215, in updateWithSimplestAdapter >> new = minimumAdapter(old,adapter,oldDepth,depth) >> File "/var/lib/python-support/python2.6/protocols/adapters.py", line >> 122, in minimumAdapter >> raise TypeError("Ambiguous adapter choice", a1, a2, d1, d2) >> TypeError: ('Ambiguous adapter choice', <class >> '__main__.FooOneAsFoo'>, <class '__main__.FooTwoAsFoo'>, 2, 2) >> >> -- >> Lup >> > > Yeah, looks like the checks are done when declaring things. You can > try giving adapters different weights to break the tie, not much else > I can suggest. I stopped using PyProtocols a few years ago myself, > mostly because of automatic adaptation not scaling well enough to > bigger apps. > > I just tried to implement this with zope.interface and it works. I guess PyProtocols does these checks for some advanced feature I won't use... Thanks ! -- Lup