[PEAK] PyProtocols: TypeError: Ambiguous adapter choice
luper rouch
luper.rouch at gmail.com
Fri Jul 10 15:26:51 EDT 2009
2009/7/10 Sergey Schetinin <maluke at gmail.com>:
> 2009/7/10 luper rouch <luper.rouch at gmail.com>:
>> 2009/7/10 Sergey Schetinin <maluke at gmail.com>:
>>> 2009/7/10 luper rouch <luper.rouch at gmail.com>:
>>>> 2009/7/10 Sergey Schetinin <maluke at gmail.com>:
>>>>> 2009/7/10 luper rouch <luper.rouch at gmail.com>:
>>>>>> 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
More information about the PEAK
mailing list