[PEAK] PyProtocols: TypeError: Ambiguous adapter choice

Sergey Schetinin maluke at gmail.com
Fri Jul 10 15:37:19 EDT 2009


AFAIR zope.interface doesn't do adapter selection or combination out
of the box at all, so yeah, there would be no errors like that.

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>:
>>>>> 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
>



-- 
Best Regards,
Sergey Schetinin

http://s3bk.com/ -- S3 Backup
http://word-to-html.com/ -- Word to HTML Converter


More information about the PEAK mailing list