diff options
| -rw-r--r-- | src/mailman/chains/base.py | 3 | ||||
| -rw-r--r-- | src/mailman/chains/tests/test_base.py | 18 | ||||
| -rw-r--r-- | src/mailman/config/config.py | 6 | ||||
| -rw-r--r-- | src/mailman/config/tests/test_configuration.py | 15 | ||||
| -rw-r--r-- | src/mailman/core/pipelines.py | 3 | ||||
| -rw-r--r-- | src/mailman/model/bounce.py | 8 | ||||
| -rw-r--r-- | src/mailman/model/domain.py | 7 | ||||
| -rw-r--r-- | src/mailman/model/listmanager.py | 10 | ||||
| -rw-r--r-- | src/mailman/model/mailinglist.py | 11 | ||||
| -rw-r--r-- | src/mailman/model/requests.py | 3 | ||||
| -rw-r--r-- | src/mailman/model/roster.py | 49 | ||||
| -rw-r--r-- | src/mailman/model/subscriptions.py | 17 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_mailinglist.py | 19 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_roster.py | 6 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_subscriptions.py | 2 | ||||
| -rw-r--r-- | src/mailman/model/usermanager.py | 12 | ||||
| -rw-r--r-- | src/mailman/mta/aliases.py | 4 | ||||
| -rw-r--r-- | src/mailman/testing/helpers.py | 3 | ||||
| -rw-r--r-- | src/mailman/testing/mta.py | 3 | ||||
| -rw-r--r-- | src/mailman/utilities/modules.py | 3 |
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) |
