summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2016-03-25 09:36:52 -0400
committerBarry Warsaw2016-03-25 09:36:52 -0400
commitb9c06627e46ff1e9f09965228ab3b48f217109af (patch)
treea600fa04dd2ac6d006b88aee2c5e605673629fa3
parent49d630f2761175e404f3b1d811e61bc43eb6b25b (diff)
downloadmailman-b9c06627e46ff1e9f09965228ab3b48f217109af.tar.gz
mailman-b9c06627e46ff1e9f09965228ab3b48f217109af.tar.zst
mailman-b9c06627e46ff1e9f09965228ab3b48f217109af.zip
-rw-r--r--src/mailman/handlers/acknowledge.py8
-rw-r--r--src/mailman/handlers/after_delivery.py8
-rw-r--r--src/mailman/handlers/avoid_duplicates.py8
-rw-r--r--src/mailman/handlers/cleanse.py8
-rw-r--r--src/mailman/handlers/cleanse_dkim.py8
-rw-r--r--src/mailman/handlers/cook_headers.py18
-rw-r--r--src/mailman/handlers/decorate.py38
-rw-r--r--src/mailman/handlers/file_recipients.py8
-rw-r--r--src/mailman/handlers/member_recipients.py15
-rw-r--r--src/mailman/handlers/mime_delete.py37
-rw-r--r--src/mailman/handlers/owner_recipients.py8
-rw-r--r--src/mailman/handlers/replybot.py21
-rw-r--r--src/mailman/handlers/rfc_2369.py9
-rw-r--r--src/mailman/handlers/subject_prefix.py9
-rw-r--r--src/mailman/handlers/tagger.py15
-rw-r--r--src/mailman/handlers/tests/test_cook_headers.py13
-rw-r--r--src/mailman/handlers/tests/test_decorate.py8
-rw-r--r--src/mailman/handlers/tests/test_file_recips.py6
-rw-r--r--src/mailman/handlers/tests/test_filter.py6
-rw-r--r--src/mailman/handlers/tests/test_mimedel.py28
-rw-r--r--src/mailman/handlers/tests/test_recipients.py8
-rw-r--r--src/mailman/handlers/tests/test_rfc_2369.py7
-rw-r--r--src/mailman/handlers/tests/test_subject_prefix.py8
-rw-r--r--src/mailman/handlers/tests/test_to_digest.py6
-rw-r--r--src/mailman/handlers/to_archive.py10
-rw-r--r--src/mailman/handlers/to_digest.py8
-rw-r--r--src/mailman/handlers/to_outgoing.py8
-rw-r--r--src/mailman/handlers/to_usenet.py12
28 files changed, 98 insertions, 248 deletions
diff --git a/src/mailman/handlers/acknowledge.py b/src/mailman/handlers/acknowledge.py
index db56c5806..809711426 100644
--- a/src/mailman/handlers/acknowledge.py
+++ b/src/mailman/handlers/acknowledge.py
@@ -20,11 +20,7 @@
This only happens if the sender has set their AcknowledgePosts attribute.
"""
-__all__ = [
- 'Acknowledge',
- ]
-
-
+from mailman import public
from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.handler import IHandler
@@ -35,7 +31,7 @@ from zope.component import getUtility
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class Acknowledge:
"""Send an acknowledgment."""
diff --git a/src/mailman/handlers/after_delivery.py b/src/mailman/handlers/after_delivery.py
index 8c4376338..efe38ec63 100644
--- a/src/mailman/handlers/after_delivery.py
+++ b/src/mailman/handlers/after_delivery.py
@@ -17,18 +17,14 @@
"""Perform some bookkeeping after a successful post."""
-__all__ = [
- 'AfterDelivery',
- ]
-
-
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.utilities.datetime import now
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class AfterDelivery:
"""Perform some bookkeeping after a successful post."""
diff --git a/src/mailman/handlers/avoid_duplicates.py b/src/mailman/handlers/avoid_duplicates.py
index 139b2545f..59cb568de 100644
--- a/src/mailman/handlers/avoid_duplicates.py
+++ b/src/mailman/handlers/avoid_duplicates.py
@@ -23,12 +23,8 @@ has already received a copy, we either drop the message, add a duplicate
warning header, or pass it through, depending on the user's preferences.
"""
-__all__ = [
- 'AvoidDuplicates',
- ]
-
-
from email.utils import getaddresses, formataddr
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
@@ -37,7 +33,7 @@ from zope.interface import implementer
COMMASPACE = ', '
-
+@public
@implementer(IHandler)
class AvoidDuplicates:
"""If the user wishes it, do not send duplicates of the same message."""
diff --git a/src/mailman/handlers/cleanse.py b/src/mailman/handlers/cleanse.py
index 4a8aac850..56add9ef7 100644
--- a/src/mailman/handlers/cleanse.py
+++ b/src/mailman/handlers/cleanse.py
@@ -17,14 +17,10 @@
"""Cleanse certain headers from all messages."""
-__all__ = [
- 'Cleanse',
- ]
-
-
import logging
from email.utils import formataddr
+from mailman import public
from mailman.core.i18n import _
from mailman.handlers.cook_headers import uheader
from mailman.interfaces.handler import IHandler
@@ -34,7 +30,7 @@ from zope.interface import implementer
log = logging.getLogger('mailman.post')
-
+@public
@implementer(IHandler)
class Cleanse:
"""Cleanse certain headers from all messages."""
diff --git a/src/mailman/handlers/cleanse_dkim.py b/src/mailman/handlers/cleanse_dkim.py
index 41041b358..72a9c5e81 100644
--- a/src/mailman/handlers/cleanse_dkim.py
+++ b/src/mailman/handlers/cleanse_dkim.py
@@ -25,19 +25,15 @@ and it will also give the MTA the opportunity to regenerate valid keys
originating at the Mailman server for the outgoing message.
"""
-__all__ = [
- 'CleanseDKIM',
- ]
-
-
from lazr.config import as_boolean
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class CleanseDKIM:
"""Remove DomainKeys headers."""
diff --git a/src/mailman/handlers/cook_headers.py b/src/mailman/handlers/cook_headers.py
index e49c2fa52..ed4c28c8c 100644
--- a/src/mailman/handlers/cook_headers.py
+++ b/src/mailman/handlers/cook_headers.py
@@ -17,15 +17,11 @@
"""Cook a message's headers."""
-__all__ = [
- 'CookHeaders',
- ]
-
-
import re
from email.header import Header
from email.utils import parseaddr, formataddr, getaddresses
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.mailinglist import Personalization, ReplyToMunging
@@ -38,7 +34,7 @@ MAXLINELEN = 78
NONASCII = re.compile('[^\s!-~]')
-
+@public
def uheader(mlist, s, header_name=None, continuation_ws='\t', maxlinelen=None):
"""Get the charset to encode the string in.
@@ -58,7 +54,6 @@ def uheader(mlist, s, header_name=None, continuation_ws='\t', maxlinelen=None):
return Header(s, charset, maxlinelen, header_name, continuation_ws)
-
def process(mlist, msg, msgdata):
"""Process the headers of the message."""
# Set the "X-Ack: no" header if noack flag is set.
@@ -103,7 +98,7 @@ def process(mlist, msg, msgdata):
# A convenience function, requires nested scopes. pair is (name, addr)
new = []
d = {}
- def add(pair):
+ def add(pair): # flake8: noqa
lcaddr = pair[1].lower()
if lcaddr in d:
return
@@ -143,8 +138,9 @@ def process(mlist, msg, msgdata):
# Also skip Cc if this is an anonymous list as list posting address
# is already in From and Reply-To in this case.
if (mlist.personalize is Personalization.full and
- mlist.reply_goes_to_list is not ReplyToMunging.point_to_list and
- not mlist.anonymous_list):
+ mlist.reply_goes_to_list is not
+ ReplyToMunging.point_to_list and
+ not mlist.anonymous_list):
# Watch out for existing Cc headers, merge, and remove dups. Note
# that RFC 2822 says only zero or one Cc header is allowed.
new = []
@@ -157,7 +153,7 @@ def process(mlist, msg, msgdata):
msg['Cc'] = COMMASPACE.join([formataddr(pair) for pair in new])
-
+@public
@implementer(IHandler)
class CookHeaders:
"""Modify message headers."""
diff --git a/src/mailman/handlers/decorate.py b/src/mailman/handlers/decorate.py
index b8cdcb9ae..186c86a6d 100644
--- a/src/mailman/handlers/decorate.py
+++ b/src/mailman/handlers/decorate.py
@@ -17,17 +17,11 @@
"""Decorate a message by sticking the header and footer around it."""
-__all__ = [
- 'Decorate',
- 'decorate',
- 'decorate_template',
- ]
-
-
import re
import logging
from email.mime.text import MIMEText
+from mailman import public
from mailman.core.i18n import _
from mailman.email.message import Message
from mailman.interfaces.handler import IHandler
@@ -43,7 +37,6 @@ log = logging.getLogger('mailman.error')
alog = logging.getLogger('mailman.archiver')
-
def process(mlist, msg, msgdata):
"""Decorate the message with headers and footers."""
# Digests and Mailman-craft messages should not get additional headers.
@@ -216,7 +209,7 @@ def process(mlist, msg, msgdata):
msg['Content-Type'] = 'multipart/mixed'
-
+@public
def decorate(mlist, uri, extradict=None):
"""Expand the decoration template from its URI."""
if uri is None:
@@ -232,22 +225,25 @@ def decorate(mlist, uri, extradict=None):
return decorate_template(mlist, template, extradict)
-
+@public
def decorate_template(mlist, template, extradict=None):
"""Expand the decoration template."""
# Create a dictionary which includes the default set of interpolation
# variables allowed in headers and footers. These will be augmented by
# any key/value pairs in the extradict.
- substitutions = dict(
- fqdn_listname = mlist.fqdn_listname,
- list_name = mlist.list_name,
- host_name = mlist.mail_host,
- display_name = mlist.display_name,
- listinfo_uri = mlist.script_url('listinfo'),
- list_requests = mlist.request_address,
- description = mlist.description,
- info = mlist.info,
- )
+ substitutions = {
+ key: getattr(mlist, key)
+ for key in ('fqdn_listname',
+ 'list_name',
+ 'mail_host',
+ 'display_name',
+ 'request_address',
+ 'description',
+ 'info',
+ )
+ }
+ # This must eventually go away.
+ substitutions['listinfo_uri'] = mlist.script_url('listinfo')
if extradict is not None:
substitutions.update(extradict)
text = expand(template, substitutions)
@@ -255,7 +251,7 @@ def decorate_template(mlist, template, extradict=None):
return re.sub(r' *\r?\n', r'\n', text)
-
+@public
@implementer(IHandler)
class Decorate:
"""Decorate a message with headers and footers."""
diff --git a/src/mailman/handlers/file_recipients.py b/src/mailman/handlers/file_recipients.py
index 7e4d07bd4..95160706a 100644
--- a/src/mailman/handlers/file_recipients.py
+++ b/src/mailman/handlers/file_recipients.py
@@ -17,20 +17,16 @@
"""Get the normal delivery recipients from a Sendmail style :include: file."""
-__all__ = [
- 'FileRecipients',
- ]
-
-
import os
import errno
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class FileRecipients:
"""Get the normal delivery recipients from an include file."""
diff --git a/src/mailman/handlers/member_recipients.py b/src/mailman/handlers/member_recipients.py
index 6a28af11a..ffcecfb18 100644
--- a/src/mailman/handlers/member_recipients.py
+++ b/src/mailman/handlers/member_recipients.py
@@ -23,11 +23,7 @@ on the `recipients' attribute of the message. This attribute is used by the
SendmailDeliver and BulkDeliver modules.
"""
-__all__ = [
- 'MemberRecipients',
- ]
-
-
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
@@ -37,7 +33,7 @@ from mailman.utilities.string import wrap
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class MemberRecipients:
"""Calculate the regular (i.e. non-digest) recipients of the message."""
@@ -92,12 +88,13 @@ for delivery. The original message as received by Mailman is attached.
recipients.remove(member.address.email)
# Handle topic classifications
# XXX: Disabled for now until we fix it properly
- #do_topic_filters(mlist, msg, msgdata, recipients)
+ #
+ # do_topic_filters(mlist, msg, msgdata, recipients)
+ #
# Bookkeeping
msgdata['recipients'] = recipients
-
def do_topic_filters(mlist, msg, msgdata, recipients):
"""Filter out recipients based on topics."""
if not mlist.topics_enabled:
@@ -135,7 +132,7 @@ def do_topic_filters(mlist, msg, msgdata, recipients):
# this message by default.
continue
if not mlist.getMemberOption(
- user, config.ReceiveNonmatchingTopics):
+ user, config.ReceiveNonmatchingTopics):
# The user has interest in some topics, but elects not to
# receive message that match no topics, so zap him.
zap_recipients.append(user)
diff --git a/src/mailman/handlers/mime_delete.py b/src/mailman/handlers/mime_delete.py
index a1e861bf8..267cb227a 100644
--- a/src/mailman/handlers/mime_delete.py
+++ b/src/mailman/handlers/mime_delete.py
@@ -24,11 +24,6 @@ wrapping only single sections after other processing are replaced by their
contents.
"""
-__all__ = [
- 'MIMEDelete',
- ]
-
-
import os
import shutil
import logging
@@ -41,6 +36,7 @@ from email.mime.message import MIMEMessage
from email.mime.text import MIMEText
from itertools import count
from lazr.config import as_boolean
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.email.message import OwnerNotification
@@ -56,21 +52,20 @@ from zope.interface import implementer
log = logging.getLogger('mailman.error')
-
def dispose(mlist, msg, msgdata, why):
if mlist.filter_action is FilterAction.reject:
# Bounce the message to the original author.
raise RejectMessage(why)
elif mlist.filter_action is FilterAction.forward:
# Forward it on to the list moderators.
- text=_("""\
+ text = _("""\
The attached message matched the $mlist.display_name mailing list's content
filtering rules and was prevented from being forwarded on to the list
membership. You are receiving the only remaining copy of the discarded
message.
""")
- subject=_('Content filter message notification')
+ subject = _('Content filter message notification')
notice = OwnerNotification(mlist, subject, roster=mlist.moderators)
notice.set_type('multipart/mixed')
notice.attach(MIMEText(text))
@@ -83,17 +78,16 @@ message.
# placed in the 'bad' queue should the site administrator want to
# inspect the message.
filebase = config.switchboards['bad'].enqueue(msg, msgdata)
- log.info('{0} preserved in file base {1}'.format(
+ log.info('{} preserved in file base {}'.format(
msg.get('message-id', 'n/a'), filebase))
else:
log.error(
- '{1} invalid FilterAction: {0}. Treating as discard'.format(
+ '{} invalid FilterAction: {}. Treating as discard'.format(
mlist.fqdn_listname, mlist.filter_action.name))
# Most cases also discard the message
raise DiscardMessage(why)
-
def process(mlist, msg, msgdata):
# We also don't care about our own digests or plaintext
ctype = msg.get_content_type()
@@ -115,11 +109,13 @@ def process(mlist, msg, msgdata):
fext = get_file_ext(msg)
if fext:
if fext in filterexts:
- dispose(mlist, msg, msgdata,
- _("The message's file extension was explicitly disallowed"))
+ dispose(
+ mlist, msg, msgdata,
+ _("The message's file extension was explicitly disallowed"))
if passexts and not (fext in passexts):
- dispose(mlist, msg, msgdata,
- _("The message's file extension was not explicitly allowed"))
+ dispose(
+ mlist, msg, msgdata,
+ _("The message's file extension was not explicitly allowed"))
numparts = len([subpart for subpart in msg.walk()])
# If the message is a multipart, filter out matching subparts
if msg.is_multipart():
@@ -158,10 +154,9 @@ def process(mlist, msg, msgdata):
reset_payload(msg, useful)
changedp = 1
if changedp:
- msg['X-Content-Filtered-By'] = 'Mailman/MimeDel {0}'.format(VERSION)
+ msg['X-Content-Filtered-By'] = 'Mailman/MimeDel {}'.format(VERSION)
-
def reset_payload(msg, subpart):
# Reset payload of msg to contents of subpart, and fix up content headers
payload = subpart.get_payload()
@@ -182,7 +177,6 @@ def reset_payload(msg, subpart):
msg['Content-Description'] = cdesc
-
def filter_parts(msg, filtertypes, passtypes, filterexts, passexts):
# Look at all the message's subparts, and recursively filter
if not msg.is_multipart():
@@ -220,7 +214,6 @@ def filter_parts(msg, filtertypes, passtypes, filterexts, passexts):
return True
-
def collapse_multipart_alternatives(msg):
if not msg.is_multipart():
return
@@ -237,7 +230,6 @@ def collapse_multipart_alternatives(msg):
msg.set_payload(newpayload)
-
def to_plaintext(msg):
changedp = 0
counter = count()
@@ -265,7 +257,6 @@ def to_plaintext(msg):
return changedp
-
def get_file_ext(m):
"""
Get filename extension. Caution: some virus don't put filename
@@ -274,7 +265,7 @@ def get_file_ext(m):
fext = ''
filename = m.get_filename('') or m.get_param('name', '')
if filename:
- fext = os.path.splitext(oneline(filename,'utf-8'))[1]
+ fext = os.path.splitext(oneline(filename, 'utf-8'))[1]
if len(fext) > 1:
fext = fext[1:]
else:
@@ -282,7 +273,7 @@ def get_file_ext(m):
return fext
-
+@public
@implementer(IHandler)
class MIMEDelete:
"""Filter the MIME content of messages."""
diff --git a/src/mailman/handlers/owner_recipients.py b/src/mailman/handlers/owner_recipients.py
index 9a18f1ceb..9ef2568f5 100644
--- a/src/mailman/handlers/owner_recipients.py
+++ b/src/mailman/handlers/owner_recipients.py
@@ -17,11 +17,7 @@
"""Calculate the list owner recipients (includes moderators)."""
-__all__ = [
- 'OwnerRecipients',
- ]
-
-
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
@@ -29,7 +25,7 @@ from mailman.interfaces.member import DeliveryStatus
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class OwnerRecipients:
"""Calculate the owner (and moderator) recipients for -owner postings."""
diff --git a/src/mailman/handlers/replybot.py b/src/mailman/handlers/replybot.py
index 0302d2793..546bb1ec4 100644
--- a/src/mailman/handlers/replybot.py
+++ b/src/mailman/handlers/replybot.py
@@ -17,13 +17,9 @@
"""Handler for automatic responses."""
-__all__ = [
- 'Replybot',
- ]
-
-
import logging
+from mailman import public
from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.autorespond import (
@@ -39,7 +35,7 @@ from zope.interface import implementer
log = logging.getLogger('mailman.error')
-
+@public
@implementer(IHandler)
class Replybot:
"""Send automatic responses."""
@@ -101,12 +97,13 @@ class Replybot:
'Auto-response for your message to the "$display_name" '
'mailing list')
# Do string interpolation into the autoresponse text
- d = dict(list_name = mlist.list_name,
- display_name = display_name,
- listurl = mlist.script_url('listinfo'),
- requestemail = mlist.request_address,
- owneremail = mlist.owner_address,
- )
+ d = dict(
+ list_name=mlist.list_name,
+ display_name=display_name,
+ listurl=mlist.script_url('listinfo'),
+ requestemail=mlist.request_address,
+ owneremail=mlist.owner_address,
+ )
# Interpolation and Wrap the response text.
text = wrap(expand(response_text, d))
outmsg = UserNotification(msg.sender, mlist.bounces_address,
diff --git a/src/mailman/handlers/rfc_2369.py b/src/mailman/handlers/rfc_2369.py
index 4f172bde1..3daf6414d 100644
--- a/src/mailman/handlers/rfc_2369.py
+++ b/src/mailman/handlers/rfc_2369.py
@@ -17,14 +17,10 @@
"""RFC 2369 List-* and related headers."""
-__all__ = [
- 'RFC2369',
- ]
-
-
import logging
from email.utils import formataddr
+from mailman import public
from mailman.core.i18n import _
from mailman.handlers.cook_headers import uheader
from mailman.interfaces.archiver import ArchivePolicy
@@ -38,7 +34,6 @@ CONTINUATION = ',\n\t'
log = logging.getLogger('mailman.archiver')
-
def process(mlist, msg, msgdata):
"""Add the RFC 2369 List-* and related headers."""
# Some people really hate the List-* headers. It seems that the free
@@ -126,7 +121,7 @@ def process(mlist, msg, msgdata):
msg[h] = v
-
+@public
@implementer(IHandler)
class RFC2369:
"""Add the RFC 2369 List-* headers."""
diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py
index c3490986c..8a9da8b42 100644
--- a/src/mailman/handlers/subject_prefix.py
+++ b/src/mailman/handlers/subject_prefix.py
@@ -17,14 +17,10 @@
"""Subject header prefix munging."""
-__all__ = [
- 'SubjectPrefix',
- ]
-
-
import re
from email.header import Header, make_header, decode_header
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
@@ -35,7 +31,6 @@ ASCII_CHARSETS = (None, 'ascii', 'us-ascii')
EMPTYSTRING = ''
-
def ascii_header(mlist, msgdata, subject, prefix, prefix_pattern, ws):
if mlist.preferred_language.charset not in ASCII_CHARSETS:
return None
@@ -127,7 +122,7 @@ def mixed_charsets(mlist, msgdata, subject, prefix, prefix_pattern, ws):
return make_header(chunks, continuation_ws=ws)
-
+@public
@implementer(IHandler)
class SubjectPrefix:
"""Add a list-specific prefix to the Subject header value."""
diff --git a/src/mailman/handlers/tagger.py b/src/mailman/handlers/tagger.py
index 50112c74f..fb0a24ba5 100644
--- a/src/mailman/handlers/tagger.py
+++ b/src/mailman/handlers/tagger.py
@@ -17,15 +17,11 @@
"""Extract topics from the original mail message."""
-__all__ = [
- 'Tagger',
- ]
-
-
import re
import email.iterators
import email.parser
+from mailman import public
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
@@ -37,7 +33,6 @@ EMPTYSTRING = ''
NLTAB = '\n\t'
-
def process(mlist, msg, msgdata):
"""Tag the message for topics."""
if not mlist.topics_enabled:
@@ -75,7 +70,6 @@ def process(mlist, msg, msgdata):
msg['X-Topics'] = NLTAB.join(sorted(hits))
-
def scanbody(msg, numlines=None):
"""Scan the body for keywords."""
# We only scan the body of the message if it is of MIME type text/plain,
@@ -84,8 +78,8 @@ def scanbody(msg, numlines=None):
found = None
if msg.get_content_type() == 'text/plain':
found = msg
- elif msg.is_multipart()\
- and msg.get_content_type() == 'multipart/alternative':
+ elif (msg.is_multipart() and
+ msg.get_content_type() == 'multipart/alternative'):
for found in msg.get_payload():
if found.get_content_type() == 'text/plain':
break
@@ -115,7 +109,6 @@ def scanbody(msg, numlines=None):
return msg.get_all('subject', []) + msg.get_all('keywords', [])
-
class _ForgivingParser(email.parser.HeaderParser):
"""An lax email parser.
@@ -173,7 +166,7 @@ class _ForgivingParser(email.parser.HeaderParser):
container[lastheader] = NLTAB.join(lastvalue)
-
+@public
@implementer(IHandler)
class Tagger:
"""Tag messages with topic matches."""
diff --git a/src/mailman/handlers/tests/test_cook_headers.py b/src/mailman/handlers/tests/test_cook_headers.py
index e68f6a23d..fad3f49d9 100644
--- a/src/mailman/handlers/tests/test_cook_headers.py
+++ b/src/mailman/handlers/tests/test_cook_headers.py
@@ -17,11 +17,6 @@
"""Test the cook_headers handler."""
-__all__ = [
- 'TestCookHeaders',
- ]
-
-
import unittest
from mailman.app.lifecycle import create_list
@@ -32,7 +27,6 @@ from mailman.testing.helpers import (
from mailman.testing.layers import ConfigLayer
-
class TestCookHeaders(unittest.TestCase):
"""Test the cook_headers handler."""
@@ -49,11 +43,10 @@ class TestCookHeaders(unittest.TestCase):
bart = subscribe(self._mlist, 'Bart')
bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
make_digest_messages(self._mlist)
- messages = [bag.msg for bag in get_queue_messages('virgin')]
- self.assertEqual(len(messages), 2)
- for msg in messages:
+ items = get_queue_messages('virgin', expected_count=2)
+ for item in items:
try:
- cook_headers.process(self._mlist, msg, {})
+ cook_headers.process(self._mlist, item.msg, {})
except AttributeError as error:
# LP: #1130696 would raise an AttributeError on .sender
self.fail(error)
diff --git a/src/mailman/handlers/tests/test_decorate.py b/src/mailman/handlers/tests/test_decorate.py
index 2a44d4186..7d44214cb 100644
--- a/src/mailman/handlers/tests/test_decorate.py
+++ b/src/mailman/handlers/tests/test_decorate.py
@@ -17,12 +17,6 @@
"""Test the decorate handler."""
-__all__ = [
- 'TestBrokenPermalink',
- 'TestDecorate',
- ]
-
-
import os
import unittest
@@ -37,7 +31,6 @@ from tempfile import TemporaryDirectory
from zope.interface import implementer
-
@implementer(IArchiver)
class TestArchiver:
"""A test archiver"""
@@ -60,7 +53,6 @@ class BrokenArchiver:
raise RuntimeError('Cannot get permalink')
-
class TestDecorate(unittest.TestCase):
"""Test the cook_headers handler."""
diff --git a/src/mailman/handlers/tests/test_file_recips.py b/src/mailman/handlers/tests/test_file_recips.py
index f7072d850..ee3084288 100644
--- a/src/mailman/handlers/tests/test_file_recips.py
+++ b/src/mailman/handlers/tests/test_file_recips.py
@@ -17,11 +17,6 @@
"""Test file-recips handler."""
-__all__ = [
- 'TestFileRecips',
- ]
-
-
import os
import unittest
@@ -31,7 +26,6 @@ from mailman.testing.helpers import specialized_message_from_string as mfs
from mailman.testing.layers import ConfigLayer
-
class TestFileRecips(unittest.TestCase):
layer = ConfigLayer
diff --git a/src/mailman/handlers/tests/test_filter.py b/src/mailman/handlers/tests/test_filter.py
index 0933d8b00..7ee6249f0 100644
--- a/src/mailman/handlers/tests/test_filter.py
+++ b/src/mailman/handlers/tests/test_filter.py
@@ -17,11 +17,6 @@
"""Test the filter handler."""
-__all__ = [
- 'TestFilters',
- ]
-
-
import unittest
from mailman.app.lifecycle import create_list
@@ -32,7 +27,6 @@ from mailman.testing.helpers import specialized_message_from_string as mfs
from mailman.testing.layers import ConfigLayer
-
class TestFilters(unittest.TestCase):
layer = ConfigLayer
diff --git a/src/mailman/handlers/tests/test_mimedel.py b/src/mailman/handlers/tests/test_mimedel.py
index d5670f1bc..e685e24f3 100644
--- a/src/mailman/handlers/tests/test_mimedel.py
+++ b/src/mailman/handlers/tests/test_mimedel.py
@@ -17,13 +17,6 @@
"""Test the mime_delete handler."""
-__all__ = [
- 'TestDispose',
- 'TestHTMLFilter',
- 'dummy_script',
- ]
-
-
import os
import sys
import shutil
@@ -45,7 +38,6 @@ from mailman.testing.layers import ConfigLayer
from zope.component import getUtility
-
@contextmanager
def dummy_script():
with ExitStack() as resources:
@@ -66,7 +58,6 @@ html_to_plain_text_command = {exe} {script} $filename
yield
-
class TestDispose(unittest.TestCase):
"""Test the mime_delete handler."""
@@ -94,7 +85,7 @@ Message-ID: <ant>
mime_delete.dispose(self._mlist, self._msg, {}, 'discarding')
self.assertEqual(cm.exception.message, 'discarding')
# There should be no messages in the 'bad' queue.
- self.assertEqual(len(get_queue_messages('bad')), 0)
+ get_queue_messages('bad', expected_count=0)
def test_dispose_bounce(self):
self._mlist.filter_action = FilterAction.reject
@@ -102,7 +93,7 @@ Message-ID: <ant>
mime_delete.dispose(self._mlist, self._msg, {}, 'rejecting')
self.assertEqual(cm.exception.message, 'rejecting')
# There should be no messages in the 'bad' queue.
- self.assertEqual(len(get_queue_messages('bad')), 0)
+ get_queue_messages('bad', expected_count=0)
def test_dispose_forward(self):
# The disposed message gets forwarded to the list moderators. So
@@ -119,9 +110,8 @@ Message-ID: <ant>
self.assertEqual(cm.exception.message, 'forwarding')
# There should now be a multipart message in the virgin queue destined
# for the mailing list owners.
- messages = get_queue_messages('virgin')
- self.assertEqual(len(messages), 1)
- message = messages[0].msg
+ items = get_queue_messages('virgin', expected_count=1)
+ message = items[0].msg
self.assertEqual(message.get_content_type(), 'multipart/mixed')
# Anne and Bart should be recipients of the message, but it will look
# like the message is going to the list owners.
@@ -160,7 +150,7 @@ message.
mime_delete.dispose(self._mlist, self._msg, {}, 'not preserved')
self.assertEqual(cm.exception.message, 'not preserved')
# There should be no messages in the 'bad' queue.
- self.assertEqual(len(get_queue_messages('bad')), 0)
+ get_queue_messages('bad', expected_count=0)
@configuration('mailman', filtered_messages_are_preservable='yes')
def test_dispose_preservable(self):
@@ -173,9 +163,8 @@ message.
mime_delete.dispose(self._mlist, self._msg, {}, 'preserved')
self.assertEqual(cm.exception.message, 'preserved')
# There should be no messages in the 'bad' queue.
- messages = get_queue_messages('bad')
- self.assertEqual(len(messages), 1)
- message = messages[0].msg
+ items = get_queue_messages('bad', expected_count=1)
+ message = items[0].msg
self.assertEqual(message['subject'], 'A disposable message')
self.assertEqual(message['message-id'], '<ant>')
@@ -194,11 +183,10 @@ message.
self.assertEqual(cm.exception.message, 'bad action')
line = mark.readline()[:-1]
self.assertTrue(line.endswith(
- '{0} invalid FilterAction: test@example.com. '
+ 'test@example.com invalid FilterAction: {}. '
'Treating as discard'.format(action.name)))
-
class TestHTMLFilter(unittest.TestCase):
"""Test the conversion of HTML to plaintext."""
diff --git a/src/mailman/handlers/tests/test_recipients.py b/src/mailman/handlers/tests/test_recipients.py
index 5fb69c272..5a6ecf226 100644
--- a/src/mailman/handlers/tests/test_recipients.py
+++ b/src/mailman/handlers/tests/test_recipients.py
@@ -17,12 +17,6 @@
"""Testing various recipients stuff."""
-__all__ = [
- 'TestMemberRecipients',
- 'TestOwnerRecipients',
- ]
-
-
import unittest
from mailman.app.lifecycle import create_list
@@ -35,7 +29,6 @@ from mailman.testing.layers import ConfigLayer
from zope.component import getUtility
-
class TestMemberRecipients(unittest.TestCase):
"""Test regular member recipient calculation."""
@@ -87,7 +80,6 @@ To: test@example.com
'dave@example.com')))
-
class TestOwnerRecipients(unittest.TestCase):
"""Test owner recipient calculation."""
diff --git a/src/mailman/handlers/tests/test_rfc_2369.py b/src/mailman/handlers/tests/test_rfc_2369.py
index cbbaf2153..e78cf9c47 100644
--- a/src/mailman/handlers/tests/test_rfc_2369.py
+++ b/src/mailman/handlers/tests/test_rfc_2369.py
@@ -17,11 +17,6 @@
"""Test the rfc_2369 handler."""
-__all__ = [
- 'TestRFC2369',
- ]
-
-
import unittest
from mailman.app.lifecycle import create_list
@@ -35,7 +30,6 @@ from urllib.parse import urljoin
from zope.interface import implementer
-
@implementer(IArchiver)
class DummyArchiver:
"""An example archiver which does nothing but return URLs."""
@@ -74,7 +68,6 @@ class BrokenArchiver:
raise RuntimeError('Cannot archive message')
-
class TestRFC2369(unittest.TestCase):
"""Test the rfc_2369 handler."""
diff --git a/src/mailman/handlers/tests/test_subject_prefix.py b/src/mailman/handlers/tests/test_subject_prefix.py
index 91c799785..1680f4d2d 100644
--- a/src/mailman/handlers/tests/test_subject_prefix.py
+++ b/src/mailman/handlers/tests/test_subject_prefix.py
@@ -17,11 +17,6 @@
"""Test the Subject header prefix munging.."""
-__all__ = [
- 'TestSubjectPrefix',
- ]
-
-
import unittest
from mailman.app.lifecycle import create_list
@@ -30,7 +25,6 @@ from mailman.email.message import Message
from mailman.testing.layers import ConfigLayer
-
class TestSubjectPrefix(unittest.TestCase):
layer = ConfigLayer
@@ -120,7 +114,7 @@ class TestSubjectPrefix(unittest.TestCase):
self._mlist.post_id = 456
msg = Message()
msg['Subject'] = \
- '[Test 123] Re: =?iso-2022-jp?b?GyRCJWEhPCVrJV4lcxsoQg==?='
+ '[Test 123] Re: =?iso-2022-jp?b?GyRCJWEhPCVrJV4lcxsoQg==?='
self._process(self._mlist, msg, {})
subject = msg['subject']
self.assertEqual(
diff --git a/src/mailman/handlers/tests/test_to_digest.py b/src/mailman/handlers/tests/test_to_digest.py
index 42a5cd65c..3ce12921e 100644
--- a/src/mailman/handlers/tests/test_to_digest.py
+++ b/src/mailman/handlers/tests/test_to_digest.py
@@ -17,11 +17,6 @@
"""Test the to_digest handler."""
-__all__ = [
- 'TestToDigest',
- ]
-
-
import os
import unittest
@@ -31,7 +26,6 @@ from mailman.testing.helpers import specialized_message_from_string as mfs
from mailman.testing.layers import ConfigLayer
-
class TestToDigest(unittest.TestCase):
"""Test the to_digest handler."""
diff --git a/src/mailman/handlers/to_archive.py b/src/mailman/handlers/to_archive.py
index 4a388bdca..d5b980ab4 100644
--- a/src/mailman/handlers/to_archive.py
+++ b/src/mailman/handlers/to_archive.py
@@ -17,11 +17,7 @@
"""Add the message to the archives."""
-__all__ = [
- 'ToArchive',
- ]
-
-
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.archiver import ArchivePolicy
@@ -29,7 +25,7 @@ from mailman.interfaces.handler import IHandler
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class ToArchive:
"""Add the message to the archives."""
@@ -41,7 +37,7 @@ class ToArchive:
"""See `IHandler`."""
# Short circuits.
if (msgdata.get('isdigest') or
- mlist.archive_policy is ArchivePolicy.never):
+ mlist.archive_policy is ArchivePolicy.never):
return
# Common practice seems to favor "X-No-Archive: yes". No other value
# for this header seems to make sense, so we'll just test for it's
diff --git a/src/mailman/handlers/to_digest.py b/src/mailman/handlers/to_digest.py
index 54679f47e..671a2197c 100644
--- a/src/mailman/handlers/to_digest.py
+++ b/src/mailman/handlers/to_digest.py
@@ -17,13 +17,9 @@
"""Add the message to the list's current digest."""
-__all__ = [
- 'ToDigest',
- ]
-
-
import os
+from mailman import public
from mailman.app.digests import maybe_send_digest_now
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
@@ -31,7 +27,7 @@ from mailman.utilities.mailbox import Mailbox
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class ToDigest:
"""Add the message to the digest, possibly sending it."""
diff --git a/src/mailman/handlers/to_outgoing.py b/src/mailman/handlers/to_outgoing.py
index 3e68016e3..b9fae912c 100644
--- a/src/mailman/handlers/to_outgoing.py
+++ b/src/mailman/handlers/to_outgoing.py
@@ -22,18 +22,14 @@ posted to the list membership. Anything else that needs to go out to some
recipient should just be placed in the out queue directly.
"""
-__all__ = [
- 'ToOutgoing',
- ]
-
-
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from zope.interface import implementer
-
+@public
@implementer(IHandler)
class ToOutgoing:
"""Send the message to the outgoing queue."""
diff --git a/src/mailman/handlers/to_usenet.py b/src/mailman/handlers/to_usenet.py
index a36248be4..4bfa00c5f 100644
--- a/src/mailman/handlers/to_usenet.py
+++ b/src/mailman/handlers/to_usenet.py
@@ -17,13 +17,9 @@
"""Move the message to the mail->news queue."""
-__all__ = [
- 'ToUsenet',
- ]
-
-
import logging
+from mailman import public
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
@@ -34,7 +30,7 @@ COMMASPACE = ', '
log = logging.getLogger('mailman.error')
-
+@public
@implementer(IHandler)
class ToUsenet:
"""Move the message to the outgoing news queue."""
@@ -46,8 +42,8 @@ class ToUsenet:
"""See `IHandler`."""
# Short circuits.
if (not mlist.gateway_to_news or
- msgdata.get('isdigest') or
- msgdata.get('fromusenet')):
+ msgdata.get('isdigest') or
+ msgdata.get('fromusenet')):
# Short-circuit.
return
# Sanity checks.