[PEAK] PyProtocols: TypeError: Ambiguous adapter choice
Sergey Schetinin
maluke at gmail.com
Fri Jul 10 13:26:59 EDT 2009
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.
--
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