[Mailman-Developers] Some issues with the CVS head

Barry A. Warsaw barry@python.org
Mon, 29 Jul 2002 20:24:11 -0400


>>>>> "RB" == Ross Boylan <RossBoylan@stanfordalumni.org> writes:

    RB> Some of the modules (e.g., DNS.py) require Python 2.2 (e.g.,
    RB> reference to email modules).  Yet the readme says Python 2.1.3
    RB> or greater is required.  The wiki
    RB> http://www.zope.org/Members/bwarsaw/MailmanDesignNotes/FrontPage
    RB> says Python 2.0 will be required.

The wiki's out of date.  Mailman 2.1 requires at least Python 2.1.
The email package is backwards compatible with Python 2.1 and is
distributed with Mailman so no worries there.

    RB> This is of particular concern for me because I'm thinking of
    RB> borrowing some parts for a Zope product, and Zope 2.5 uses
    RB> Python 2.1 and reportedly will not work with 2.2.  This is, of
    RB> course, not a good reason for Mailman to stay on Python 2.1.

I'm specifically not requiring Python 2.2 for Mailman 2.1, although I
will likely require Python 2.2 for subsequent versions.  Note that
while Zope 2.5 and 2.6 can't officially claim to work with Python 2.2,
we've had success with that combination.  Zope 2.7 will require Python
2.2 at least.

    RB> Bouncer uses getBounceInfo.  MemberAdaptor implements this (as
    RB> well as OldMemberAdaptor), but MailingList doesn't inherit
    RB> from it.  So it looks as if everything is not quite hooked up
    RB> yet.

Not quite correct.  The membership database is a component of the
MailList object, not a base class, although MailList delegates
membership method calls to its MemberAdaptor instance (in the default
case, an OldStyleMemberships instance).

    RB> I also find it a little weird to see base classes making calls
    RB> to methods that they don't define or inherit from, on the
    RB> assumption that they will be mixed into something that does
    RB> define them.

Why?  Seems like classic mixin design to me.  I'm not saying I'm
crazy about the mixin design of the MailList class, but there's
nothing weird going on.  Now the delegation to the MemberAdaptor
instance /is/ slightly idiosyncratic but it's not too strange.
    
    RB> It seems to me if this could be avoided, or at
    RB> least if the classes could inherit from the classes with the
    RB> relevant protocols, it would be cleaner.  A lower tech
    RB> approach would be to note the dependencies in class comments.

    RB> But I think the inheritance might make the dependencies
    RB> explicit while still preserving the ability to factor out
    RB> chunks of functionality.

Hmm.  I have a strong desire to use Zope's Interface package (which by
that time might make it into Python) to be very explicit about the
pluggable components in the system.  That's for a future release though.

    RB> 4) A Little Python Question

    RB> Could anyone explain to me what this is doing? (e.g. from
    RB> DNS.py) return filter(None, addrs) There are several uses of
    RB> this filter(None,..) idiom in the code.

    | The 2.0 code even says
    |     return filter(None, addrs) or None

    RB> The docs for filter say the first argument should be a
    RB> function, which None is not.  When I try it, it seems to be a
    RB> noop (i.e., filter(None, foo) == foo).  And or'ing with None
    RB> (false) also seems pointless.

>From the Python 2.2 docs:

filter(function, list)
    Construct a list from those elements of list for which function
    returns true. list may be either a sequence, a container which
    supports iteration, or an iterator, If list is a string or a
    tuple, the result also has that type; otherwise it is always a
    list. If function is None, the identity function is assumed, that
    is, all elements of list that are false (zero or empty) are
    removed.

So "filter(None, addrs)" just removes the false elements from the
list.  A more modern Pythonic way to spell this would be with a list
comprehension:

    return [x for x in addrs if x]

Makes more sense too! :)
-Barry