Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 266669
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T23:27:49+00:00 2026-05-11T23:27:49+00:00

Updated question, see below I’m starting a new project and I would like to

  • 0

Updated question, see below

I’m starting a new project and I would like to experiment with components based architecture (I chose PyProtocols). It’s a little program to display and interract with realtime graphics.

I started by designing the user input components:

  • IInputDevice – e.g. a mouse, keyboard, etc… An InputDevice may have one or more output channels:
    • IOutput – an output channel containing a single value (e.g. the value of a MIDI slider)
    • ISequenceOutput – an output channel containing a sequence of values (e.g. 2 integers representing mouse position)
    • IDictOutput – an output channel containing named values (e.g. the state of each key of the keyboard, indexed by keyboard symbols)

Now I would like to define interfaces to filter those outputs (smooth, jitter, invert, etc…).

My first approach was to create an InputFilter interface, that had different filter methods for each kind of output channel it was connected to… But the introduction in PyProtocols documentation clearly says that the whole interface and adapters thing is about avoiding type checking !

So my guess is that my InputFilter interfaces should look like this:

  • IInputFilter – filters IOutput
  • ISequenceInputFilter – filters ISequenceOutput
  • IDictInputFilter – filters IDictOutput

Then I could have a connect() method in the I*Ouptut interfaces, that could magically adapt my filters and use the one appropriate for the type of output.

I tried to implement that, and it kind of works:

class InputFilter(object):
    """
    Basic InputFilter implementation. 
    """

    advise(
            instancesProvide=[IInputFilter],
        )

    def __init__(self):
        self.parameters = {}

    def connect(self, src):
        self.src = src

    def read(self):
        return self.src.read()


class InvertInputFilter(InputFilter):
    """
    A filter inverting single values.
    """

    def read(self):
        return -self.src.read()


class InvertSequenceInputFilter(InputFilter):
    """
    A filter inverting sequences of values.
    """

    advise(
            instancesProvide=[ISequenceInputFilter],
            asAdapterForProtocols=[IInputFilter],
        )

    def __init__(self, ob):
        self.ob = ob

    def read(self):
        res = [] 
        for value in self.src.read():
            res.append(-value)
        return res

Now I can adapt my filters to the type of output:

filter = InvertInputFilter()
single_filter = IInputFilter(filter)           # noop
sequence_filter = ISequenceInputFilter(filter) # creates an InvertSequenceInputFilter instance

single_filter and sequence_filter have the correct behaviors and produce single and sequence data types. Now if I define a new InputFilter type on the same model, I get errors like this:

TypeError: ('Ambiguous adapter choice', <class 'InvertSequenceInputFilter'>, <class 'SomeOtherSequenceInputFilter'>, 1, 1)

I must be doing something terribly wrong, is my design even correct ? Or maybe am I missing the point on how to implement my InputFilterS ?

Update 2

I understand I was expecting a little too much magic here, adapters don’t type check the objects they are adapting and just look at the interface they provide, which now sounds normal to me (remember I’m new to these concepts !).

So I came up with a new design (stripped to the bare minimum and omitted the dict interfaces):

class IInputFilter(Interface):

    def read():
        pass

    def connect(src):
        pass


class ISingleInputFilter(Interface):        

    def read_single():
        pass


class ISequenceInputFilter(Interface):

    def read_sequence():
        pass

So IInputFilter is now a sort of generic component, the one that is actually used, ISingleInputFilter and ISequenceInputFilter provide the specialized implementations. Now I can write adapters from the specialized to the generic interfaces:

class SingleInputFilterAsInputFilter(object):

    advise(
            instancesProvide=[IInputFilter],
            asAdapterForProtocols=[ISingleInputFilter],
        )

    def __init__(self, ob):
        self.read = ob.read_single


class SequenceInputFilterAsInputFilter(object):

    advise(
            instancesProvide=[IInputFilter],
            asAdapterForProtocols=[ISequenceInputFilter],
        )

    def __init__(self, ob):
        self.read = ob.read_sequence

Now I write my InvertInputFilter like this:

class InvertInputFilter(object):

    advise(
            instancesProvide=[
                    ISingleInputFilter, 
                    ISequenceInputFilter
                ]
        )

    def read_single(self):
        # Return single value inverted

    def read_sequence(self):
        # Return sequence of inverted values 

And to use it with the various output types I would do:

filter = InvertInputFilter()
single_filter = SingleInputFilterAsInputFilter(filter)
sequence_filter = SequenceInputFilterAsInputFilter(filter)

But, again, this fails miserably with the same kind of error, and this time it’s triggered directly by the InvertInputFilter definition:

TypeError: ('Ambiguous adapter choice', <class 'SingleInputFilterAsInputFilter'>, <class 'SequenceInputFilterAsInputFilter'>, 2, 2)

(the error disapears as soon as I put exactly one interface in the class’ instancesProvide clause)

Update 3

After some discussion on the PEAK mailing list, it seems that this last error is due to a design flaw in PyProtocols, that does some extra checks at declaration time. I rewrote everything with zope.interface and it works perfectly.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T23:27:49+00:00Added an answer on May 11, 2026 at 11:27 pm

    I haven’t used PyProtocols, only the Zope Component Architecture, but they are similar enough for these principles to be the same.

    Your error is that you have two adapters that can adapt the same thing. You both have an averaging filter and an inversion filter. When you then ask for the filter, both are found, and you get the “ambigous adapter” error.

    You can handle this by having different interfaces for averaging filters and inverting filters, but it’s getting silly. In the Zope component architecture you would typically handle this case with named adapters. Each adapter gets a name, by default ”. In this case you would give the adapter names like “averaging” and “inverting”, and you’d look them up with that name, so you know if you get the averaging or the inverting filter.

    For the more general question, if the design makes sense or not, it’s hard to tell. You having three different kinds of outputs and three different kinds of filters doesn’t seem like a good idea. Perhaps you could make the sequence and dict outputs into composites of the single value output, so that each output value gets it’s own object, so it can be filtered independently. That would make more sense to me.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Here is the updated question: the current query is doing something like: $sql1 =
See below the solid line for my original question. I have a folder in
Update: this question has been answered (see below). I'll leave it up in case
Update: this question, including the title, was rephrased, see history for details I know
Duplicate of this question . update - This is not an exact duplicate. See
The same as this question but for java Update Based on the comments and
Question summary: How do I modify the code below so that untrusted, dynamically-loaded code
Replaces Question: Update multiple rows into SQL table Here's a Code Snippet to update
Update: Check out this follow-up question: Gem Update on Windows - is it broken?
Update: Please read this question in the context of design principles, elegance, expression of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.