Some issues with the CVS head
I just got the latest Mailman sources from CVS, and noticed a couple of things.
- Required Python Version
Some of the modules (e.g., DNS.py) require Python 2.2 (e.g., reference to email modules). Yet the readme says Python 2.1.3 or greater is required. The wiki http://www.zope.org/Members/bwarsaw/MailmanDesignNotes/FrontPage says Python 2.0 will be required.
This is of particular concern for me because I'm thinking of borrowing some parts for a Zope product, and Zope 2.5 uses Python 2.1 and reportedly will not work with 2.2. This is, of course, not a good reason for Mailman to stay on Python 2.1.
I'm aware of the ZMailman project and sent a message to their list. However, what I'm doing probably goes in a different direction (I really just want the Bounce handling).
- Code Inconsistencies
Bouncer uses getBounceInfo. MemberAdaptor implements this (as well as OldMemberAdaptor), but MailingList doesn't inherit from it. So it looks as if everything is not quite hooked up yet.
- A Stylistic Comment
I also find it a little weird to see base classes making calls to methods that they don't define or inherit from, on the assumption that they will be mixed into something that does define them. It seems to me if this could be avoided, or at least if the classes could inherit from the classes with the relevant protocols, it would be cleaner. A lower tech approach would be to note the dependencies in class comments.
But I think the inheritance might make the dependencies explicit while still preserving the ability to factor out chunks of functionality.
- A Little Python Question
Could anyone explain to me what this is doing? (e.g. from DNS.py) return filter(None, addrs) There are several uses of this filter(None,..) idiom in the code.
The 2.0 code even says return filter(None, addrs) or None
The docs for filter say the first argument should be a function, which None is not. When I try it, it seems to be a noop (i.e., filter(None, foo) == foo). And or'ing with None (false) also seems pointless.
"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
participants (2)
-
barry@python.org
-
Ross Boylan