Re: PyProtocols: TypeError: Ambiguous adapter choice
Sergey Schetinin <[email protected]> Fri, 10 Jul 2009 20:26:59 +0300
| Newsgroups | gmane.comp.python.peak |
|---|---|
| Message-ID | <[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. -- Best Regards, Sergey Schetinin http://s3bk.com/ -- S3 Backup http://word-to-html.com/ -- Word to HTML Converter