The PEAK Developers' Center   ProtocolSubsets UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View

I originally posted this [WWW]here but figured it would be good netiquette to re-post the details of it on this wiki :-) Comments/corrections greatly appreciated.

If you have code similar to the following, which produces a "?TypeError" with an "Ambiguous adapter choice" error message, you are missing an adapter that makes the choice unambiguous:

    1 #!/usr/bin/env python
    2 
    3 import protocols
    4 
    5 class IBase(protocols.Interface):
    6     pass
    7 class IWhy(IBase):
    8     pass
    9 class IZee(IBase):
   10     pass
   11 
   12 class X(object):
   13     value = 'foo'
   14 class Y(object):
   15     protocols.advise(instancesProvide=[IWhy])
   16     def __init__(self, ob):
   17         self.value = ob.value + 'bar'
   18 class Z(object):
   19     protocols.advise(instancesProvide=[IZee])
   20     def __init__(self, ob):
   21         self.value = ob.value + 'baz'
   22 
   23 protocols.declareAdapter(factory=Y, provides=[IWhy], forTypes=[X])
   24 protocols.declareAdapter(factory=Z, provides=[IZee], forTypes=[X])
   25 
   26 x = X(); print 'x', x.value
   27 y = IWhy(x); print 'y', y.value
   28 z = IZee(x); print 'z', z.value

By adding this adapter *above* the other two adapters, you make the adapter choices unambiguous: (In this case, we do not want to allow adapting type X to interface IBase)

protocols.declareAdapter( 
    factory=protocols.DOES_NOT_SUPPORT, 
    provides=[IBase], 
    forTypes[X], 
    ) 

What you DO NOT WANT TO DO is to make subsets of the base interface. Even though this makes adapter choices unambiguous, it still has the opposite effect of what you might have intended. Do not use the following pattern to fix the problem described above. See Phillip Eby's comments on the original post linked to above for a more thorough explanation.

    1 #!/usr/bin/env python
    2 
    3 import protocols
    4 
    5 class IBase(protocols.Interface):
    6     pass
    7 class IWhy(protocols.Interface):
    8     protocols.advise(protocolIsSubsetOf=[IBase])
    9 class IZee(protocols.Interface):
   10     protocols.advise(protocolIsSubsetOf=[IBase])
   11 
   12 class X(object):
   13     value = 'foo'
   14 class Y(object):
   15     protocols.advise(instancesProvide=[IWhy])
   16     def __init__(self, ob):
   17         self.value = ob.value + 'bar'
   18 class Z(object):
   19     protocols.advise(instancesProvide=[IZee])
   20     def __init__(self, ob):
   21         self.value = ob.value + 'baz'
   22 
   23 protocols.declareAdapter(factory=Y, provides=[IWhy], forTypes=[X])
   24 protocols.declareAdapter(factory=Z, provides=[IZee], forTypes=[X])
   25 
   26 x = X(); print 'x', x.value
   27 y = IWhy(x); print 'y', y.value
   28 z = IZee(x); print 'z', z.value

PythonPowered
EditText of this page (last modified 2004-07-14 17:01:30)
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck