[Twisted-Python] Re: [Zope3-dev] Twisted and Component Architecture

Phillip J. Eby pje at telecommunity.com
Sun Apr 21 16:32:08 EDT 2002

At 09:19 PM 4/21/02 +0200, Itamar Shtull-Trauring wrote:
>Well, since it's been mentioned here, guess I'll step in.
>First, I implemented a simplistic system because I needed adapters for 
>Twisted's config system (it used to use mixin classes *shudder*), so I 
>quickly wrote up something which implemented them. The fact that 
>__implements__ checks the class is an implementation artifact - I can 
>easily change it so it works like Zope3's.

I think it should be sufficient to use Zope 2's Interface implementation, 
with your own adapter system.

>Which brings us to the next issue - should I be using Zope3's CA? 
>Apparently I can't - Twisted is intended to run on 1.5.2 upwards, and even 
>we drop 1.5.2 support we will be using 2.1 as the baseline. Interface 
>packages and CA package are 2.2 only.

As far as I know, older versions of the Interface package are compatible 
with 1.5.2, and the one currently in Zope 2.x is certainly compatible with 
2.1 - maybe 1.5.2 as well.

>So, this is what I think I'll do - I'll refactor the minimum 
>implementation Twisted's uses, making sure that it uses the same semantics 
>and syntax as Zope3's (e.g. __implements__ being a tuple/singelton instead 
>of lists - why was this made inconsistent in Zope, anyway?).

Tuples because they're immutable, and therefore can be used as dictionary 
keys for caching purposes.  Singletons or nested tuples because it's really 
easy to forget to put the comma on the end, and it allows you to join base 
class __implements__ values thusly:

class Foo(Bar,Baz):
     __implements__ = Bar.__implements__, Baz.__implements__

Personally, I'd have preferred to make interfaces addable, such that:

class Foo(Bar,Baz):
     __implements__ = Bar.__implements__ + Baz.__implements__

would actually yield a new Interface object that inherited from the 
previous ones.  Then, an interface assertion would always *be* an interface 
object, which IMHO would simplify many things.  But that's a subject for 
future discussion on Zope3-Dev, methinks.  :)

>  If Zope3 is importable then Zope.CA's implementation will be used instead.
>Any issues anyone can think of in doing this?

Having had to deal with Z2 vs. Z3 Interface package quirks in TransWarp, my 
suggestion would be to use the Zope 2 Interface package rather than create 
a new one.  For TransWarp, I'm simply requiring the user to install the 
Interface package; but I imagine you could include it in your distribution 
if the ZPL licensing is agreeable.

For the adapter registry, I would suggest that you use your own, 
independent of Zope 3.  Since Zope 3 allows you to replace its principal 
components (such as the adapter registry), you can always at a later time 
elect to either hook your adapter registry API to the one in Zope, or hook 
the one in Zope to call yours.  So there's no need to worry about it much.

The main issues are in __implements__, __class_implements__, the type 
registry, and the Interface package.  If you don't use the same Interface 
package, then people can't write components that work with both Twisted and 
Zope, because they won't be using the same Interface metaclass, etc.

The alternative, if you don't want to deal with all of this, is to use a 
different attribute name, like __twisted_interfaces__ or something of that 
sort.  Then, a component being used for both has to create two different 
interfaces and declare them both via different attributes, but at least you 
can write something that'll work with both.

Maybe once enough of the Z3 CA stabilizes, and maybe a few cleanups of the 
Interface package occur, we should all lobby to get Interface in the Python 
standard library, where all of these various frameworks could use it.  :)

More information about the Twisted-Python mailing list