The PEAK Developers' Center   ProtocolSubsets UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View
Version as of 2004-07-13 23:59:39

Clear message


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 probably making an incorrect assumption about how to differentiate interfaces that are related to eachother via another interface that is common between them. ("Fixed" code is below the "Broken" code)

    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

Subclassing IBase as shown above *extends* it which make IWhy and IZee ambiguously similar since they both have the entire IBase interface in common. Instead, to differentiate them you want to make IWhy and IZee *subsets* of IBase:

    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-13 23:59:39)
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck