[Twisted-Python] Components

Glyph Lefkowitz glyph at twistedmatrix.com
Fri Feb 27 00:40:55 EST 2004

On Thu, 2004-02-26 at 19:17, Phillip J. Eby wrote:
> At 05:56 PM 2/26/04 -0500, Glyph Lefkowitz wrote:
> >On Thu, 2004-02-26 at 14:59, Phillip J. Eby wrote:
> > > Yep, just subclass InterfaceClass and add a __call__ method that calls 
> > back
> > > to adapt() and you'd be all set.  One other benefit to PyProtocols is that
> > > you can track what interfaces an *instance* supports, independent of what
> > > its class supports.
> >
> >Would you consider adding this to PyProtocols directly?
> I have considered it.  Unfortunately, it runs counter to one PyProtocols 
> use case I'd like to support, which is the ability to use an abstract base 
> class as a protocol.  That is, somebody should be able to instantiate 
> non-abstract subclasses of a protocol.  While I don't personally use this 
> except for some stuff in peak.util.fmtparse, I've had some previous 
> indications that Guido may favor an ABC-style (Abstract Base Class) for 
> interfaces when they eventually land in Python.  So, I'd like to avoid 
> making it impossible to instantiate interface subclasses.

Considering that this is a rather uncommon use-case, can it be made into
the non-default Interface class?  Or an attribute/feature of the default
one, such as

	class MyAbstractSub(IMyAbstract.ABC):

	class DontUseABC:
		__implements__ = MyAbstractSub.Interface

> Again, this would be easily solved by a Twisted-specific subclass of 
> protocols.InterfaceClass, and I don't see that doing it is necessarily a 
> bad thing for either Twisted or PyProtocols, although it may be that it 
> should be considered simply a transitional, backward-compatibility thing.

The __call__ hack, for me, is more than just syntactic sugar, or a
"transitional, backward-compatibility thing".  It's fundamental to my
personal use of the component system.  One-argument callables are used
_everywhere_ in Twisted, thanks mostly to Deferreds, but also because
"thing which takes one argument" is a very convenient interface for
using for a variety of different kinds of processing.  An idiom I find
tremendously convenient (even, perhaps especially, when debugging) is
"return foo.doSomethingDeferred().addCallback(IWhatever)".  IWhatever is
sometimes a variable, too - and it's quite common to use 'str', 'int',
or 'list' there instead of an interface.

Of course, I like the syntactic sugar quite a bit, too :).  It's
self-documenting.  When I have run tutorials for others on the use of
components, showing them an error on x.what(), and then success on
IWhatever(x).what() is enlightening.  Previously,  our analogue of
"adapt", "getAdapter", was difficult to explain.

(BTW: a common idiom for using interfaces is to scope method names.  An
optimization I want to add to Twisted at some point is stateless
interface-method-call syntax which can do this efficiently, something
like: IWhatever.what(x).  I believe you should be able to avoid a bunch
of Python object allocation overhead by doing it that way.  Does
PyProtocols provide any such facility?)

> >   If we're going
> >to maintain a component system as part of Twisted, I would like to at
> >least get the benefit of having full control over the component system
> >within Twisted.  I don't want to have some people using PyProtocols and
> >others using PyProtocols+TwistedHacks.
> I'm not sure I follow you here.  Private extensions to PyProtocols' base 
> classes is certainly permitted and encouraged, to provide additional 
> features needed by particular frameworks, as long as the core interfaces 
> are respected (e.g. 'IOpenProtocol').  PyProtocols itself offers several 
> specialized protocol implementations, including Protocol, InterfaceClass, 
> Variation, URIProtocol, SequenceProtocol, and so on.
> Actually, if I understand correctly, these mostly sound like things outside 
> PyProtocols' scope.  peak.binding and peak.config implement some of this 
> stuff by defining various interfaces they want, and using PyProtocols to 
> adapt things to those interfaces.  But that's entirely independent of 
> PyProtocols itself.

> In other words, PyProtocols isn't tightly coupled to a component 
> architecture, but is instead a convenient base for building component 
> architectures.

Perhaps we should be discussing Twisted using PEAK, then?  I don't want
to use half a component system and implement the other half myself. 
Maybe you can come up with a counterexample, but it seems to me that the
benefit of a common protocol system would be lost without the use of a
common component model.

> Let's take a specific example: you mentioned locating nearby services by 
> interface.  peak.config does this with two interfaces: IConfigSource and 
> IConfigKey:

Woah there, sparky!  That looks a lot like the earlier documentation I
was having trouble with.  A brief example, maybe? :)

> >Then we have the issue of the PyProtocols dependency; dependency
> >management can be quite hairy on windows.
> Indeed.  I've begun correspondence with Bob off-list about the possibility 
> of me helping to port PIMP/PackMan to other platforms, though.

Thank goodness.  It needs to be done; Twisted needs to be broken up into
smaller pieces.

> By the way, though, I don't know what you mean by "default adapter".  Do 
> you mean the adapter for type 'object', perhaps?  I can't imagine why 
> somebody would care about that, though.

I mean the adapter for type "Thing", mostly.  The general idea being
that you want to override what happens before someone picks up a
"normal" object when they're under the influence of a particular
enchantment.  It is difficult to specify rules for which enchantment's
hook takes precedence, so authors get into fights by specifying
ever-lower numbers.

> Stop trying to understand it and just use it.  ;)

Really, an interface specification / lookup system is a pretty basic
part of a system which uses it, on par with a function calling
convention.  I want to know _exactly_ what goes on when I use it; I
never want to be surprised by a weird component getting looked up when
that wasn't what I intended.  With so much indirection in place that's
too easy already.

> So, as you can see right there, writing docs with Jim Fulton in mind as the 
> intended audience is where I made my big mistake.  :)

Quite.  But, it seems like for that audience, you wrote it well :).  As
much as I respect his work, I don't think it would be a misnomer to call
me bizarro jim fulton.  I tend to have near-opposite interest in
problems, but to come up with identical-looking solutions more often
than not...

> No, 

Sad to hear that :-(

> but I have an IRC client.  :)

irc.freenode.net/#twisted is always there (and I am often in it)

More information about the Twisted-Python mailing list