[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