I've now configured and made this branch with both Python 2.4.3 and Python 2.6. There is a problem. I've fixed it on my local branch, but I don't have permission to push it back. The problem is that now that we accept an installed email library > 2.5.8, the several calls of the email message get_type() method either give a deprecation warning or throw an exception depending on email version. As I say, I fixed it on my copy of the branch, and I think we're ready to merge with this fix. Here's the diff for these changes. === modified file 'Mailman/Bouncers/Caiwireless.py' --- Mailman/Bouncers/Caiwireless.py 2005-08-27 01:40:17 +0000 +++ Mailman/Bouncers/Caiwireless.py 2008-12-01 01:32:51 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -27,7 +27,7 @@ def process(msg): - if msg.get_type() <> 'multipart/mixed': + if msg.get_content_type() <> 'multipart/mixed': return None # simple state machine # 0 == nothing seen === modified file 'Mailman/Bouncers/GroupWise.py' --- Mailman/Bouncers/GroupWise.py 2008-06-15 19:39:31 +0000 +++ Mailman/Bouncers/GroupWise.py 2008-12-01 02:56:44 +0000 @@ -30,7 +30,7 @@ def find_textplain(msg): - if msg.get_type(msg.get_default_type()) == 'text/plain': + if msg.get_content_type() == 'text/plain': return msg if msg.is_multipart: for part in msg.get_payload(): @@ -44,7 +44,7 @@ def process(msg): - if msg.get_type() <> 'multipart/mixed' or not msg['x-mailer']: + if msg.get_content_type() <> 'multipart/mixed' or not msg['x-mailer']: return None if msg['x-mailer'][:3].lower() not in ('nov', 'ntm', 'int'): return None === modified file 'Mailman/Bouncers/Microsoft.py' --- Mailman/Bouncers/Microsoft.py 2005-08-27 01:40:17 +0000 +++ Mailman/Bouncers/Microsoft.py 2008-12-01 01:33:09 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -25,7 +25,7 @@ def process(msg): - if msg.get_type() <> 'multipart/mixed': + if msg.get_content_type() <> 'multipart/mixed': return None # Find the first subpart, which has no MIME type try: === modified file 'Mailman/Bouncers/Netscape.py' --- Mailman/Bouncers/Netscape.py 2005-08-27 01:40:17 +0000 +++ Mailman/Bouncers/Netscape.py 2008-12-01 01:33:37 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -61,7 +61,7 @@ leaves = [] flatten(msg, leaves) for i, subpart in zip(range(len(leaves)-1), leaves): - if subpart.get_type() == 'text/plain': + if subpart.get_content_type() == 'text/plain': plainmsg = subpart break if not plainmsg: === modified file 'Mailman/Bouncers/Postfix.py' --- Mailman/Bouncers/Postfix.py 2005-08-27 01:40:17 +0000 +++ Mailman/Bouncers/Postfix.py 2008-12-01 01:33:49 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -71,14 +71,14 @@ def process(msg): - if msg.get_type() not in ('multipart/mixed', 'multipart/report'): + if msg.get_content_type() not in ('multipart/mixed', 'multipart/report'): return None # We're looking for the plain/text subpart with a Content-Description: of # `notification'. leaves = [] flatten(msg, leaves) for subpart in leaves: - if subpart.get_type() == 'text/plain' and \ + if subpart.get_content_type() == 'text/plain' and \ subpart.get('content-description', '').lower() == 'notification': # then... return findaddr(subpart) === modified file 'Mailman/Handlers/Decorate.py' --- Mailman/Handlers/Decorate.py 2008-10-03 21:59:00 +0000 +++ Mailman/Handlers/Decorate.py 2008-12-01 01:27:24 +0000 @@ -130,7 +130,7 @@ wrap = False except (LookupError, UnicodeError): pass - elif msg.get_type() == 'multipart/mixed': + elif msg.get_content_type() == 'multipart/mixed': # The next easiest thing to do is just prepend the header and append # the footer as additional subparts payload = msg.get_payload() === modified file 'Mailman/Handlers/Scrubber.py' --- Mailman/Handlers/Scrubber.py 2008-11-13 04:02:29 +0000 +++ Mailman/Handlers/Scrubber.py 2008-12-01 02:57:37 +0000 @@ -189,7 +189,7 @@ # Now walk over all subparts of this message and scrub out various types format = delsp = None for part in msg.walk(): - ctype = part.get_type(part.get_default_type()) + ctype = part.get_content_type() # If the part is text/plain, we leave it alone if ctype == 'text/plain': # We need to choose a charset for the scrubbed message, so we'll @@ -300,7 +300,7 @@ # will transform the url into a hyperlink. elif part.get_payload() and not part.is_multipart(): payload = part.get_payload(decode=True) - ctype = part.get_type() + ctype = part.get_content_type() # XXX Under email 2.5, it is possible that payload will be None. # This can happen when you have a Content-Type: multipart/* with # only one part and that part has two blank lines between the === modified file 'Mailman/Handlers/Tagger.py' --- Mailman/Handlers/Tagger.py 2005-08-27 01:40:17 +0000 +++ Mailman/Handlers/Tagger.py 2008-12-01 02:59:00 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001,2002 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2008 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -69,11 +69,12 @@ # or if the outer type is multipart/alternative and there is a text/plain # part. Anything else, and the body is ignored for header-scan purposes. found = None - if msg.get_type('text/plain') == 'text/plain': + if msg.get_content_type() == 'text/plain': found = msg - elif msg.is_multipart() and msg.get_type() == 'multipart/alternative': + elif (msg.is_multipart() and + msg.get_content_type() == 'multipart/alternative'): for found in msg.get_payload(): - if found.get_type('text/plain') == 'text/plain': + if found.get_content_type() == 'text/plain': break else: found = None === modified file 'tests/test_handlers.py' --- tests/test_handlers.py 2008-11-13 04:02:29 +0000 +++ tests/test_handlers.py 2008-12-01 01:28:23 +0000 @@ -133,7 +133,7 @@ eq(str(str(qmsg['subject'])), '_xtest post acknowledgement') eq(qmsg['to'], '