summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2016-01-11 22:52:33 -0500
committerBarry Warsaw2016-01-11 22:52:33 -0500
commit03bb57c8c2a47a08e19b20975622ebb2ef2b81c6 (patch)
tree332bf1e5e36da0a3cb4271b1a471a62865071a62 /src
parent58ee14bfb1c1c24d06fb0509e42e06e37a505479 (diff)
downloadmailman-03bb57c8c2a47a08e19b20975622ebb2ef2b81c6.tar.gz
mailman-03bb57c8c2a47a08e19b20975622ebb2ef2b81c6.tar.zst
mailman-03bb57c8c2a47a08e19b20975622ebb2ef2b81c6.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/chains/base.py3
-rw-r--r--src/mailman/chains/tests/test_base.py18
-rw-r--r--src/mailman/config/config.py6
-rw-r--r--src/mailman/config/tests/test_configuration.py15
-rw-r--r--src/mailman/core/pipelines.py3
-rw-r--r--src/mailman/model/bounce.py8
-rw-r--r--src/mailman/model/domain.py7
-rw-r--r--src/mailman/model/listmanager.py10
-rw-r--r--src/mailman/model/mailinglist.py11
-rw-r--r--src/mailman/model/requests.py3
-rw-r--r--src/mailman/model/roster.py49
-rw-r--r--src/mailman/model/subscriptions.py17
-rw-r--r--src/mailman/model/tests/test_mailinglist.py19
-rw-r--r--src/mailman/model/tests/test_roster.py6
-rw-r--r--src/mailman/model/tests/test_subscriptions.py2
-rw-r--r--src/mailman/model/usermanager.py12
-rw-r--r--src/mailman/mta/aliases.py4
-rw-r--r--src/mailman/testing/helpers.py3
-rw-r--r--src/mailman/testing/mta.py3
-rw-r--r--src/mailman/utilities/modules.py3
20 files changed, 105 insertions, 97 deletions
diff --git a/src/mailman/chains/base.py b/src/mailman/chains/base.py
index a2266cf38..54bddfe0b 100644
--- a/src/mailman/chains/base.py
+++ b/src/mailman/chains/base.py
@@ -114,8 +114,7 @@ class Chain:
"""Return an iterator over the links."""
# We do it this way in order to preserve a separation of interfaces,
# and allows .get_links() to be overridden.
- for link in self._links:
- yield link
+ yield from self._links
diff --git a/src/mailman/chains/tests/test_base.py b/src/mailman/chains/tests/test_base.py
index 7216a6178..dc50252c3 100644
--- a/src/mailman/chains/tests/test_base.py
+++ b/src/mailman/chains/tests/test_base.py
@@ -19,15 +19,22 @@
__all__ = [
'TestMiscellaneous',
+ 'TestTerminalChainBase',
]
import unittest
from mailman.chains.accept import AcceptChain
-from mailman.chains.base import Chain, Link
+from mailman.chains.base import Chain, Link, TerminalChainBase
from mailman.interfaces.chain import LinkAction
from mailman.rules.any import Any
+from mailman.testing.layers import ConfigLayer
+
+
+class SimpleChain(TerminalChainBase):
+ def _process(self, mlist, msg, msgdata):
+ pass
@@ -75,3 +82,12 @@ class TestMiscellaneous(unittest.TestCase):
chain.flush()
count = sum(1 for link in chain.get_iterator())
self.assertEqual(count, 0)
+
+
+class TestTerminalChainBase(unittest.TestCase):
+ layer = ConfigLayer
+
+ def test_terminal_chain_iterator(self):
+ chain = SimpleChain()
+ self.assertEqual([link.action for link in chain],
+ [LinkAction.run, LinkAction.stop])
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index 69ddfb04f..424ad03c0 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -245,8 +245,7 @@ class Configuration:
@property
def runner_configs(self):
"""Iterate over all the runner configuration sections."""
- for section in self._config.getByCategory('runner', []):
- yield section
+ yield from self._config.getByCategory('runner', [])
@property
def archivers(self):
@@ -262,8 +261,7 @@ class Configuration:
@property
def language_configs(self):
"""Iterate over all the language configuration sections."""
- for section in self._config.getByCategory('language', []):
- yield section
+ yield from self._config.getByCategory('language', [])
diff --git a/src/mailman/config/tests/test_configuration.py b/src/mailman/config/tests/test_configuration.py
index 48cf21983..abbfce2c2 100644
--- a/src/mailman/config/tests/test_configuration.py
+++ b/src/mailman/config/tests/test_configuration.py
@@ -58,6 +58,21 @@ class TestConfiguration(unittest.TestCase):
pass
self.assertEqual(events, ['first', 'second', 'first'])
+ def test_config_template_dir_is_source(self):
+ fd, filename = tempfile.mkstemp()
+ self.addCleanup(os.remove, filename)
+ os.close(fd)
+ with open(filename, 'w') as fp:
+ print("""\
+[paths.here]
+template_dir: :source:
+""", file=fp)
+ config = Configuration()
+ config.load(filename)
+ import mailman.templates
+ self.assertEqual(config.TEMPLATE_DIR,
+ os.path.dirname(mailman.templates.__file__))
+
class TestExternal(unittest.TestCase):
diff --git a/src/mailman/core/pipelines.py b/src/mailman/core/pipelines.py
index a3c1bd58e..a353e3ad8 100644
--- a/src/mailman/core/pipelines.py
+++ b/src/mailman/core/pipelines.py
@@ -85,8 +85,7 @@ class BasePipeline:
def __iter__(self):
"""See `IPipeline`."""
- for handler in self._handlers:
- yield handler
+ yield from self._handlers
diff --git a/src/mailman/model/bounce.py b/src/mailman/model/bounce.py
index e05bda516..3ccf58091 100644
--- a/src/mailman/model/bounce.py
+++ b/src/mailman/model/bounce.py
@@ -54,8 +54,6 @@ class BounceEvent(Model):
self.email = email
self.timestamp = now()
msgid = msg['message-id']
- if isinstance(msgid, bytes):
- msgid = msgid.decode('ascii')
self.message_id = msgid
self.context = (BounceContext.normal if context is None else context)
self.processed = False
@@ -77,12 +75,10 @@ class BounceProcessor:
@dbconnection
def events(self, store):
"""See `IBounceProcessor`."""
- for event in store.query(BounceEvent).all():
- yield event
+ yield from store.query(BounceEvent).all()
@property
@dbconnection
def unprocessed(self, store):
"""See `IBounceProcessor`."""
- for event in store.query(BounceEvent).filter_by(processed=False):
- yield event
+ yield from store.query(BounceEvent).filter_by(processed=False)
diff --git a/src/mailman/model/domain.py b/src/mailman/model/domain.py
index 1218a3481..7fb6d6821 100644
--- a/src/mailman/model/domain.py
+++ b/src/mailman/model/domain.py
@@ -94,11 +94,9 @@ class Domain(Model):
@dbconnection
def mailing_lists(self, store):
"""See `IDomain`."""
- mailing_lists = store.query(MailingList).filter(
+ yield from store.query(MailingList).filter(
MailingList.mail_host == self.mail_host
).order_by(MailingList._list_id)
- for mlist in mailing_lists:
- yield mlist
def confirm_url(self, token=''):
"""See `IDomain`."""
@@ -194,8 +192,7 @@ class DomainManager:
@dbconnection
def __iter__(self, store):
"""See `IDomainManager`."""
- for domain in store.query(Domain).order_by(Domain.mail_host).all():
- yield domain
+ yield from store.query(Domain).order_by(Domain.mail_host).all()
@dbconnection
def __contains__(self, store, mail_host):
diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py
index fcf7a61e0..c4135a8c7 100644
--- a/src/mailman/model/listmanager.py
+++ b/src/mailman/model/listmanager.py
@@ -88,15 +88,13 @@ class ListManager:
@dbconnection
def mailing_lists(self, store):
"""See `IListManager`."""
- for mlist in store.query(MailingList).order_by(
- MailingList._list_id).all():
- yield mlist
+ yield from store.query(MailingList).order_by(
+ MailingList._list_id).all()
@dbconnection
def __iter__(self, store):
"""See `IListManager`."""
- for mlist in store.query(MailingList).all():
- yield mlist
+ yield from store.query(MailingList).all()
@property
@dbconnection
@@ -105,7 +103,7 @@ class ListManager:
result_set = store.query(MailingList)
for mail_host, list_name in result_set.values(MailingList.mail_host,
MailingList.list_name):
- yield '{0}@{1}'.format(list_name, mail_host)
+ yield '{}@{}'.format(list_name, mail_host)
@property
@dbconnection
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py
index 43cc26c6e..f8d1481a2 100644
--- a/src/mailman/model/mailinglist.py
+++ b/src/mailman/model/mailinglist.py
@@ -431,7 +431,7 @@ class MailingList(Model):
ContentFilter.mailing_list == self,
ContentFilter.filter_type == FilterType.pass_extension)
for content_filter in results:
- yield content_filter.pass_pattern
+ yield content_filter.filter_pattern
@pass_extensions.setter
@dbconnection
@@ -459,7 +459,7 @@ class MailingList(Model):
elif role is MemberRole.nonmember:
return self.nonmembers
else:
- raise TypeError('Undefined MemberRole: {}'.format(role))
+ raise ValueError('Undefined MemberRole: {}'.format(role))
@dbconnection
def subscribe(self, store, subscriber, role=MemberRole.member):
@@ -576,10 +576,10 @@ class ListArchiver(Model):
@property
def system_archiver(self):
- for archiver in config.archivers:
+ for archiver in config.archivers: # pragma: no branch
if archiver.name == self.name:
return archiver
- return None
+ raise AssertionError('Archiver not found: {}'.format(self.name))
@property
def is_enabled(self):
@@ -613,8 +613,7 @@ class ListArchiverSet:
def archivers(self, store):
entries = store.query(ListArchiver).filter(
ListArchiver.mailing_list == self._mailing_list)
- for entry in entries:
- yield entry
+ yield from entries
@dbconnection
def get(self, store, archiver_name):
diff --git a/src/mailman/model/requests.py b/src/mailman/model/requests.py
index c7e61299c..831674aa1 100644
--- a/src/mailman/model/requests.py
+++ b/src/mailman/model/requests.py
@@ -83,8 +83,7 @@ class ListRequests:
def held_requests(self, store):
results = store.query(_Request).filter_by(
mailing_list=self.mailing_list)
- for request in results:
- yield request
+ yield from results
@dbconnection
def of_type(self, store, request_type):
diff --git a/src/mailman/model/roster.py b/src/mailman/model/roster.py
index 9fbb8816b..6890debf4 100644
--- a/src/mailman/model/roster.py
+++ b/src/mailman/model/roster.py
@@ -68,8 +68,7 @@ class AbstractRoster:
@property
def members(self):
"""See `IRoster`."""
- for member in self._query():
- yield member
+ yield from self._query()
@property
def member_count(self):
@@ -84,9 +83,7 @@ class AbstractRoster:
# keep a set of unique users. It's possible for the same user to be
# subscribed to a mailing list multiple times with different
# addresses.
- users = set(member.address.user for member in self.members)
- for user in users:
- yield user
+ yield from set(member.address.user for member in self.members)
@property
def addresses(self):
@@ -189,19 +186,12 @@ class AdministratorRoster(AbstractRoster):
@dbconnection
def get_member(self, store, email):
"""See `IRoster`."""
- results = store.query(Member).filter(
+ return store.query(Member).filter(
Member.list_id == self._mlist.list_id,
or_(Member.role == MemberRole.moderator,
Member.role == MemberRole.owner),
Address.email == email,
- Member.address_id == Address.id)
- if results.count() == 0:
- return None
- elif results.count() == 1:
- return results[0]
- else:
- raise AssertionError(
- 'Too many matching member results: {0}'.format(results))
+ Member.address_id == Address.id).one_or_none()
@@ -243,8 +233,7 @@ class RegularMemberRoster(DeliveryMemberRoster):
@property
def members(self):
"""See `IRoster`."""
- for member in self._get_members(DeliveryMode.regular):
- yield member
+ yield from self._get_members(DeliveryMode.regular)
@@ -256,10 +245,10 @@ class DigestMemberRoster(DeliveryMemberRoster):
@property
def members(self):
"""See `IRoster`."""
- for member in self._get_members(DeliveryMode.plaintext_digests,
- DeliveryMode.mime_digests,
- DeliveryMode.summary_digests):
- yield member
+ yield from self._get_members(
+ DeliveryMode.plaintext_digests,
+ DeliveryMode.mime_digests,
+ DeliveryMode.summary_digests)
@@ -301,8 +290,7 @@ class Memberships:
@property
def members(self):
"""See `IRoster`."""
- for member in self._query():
- yield member
+ yield from self._query()
@property
def users(self):
@@ -312,27 +300,14 @@ class Memberships:
@property
def addresses(self):
"""See `IRoster`."""
- for address in self._user.addresses:
- yield address
+ yield from self._user.addresses
@dbconnection
def get_member(self, store, email):
"""See `IRoster`."""
- results = store.query(Member).filter(
- Member.address_id == Address.id,
- Address.user_id == self._user.id)
- if results.count() == 0:
- return None
- elif results.count() == 1:
- return results[0]
- else:
- raise AssertionError(
- 'Too many matching member results: {0}'.format(
- results.count()))
+ raise NotImplementedError
@dbconnection
def get_memberships(self, store, address):
"""See `IRoster`."""
- # 2015-04-14 BAW: See LP: #1444055 -- this currently exists just to
- # pass a test.
raise NotImplementedError
diff --git a/src/mailman/model/subscriptions.py b/src/mailman/model/subscriptions.py
index 93c7c97c2..b7276b2cd 100644
--- a/src/mailman/model/subscriptions.py
+++ b/src/mailman/model/subscriptions.py
@@ -82,7 +82,7 @@ class SubscriptionService:
# which are controlled by the user, otherwise we'll just search for
# the given address.
if subscriber is None and list_id is None and role is None:
- raise NoResultFound
+ return None
order = (Member.list_id, Address.email, Member.role)
# Querying for the subscriber is the most complicated part, because
# the parameter can either be an email address or a user id. Start by
@@ -116,24 +116,23 @@ class SubscriptionService:
def find_members(self, subscriber=None, list_id=None, role=None):
"""See `ISubscriptionService`."""
- try:
- query = self._find_members(subscriber, list_id, role)
- except NoResultFound:
- query = None
- return QuerySequence(query)
+ return QuerySequence(self._find_members(subscriber, list_id, role))
def find_member(self, subscriber=None, list_id=None, role=None):
"""See `ISubscriptionService`."""
try:
- return self._find_members(subscriber, list_id, role).one()
+ result = self._find_members(subscriber, list_id, role)
+ return (result if result is None else result.one())
except NoResultFound:
return None
except MultipleResultsFound:
+ # Coerce the exception into a Mailman-layer exception so call
+ # sites don't have to import from SQLAlchemy, resulting in a layer
+ # violation.
raise TooManyMembersError(subscriber, list_id, role)
def __iter__(self):
- for member in self.get_members():
- yield member
+ yield from self.get_members()
def leave(self, list_id, email):
"""See `ISubscriptionService`."""
diff --git a/src/mailman/model/tests/test_mailinglist.py b/src/mailman/model/tests/test_mailinglist.py
index 17259621e..9e3708ee5 100644
--- a/src/mailman/model/tests/test_mailinglist.py
+++ b/src/mailman/model/tests/test_mailinglist.py
@@ -75,6 +75,17 @@ class TestMailingList(unittest.TestCase):
self.assertRaises(MissingPreferredAddressError,
self._mlist.subscribe, anne)
+ def test_pass_extensions(self):
+ self._mlist.pass_extensions = ('foo', 'bar', 'baz')
+ self.assertEqual(list(self._mlist.pass_extensions),
+ ['foo', 'bar', 'baz'])
+
+ def test_get_roster_argument(self):
+ self.assertRaises(ValueError, self._mlist.get_roster, 'members')
+
+ def test_subscribe_argument(self):
+ self.assertRaises(ValueError, self._mlist.subscribe, 'anne')
+
class TestListArchiver(unittest.TestCase):
@@ -218,3 +229,11 @@ class TestHeaderMatch(unittest.TestCase):
('header', 'pattern', None),
('subject', 'patt.*', None),
])
+
+ def test_clear(self):
+ header_matches = IHeaderMatchSet(self._mlist)
+ header_matches.add('Header', 'pattern')
+ self.assertEqual(len(self._mlist.header_matches), 1)
+ with transaction():
+ header_matches.clear()
+ self.assertEqual(len(self._mlist.header_matches), 0)
diff --git a/src/mailman/model/tests/test_roster.py b/src/mailman/model/tests/test_roster.py
index 15e78b288..184c8c157 100644
--- a/src/mailman/model/tests/test_roster.py
+++ b/src/mailman/model/tests/test_roster.py
@@ -200,3 +200,9 @@ class TestMembershipsRoster(unittest.TestCase):
self.assertEqual(
[record.address.email for record in memberships],
['anne@example.com', 'anne@example.com'])
+
+ def test_memberships_users(self):
+ self._ant.subscribe(self._anne)
+ users = list(self._anne.memberships.users)
+ self.assertEqual(len(users), 1)
+ self.assertEqual(users[0], self._anne)
diff --git a/src/mailman/model/tests/test_subscriptions.py b/src/mailman/model/tests/test_subscriptions.py
index 3e97bd427..f389cff55 100644
--- a/src/mailman/model/tests/test_subscriptions.py
+++ b/src/mailman/model/tests/test_subscriptions.py
@@ -234,7 +234,7 @@ class TestSubscriptionService(unittest.TestCase):
('test3', 'anne3', MemberRole.moderator),
])
- def test_find_members_shortcut(self):
+ def test_find_no_members(self):
members = self._service.find_members()
self.assertEqual(len(members), 0)
diff --git a/src/mailman/model/usermanager.py b/src/mailman/model/usermanager.py
index 93dd03e20..8b923f07e 100644
--- a/src/mailman/model/usermanager.py
+++ b/src/mailman/model/usermanager.py
@@ -103,8 +103,7 @@ class UserManager:
@dbconnection
def users(self, store):
"""See `IUserManager`."""
- for user in store.query(User).all():
- yield user
+ yield from store.query(User).all()
@dbconnection
def create_address(self, store, email, display_name=None):
@@ -152,19 +151,16 @@ class UserManager:
@dbconnection
def addresses(self, store):
"""See `IUserManager`."""
- for address in store.query(Address).all():
- yield address
+ yield from store.query(Address).all()
@property
@dbconnection
def members(self, store):
"""See `IUserManager."""
- for member in store.query(Member).all():
- yield member
+ yield from store.query(Member).all()
@property
@dbconnection
def server_owners(self, store):
""" See `IUserManager."""
- users = store.query(User).filter_by(is_server_owner=True)
- yield from users
+ yield from store.query(User).filter_by(is_server_owner=True)
diff --git a/src/mailman/mta/aliases.py b/src/mailman/mta/aliases.py
index 768f8caac..ae7e70a7f 100644
--- a/src/mailman/mta/aliases.py
+++ b/src/mailman/mta/aliases.py
@@ -48,7 +48,7 @@ class MailTransportAgentAliases:
# Always return
yield mlist.posting_address
for destination in sorted(SUBDESTINATIONS):
- yield '{0}-{1}@{2}'.format(
+ yield '{}-{}@{}'.format(
mlist.list_name, destination, mlist.mail_host)
def destinations(self, mlist):
@@ -56,4 +56,4 @@ class MailTransportAgentAliases:
# Always return
yield mlist.list_name
for destination in sorted(SUBDESTINATIONS):
- yield '{0}-{1}'.format(mlist.list_name, destination)
+ yield '{}-{}'.format(mlist.list_name, destination)
diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py
index ea940dbcf..fa16c1f7f 100644
--- a/src/mailman/testing/helpers.py
+++ b/src/mailman/testing/helpers.py
@@ -220,8 +220,7 @@ class TestableMaster(Master):
@property
def runner_pids(self):
"""The pids of all the child runner processes."""
- for pid in self._started_kids:
- yield pid
+ yield from self._started_kids
diff --git a/src/mailman/testing/mta.py b/src/mailman/testing/mta.py
index a75e49237..9642803e2 100644
--- a/src/mailman/testing/mta.py
+++ b/src/mailman/testing/mta.py
@@ -251,8 +251,7 @@ class ConnectionCountingController(QueueController):
@property
def messages(self):
"""Return all the messages received by the SMTP server."""
- for message in self:
- yield message
+ yield from self
def clear(self):
"""Clear all the messages from the queue."""
diff --git a/src/mailman/utilities/modules.py b/src/mailman/utilities/modules.py
index 3d9f45470..4a506321e 100644
--- a/src/mailman/utilities/modules.py
+++ b/src/mailman/utilities/modules.py
@@ -106,8 +106,7 @@ def find_components(package, interface):
module = sys.modules[module_name]
if not hasattr(module, '__all__'):
continue
- for component in scan_module(module, interface):
- yield component
+ yield from scan_module(module, interface)