From 36d114b37755ef96c4b0215feabe5095237c15e2 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Wed, 30 Mar 2016 12:07:22 +0200 Subject: Cover another header match import case --- src/mailman/utilities/importer.py | 2 +- src/mailman/utilities/tests/test_import.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py index c908a2ada..b2138cb9b 100644 --- a/src/mailman/utilities/importer.py +++ b/src/mailman/utilities/importer.py @@ -336,7 +336,7 @@ def import_config_pck(mlist, config_dict): for line_pattern in line_patterns.splitlines(): if len(line_pattern.strip()) == 0: continue - for sep in (': ', ':.', ':'): + for sep in (': ', ':.*', ':.', ':'): header, sep, pattern = line_pattern.partition(sep) if sep: # We found it. diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py index d2729e8e1..0d245d594 100644 --- a/src/mailman/utilities/tests/test_import.py +++ b/src/mailman/utilities/tests/test_import.py @@ -336,6 +336,7 @@ class TestBasicImport(unittest.TestCase): ('^Subject: dev-\r\n^Subject: staging-', 3, False), ('from: .*info@aolanchem.com\r\nfrom: .*@jw-express.com', 2, False), + ('^Subject:.*\\Wwas:\\W', 3, False), ('^Received: from smtp-.*\\.fedoraproject\\.org\r\n' '^Received: from mx.*\\.redhat.com\r\n' '^Resent-date:\r\n' @@ -372,6 +373,7 @@ class TestBasicImport(unittest.TestCase): ('subject', 'staging-', 'discard'), ('from', '.*info@aolanchem.com', 'reject'), ('from', '.*@jw-express.com', 'reject'), + ('subject', '\\Wwas:\\W', 'discard'), ('received', 'from smtp-.*\\.fedoraproject\\.org', 'hold'), ('received', 'from mx.*\\.redhat.com', 'hold'), ('resent-date', '.*', 'hold'), -- cgit v1.3.1 From a8f2fc64c683420f40bac1b4c5d551305a0e0ecc Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Mon, 18 Jan 2016 18:25:03 +0100 Subject: Don't show the disabled archivers in the REST API Because one can't add a configuration overlay to the running REST server in testing mode, the prototype archiver was disabled in the testing configuration. This is where most of the changes in this commit come from. --- src/mailman/rest/docs/lists.rst | 4 ---- src/mailman/rest/lists.py | 6 ++++-- src/mailman/rest/tests/test_lists.py | 10 ++++------ src/mailman/testing/testing.cfg | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/mailman/rest/docs/lists.rst b/src/mailman/rest/docs/lists.rst index 6554b04c2..0fb877722 100644 --- a/src/mailman/rest/docs/lists.rst +++ b/src/mailman/rest/docs/lists.rst @@ -250,7 +250,6 @@ archivers are available, and whether they are enabled for this mailing list. http_etag: "..." mail-archive: True mhonarc: True - prototype: True You can set all the archiver states by putting new state flags on the resource. @@ -260,7 +259,6 @@ resource. ... 'http://localhost:9001/3.0/lists/dog@example.com/archivers', { ... 'mail-archive': False, ... 'mhonarc': True, - ... 'prototype': False, ... }, method='PUT') content-length: 0 date: ... @@ -271,7 +269,6 @@ resource. http_etag: "..." mail-archive: False mhonarc: True - prototype: False You can change the state of a subset of the list archivers. :: @@ -289,7 +286,6 @@ You can change the state of a subset of the list archivers. http_etag: "..." mail-archive: False mhonarc: False - prototype: False List digests diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py index c3919c001..8e82cd1a4 100644 --- a/src/mailman/rest/lists.py +++ b/src/mailman/rest/lists.py @@ -330,13 +330,15 @@ class ListArchivers: """Get all the archiver statuses.""" archiver_set = IListArchiverSet(self._mlist) resource = {archiver.name: archiver.is_enabled - for archiver in archiver_set.archivers} + for archiver in archiver_set.archivers + if archiver.system_archiver.is_enabled} okay(response, etag(resource)) def patch_put(self, request, response, is_optional): archiver_set = IListArchiverSet(self._mlist) kws = {archiver.name: ArchiverGetterSetter(self._mlist) - for archiver in archiver_set.archivers} + for archiver in archiver_set.archivers + if archiver.system_archiver.is_enabled} if is_optional: # For a PATCH, all attributes are optional. kws['_optional'] = kws.keys() diff --git a/src/mailman/rest/tests/test_lists.py b/src/mailman/rest/tests/test_lists.py index 787009855..d83f70058 100644 --- a/src/mailman/rest/tests/test_lists.py +++ b/src/mailman/rest/tests/test_lists.py @@ -32,7 +32,7 @@ from mailman.interfaces.usermanager import IUserManager from mailman.model.mailinglist import AcceptableAlias from mailman.runners.digest import DigestRunner from mailman.testing.helpers import ( - call_api, get_queue_messages, make_testable_runner, + call_api, configuration, get_queue_messages, make_testable_runner, specialized_message_from_string as mfs) from mailman.testing.layers import RESTLayer from mailman.utilities.datetime import now as right_now @@ -339,7 +339,6 @@ class TestListArchivers(unittest.TestCase): self.assertEqual(resource, { 'mail-archive': True, 'mhonarc': True, - 'prototype': True, }) def test_archiver_statuses_on_missing_lists(self): @@ -375,7 +374,7 @@ class TestListArchivers(unittest.TestCase): def test_put_incomplete_statuses(self): # PUT requires the full resource representation. This one forgets to - # specify the prototype and mhonarc archiver. + # specify the mhonarc archiver. with self.assertRaises(HTTPError) as cm: call_api( 'http://localhost:9001/3.0/lists/ant.example.com/archivers', { @@ -384,7 +383,7 @@ class TestListArchivers(unittest.TestCase): method='PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Missing parameters: mhonarc, prototype') + b'Missing parameters: mhonarc') def test_patch_bogus_status(self): # Archiver statuses must be interpretable as booleans. @@ -392,8 +391,7 @@ class TestListArchivers(unittest.TestCase): call_api( 'http://localhost:9001/3.0/lists/ant.example.com/archivers', { 'mail-archive': 'sure', - 'mhonarc': False, - 'prototype': 'no' + 'mhonarc': 'no' }, method='PATCH') self.assertEqual(cm.exception.code, 400) diff --git a/src/mailman/testing/testing.cfg b/src/mailman/testing/testing.cfg index 022f9f289..8b6a48c36 100644 --- a/src/mailman/testing/testing.cfg +++ b/src/mailman/testing/testing.cfg @@ -65,7 +65,7 @@ max_restarts: 1 max_restarts: 1 [archiver.prototype] -enable: yes +enable: no [archiver.mail_archive] enable: yes -- cgit v1.3.1 From accc4f1a883d4a5757eb9b0156e58e72b77a8af7 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Thu, 21 Jan 2016 11:46:49 +0100 Subject: Fix tests --- src/mailman/config/tests/test_archivers.py | 6 +++--- src/mailman/model/tests/test_mailinglist.py | 14 +++++++------- src/mailman/rest/tests/test_lists.py | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mailman/config/tests/test_archivers.py b/src/mailman/config/tests/test_archivers.py index 322a5040d..b09b89273 100644 --- a/src/mailman/config/tests/test_archivers.py +++ b/src/mailman/config/tests/test_archivers.py @@ -28,11 +28,11 @@ class TestArchivers(unittest.TestCase): layer = ConfigLayer def test_enabled(self): - # By default, the testing configuration enables the archivers. + # By default, the testing configuration enables some archivers. archivers = {} for archiver in config.archivers: archivers[archiver.name] = archiver - self.assertTrue(archivers['prototype'].is_enabled) + self.assertFalse(archivers['prototype'].is_enabled) self.assertTrue(archivers['mail-archive'].is_enabled) self.assertTrue(archivers['mhonarc'].is_enabled) @@ -42,6 +42,6 @@ class TestArchivers(unittest.TestCase): archivers = {} for archiver in config.archivers: archivers[archiver.name] = archiver - self.assertTrue(archivers['prototype'].is_enabled) + self.assertFalse(archivers['prototype'].is_enabled) self.assertTrue(archivers['mail-archive'].is_enabled) self.assertFalse(archivers['mhonarc'].is_enabled) diff --git a/src/mailman/model/tests/test_mailinglist.py b/src/mailman/model/tests/test_mailinglist.py index c9aecc93b..0f37fa2f3 100644 --- a/src/mailman/model/tests/test_mailinglist.py +++ b/src/mailman/model/tests/test_mailinglist.py @@ -108,11 +108,11 @@ class TestListArchiver(unittest.TestCase): def test_get_archiver(self): # Use .get() to see if a mailing list has an archiver. - archiver = self._set.get('prototype') - self.assertEqual(archiver.name, 'prototype') + archiver = self._set.get('mhonarc') + self.assertEqual(archiver.name, 'mhonarc') self.assertTrue(archiver.is_enabled) self.assertEqual(archiver.mailing_list, self._mlist) - self.assertEqual(archiver.system_archiver.name, 'prototype') + self.assertEqual(archiver.system_archiver.name, 'mhonarc') def test_get_archiver_no_such(self): # Using .get() on a non-existing name returns None. @@ -124,15 +124,15 @@ class TestListArchiver(unittest.TestCase): # then the site-wide archiver gets disabled, so the list specific # archiver will also be disabled. archiver_set = IListArchiverSet(self._mlist) - archiver = archiver_set.get('prototype') + archiver = archiver_set.get('mhonarc') self.assertTrue(archiver.is_enabled) # Disable the site-wide archiver. - config.push('enable prototype', """\ - [archiver.prototype] + config.push('enable mhonarc', """\ + [archiver.mhonarc] enable: no """) self.assertFalse(archiver.is_enabled) - config.pop('enable prototype') + config.pop('enable mhonarc') class TestDisabledListArchiver(unittest.TestCase): diff --git a/src/mailman/rest/tests/test_lists.py b/src/mailman/rest/tests/test_lists.py index d83f70058..3bee23314 100644 --- a/src/mailman/rest/tests/test_lists.py +++ b/src/mailman/rest/tests/test_lists.py @@ -32,7 +32,7 @@ from mailman.interfaces.usermanager import IUserManager from mailman.model.mailinglist import AcceptableAlias from mailman.runners.digest import DigestRunner from mailman.testing.helpers import ( - call_api, configuration, get_queue_messages, make_testable_runner, + call_api, get_queue_messages, make_testable_runner, specialized_message_from_string as mfs) from mailman.testing.layers import RESTLayer from mailman.utilities.datetime import now as right_now -- cgit v1.3.1 From 228e70d799ab9e37ed0d42dd96b9126d77e20d45 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 09:43:49 -0500 Subject: Start porting to Python 3.6 --- BREAKS.rst | 5 +++++ src/mailman/handlers/subject_prefix.py | 2 +- tox.ini | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 BREAKS.rst diff --git a/BREAKS.rst b/BREAKS.rst new file mode 100644 index 000000000..020126ad1 --- /dev/null +++ b/BREAKS.rst @@ -0,0 +1,5 @@ +====================== + Python 3.6 breakages +====================== + +* https://bugs.python.org/issue27030 diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index ff728d92e..5dcfe410a 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -158,7 +158,7 @@ class SubjectPrefix: prefix_pattern = re.escape(prefix) # Unescape '%'. prefix_pattern = '%'.join(prefix_pattern.split(r'\%')) - p = re.compile('%\d*d') + p = re.compile(r'%\d*d') if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. diff --git a/tox.ini b/tox.ini index c015cc699..7892b557a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py34,py35}{,-coverage,-diffcov}{,-pg}{,-mysql},qa +envlist = {py34,py35,py36}{,-coverage,-diffcov}{,-pg}{,-mysql},qa recreate = True skip_missing_interpreters = True -- cgit v1.3.1 From 2ca7f91cf4a95cfb91152d0cb8fa342e1883b534 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 13:22:25 -0500 Subject: Back out the last change. --- src/mailman/handlers/subject_prefix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index 5dcfe410a..ff728d92e 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -158,7 +158,7 @@ class SubjectPrefix: prefix_pattern = re.escape(prefix) # Unescape '%'. prefix_pattern = '%'.join(prefix_pattern.split(r'\%')) - p = re.compile(r'%\d*d') + p = re.compile('%\d*d') if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. -- cgit v1.3.1 From 40b586facc07f71be4fd65a1b06af93681ba0441 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 15:52:34 -0500 Subject: A couple of fixes for Python 3.6 --- src/mailman/handlers/subject_prefix.py | 2 +- src/mailman/testing/mta.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index ff728d92e..20f47fc5d 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -162,7 +162,7 @@ class SubjectPrefix: if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. - prefix_pattern = p.sub(r'\s*\d+\s*', prefix_pattern) + prefix_pattern = p.sub(r'\\s*\\d+\\s*', prefix_pattern) # Substitute %d in prefix with post_id with suppress(TypeError): prefix = prefix % mlist.post_id diff --git a/src/mailman/testing/mta.py b/src/mailman/testing/mta.py index c1327f428..fbbb890d8 100644 --- a/src/mailman/testing/mta.py +++ b/src/mailman/testing/mta.py @@ -183,7 +183,7 @@ class ConnectionCountingServer(QueueServer): log.info('[ConnectionCountingServer] accepted: %s', address) StatisticsChannel(self, connection, address) - def process_message(self, peer, mailfrom, rcpttos, data): + def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): # Provide a guaranteed order to recpttos. QueueServer.process_message( self, peer, mailfrom, sorted(rcpttos), data) -- cgit v1.3.1 From 2bcab3d589de9b16ca7b9405b452fd47e2c094b0 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 09:43:49 -0500 Subject: Start porting to Python 3.6 --- BREAKS.rst | 5 +++++ src/mailman/handlers/subject_prefix.py | 2 +- tox.ini | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 BREAKS.rst diff --git a/BREAKS.rst b/BREAKS.rst new file mode 100644 index 000000000..020126ad1 --- /dev/null +++ b/BREAKS.rst @@ -0,0 +1,5 @@ +====================== + Python 3.6 breakages +====================== + +* https://bugs.python.org/issue27030 diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index ff728d92e..5dcfe410a 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -158,7 +158,7 @@ class SubjectPrefix: prefix_pattern = re.escape(prefix) # Unescape '%'. prefix_pattern = '%'.join(prefix_pattern.split(r'\%')) - p = re.compile('%\d*d') + p = re.compile(r'%\d*d') if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. diff --git a/tox.ini b/tox.ini index c015cc699..7892b557a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py34,py35}{,-coverage,-diffcov}{,-pg}{,-mysql},qa +envlist = {py34,py35,py36}{,-coverage,-diffcov}{,-pg}{,-mysql},qa recreate = True skip_missing_interpreters = True -- cgit v1.3.1 From f638cc15a9db75c2a97758d67e5829293e8765bf Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 13:22:25 -0500 Subject: Back out the last change. --- src/mailman/handlers/subject_prefix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index 5dcfe410a..ff728d92e 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -158,7 +158,7 @@ class SubjectPrefix: prefix_pattern = re.escape(prefix) # Unescape '%'. prefix_pattern = '%'.join(prefix_pattern.split(r'\%')) - p = re.compile(r'%\d*d') + p = re.compile('%\d*d') if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. -- cgit v1.3.1 From 867c7e562b82015a4fd38b45e875691cb06ea134 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 22 Nov 2016 15:52:34 -0500 Subject: A couple of fixes for Python 3.6 --- src/mailman/handlers/subject_prefix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index ff728d92e..20f47fc5d 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -162,7 +162,7 @@ class SubjectPrefix: if p.search(prefix, 1): # The prefix has number, so we should search prefix w/number in # subject. Also, force new style. - prefix_pattern = p.sub(r'\s*\d+\s*', prefix_pattern) + prefix_pattern = p.sub(r'\\s*\\d+\\s*', prefix_pattern) # Substitute %d in prefix with post_id with suppress(TypeError): prefix = prefix % mlist.post_id -- cgit v1.3.1 From ffc8ed1347121079c047ec454f94e27bf54a9d42 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Fri, 25 Nov 2016 09:05:26 -0500 Subject: Handle a Python 3.6 difference in interact(). Also: * Fix a regexp that 3.6 raises an exception on. * Remove a deprecated attribute from passlib.cfg. --- src/mailman/config/passlib.cfg | 1 - src/mailman/utilities/interact.py | 9 ++++++++- src/mailman/utilities/tests/test_import.py | 7 ++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/mailman/config/passlib.cfg b/src/mailman/config/passlib.cfg index 805f0fb11..0564f9eb3 100644 --- a/src/mailman/config/passlib.cfg +++ b/src/mailman/config/passlib.cfg @@ -3,7 +3,6 @@ # See http://packages.python.org/passlib/index.html for details. schemes = sha512_crypt, sha256_crypt default = sha512_crypt -all__vary_rounds = 0.1 sha256_crypt__min_rounds = 80000 sha512_crypt__min_rounds = 60000 admin__sha256_crypt__min_rounds = 160000 diff --git a/src/mailman/utilities/interact.py b/src/mailman/utilities/interact.py index fec980b80..ac1612156 100644 --- a/src/mailman/utilities/interact.py +++ b/src/mailman/utilities/interact.py @@ -22,6 +22,7 @@ import sys import code from contextlib import suppress +from inspect import signature from mailman import public @@ -67,4 +68,10 @@ def interact(upframe=True, banner=DEFAULT_BANNER, overrides=None): Python %s on %s Type "help", "copyright", "credits" or "license" for more information.''' % ( sys.version, sys.platform) - interp.interact(banner) + # Python 3.6 added an exitmsg keyword but we don't currently support + # configuring it. For consistency between Python 3.6 and earlier + # versions, suppress the exit message if possible. + kws = dict(banner=banner) + if 'exitmsg' in signature(interp.interact).parameters: + kws['exitmsg'] = '' + interp.interact(**kws) diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py index ca3a4afb7..5a226ba26 100644 --- a/src/mailman/utilities/tests/test_import.py +++ b/src/mailman/utilities/tests/test_import.py @@ -65,6 +65,7 @@ def list_to_string(data): class TestBasicImport(unittest.TestCase): layer = ConfigLayer + maxDiff = None def setUp(self): self._mlist = create_list('blank@example.com') @@ -322,12 +323,12 @@ class TestBasicImport(unittest.TestCase): SubscriptionPolicy.confirm_then_moderate) def test_header_matches(self): - # This test contail real cases of header_filter_rules + # This test containes real cases of header_filter_rules. self._pckdict['header_filter_rules'] = [ ('X\\-Spam\\-Status\\: Yes.*', 3, False), ('^X-Spam-Status: Yes\r\n\r\n', 2, False), ('^X-Spam-Level: \\*\\*\\*.*$', 3, False), - ('^X-Spam-Level:.\\*\\*\r\n^X-Spam:.\\Yes', 3, False), + ('^X-Spam-Level:.\\*\\*\r\n^X-Spam:.Yes', 3, False), ('Subject: \\[SPAM\\].*', 3, False), ('^Subject: .*loan.*', 3, False), ('Original-Received: from *linkedin.com*\r\n', 3, False), @@ -362,7 +363,7 @@ class TestBasicImport(unittest.TestCase): ('x-spam-status', 'Yes', 'reject'), ('x-spam-level', '\\*\\*\\*.*$', 'discard'), ('x-spam-level', '\\*\\*', 'discard'), - ('x-spam', '\\Yes', 'discard'), + ('x-spam', 'Yes', 'discard'), ('subject', '\\[SPAM\\].*', 'discard'), ('subject', '.*loan.*', 'discard'), ('original-received', 'from *linkedin.com*', 'discard'), -- cgit v1.3.1 From 86162ef47bbf9ab71faceed9eaa656ebb8e1ec63 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Sat, 26 Nov 2016 00:06:55 -0500 Subject: NEWS. --- src/mailman/docs/NEWS.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index 27f3ea5eb..26d7433c3 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -245,6 +245,8 @@ REST Aurélien Bompard. (Closes #284) * Query parameters now allow you to filter mailing lists by the ``advertised`` boolean parameter. Given by Aurélien Bompard. + * Only the system-enabled archivers are returned in the REST API. Given by + Aurélien Bompard. Other ----- -- cgit v1.3.1 From b9250ebdefaae0ca98324cf42e4dd51ad550d839 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Mon, 28 Nov 2016 17:22:28 -0500 Subject: Officially support Python 3.6. Closes #295 --- .gitlab-ci.yml | 6 +++--- src/mailman/docs/NEWS.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 94f8b1de7..8630fe549 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,13 +21,13 @@ docs: sqlite: script: - - tox -e py34,py35 + - tox -e py34,py35,py36 pgsql: services: - postgres:latest script: - - MAILMAN_EXTRA_TESTING_CFG=/home/runner/configs/postgres.cfg tox -e py34-pg,py35-pg + - MAILMAN_EXTRA_TESTING_CFG=/home/runner/configs/postgres.cfg tox -e py34-pg,py35-pg,py36-pg tags: - postgres @@ -35,6 +35,6 @@ mysql: services: - mysql:latest script: - - MAILMAN_EXTRA_TESTING_CFG=/home/runner/configs/mysql.cfg tox -e py34-mysql,py35-mysql + - MAILMAN_EXTRA_TESTING_CFG=/home/runner/configs/mysql.cfg tox -e py34-mysql,py35-mysql,py36-mysql tags: - mysql diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index 26d7433c3..1841f8fb7 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -151,6 +151,7 @@ Interfaces Internal -------- + * Add official support for Python 3.6. (Closes #295) * A handful of unused legacy exceptions have been removed. The redundant `MailmanException` has been removed; use `MailmanError` everywhere. * Drop the use of the `lazr.smtptest` library, which is based on the -- cgit v1.3.1 From f977a1a815460042baeb9704bc25c8a8e75652a4 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Fri, 20 Nov 2015 08:17:36 +0100 Subject: Fix the email senders list when there's a Header instance The mailman.email.Message.senders property would fail when one of the headers was an email.header.Header instance. --- src/mailman/email/message.py | 7 ++++--- src/mailman/email/tests/test_message.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py index ebfef9d9b..26bc35b78 100644 --- a/src/mailman/email/message.py +++ b/src/mailman/email/message.py @@ -93,9 +93,10 @@ class Message(email.message.Message): if envelope_sender is not None else '') else: - field_values = self.get_all(header, []) - senders.extend(address.lower() for (display_name, address) - in email.utils.getaddresses(field_values)) + for field_value in self.get_all(header, []): + # Convert the header to str in case it's a Header instance. + name, address = email.utils.parseaddr(str(field_value)) + senders.append(address.lower()) # Filter out None and the empty string, and convert to unicode. clean_senders = [] for sender in senders: diff --git a/src/mailman/email/tests/test_message.py b/src/mailman/email/tests/test_message.py index 3ec099904..c23d37f7f 100644 --- a/src/mailman/email/tests/test_message.py +++ b/src/mailman/email/tests/test_message.py @@ -19,6 +19,7 @@ import unittest +from email.header import Header from email.parser import FeedParser from mailman.app.lifecycle import create_list from mailman.email.message import Message, UserNotification @@ -52,6 +53,9 @@ class TestMessage(unittest.TestCase): class TestMessageSubclass(unittest.TestCase): + + layer = ConfigLayer + def test_i18n_filenames(self): parser = FeedParser(_factory=Message) parser.feed("""\ @@ -79,3 +83,9 @@ Test content except TypeError as error: self.fail(error) self.assertEqual(filename, u'd\xe9jeuner.txt') + + def test_senders_header_instances(self): + msg = Message() + msg['From'] = Header('test@example.com') + # Make sure the senders property does not fail + self.assertEqual(msg.senders, ["test@example.com"]) -- cgit v1.3.1 From 432088db522219d6caa6c2cfede3df45acb6f3e0 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Fri, 20 Nov 2015 08:33:34 +0100 Subject: Fix a crash with the no_subject rule and Header instances --- src/mailman/rules/no_subject.py | 4 ++- src/mailman/rules/tests/test_no_subject.py | 57 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/mailman/rules/tests/test_no_subject.py diff --git a/src/mailman/rules/no_subject.py b/src/mailman/rules/no_subject.py index 4b53067a5..e6a3be6ed 100644 --- a/src/mailman/rules/no_subject.py +++ b/src/mailman/rules/no_subject.py @@ -34,5 +34,7 @@ class NoSubject: def check(self, mlist, msg, msgdata): """See `IRule`.""" - subject = msg.get('subject', '').strip() + # Convert the header value to string because it may be an + # email.header.Header instance. + subject = str(msg.get('subject', '')).strip() return subject == '' diff --git a/src/mailman/rules/tests/test_no_subject.py b/src/mailman/rules/tests/test_no_subject.py new file mode 100644 index 000000000..1647f96d5 --- /dev/null +++ b/src/mailman/rules/tests/test_no_subject.py @@ -0,0 +1,57 @@ +# Copyright (C) 2015 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see . + +"""Test the `no_subject` header rule.""" + +__all__ = [ + 'TestNoSubject', + ] + + +import os +import unittest +from email.header import Header + +from mailman.app.lifecycle import create_list +from mailman.email.message import Message +from mailman.rules import no_subject +from mailman.testing.layers import ConfigLayer + + + +class TestNoSubject(unittest.TestCase): + """Test the no_subject rule.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + self._rule = no_subject.NoSubject() + + def test_header_instance_empty(self): + # Check the case where the subject is a Header instance + msg = Message() + msg["Subject"] = Header("") + result = self._rule.check(self._mlist, msg, {}) + self.assertTrue(result) + + def test_header_instance_not_empty(self): + # Check the case where the subject is a Header instance + msg = Message() + msg["Subject"] = Header("Test subject") + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) -- cgit v1.3.1 From b570b76724c6341921ebe531071904df312d39e6 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Fri, 20 Nov 2015 09:11:56 +0100 Subject: Fix a crash with the suspicious rule and Header instances --- src/mailman/rules/suspicious.py | 4 ++- src/mailman/rules/tests/test_suspicious.py | 52 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/mailman/rules/tests/test_suspicious.py diff --git a/src/mailman/rules/suspicious.py b/src/mailman/rules/suspicious.py index f349a313e..acb17334a 100644 --- a/src/mailman/rules/suspicious.py +++ b/src/mailman/rules/suspicious.py @@ -87,6 +87,8 @@ def has_matching_bounce_header(mlist, msg): """ for header, cre, line in _parse_matching_header_opt(mlist): for value in msg.get_all(header, []): - if cre.search(value): + # Convert the header value to string because it may be an + # email.header.Header instance. + if cre.search(str(value)): return True return False diff --git a/src/mailman/rules/tests/test_suspicious.py b/src/mailman/rules/tests/test_suspicious.py new file mode 100644 index 000000000..1be0eb8e7 --- /dev/null +++ b/src/mailman/rules/tests/test_suspicious.py @@ -0,0 +1,52 @@ +# Copyright (C) 2015 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see . + +"""Test the `suspicious` rule.""" + +__all__ = [ + 'TestSuspicious', + ] + + +import os +import unittest +from email.header import Header + +from mailman.app.lifecycle import create_list +from mailman.email.message import Message +from mailman.rules import suspicious +from mailman.testing.layers import ConfigLayer + + + +class TestSuspicious(unittest.TestCase): + """Test the suspicous rule.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + self._rule = suspicious.SuspiciousHeader() + + def test_header_instance(self): + # Check the case where the subject is a Header instance + msg = Message() + msg["From"] = Header("user@example.com") + self._mlist.bounce_matching_headers = 'from: spam@example.com' + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) + -- cgit v1.3.1 From b521d6739edda8737fb784536d9282fbc708e3e2 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Fri, 20 Nov 2015 11:54:31 +0100 Subject: Learn to encode Messages and Header instances to JSON --- src/mailman/rest/helpers.py | 6 ++++++ src/mailman/rest/tests/test_helpers.py | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 9ab1f434e..a4b072408 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -23,6 +23,8 @@ import hashlib from contextlib import suppress from datetime import datetime, timedelta +from email.header import Header +from email.message import Message from enum import Enum from lazr.config import as_boolean from mailman import public @@ -49,6 +51,10 @@ class ExtendedEncoder(json.JSONEncoder): return obj.name elif isinstance(obj, bytes): return bytes_to_str(obj) + elif isinstance(obj, Message): + return obj.as_string() + elif isinstance(obj, Header): + return str(obj) return super().default(obj) diff --git a/src/mailman/rest/tests/test_helpers.py b/src/mailman/rest/tests/test_helpers.py index 982b97ef3..31ed8c88b 100644 --- a/src/mailman/rest/tests/test_helpers.py +++ b/src/mailman/rest/tests/test_helpers.py @@ -17,11 +17,14 @@ """Additional tests for helpers.""" +import json import unittest +from email.message import Message +from email.header import Header from datetime import timedelta from mailman.rest import helpers -from mailman.testing.layers import ConfigLayer +from mailman.testing.layers import ConfigLayer, RESTLayer class FakeResponse: @@ -74,3 +77,31 @@ class TestHelpers(unittest.TestCase): def test_json_encoding_default(self): resource = dict(interval=Unserializable()) self.assertRaises(TypeError, helpers.etag, resource) + + + +class TestJSONEncoder(unittest.TestCase): + """Test the JSON ExtendedEncoder.""" + + layer = RESTLayer + + def test_encode_message(self): + msg = Message() + msg['From'] = 'test@example.com' + msg.set_payload('Test content.') + try: + result = json.dumps(msg, cls=helpers.ExtendedEncoder) + except TypeError as e: + self.fail(e) + self.assertEqual(result, + json.dumps('From: test@example.com\n\nTest content.')) + + def test_encode_header(self): + value = 'Contains non-ascii \u00e9 \u00e7 \u00e0' + header = Header(value, charset='utf-8') + try: + result = json.dumps(Header(value, charset='utf-8'), + cls=helpers.ExtendedEncoder) + except TypeError as e: + self.fail(e) + self.assertEqual(result, json.dumps(value)) -- cgit v1.3.1 From 8ee8a7d2cb598138aeadfebe8eb5cc3f8fb2d88a Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Tue, 24 May 2016 10:50:41 +0200 Subject: Fix Flake8 errors --- src/mailman/rest/tests/test_helpers.py | 15 +++++++-------- src/mailman/rules/tests/test_no_subject.py | 8 +------- src/mailman/rules/tests/test_suspicious.py | 9 +-------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/mailman/rest/tests/test_helpers.py b/src/mailman/rest/tests/test_helpers.py index 31ed8c88b..3f19a9e5e 100644 --- a/src/mailman/rest/tests/test_helpers.py +++ b/src/mailman/rest/tests/test_helpers.py @@ -20,9 +20,9 @@ import json import unittest -from email.message import Message -from email.header import Header from datetime import timedelta +from email.header import Header +from email.message import Message from mailman.rest import helpers from mailman.testing.layers import ConfigLayer, RESTLayer @@ -79,7 +79,6 @@ class TestHelpers(unittest.TestCase): self.assertRaises(TypeError, helpers.etag, resource) - class TestJSONEncoder(unittest.TestCase): """Test the JSON ExtendedEncoder.""" @@ -93,15 +92,15 @@ class TestJSONEncoder(unittest.TestCase): result = json.dumps(msg, cls=helpers.ExtendedEncoder) except TypeError as e: self.fail(e) - self.assertEqual(result, - json.dumps('From: test@example.com\n\nTest content.')) + self.assertEqual( + result, json.dumps('From: test@example.com\n\nTest content.')) def test_encode_header(self): value = 'Contains non-ascii \u00e9 \u00e7 \u00e0' - header = Header(value, charset='utf-8') try: - result = json.dumps(Header(value, charset='utf-8'), - cls=helpers.ExtendedEncoder) + result = json.dumps( + Header(value, charset='utf-8'), + cls=helpers.ExtendedEncoder) except TypeError as e: self.fail(e) self.assertEqual(result, json.dumps(value)) diff --git a/src/mailman/rules/tests/test_no_subject.py b/src/mailman/rules/tests/test_no_subject.py index 1647f96d5..efe942af6 100644 --- a/src/mailman/rules/tests/test_no_subject.py +++ b/src/mailman/rules/tests/test_no_subject.py @@ -17,22 +17,16 @@ """Test the `no_subject` header rule.""" -__all__ = [ - 'TestNoSubject', - ] - -import os import unittest -from email.header import Header +from email.header import Header from mailman.app.lifecycle import create_list from mailman.email.message import Message from mailman.rules import no_subject from mailman.testing.layers import ConfigLayer - class TestNoSubject(unittest.TestCase): """Test the no_subject rule.""" diff --git a/src/mailman/rules/tests/test_suspicious.py b/src/mailman/rules/tests/test_suspicious.py index 1be0eb8e7..e1649928c 100644 --- a/src/mailman/rules/tests/test_suspicious.py +++ b/src/mailman/rules/tests/test_suspicious.py @@ -17,22 +17,16 @@ """Test the `suspicious` rule.""" -__all__ = [ - 'TestSuspicious', - ] - -import os import unittest -from email.header import Header +from email.header import Header from mailman.app.lifecycle import create_list from mailman.email.message import Message from mailman.rules import suspicious from mailman.testing.layers import ConfigLayer - class TestSuspicious(unittest.TestCase): """Test the suspicous rule.""" @@ -49,4 +43,3 @@ class TestSuspicious(unittest.TestCase): self._mlist.bounce_matching_headers = 'from: spam@example.com' result = self._rule.check(self._mlist, msg, {}) self.assertFalse(result) - -- cgit v1.3.1 From da0789ceedbeddcae6b47545c115f5e659de019d Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Mon, 28 Nov 2016 17:19:18 -0500 Subject: Starting to clean up the branch. --- src/mailman/email/tests/test_message.py | 3 +-- src/mailman/rest/tests/test_helpers.py | 15 ++++----------- src/mailman/rules/no_subject.py | 2 +- src/mailman/rules/suspicious.py | 2 +- src/mailman/rules/tests/test_no_subject.py | 9 +++------ src/mailman/rules/tests/test_suspicious.py | 7 +++---- 6 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/mailman/email/tests/test_message.py b/src/mailman/email/tests/test_message.py index c23d37f7f..461659865 100644 --- a/src/mailman/email/tests/test_message.py +++ b/src/mailman/email/tests/test_message.py @@ -53,7 +53,6 @@ class TestMessage(unittest.TestCase): class TestMessageSubclass(unittest.TestCase): - layer = ConfigLayer def test_i18n_filenames(self): @@ -88,4 +87,4 @@ Test content msg = Message() msg['From'] = Header('test@example.com') # Make sure the senders property does not fail - self.assertEqual(msg.senders, ["test@example.com"]) + self.assertEqual(msg.senders, ['test@example.com']) diff --git a/src/mailman/rest/tests/test_helpers.py b/src/mailman/rest/tests/test_helpers.py index 3f19a9e5e..07ae784c8 100644 --- a/src/mailman/rest/tests/test_helpers.py +++ b/src/mailman/rest/tests/test_helpers.py @@ -81,26 +81,19 @@ class TestHelpers(unittest.TestCase): class TestJSONEncoder(unittest.TestCase): """Test the JSON ExtendedEncoder.""" - layer = RESTLayer def test_encode_message(self): msg = Message() msg['From'] = 'test@example.com' msg.set_payload('Test content.') - try: - result = json.dumps(msg, cls=helpers.ExtendedEncoder) - except TypeError as e: - self.fail(e) + result = json.dumps(msg, cls=helpers.ExtendedEncoder) self.assertEqual( result, json.dumps('From: test@example.com\n\nTest content.')) def test_encode_header(self): value = 'Contains non-ascii \u00e9 \u00e7 \u00e0' - try: - result = json.dumps( - Header(value, charset='utf-8'), - cls=helpers.ExtendedEncoder) - except TypeError as e: - self.fail(e) + result = json.dumps( + Header(value, charset='utf-8'), + cls=helpers.ExtendedEncoder) self.assertEqual(result, json.dumps(value)) diff --git a/src/mailman/rules/no_subject.py b/src/mailman/rules/no_subject.py index e6a3be6ed..ed020b81e 100644 --- a/src/mailman/rules/no_subject.py +++ b/src/mailman/rules/no_subject.py @@ -34,7 +34,7 @@ class NoSubject: def check(self, mlist, msg, msgdata): """See `IRule`.""" - # Convert the header value to string because it may be an + # Convert the header value to a str because it may be an # email.header.Header instance. subject = str(msg.get('subject', '')).strip() return subject == '' diff --git a/src/mailman/rules/suspicious.py b/src/mailman/rules/suspicious.py index acb17334a..679605fd6 100644 --- a/src/mailman/rules/suspicious.py +++ b/src/mailman/rules/suspicious.py @@ -87,7 +87,7 @@ def has_matching_bounce_header(mlist, msg): """ for header, cre, line in _parse_matching_header_opt(mlist): for value in msg.get_all(header, []): - # Convert the header value to string because it may be an + # Convert the header value to a str because it may be an # email.header.Header instance. if cre.search(str(value)): return True diff --git a/src/mailman/rules/tests/test_no_subject.py b/src/mailman/rules/tests/test_no_subject.py index efe942af6..0155e25ee 100644 --- a/src/mailman/rules/tests/test_no_subject.py +++ b/src/mailman/rules/tests/test_no_subject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 by the Free Software Foundation, Inc. +# Copyright (C) 2016 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,7 +17,6 @@ """Test the `no_subject` header rule.""" - import unittest from email.header import Header @@ -37,15 +36,13 @@ class TestNoSubject(unittest.TestCase): self._rule = no_subject.NoSubject() def test_header_instance_empty(self): - # Check the case where the subject is a Header instance msg = Message() - msg["Subject"] = Header("") + msg['Subject'] = Header('') result = self._rule.check(self._mlist, msg, {}) self.assertTrue(result) def test_header_instance_not_empty(self): - # Check the case where the subject is a Header instance msg = Message() - msg["Subject"] = Header("Test subject") + msg['Subject'] = Header('Test subject') result = self._rule.check(self._mlist, msg, {}) self.assertFalse(result) diff --git a/src/mailman/rules/tests/test_suspicious.py b/src/mailman/rules/tests/test_suspicious.py index e1649928c..441fb0b48 100644 --- a/src/mailman/rules/tests/test_suspicious.py +++ b/src/mailman/rules/tests/test_suspicious.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 by the Free Software Foundation, Inc. +# Copyright (C) 2016 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -28,7 +28,7 @@ from mailman.testing.layers import ConfigLayer class TestSuspicious(unittest.TestCase): - """Test the suspicous rule.""" + """Test the suspicious rule.""" layer = ConfigLayer @@ -37,9 +37,8 @@ class TestSuspicious(unittest.TestCase): self._rule = suspicious.SuspiciousHeader() def test_header_instance(self): - # Check the case where the subject is a Header instance msg = Message() - msg["From"] = Header("user@example.com") + msg['From'] = Header('user@example.com') self._mlist.bounce_matching_headers = 'from: spam@example.com' result = self._rule.check(self._mlist, msg, {}) self.assertFalse(result) -- cgit v1.3.1 From cb498d3e960af6c741fac9896d8a60bab9f79865 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Mon, 28 Nov 2016 21:06:35 -0500 Subject: Remove cruft. --- BREAKS.rst | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 BREAKS.rst diff --git a/BREAKS.rst b/BREAKS.rst deleted file mode 100644 index 020126ad1..000000000 --- a/BREAKS.rst +++ /dev/null @@ -1,5 +0,0 @@ -====================== - Python 3.6 breakages -====================== - -* https://bugs.python.org/issue27030 -- cgit v1.3.1 From fe22ebdb98d125db840c980cbd953a8fbc2e5cdf Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 29 Nov 2016 18:51:05 -0500 Subject: Use `atpublic` for @public instead of internal copy. --- setup.py | 1 + src/mailman/__init__.py | 14 -------------- src/mailman/app/bounces.py | 2 +- src/mailman/app/commands.py | 2 +- src/mailman/app/digests.py | 2 +- src/mailman/app/domain.py | 2 +- src/mailman/app/events.py | 2 +- src/mailman/app/inject.py | 2 +- src/mailman/app/lifecycle.py | 2 +- src/mailman/app/membership.py | 2 +- src/mailman/app/moderator.py | 2 +- src/mailman/app/notifications.py | 2 +- src/mailman/app/replybot.py | 2 +- src/mailman/app/subscriptions.py | 2 +- src/mailman/app/workflow.py | 2 +- src/mailman/archiving/mailarchive.py | 2 +- src/mailman/archiving/mhonarc.py | 2 +- src/mailman/archiving/prototype.py | 2 +- src/mailman/bin/mailman.py | 2 +- src/mailman/bin/master.py | 2 +- src/mailman/bin/runner.py | 2 +- src/mailman/chains/accept.py | 2 +- src/mailman/chains/base.py | 2 +- src/mailman/chains/builtin.py | 2 +- src/mailman/chains/discard.py | 2 +- src/mailman/chains/headers.py | 2 +- src/mailman/chains/hold.py | 2 +- src/mailman/chains/moderation.py | 2 +- src/mailman/chains/owner.py | 2 +- src/mailman/chains/reject.py | 2 +- src/mailman/commands/cli_aliases.py | 2 +- src/mailman/commands/cli_conf.py | 2 +- src/mailman/commands/cli_control.py | 2 +- src/mailman/commands/cli_digests.py | 2 +- src/mailman/commands/cli_help.py | 2 +- src/mailman/commands/cli_import.py | 2 +- src/mailman/commands/cli_info.py | 2 +- src/mailman/commands/cli_inject.py | 2 +- src/mailman/commands/cli_lists.py | 2 +- src/mailman/commands/cli_members.py | 2 +- src/mailman/commands/cli_qfile.py | 2 +- src/mailman/commands/cli_status.py | 2 +- src/mailman/commands/cli_unshunt.py | 2 +- src/mailman/commands/cli_version.py | 2 +- src/mailman/commands/cli_withlist.py | 2 +- src/mailman/commands/eml_confirm.py | 2 +- src/mailman/commands/eml_echo.py | 2 +- src/mailman/commands/eml_end.py | 2 +- src/mailman/commands/eml_help.py | 2 +- src/mailman/commands/eml_membership.py | 2 +- src/mailman/config/__init__.py | 2 +- src/mailman/config/config.py | 2 +- src/mailman/core/api.py | 2 +- src/mailman/core/chains.py | 2 +- src/mailman/core/constants.py | 2 +- src/mailman/core/i18n.py | 2 +- src/mailman/core/initialize.py | 2 +- src/mailman/core/logging.py | 2 +- src/mailman/core/pipelines.py | 2 +- src/mailman/core/rules.py | 2 +- src/mailman/core/runner.py | 2 +- src/mailman/core/switchboard.py | 2 +- src/mailman/core/system.py | 2 +- src/mailman/database/alembic/__init__.py | 2 +- src/mailman/database/alembic/env.py | 2 +- src/mailman/database/base.py | 2 +- src/mailman/database/factory.py | 2 +- src/mailman/database/helpers.py | 2 +- src/mailman/database/model.py | 2 +- src/mailman/database/mysql.py | 2 +- src/mailman/database/postgresql.py | 2 +- src/mailman/database/sqlite.py | 2 +- src/mailman/database/transaction.py | 2 +- src/mailman/database/types.py | 2 +- src/mailman/docs/__init__.py | 2 +- src/mailman/email/message.py | 2 +- src/mailman/email/validate.py | 2 +- src/mailman/handlers/acknowledge.py | 2 +- src/mailman/handlers/after_delivery.py | 2 +- src/mailman/handlers/avoid_duplicates.py | 2 +- src/mailman/handlers/cleanse.py | 2 +- src/mailman/handlers/cleanse_dkim.py | 2 +- src/mailman/handlers/cook_headers.py | 2 +- src/mailman/handlers/decorate.py | 2 +- src/mailman/handlers/file_recipients.py | 2 +- src/mailman/handlers/member_recipients.py | 2 +- src/mailman/handlers/mime_delete.py | 2 +- src/mailman/handlers/owner_recipients.py | 2 +- src/mailman/handlers/replybot.py | 2 +- src/mailman/handlers/rfc_2369.py | 2 +- src/mailman/handlers/subject_prefix.py | 2 +- src/mailman/handlers/tagger.py | 2 +- src/mailman/handlers/to_archive.py | 2 +- src/mailman/handlers/to_digest.py | 2 +- src/mailman/handlers/to_outgoing.py | 2 +- src/mailman/handlers/to_usenet.py | 2 +- src/mailman/interfaces/action.py | 2 +- src/mailman/interfaces/address.py | 2 +- src/mailman/interfaces/api.py | 2 +- src/mailman/interfaces/archiver.py | 2 +- src/mailman/interfaces/autorespond.py | 2 +- src/mailman/interfaces/bans.py | 2 +- src/mailman/interfaces/bounce.py | 2 +- src/mailman/interfaces/cache.py | 2 +- src/mailman/interfaces/chain.py | 2 +- src/mailman/interfaces/command.py | 2 +- src/mailman/interfaces/configuration.py | 2 +- src/mailman/interfaces/database.py | 2 +- src/mailman/interfaces/digests.py | 2 +- src/mailman/interfaces/domain.py | 2 +- src/mailman/interfaces/errors.py | 2 +- src/mailman/interfaces/handler.py | 2 +- src/mailman/interfaces/languages.py | 2 +- src/mailman/interfaces/listmanager.py | 2 +- src/mailman/interfaces/mailinglist.py | 2 +- src/mailman/interfaces/member.py | 2 +- src/mailman/interfaces/messages.py | 2 +- src/mailman/interfaces/mime.py | 2 +- src/mailman/interfaces/mlistrequest.py | 2 +- src/mailman/interfaces/mta.py | 2 +- src/mailman/interfaces/nntp.py | 2 +- src/mailman/interfaces/pending.py | 2 +- src/mailman/interfaces/pipeline.py | 2 +- src/mailman/interfaces/preferences.py | 2 +- src/mailman/interfaces/requests.py | 2 +- src/mailman/interfaces/roster.py | 2 +- src/mailman/interfaces/rules.py | 2 +- src/mailman/interfaces/runner.py | 2 +- src/mailman/interfaces/styles.py | 2 +- src/mailman/interfaces/subscriptions.py | 2 +- src/mailman/interfaces/switchboard.py | 2 +- src/mailman/interfaces/system.py | 2 +- src/mailman/interfaces/template.py | 2 +- src/mailman/interfaces/user.py | 2 +- src/mailman/interfaces/usermanager.py | 2 +- src/mailman/interfaces/workflow.py | 2 +- src/mailman/languages/language.py | 2 +- src/mailman/languages/manager.py | 2 +- src/mailman/model/address.py | 2 +- src/mailman/model/autorespond.py | 2 +- src/mailman/model/bans.py | 2 +- src/mailman/model/bounce.py | 2 +- src/mailman/model/cache.py | 2 +- src/mailman/model/digests.py | 2 +- src/mailman/model/domain.py | 2 +- src/mailman/model/language.py | 2 +- src/mailman/model/listmanager.py | 2 +- src/mailman/model/mailinglist.py | 2 +- src/mailman/model/member.py | 2 +- src/mailman/model/message.py | 2 +- src/mailman/model/messagestore.py | 2 +- src/mailman/model/mime.py | 2 +- src/mailman/model/pending.py | 2 +- src/mailman/model/preferences.py | 2 +- src/mailman/model/requests.py | 2 +- src/mailman/model/roster.py | 2 +- src/mailman/model/subscriptions.py | 2 +- src/mailman/model/template.py | 2 +- src/mailman/model/uid.py | 2 +- src/mailman/model/user.py | 2 +- src/mailman/model/usermanager.py | 2 +- src/mailman/model/workflow.py | 2 +- src/mailman/mta/aliases.py | 2 +- src/mailman/mta/base.py | 2 +- src/mailman/mta/bulk.py | 2 +- src/mailman/mta/connection.py | 2 +- src/mailman/mta/decorating.py | 2 +- src/mailman/mta/deliver.py | 2 +- src/mailman/mta/exim4.py | 2 +- src/mailman/mta/null.py | 2 +- src/mailman/mta/personalized.py | 2 +- src/mailman/mta/postfix.py | 2 +- src/mailman/mta/verp.py | 2 +- src/mailman/rest/addresses.py | 2 +- src/mailman/rest/bans.py | 2 +- src/mailman/rest/docs/__init__.py | 2 +- src/mailman/rest/domains.py | 2 +- src/mailman/rest/header_matches.py | 2 +- src/mailman/rest/helpers.py | 2 +- src/mailman/rest/listconf.py | 2 +- src/mailman/rest/lists.py | 2 +- src/mailman/rest/members.py | 2 +- src/mailman/rest/post_moderation.py | 2 +- src/mailman/rest/preferences.py | 2 +- src/mailman/rest/queues.py | 2 +- src/mailman/rest/root.py | 2 +- src/mailman/rest/sub_moderation.py | 2 +- src/mailman/rest/templates.py | 2 +- src/mailman/rest/uris.py | 2 +- src/mailman/rest/users.py | 2 +- src/mailman/rest/validator.py | 2 +- src/mailman/rest/wsgiapp.py | 2 +- src/mailman/rules/administrivia.py | 2 +- src/mailman/rules/any.py | 2 +- src/mailman/rules/approved.py | 2 +- src/mailman/rules/banned_address.py | 2 +- src/mailman/rules/emergency.py | 2 +- src/mailman/rules/implicit_dest.py | 2 +- src/mailman/rules/loop.py | 2 +- src/mailman/rules/max_recipients.py | 2 +- src/mailman/rules/max_size.py | 2 +- src/mailman/rules/moderation.py | 2 +- src/mailman/rules/news_moderation.py | 2 +- src/mailman/rules/no_subject.py | 2 +- src/mailman/rules/suspicious.py | 2 +- src/mailman/rules/truth.py | 2 +- src/mailman/runners/archive.py | 2 +- src/mailman/runners/bounce.py | 2 +- src/mailman/runners/command.py | 2 +- src/mailman/runners/digest.py | 2 +- src/mailman/runners/incoming.py | 2 +- src/mailman/runners/lmtp.py | 2 +- src/mailman/runners/nntp.py | 2 +- src/mailman/runners/outgoing.py | 2 +- src/mailman/runners/pipeline.py | 2 +- src/mailman/runners/rest.py | 2 +- src/mailman/runners/retry.py | 2 +- src/mailman/runners/virgin.py | 2 +- src/mailman/styles/base.py | 2 +- src/mailman/styles/default.py | 2 +- src/mailman/styles/manager.py | 2 +- src/mailman/testing/documentation.py | 2 +- src/mailman/testing/helpers.py | 2 +- src/mailman/testing/i18n.py | 2 +- src/mailman/testing/layers.py | 2 +- src/mailman/testing/mta.py | 2 +- src/mailman/testing/nose.py | 2 +- src/mailman/utilities/datetime.py | 2 +- src/mailman/utilities/email.py | 2 +- src/mailman/utilities/filesystem.py | 2 +- src/mailman/utilities/i18n.py | 2 +- src/mailman/utilities/importer.py | 2 +- src/mailman/utilities/interact.py | 2 +- src/mailman/utilities/mailbox.py | 3 ++- src/mailman/utilities/modules.py | 2 +- src/mailman/utilities/options.py | 2 +- src/mailman/utilities/passwords.py | 2 +- src/mailman/utilities/protocols.py | 2 +- src/mailman/utilities/queries.py | 2 +- src/mailman/utilities/string.py | 2 +- src/mailman/utilities/tests/test_modules.py | 4 ++-- src/mailman/utilities/uid.py | 2 +- 242 files changed, 243 insertions(+), 255 deletions(-) diff --git a/setup.py b/setup.py index 2d182cdc7..080c83925 100644 --- a/setup.py +++ b/setup.py @@ -106,6 +106,7 @@ case second `m'. Any other spelling is incorrect.""", install_requires = [ 'aiosmtpd', 'alembic', + 'atpublic', 'falcon>=1.0.0rc1', 'flufl.bounce', 'flufl.i18n', diff --git a/src/mailman/__init__.py b/src/mailman/__init__.py index c54830915..15ce69608 100644 --- a/src/mailman/__init__.py +++ b/src/mailman/__init__.py @@ -29,20 +29,6 @@ except ImportError: # pragma: no cover __path__ = pkgutil.extend_path(__path__, __name__) -# I hate myself: http://bugs.python.org/issue26632 -def public(thing=None, **kws): - mdict = (sys._getframe(1).f_globals - if thing is None - else sys.modules[thing.__module__].__dict__) - dunder_all = mdict.setdefault('__all__', []) - if thing is not None: - dunder_all.append(thing.__name__) - for key, value in kws.items(): - dunder_all.append(key) - mdict[key] = value - return thing - - # We have to initialize the i18n subsystem before anything else happens, # however, we'll initialize it differently for tests. We have to do it this # early so that module contents is set up before anything that needs it is diff --git a/src/mailman/app/bounces.py b/src/mailman/app/bounces.py index 98076dc9b..7fcbe4c2a 100644 --- a/src/mailman/app/bounces.py +++ b/src/mailman/app/bounces.py @@ -24,7 +24,6 @@ import logging from email.mime.message import MIMEMessage from email.mime.text import MIMEText from email.utils import parseaddr -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.email.message import OwnerNotification, UserNotification @@ -35,6 +34,7 @@ from mailman.interfaces.subscriptions import ISubscriptionService from mailman.interfaces.template import ITemplateLoader from mailman.utilities.email import split_email from mailman.utilities.string import expand, oneline, wrap +from public import public from string import Template from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/app/commands.py b/src/mailman/app/commands.py index 4c484bc0b..093156d78 100644 --- a/src/mailman/app/commands.py +++ b/src/mailman/app/commands.py @@ -17,10 +17,10 @@ """Initialize the email commands.""" -from mailman import public from mailman.config import config from mailman.interfaces.command import IEmailCommand from mailman.utilities.modules import find_components +from public import public from zope.interface.verify import verifyObject diff --git a/src/mailman/app/digests.py b/src/mailman/app/digests.py index 0d47df328..409c22125 100644 --- a/src/mailman/app/digests.py +++ b/src/mailman/app/digests.py @@ -19,11 +19,11 @@ import os -from mailman import public from mailman.config import config from mailman.email.message import Message from mailman.interfaces.digests import DigestFrequency from mailman.utilities.datetime import now as right_now +from public import public @public diff --git a/src/mailman/app/domain.py b/src/mailman/app/domain.py index 66abf9c3e..33546d34a 100644 --- a/src/mailman/app/domain.py +++ b/src/mailman/app/domain.py @@ -17,9 +17,9 @@ """Application level domain support.""" -from mailman import public from mailman.interfaces.domain import DomainDeletingEvent from mailman.interfaces.listmanager import IListManager +from public import public from zope.component import getUtility diff --git a/src/mailman/app/events.py b/src/mailman/app/events.py index f3323b6ce..c7d4857cb 100644 --- a/src/mailman/app/events.py +++ b/src/mailman/app/events.py @@ -17,12 +17,12 @@ """Global events.""" -from mailman import public from mailman.app import domain, membership, moderator, subscriptions from mailman.core import i18n, switchboard from mailman.languages import manager as language_manager from mailman.styles import manager as style_manager from mailman.utilities import passwords +from public import public from zope import event diff --git a/src/mailman/app/inject.py b/src/mailman/app/inject.py index decc0fd0e..ca03942ea 100644 --- a/src/mailman/app/inject.py +++ b/src/mailman/app/inject.py @@ -19,10 +19,10 @@ from email import message_from_string from email.utils import formatdate, make_msgid -from mailman import public from mailman.config import config from mailman.email.message import Message from mailman.utilities.email import add_message_hash +from public import public @public diff --git a/src/mailman/app/lifecycle.py b/src/mailman/app/lifecycle.py index 50145ce8f..ccd3e4b35 100644 --- a/src/mailman/app/lifecycle.py +++ b/src/mailman/app/lifecycle.py @@ -21,7 +21,6 @@ import shutil import logging from contextlib import suppress -from mailman import public from mailman.config import config from mailman.interfaces.address import IEmailValidator from mailman.interfaces.domain import ( @@ -31,6 +30,7 @@ from mailman.interfaces.member import MemberRole from mailman.interfaces.styles import IStyleManager from mailman.interfaces.usermanager import IUserManager from mailman.utilities.modules import call_name +from public import public from zope.component import getUtility diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py index 534eed15d..5eb15cf30 100644 --- a/src/mailman/app/membership.py +++ b/src/mailman/app/membership.py @@ -18,7 +18,6 @@ """Application support for membership management.""" from email.utils import formataddr -from mailman import public from mailman.app.notifications import ( send_admin_subscription_notice, send_goodbye_message, send_welcome_message) @@ -33,6 +32,7 @@ from mailman.interfaces.template import ITemplateLoader from mailman.interfaces.user import IUser from mailman.interfaces.usermanager import IUserManager from mailman.utilities.string import expand +from public import public from zope.component import getUtility diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py index 9d3856f33..fe7a81383 100644 --- a/src/mailman/app/moderator.py +++ b/src/mailman/app/moderator.py @@ -21,7 +21,6 @@ import time import logging from email.utils import formatdate, getaddresses, make_msgid -from mailman import public from mailman.app.membership import delete_member from mailman.config import config from mailman.core.i18n import _ @@ -34,6 +33,7 @@ from mailman.interfaces.requests import IListRequests, RequestType from mailman.interfaces.template import ITemplateLoader from mailman.utilities.datetime import now from mailman.utilities.string import expand, wrap +from public import public from zope.component import getUtility diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py index 31a15d820..4d5c1be12 100644 --- a/src/mailman/app/notifications.py +++ b/src/mailman/app/notifications.py @@ -21,13 +21,13 @@ import logging from email.utils import formataddr 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, UserNotification from mailman.interfaces.member import DeliveryMode from mailman.interfaces.template import ITemplateLoader from mailman.utilities.string import expand, wrap +from public import public from zope.component import getUtility diff --git a/src/mailman/app/replybot.py b/src/mailman/app/replybot.py index fc911c5a1..f707fec89 100644 --- a/src/mailman/app/replybot.py +++ b/src/mailman/app/replybot.py @@ -17,7 +17,7 @@ """Application level auto-reply code.""" -from mailman import public +from public import public @public diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index f88a967c2..a38b3061d 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -23,7 +23,6 @@ import logging from datetime import timedelta from email.utils import formataddr from enum import Enum -from mailman import public from mailman.app.membership import delete_member from mailman.app.workflow import Workflow from mailman.core.i18n import _ @@ -45,6 +44,7 @@ from mailman.interfaces.usermanager import IUserManager from mailman.interfaces.workflow import IWorkflowStateManager from mailman.utilities.datetime import now from mailman.utilities.string import expand, wrap +from public import public from zope.component import getUtility from zope.event import notify from zope.interface import implementer diff --git a/src/mailman/app/workflow.py b/src/mailman/app/workflow.py index cd9124993..e11ae03cf 100644 --- a/src/mailman/app/workflow.py +++ b/src/mailman/app/workflow.py @@ -22,8 +22,8 @@ import json import logging from collections import deque -from mailman import public from mailman.interfaces.workflow import IWorkflowStateManager +from public import public from zope.component import getUtility diff --git a/src/mailman/archiving/mailarchive.py b/src/mailman/archiving/mailarchive.py index 782cec29a..bd1a34580 100644 --- a/src/mailman/archiving/mailarchive.py +++ b/src/mailman/archiving/mailarchive.py @@ -17,10 +17,10 @@ """The Mail-Archive.com archiver.""" -from mailman import public from mailman.config import config from mailman.config.config import external_configuration from mailman.interfaces.archiver import ArchivePolicy, IArchiver +from public import public from urllib.parse import quote, urljoin from zope.interface import implementer diff --git a/src/mailman/archiving/mhonarc.py b/src/mailman/archiving/mhonarc.py index 857a61e06..80cba043b 100644 --- a/src/mailman/archiving/mhonarc.py +++ b/src/mailman/archiving/mhonarc.py @@ -19,11 +19,11 @@ import logging -from mailman import public from mailman.config import config from mailman.config.config import external_configuration from mailman.interfaces.archiver import IArchiver from mailman.utilities.string import expand +from public import public from subprocess import PIPE, Popen from urllib.parse import urljoin from zope.interface import implementer diff --git a/src/mailman/archiving/prototype.py b/src/mailman/archiving/prototype.py index 9790129da..b37bfa61e 100644 --- a/src/mailman/archiving/prototype.py +++ b/src/mailman/archiving/prototype.py @@ -24,9 +24,9 @@ from contextlib import suppress from datetime import timedelta from flufl.lock import Lock, TimeOutError from mailbox import Maildir -from mailman import public from mailman.config import config from mailman.interfaces.archiver import IArchiver +from public import public from zope.interface import implementer diff --git a/src/mailman/bin/mailman.py b/src/mailman/bin/mailman.py index b4d144b7c..3f8f66d6e 100644 --- a/src/mailman/bin/mailman.py +++ b/src/mailman/bin/mailman.py @@ -21,13 +21,13 @@ import os import argparse from functools import cmp_to_key -from mailman import public from mailman.core.i18n import _ from mailman.core.initialize import initialize from mailman.database.transaction import transaction from mailman.interfaces.command import ICLISubCommand from mailman.utilities.modules import find_components from mailman.version import MAILMAN_VERSION_FULL +from public import public from zope.interface.verify import verifyObject diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py index 8e0b1265f..3acff1fc8 100644 --- a/src/mailman/bin/master.py +++ b/src/mailman/bin/master.py @@ -28,11 +28,11 @@ from datetime import timedelta from enum import Enum from flufl.lock import Lock, NotLockedError, TimeOutError from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.logging import reopen from mailman.utilities.options import Options +from public import public DOT = '.' diff --git a/src/mailman/bin/runner.py b/src/mailman/bin/runner.py index 591f5ee31..39e1e9105 100644 --- a/src/mailman/bin/runner.py +++ b/src/mailman/bin/runner.py @@ -24,12 +24,12 @@ import logging import argparse import traceback -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.initialize import initialize from mailman.utilities.modules import find_name from mailman.version import MAILMAN_VERSION_FULL +from public import public log = None diff --git a/src/mailman/chains/accept.py b/src/mailman/chains/accept.py index 8b0a0507e..c245927bf 100644 --- a/src/mailman/chains/accept.py +++ b/src/mailman/chains/accept.py @@ -19,11 +19,11 @@ import logging -from mailman import public from mailman.chains.base import TerminalChainBase from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.chain import AcceptEvent +from public import public from zope.event import notify diff --git a/src/mailman/chains/base.py b/src/mailman/chains/base.py index 677ec501c..d54baf8b6 100644 --- a/src/mailman/chains/base.py +++ b/src/mailman/chains/base.py @@ -17,11 +17,11 @@ """Base class for terminal chains.""" -from mailman import public from mailman.config import config from mailman.interfaces.chain import ( IChain, IChainIterator, IChainLink, IMutableChain, LinkAction) from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/chains/builtin.py b/src/mailman/chains/builtin.py index b805fca0f..16de1043a 100644 --- a/src/mailman/chains/builtin.py +++ b/src/mailman/chains/builtin.py @@ -19,10 +19,10 @@ import logging -from mailman import public from mailman.chains.base import Link from mailman.core.i18n import _ from mailman.interfaces.chain import IChain, LinkAction +from public import public from zope.interface import implementer diff --git a/src/mailman/chains/discard.py b/src/mailman/chains/discard.py index f77c7eb0f..e9fc8d05d 100644 --- a/src/mailman/chains/discard.py +++ b/src/mailman/chains/discard.py @@ -19,10 +19,10 @@ import logging -from mailman import public from mailman.chains.base import TerminalChainBase from mailman.core.i18n import _ from mailman.interfaces.chain import DiscardEvent +from public import public from zope.event import notify diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py index 5698740d3..56ac179e9 100644 --- a/src/mailman/chains/headers.py +++ b/src/mailman/chains/headers.py @@ -21,12 +21,12 @@ import re import logging from itertools import count -from mailman import public from mailman.chains.base import Chain, Link from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.chain import LinkAction from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index 42fed66a6..0b50964b7 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -22,7 +22,6 @@ import logging from email.mime.message import MIMEMessage from email.mime.text import MIMEText from email.utils import formatdate, make_msgid -from mailman import public from mailman.app.moderator import hold_message from mailman.app.replybot import can_acknowledge from mailman.chains.base import TerminalChainBase @@ -36,6 +35,7 @@ from mailman.interfaces.pending import IPendable, IPendings from mailman.interfaces.template import ITemplateLoader from mailman.interfaces.usermanager import IUserManager from mailman.utilities.string import expand, oneline, wrap +from public import public from zope.component import getUtility from zope.event import notify from zope.interface import implementer diff --git a/src/mailman/chains/moderation.py b/src/mailman/chains/moderation.py index 9bb4bf0d5..e8f507603 100644 --- a/src/mailman/chains/moderation.py +++ b/src/mailman/chains/moderation.py @@ -34,11 +34,11 @@ made as to the disposition of the message. `defer` is the default for members, while `hold` is the default for nonmembers. """ -from mailman import public from mailman.chains.base import Link from mailman.core.i18n import _ from mailman.interfaces.action import Action from mailman.interfaces.chain import IChain, LinkAction +from public import public from zope.interface import implementer diff --git a/src/mailman/chains/owner.py b/src/mailman/chains/owner.py index f7454435f..4fb8e1723 100644 --- a/src/mailman/chains/owner.py +++ b/src/mailman/chains/owner.py @@ -19,11 +19,11 @@ import logging -from mailman import public from mailman.chains.base import TerminalChainBase from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.chain import AcceptOwnerEvent +from public import public from zope.event import notify diff --git a/src/mailman/chains/reject.py b/src/mailman/chains/reject.py index 27fce8d4e..96be8f2de 100644 --- a/src/mailman/chains/reject.py +++ b/src/mailman/chains/reject.py @@ -19,12 +19,12 @@ import logging -from mailman import public from mailman.app.bounces import bounce_message from mailman.chains.base import TerminalChainBase from mailman.core.i18n import _ from mailman.interfaces.chain import RejectEvent from mailman.interfaces.pipeline import RejectMessage +from public import public from zope.event import notify diff --git a/src/mailman/commands/cli_aliases.py b/src/mailman/commands/cli_aliases.py index 76713555a..f48814854 100644 --- a/src/mailman/commands/cli_aliases.py +++ b/src/mailman/commands/cli_aliases.py @@ -17,11 +17,11 @@ """Generate Mailman alias files for your MTA.""" -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.utilities.modules import call_name +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_conf.py b/src/mailman/commands/cli_conf.py index 67db4ac53..0a00f5006 100644 --- a/src/mailman/commands/cli_conf.py +++ b/src/mailman/commands/cli_conf.py @@ -21,10 +21,10 @@ import sys from contextlib import closing from lazr.config._config import Section -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_control.py b/src/mailman/commands/cli_control.py index 5ba0b5427..846f4a5c6 100644 --- a/src/mailman/commands/cli_control.py +++ b/src/mailman/commands/cli_control.py @@ -23,11 +23,11 @@ import errno import signal import logging -from mailman import public from mailman.bin.master import WatcherState, master_state from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_digests.py b/src/mailman/commands/cli_digests.py index 3a4d6614f..151a9332c 100644 --- a/src/mailman/commands/cli_digests.py +++ b/src/mailman/commands/cli_digests.py @@ -19,12 +19,12 @@ import sys -from mailman import public from mailman.app.digests import ( bump_digest_number_and_volume, maybe_send_digest_now) from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/commands/cli_help.py b/src/mailman/commands/cli_help.py index 9222cd00f..5d6372e51 100644 --- a/src/mailman/commands/cli_help.py +++ b/src/mailman/commands/cli_help.py @@ -17,8 +17,8 @@ """The 'help' subcommand.""" -from mailman import public from mailman.interfaces.command import ICLISubCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_import.py b/src/mailman/commands/cli_import.py index 126c026d0..d9384b5bc 100644 --- a/src/mailman/commands/cli_import.py +++ b/src/mailman/commands/cli_import.py @@ -21,12 +21,12 @@ import sys import pickle from contextlib import ExitStack, contextmanager -from mailman import public from mailman.core.i18n import _ from mailman.database.transaction import transactional from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager from mailman.utilities.importer import Import21Error, import_config_pck +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/commands/cli_info.py b/src/mailman/commands/cli_info.py index fd6c83f88..46643ae1d 100644 --- a/src/mailman/commands/cli_info.py +++ b/src/mailman/commands/cli_info.py @@ -20,12 +20,12 @@ import sys from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.core.api import API30, API31 from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.version import MAILMAN_VERSION_FULL +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_inject.py b/src/mailman/commands/cli_inject.py index acbc37d67..0255b71d2 100644 --- a/src/mailman/commands/cli_inject.py +++ b/src/mailman/commands/cli_inject.py @@ -19,12 +19,12 @@ import sys -from mailman import public from mailman.app.inject import inject_text from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py index f5e6d724a..3a598ab05 100644 --- a/src/mailman/commands/cli_lists.py +++ b/src/mailman/commands/cli_lists.py @@ -17,7 +17,6 @@ """The 'lists' subcommand.""" -from mailman import public from mailman.app.lifecycle import create_list, remove_list from mailman.core.constants import system_preferences from mailman.core.i18n import _ @@ -32,6 +31,7 @@ from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError from mailman.interfaces.template import ITemplateLoader from mailman.utilities.string import expand, wrap +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/commands/cli_members.py b/src/mailman/commands/cli_members.py index 476d1f77d..1eb6550d6 100644 --- a/src/mailman/commands/cli_members.py +++ b/src/mailman/commands/cli_members.py @@ -21,7 +21,6 @@ import sys from contextlib import ExitStack from email.utils import formataddr, parseaddr -from mailman import public from mailman.app.membership import add_member from mailman.core.i18n import _ from mailman.database.transaction import transactional @@ -31,6 +30,7 @@ from mailman.interfaces.member import ( AlreadySubscribedError, DeliveryMode, DeliveryStatus, MemberRole) from mailman.interfaces.subscriptions import RequestRecord from operator import attrgetter +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/commands/cli_qfile.py b/src/mailman/commands/cli_qfile.py index f6502f14a..c8d3ec84b 100644 --- a/src/mailman/commands/cli_qfile.py +++ b/src/mailman/commands/cli_qfile.py @@ -19,11 +19,11 @@ import pickle -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.utilities.interact import interact from pprint import PrettyPrinter +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_status.py b/src/mailman/commands/cli_status.py index 6b4abe45e..b60ba8841 100644 --- a/src/mailman/commands/cli_status.py +++ b/src/mailman/commands/cli_status.py @@ -19,10 +19,10 @@ import socket -from mailman import public from mailman.bin.master import WatcherState, master_state from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_unshunt.py b/src/mailman/commands/cli_unshunt.py index 6bb1a9800..49b9c6e26 100644 --- a/src/mailman/commands/cli_unshunt.py +++ b/src/mailman/commands/cli_unshunt.py @@ -19,10 +19,10 @@ import sys -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_version.py b/src/mailman/commands/cli_version.py index 4660087de..bc26d0115 100644 --- a/src/mailman/commands/cli_version.py +++ b/src/mailman/commands/cli_version.py @@ -17,9 +17,9 @@ """The Mailman version.""" -from mailman import public from mailman.interfaces.command import ICLISubCommand from mailman.version import MAILMAN_VERSION_FULL +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/cli_withlist.py b/src/mailman/commands/cli_withlist.py index 23250c1a5..42eb57cfc 100644 --- a/src/mailman/commands/cli_withlist.py +++ b/src/mailman/commands/cli_withlist.py @@ -23,13 +23,13 @@ import sys from contextlib import ExitStack, suppress from functools import partial from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager from mailman.utilities.interact import DEFAULT_BANNER, interact from mailman.utilities.modules import call_name +from public import public from string import Template from traceback import print_exc from zope.component import getUtility diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py index 6787b0987..425bb00e8 100644 --- a/src/mailman/commands/eml_confirm.py +++ b/src/mailman/commands/eml_confirm.py @@ -17,10 +17,10 @@ """The 'confirm' email command.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand from mailman.interfaces.subscriptions import ISubscriptionManager, TokenOwner +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/eml_echo.py b/src/mailman/commands/eml_echo.py index 67f917d3e..db340fda9 100644 --- a/src/mailman/commands/eml_echo.py +++ b/src/mailman/commands/eml_echo.py @@ -17,9 +17,9 @@ """The email command 'echo'.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/eml_end.py b/src/mailman/commands/eml_end.py index 82b66a1a6..c280cc52f 100644 --- a/src/mailman/commands/eml_end.py +++ b/src/mailman/commands/eml_end.py @@ -17,9 +17,9 @@ """The email commands 'end' and 'stop'.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/eml_help.py b/src/mailman/commands/eml_help.py index 4ca2d72a4..b4a39009a 100644 --- a/src/mailman/commands/eml_help.py +++ b/src/mailman/commands/eml_help.py @@ -17,11 +17,11 @@ """The email command 'help'.""" -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand from mailman.utilities.string import wrap +from public import public from zope.interface import implementer diff --git a/src/mailman/commands/eml_membership.py b/src/mailman/commands/eml_membership.py index e658e7b58..22f26e24d 100644 --- a/src/mailman/commands/eml_membership.py +++ b/src/mailman/commands/eml_membership.py @@ -18,13 +18,13 @@ """The email commands 'join' and 'subscribe'.""" from email.utils import formataddr, parseaddr -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand from mailman.interfaces.member import DeliveryMode, MemberRole from mailman.interfaces.subscriptions import ( ISubscriptionManager, ISubscriptionService) from mailman.interfaces.usermanager import IUserManager +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/config/__init__.py b/src/mailman/config/__init__.py index 5c45d6599..66b298217 100644 --- a/src/mailman/config/__init__.py +++ b/src/mailman/config/__init__.py @@ -17,8 +17,8 @@ """Mailman configuration package.""" -from mailman import public from mailman.config.config import Configuration +from public import public public(config=Configuration()) diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py index 5454c5e5a..1f4384eb7 100644 --- a/src/mailman/config/config.py +++ b/src/mailman/config/config.py @@ -24,13 +24,13 @@ import mailman.templates from configparser import ConfigParser from flufl.lock import Lock from lazr.config import ConfigSchema, as_boolean -from mailman import public, version from mailman.interfaces.configuration import ( ConfigurationUpdatedEvent, IConfiguration, MissingConfigurationFileError) from mailman.interfaces.languages import ILanguageManager from mailman.utilities.filesystem import makedirs from mailman.utilities.modules import call_name, expand_path from pkg_resources import resource_filename, resource_string as resource_bytes +from public import public, version from string import Template from zope.component import getUtility from zope.event import notify diff --git a/src/mailman/core/api.py b/src/mailman/core/api.py index e6e013af0..c9e377bbf 100644 --- a/src/mailman/core/api.py +++ b/src/mailman/core/api.py @@ -18,9 +18,9 @@ """REST web service API contexts.""" from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.interfaces.api import IAPI +from public import public from uuid import UUID from zope.interface import implementer diff --git a/src/mailman/core/chains.py b/src/mailman/core/chains.py index ec84db2c4..0af61fd2a 100644 --- a/src/mailman/core/chains.py +++ b/src/mailman/core/chains.py @@ -17,11 +17,11 @@ """Application support for chain processing.""" -from mailman import public from mailman.chains.base import Chain, TerminalChainBase from mailman.config import config from mailman.interfaces.chain import IChain, LinkAction from mailman.utilities.modules import find_components +from public import public from zope.interface.verify import verifyObject diff --git a/src/mailman/core/constants.py b/src/mailman/core/constants.py index f82783e9f..e5d265256 100644 --- a/src/mailman/core/constants.py +++ b/src/mailman/core/constants.py @@ -17,11 +17,11 @@ """Various constants and enumerations.""" -from mailman import public from mailman.config import config from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.interfaces.preferences import IPreferences +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/core/i18n.py b/src/mailman/core/i18n.py index 5536fcdaf..345020a13 100644 --- a/src/mailman/core/i18n.py +++ b/src/mailman/core/i18n.py @@ -20,8 +20,8 @@ import mailman.messages from flufl.i18n import PackageStrategy, registry -from mailman import public from mailman.interfaces.configuration import ConfigurationUpdatedEvent +from public import public public(_=None) diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py index 7b39465c5..6bd1d6777 100644 --- a/src/mailman/core/initialize.py +++ b/src/mailman/core/initialize.py @@ -29,10 +29,10 @@ import sys import mailman.config.config import mailman.core.logging -from mailman import public from mailman.interfaces.database import IDatabaseFactory from mailman.utilities.modules import call_name from pkg_resources import resource_string as resource_bytes +from public import public from zope.component import getUtility from zope.configuration import xmlconfig diff --git a/src/mailman/core/logging.py b/src/mailman/core/logging.py index a7e8b2554..53bb2cf1c 100644 --- a/src/mailman/core/logging.py +++ b/src/mailman/core/logging.py @@ -23,8 +23,8 @@ import codecs import logging from lazr.config import as_boolean, as_log_level -from mailman import public from mailman.config import config +from public import public _handlers = {} diff --git a/src/mailman/core/pipelines.py b/src/mailman/core/pipelines.py index 5df21ed15..fb663cee9 100644 --- a/src/mailman/core/pipelines.py +++ b/src/mailman/core/pipelines.py @@ -19,7 +19,6 @@ import logging -from mailman import public from mailman.app.bounces import bounce_message from mailman.config import config from mailman.core.i18n import _ @@ -27,6 +26,7 @@ from mailman.interfaces.handler import IHandler from mailman.interfaces.pipeline import ( DiscardMessage, IPipeline, RejectMessage) from mailman.utilities.modules import find_components +from public import public from zope.interface import implementer from zope.interface.verify import verifyObject diff --git a/src/mailman/core/rules.py b/src/mailman/core/rules.py index f6ca87726..680d4f007 100644 --- a/src/mailman/core/rules.py +++ b/src/mailman/core/rules.py @@ -17,10 +17,10 @@ """Various rule helpers""" -from mailman import public from mailman.config import config from mailman.interfaces.rules import IRule from mailman.utilities.modules import find_components +from public import public from zope.interface.verify import verifyObject diff --git a/src/mailman/core/runner.py b/src/mailman/core/runner.py index d0ff6f5ce..ed1c26d38 100644 --- a/src/mailman/core/runner.py +++ b/src/mailman/core/runner.py @@ -25,7 +25,6 @@ import traceback from contextlib import suppress from io import StringIO from lazr.config import as_boolean, as_timedelta -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.logging import reopen @@ -34,6 +33,7 @@ from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.listmanager import IListManager from mailman.interfaces.runner import IRunner, RunnerCrashEvent from mailman.utilities.string import expand +from public import public from zope.component import getUtility from zope.event import notify from zope.interface import implementer diff --git a/src/mailman/core/switchboard.py b/src/mailman/core/switchboard.py index cfbb371ba..f03ee11e5 100644 --- a/src/mailman/core/switchboard.py +++ b/src/mailman/core/switchboard.py @@ -31,13 +31,13 @@ import pickle import hashlib import logging -from mailman import public from mailman.config import config from mailman.email.message import Message from mailman.interfaces.configuration import ConfigurationUpdatedEvent from mailman.interfaces.switchboard import ISwitchboard from mailman.utilities.filesystem import makedirs from mailman.utilities.string import expand +from public import public from zope.interface import implementer diff --git a/src/mailman/core/system.py b/src/mailman/core/system.py index ee88c5adf..2d76f0c97 100644 --- a/src/mailman/core/system.py +++ b/src/mailman/core/system.py @@ -19,8 +19,8 @@ import sys -from mailman import public, version from mailman.interfaces.system import ISystem +from public import public, version from zope.interface import implementer diff --git a/src/mailman/database/alembic/__init__.py b/src/mailman/database/alembic/__init__.py index af2596f04..ff74113d7 100644 --- a/src/mailman/database/alembic/__init__.py +++ b/src/mailman/database/alembic/__init__.py @@ -18,8 +18,8 @@ """Alembic configuration initization.""" from alembic.config import Config -from mailman import public from mailman.utilities.modules import expand_path +from public import public public(alembic_cfg=Config(expand_path('python:mailman.config.alembic'))) diff --git a/src/mailman/database/alembic/env.py b/src/mailman/database/alembic/env.py index c7a5e151d..e359b201d 100644 --- a/src/mailman/database/alembic/env.py +++ b/src/mailman/database/alembic/env.py @@ -19,11 +19,11 @@ from alembic import context from contextlib import closing -from mailman import public from mailman.config import config from mailman.core.initialize import initialize_1 from mailman.database.model import Model from mailman.utilities.string import expand +from public import public from sqlalchemy import create_engine diff --git a/src/mailman/database/base.py b/src/mailman/database/base.py index f57228029..586e1b20d 100644 --- a/src/mailman/database/base.py +++ b/src/mailman/database/base.py @@ -19,10 +19,10 @@ import logging -from mailman import public from mailman.config import config from mailman.interfaces.database import IDatabase from mailman.utilities.string import expand +from public import public from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from zope.interface import implementer diff --git a/src/mailman/database/factory.py b/src/mailman/database/factory.py index ff7fa59a9..4d003c39c 100644 --- a/src/mailman/database/factory.py +++ b/src/mailman/database/factory.py @@ -24,13 +24,13 @@ import alembic.command from alembic.migration import MigrationContext from alembic.script import ScriptDirectory from flufl.lock import Lock -from mailman import public from mailman.config import config from mailman.database.alembic import alembic_cfg from mailman.database.model import Model from mailman.interfaces.database import ( DatabaseError, IDatabase, IDatabaseFactory) from mailman.utilities.modules import call_name +from public import public from sqlalchemy import MetaData from zope.interface import implementer from zope.interface.verify import verifyObject diff --git a/src/mailman/database/helpers.py b/src/mailman/database/helpers.py index b1dc381df..27c870058 100644 --- a/src/mailman/database/helpers.py +++ b/src/mailman/database/helpers.py @@ -19,7 +19,7 @@ import sqlalchemy as sa -from mailman import public +from public import public @public diff --git a/src/mailman/database/model.py b/src/mailman/database/model.py index c2ee90491..098f62d4b 100644 --- a/src/mailman/database/model.py +++ b/src/mailman/database/model.py @@ -18,8 +18,8 @@ """Base class for all database classes.""" from contextlib import closing -from mailman import public from mailman.config import config +from public import public from sqlalchemy.ext.declarative import declarative_base diff --git a/src/mailman/database/mysql.py b/src/mailman/database/mysql.py index 0c0de54a9..cff16e208 100644 --- a/src/mailman/database/mysql.py +++ b/src/mailman/database/mysql.py @@ -17,9 +17,9 @@ """MySQL database support""" -from mailman import public from mailman.database.base import SABaseDatabase from mailman.database.model import Model +from public import public @public diff --git a/src/mailman/database/postgresql.py b/src/mailman/database/postgresql.py index b1095e45f..d0c208a50 100644 --- a/src/mailman/database/postgresql.py +++ b/src/mailman/database/postgresql.py @@ -17,9 +17,9 @@ """PostgreSQL database support.""" -from mailman import public from mailman.database.base import SABaseDatabase from mailman.database.model import Model +from public import public from sqlalchemy import Integer diff --git a/src/mailman/database/sqlite.py b/src/mailman/database/sqlite.py index 08700bfb2..3659efaff 100644 --- a/src/mailman/database/sqlite.py +++ b/src/mailman/database/sqlite.py @@ -19,8 +19,8 @@ import os -from mailman import public from mailman.database.base import SABaseDatabase +from public import public from urllib.parse import urlparse diff --git a/src/mailman/database/transaction.py b/src/mailman/database/transaction.py index 09dfda8e3..1b5368a39 100644 --- a/src/mailman/database/transaction.py +++ b/src/mailman/database/transaction.py @@ -18,8 +18,8 @@ """Transactional support.""" from contextlib import contextmanager -from mailman import public from mailman.config import config +from public import public @public diff --git a/src/mailman/database/types.py b/src/mailman/database/types.py index bbd040d96..10b826e7c 100644 --- a/src/mailman/database/types.py +++ b/src/mailman/database/types.py @@ -19,7 +19,7 @@ import uuid -from mailman import public +from public import public from sqlalchemy import Integer from sqlalchemy.dialects import postgresql from sqlalchemy.ext.compiler import compiles diff --git a/src/mailman/docs/__init__.py b/src/mailman/docs/__init__.py index 68c7bb4cf..939c1e6e6 100644 --- a/src/mailman/docs/__init__.py +++ b/src/mailman/docs/__init__.py @@ -17,8 +17,8 @@ """General Mailman doc tests.""" -from mailman import public from mailman.testing.layers import ConfigLayer +from public import public public(layer=ConfigLayer) diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py index 26bc35b78..da2ce837f 100644 --- a/src/mailman/email/message.py +++ b/src/mailman/email/message.py @@ -29,9 +29,9 @@ import email.utils from email.header import Header from email.mime.multipart import MIMEMultipart -from mailman import public from mailman.config import config from mailman.interfaces.member import DeliveryStatus +from public import public COMMASPACE = ', ' diff --git a/src/mailman/email/validate.py b/src/mailman/email/validate.py index 99371d9e5..be8ba775a 100644 --- a/src/mailman/email/validate.py +++ b/src/mailman/email/validate.py @@ -19,10 +19,10 @@ import re -from mailman import public from mailman.interfaces.address import ( IEmailValidator, InvalidEmailAddressError) from mailman.utilities.email import split_email +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/acknowledge.py b/src/mailman/handlers/acknowledge.py index c7035de67..56608a3e9 100644 --- a/src/mailman/handlers/acknowledge.py +++ b/src/mailman/handlers/acknowledge.py @@ -20,13 +20,13 @@ This only happens if the sender has set their AcknowledgePosts attribute. """ -from mailman import public from mailman.core.i18n import _ from mailman.email.message import UserNotification from mailman.interfaces.handler import IHandler from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.template import ITemplateLoader from mailman.utilities.string import expand, oneline +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/handlers/after_delivery.py b/src/mailman/handlers/after_delivery.py index efe38ec63..928f90f76 100644 --- a/src/mailman/handlers/after_delivery.py +++ b/src/mailman/handlers/after_delivery.py @@ -17,10 +17,10 @@ """Perform some bookkeeping after a successful post.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler from mailman.utilities.datetime import now +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/avoid_duplicates.py b/src/mailman/handlers/avoid_duplicates.py index 59cb568de..7fe2136da 100644 --- a/src/mailman/handlers/avoid_duplicates.py +++ b/src/mailman/handlers/avoid_duplicates.py @@ -24,9 +24,9 @@ warning header, or pass it through, depending on the user's preferences. """ from email.utils import getaddresses, formataddr -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/cleanse.py b/src/mailman/handlers/cleanse.py index 56add9ef7..8704491f6 100644 --- a/src/mailman/handlers/cleanse.py +++ b/src/mailman/handlers/cleanse.py @@ -20,10 +20,10 @@ 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 +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/cleanse_dkim.py b/src/mailman/handlers/cleanse_dkim.py index 72a9c5e81..cc04858be 100644 --- a/src/mailman/handlers/cleanse_dkim.py +++ b/src/mailman/handlers/cleanse_dkim.py @@ -26,10 +26,10 @@ originating at the Mailman server for the outgoing message. """ 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 public import public from zope.interface import implementer diff --git a/src/mailman/handlers/cook_headers.py b/src/mailman/handlers/cook_headers.py index 5f203fcbd..672738bf9 100644 --- a/src/mailman/handlers/cook_headers.py +++ b/src/mailman/handlers/cook_headers.py @@ -22,11 +22,11 @@ import logging from email.header import Header from email.utils import formataddr, getaddresses, parseaddr -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler from mailman.interfaces.mailinglist import Personalization, ReplyToMunging from mailman.version import VERSION +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/decorate.py b/src/mailman/handlers/decorate.py index 7f5519fd0..6a16dfc76 100644 --- a/src/mailman/handlers/decorate.py +++ b/src/mailman/handlers/decorate.py @@ -22,13 +22,13 @@ import logging from email.mime.text import MIMEText from email.utils import formataddr -from mailman import public from mailman.core.i18n import _ from mailman.email.message import Message from mailman.interfaces.handler import IHandler from mailman.interfaces.mailinglist import IListArchiverSet from mailman.interfaces.template import ITemplateLoader from mailman.utilities.string import expand +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/handlers/file_recipients.py b/src/mailman/handlers/file_recipients.py index 95160706a..e283d936e 100644 --- a/src/mailman/handlers/file_recipients.py +++ b/src/mailman/handlers/file_recipients.py @@ -20,9 +20,9 @@ import os import errno -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/member_recipients.py b/src/mailman/handlers/member_recipients.py index ffcecfb18..309603ef0 100644 --- a/src/mailman/handlers/member_recipients.py +++ b/src/mailman/handlers/member_recipients.py @@ -23,13 +23,13 @@ on the `recipients' attribute of the message. This attribute is used by the SendmailDeliver and BulkDeliver modules. """ -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler from mailman.interfaces.member import DeliveryStatus from mailman.interfaces.pipeline import RejectMessage from mailman.utilities.string import wrap +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/mime_delete.py b/src/mailman/handlers/mime_delete.py index b88c40b0c..ac56e5dd6 100644 --- a/src/mailman/handlers/mime_delete.py +++ b/src/mailman/handlers/mime_delete.py @@ -36,7 +36,6 @@ 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 @@ -45,6 +44,7 @@ from mailman.interfaces.handler import IHandler from mailman.interfaces.pipeline import DiscardMessage, RejectMessage from mailman.utilities.string import oneline from mailman.version import VERSION +from public import public from string import Template from zope.interface import implementer diff --git a/src/mailman/handlers/owner_recipients.py b/src/mailman/handlers/owner_recipients.py index 9ef2568f5..4a4ee9a24 100644 --- a/src/mailman/handlers/owner_recipients.py +++ b/src/mailman/handlers/owner_recipients.py @@ -17,11 +17,11 @@ """Calculate the list owner recipients (includes moderators).""" -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler from mailman.interfaces.member import DeliveryStatus +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/replybot.py b/src/mailman/handlers/replybot.py index a86ccbbf3..e8b9e4fc6 100644 --- a/src/mailman/handlers/replybot.py +++ b/src/mailman/handlers/replybot.py @@ -19,7 +19,6 @@ import logging -from mailman import public from mailman.core.i18n import _ from mailman.email.message import UserNotification from mailman.interfaces.autorespond import ( @@ -28,6 +27,7 @@ from mailman.interfaces.handler import IHandler from mailman.interfaces.usermanager import IUserManager from mailman.utilities.datetime import today from mailman.utilities.string import expand, wrap +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/handlers/rfc_2369.py b/src/mailman/handlers/rfc_2369.py index e042bc5e3..7f36dd057 100644 --- a/src/mailman/handlers/rfc_2369.py +++ b/src/mailman/handlers/rfc_2369.py @@ -20,12 +20,12 @@ 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 from mailman.interfaces.handler import IHandler from mailman.interfaces.mailinglist import IListArchiverSet +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/subject_prefix.py b/src/mailman/handlers/subject_prefix.py index 20f47fc5d..7bb1a3e5d 100644 --- a/src/mailman/handlers/subject_prefix.py +++ b/src/mailman/handlers/subject_prefix.py @@ -21,9 +21,9 @@ import re from contextlib import suppress from email.header import Header, decode_header, make_header -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/tagger.py b/src/mailman/handlers/tagger.py index fb0a24ba5..f7c637085 100644 --- a/src/mailman/handlers/tagger.py +++ b/src/mailman/handlers/tagger.py @@ -21,9 +21,9 @@ import re import email.iterators import email.parser -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/to_archive.py b/src/mailman/handlers/to_archive.py index d5b980ab4..d2805ea3e 100644 --- a/src/mailman/handlers/to_archive.py +++ b/src/mailman/handlers/to_archive.py @@ -17,11 +17,11 @@ """Add the message to the archives.""" -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.archiver import ArchivePolicy from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/to_digest.py b/src/mailman/handlers/to_digest.py index 671a2197c..2de911f46 100644 --- a/src/mailman/handlers/to_digest.py +++ b/src/mailman/handlers/to_digest.py @@ -19,11 +19,11 @@ 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 from mailman.utilities.mailbox import Mailbox +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/to_outgoing.py b/src/mailman/handlers/to_outgoing.py index b9fae912c..4726973f2 100644 --- a/src/mailman/handlers/to_outgoing.py +++ b/src/mailman/handlers/to_outgoing.py @@ -22,10 +22,10 @@ posted to the list membership. Anything else that needs to go out to some recipient should just be placed in the out queue directly. """ -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/handlers/to_usenet.py b/src/mailman/handlers/to_usenet.py index 4bfa00c5f..f5e01ef6e 100644 --- a/src/mailman/handlers/to_usenet.py +++ b/src/mailman/handlers/to_usenet.py @@ -19,10 +19,10 @@ import logging -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.handler import IHandler +from public import public from zope.interface import implementer diff --git a/src/mailman/interfaces/action.py b/src/mailman/interfaces/action.py index dcff41cbd..08dc9c5ca 100644 --- a/src/mailman/interfaces/action.py +++ b/src/mailman/interfaces/action.py @@ -18,7 +18,7 @@ """Message actions.""" from enum import Enum -from mailman import public +from public import public @public diff --git a/src/mailman/interfaces/address.py b/src/mailman/interfaces/address.py index 8a1ac81d5..d460e96ca 100644 --- a/src/mailman/interfaces/address.py +++ b/src/mailman/interfaces/address.py @@ -17,8 +17,8 @@ """Interface for email address related information.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/api.py b/src/mailman/interfaces/api.py index 3ba158b35..e2c6645db 100644 --- a/src/mailman/interfaces/api.py +++ b/src/mailman/interfaces/api.py @@ -17,7 +17,7 @@ """REST web service API context.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/archiver.py b/src/mailman/interfaces/archiver.py index cd10b22e3..eb9227dd8 100644 --- a/src/mailman/interfaces/archiver.py +++ b/src/mailman/interfaces/archiver.py @@ -18,7 +18,7 @@ """Interface for archiving schemes.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/autorespond.py b/src/mailman/interfaces/autorespond.py index 645a6c76b..b9f3f0e3a 100644 --- a/src/mailman/interfaces/autorespond.py +++ b/src/mailman/interfaces/autorespond.py @@ -19,7 +19,7 @@ from datetime import timedelta from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/bans.py b/src/mailman/interfaces/bans.py index 055ad69a3..59928ff8e 100644 --- a/src/mailman/interfaces/bans.py +++ b/src/mailman/interfaces/bans.py @@ -17,7 +17,7 @@ """Manager of email address bans.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/bounce.py b/src/mailman/interfaces/bounce.py index 0e39ca3b9..368657c47 100644 --- a/src/mailman/interfaces/bounce.py +++ b/src/mailman/interfaces/bounce.py @@ -18,7 +18,7 @@ """Interface to bounce detection components.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/cache.py b/src/mailman/interfaces/cache.py index 74fb2084a..39d3e7c73 100644 --- a/src/mailman/interfaces/cache.py +++ b/src/mailman/interfaces/cache.py @@ -17,7 +17,7 @@ """File caches.""" -from mailman import public +from public import public from zope.interface import Interface diff --git a/src/mailman/interfaces/chain.py b/src/mailman/interfaces/chain.py index 0af9bf8e5..146abafd7 100644 --- a/src/mailman/interfaces/chain.py +++ b/src/mailman/interfaces/chain.py @@ -18,7 +18,7 @@ """Interfaces describing the basics of chains and links.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/command.py b/src/mailman/interfaces/command.py index 95719b504..be3fd5bb2 100644 --- a/src/mailman/interfaces/command.py +++ b/src/mailman/interfaces/command.py @@ -18,7 +18,7 @@ """Interfaces defining email commands.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/configuration.py b/src/mailman/interfaces/configuration.py index 2e38e614c..b4f9d696c 100644 --- a/src/mailman/interfaces/configuration.py +++ b/src/mailman/interfaces/configuration.py @@ -17,8 +17,8 @@ """Configuration system interface.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Interface diff --git a/src/mailman/interfaces/database.py b/src/mailman/interfaces/database.py index 1f658c556..052c7d4bb 100644 --- a/src/mailman/interfaces/database.py +++ b/src/mailman/interfaces/database.py @@ -17,8 +17,8 @@ """Interfaces for database interaction.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/digests.py b/src/mailman/interfaces/digests.py index cff838284..fd38b374a 100644 --- a/src/mailman/interfaces/digests.py +++ b/src/mailman/interfaces/digests.py @@ -18,7 +18,7 @@ """One last digest.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/domain.py b/src/mailman/interfaces/domain.py index b1940f400..6318e9551 100644 --- a/src/mailman/interfaces/domain.py +++ b/src/mailman/interfaces/domain.py @@ -17,8 +17,8 @@ """Interface representing domains.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/errors.py b/src/mailman/interfaces/errors.py index dbf74c035..b21d07418 100644 --- a/src/mailman/interfaces/errors.py +++ b/src/mailman/interfaces/errors.py @@ -22,7 +22,7 @@ components. More specific exceptions will be located in the relevant interfaces. """ -from mailman import public +from public import public @public diff --git a/src/mailman/interfaces/handler.py b/src/mailman/interfaces/handler.py index f6b2aea66..29061c369 100644 --- a/src/mailman/interfaces/handler.py +++ b/src/mailman/interfaces/handler.py @@ -17,7 +17,7 @@ """Interface describing a pipeline handler.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/languages.py b/src/mailman/interfaces/languages.py index b45083575..18f928be9 100644 --- a/src/mailman/interfaces/languages.py +++ b/src/mailman/interfaces/languages.py @@ -17,7 +17,7 @@ """Interfaces for managing languages.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/listmanager.py b/src/mailman/interfaces/listmanager.py index 2c7208496..dde23ab1f 100644 --- a/src/mailman/interfaces/listmanager.py +++ b/src/mailman/interfaces/listmanager.py @@ -17,8 +17,8 @@ """Interface for list storage, deleting, and finding.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py index 877016f41..359cd5069 100644 --- a/src/mailman/interfaces/mailinglist.py +++ b/src/mailman/interfaces/mailinglist.py @@ -18,8 +18,8 @@ """Interface for a mailing list.""" from enum import Enum -from mailman import public from mailman.interfaces.member import MemberRole +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/member.py b/src/mailman/interfaces/member.py index 094652521..a2a9c7cbd 100644 --- a/src/mailman/interfaces/member.py +++ b/src/mailman/interfaces/member.py @@ -18,8 +18,8 @@ """Interface describing the basics of a member.""" from enum import Enum -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/messages.py b/src/mailman/interfaces/messages.py index 2ea2aa312..29f92fdc7 100644 --- a/src/mailman/interfaces/messages.py +++ b/src/mailman/interfaces/messages.py @@ -17,7 +17,7 @@ """The message storage service.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/mime.py b/src/mailman/interfaces/mime.py index c1a6e050f..94a98b58e 100644 --- a/src/mailman/interfaces/mime.py +++ b/src/mailman/interfaces/mime.py @@ -18,7 +18,7 @@ """MIME content filtering.""" from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/mlistrequest.py b/src/mailman/interfaces/mlistrequest.py index 45712ed86..ca83f77c1 100644 --- a/src/mailman/interfaces/mlistrequest.py +++ b/src/mailman/interfaces/mlistrequest.py @@ -17,7 +17,7 @@ """Interface for a web request accessing a mailing list.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/mta.py b/src/mailman/interfaces/mta.py index 47436ead5..2917c0f79 100644 --- a/src/mailman/interfaces/mta.py +++ b/src/mailman/interfaces/mta.py @@ -17,8 +17,8 @@ """Interface for mail transport agent integration.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Interface diff --git a/src/mailman/interfaces/nntp.py b/src/mailman/interfaces/nntp.py index 72a74fe90..2bb9c45b1 100644 --- a/src/mailman/interfaces/nntp.py +++ b/src/mailman/interfaces/nntp.py @@ -18,7 +18,7 @@ """NNTP and newsgroup interfaces.""" from enum import Enum -from mailman import public +from public import public @public diff --git a/src/mailman/interfaces/pending.py b/src/mailman/interfaces/pending.py index cf92fed9e..c630e2133 100644 --- a/src/mailman/interfaces/pending.py +++ b/src/mailman/interfaces/pending.py @@ -22,7 +22,7 @@ maps these events to a unique hash that can be used as a token for end user confirmation. """ -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/pipeline.py b/src/mailman/interfaces/pipeline.py index cdef6a768..a41e9b6f7 100644 --- a/src/mailman/interfaces/pipeline.py +++ b/src/mailman/interfaces/pipeline.py @@ -17,7 +17,7 @@ """Interface for describing pipelines.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/preferences.py b/src/mailman/interfaces/preferences.py index 024fdea3c..0d830bdd7 100644 --- a/src/mailman/interfaces/preferences.py +++ b/src/mailman/interfaces/preferences.py @@ -17,7 +17,7 @@ """Interface for preferences.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/requests.py b/src/mailman/interfaces/requests.py index 3098772a9..8b316e79f 100644 --- a/src/mailman/interfaces/requests.py +++ b/src/mailman/interfaces/requests.py @@ -22,7 +22,7 @@ moderators, such as subscription requests and held messages. """ from enum import Enum -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/roster.py b/src/mailman/interfaces/roster.py index 2993e4fc4..bf8489e33 100644 --- a/src/mailman/interfaces/roster.py +++ b/src/mailman/interfaces/roster.py @@ -17,7 +17,7 @@ """Interface for a roster of members.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/rules.py b/src/mailman/interfaces/rules.py index 9f5f1365e..cca8cf565 100644 --- a/src/mailman/interfaces/rules.py +++ b/src/mailman/interfaces/rules.py @@ -17,7 +17,7 @@ """Interface describing the basics of rules.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/runner.py b/src/mailman/interfaces/runner.py index e39efb097..06caf0e95 100644 --- a/src/mailman/interfaces/runner.py +++ b/src/mailman/interfaces/runner.py @@ -17,7 +17,7 @@ """Interface for runners.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/styles.py b/src/mailman/interfaces/styles.py index a183933f7..e4b5288c1 100644 --- a/src/mailman/interfaces/styles.py +++ b/src/mailman/interfaces/styles.py @@ -17,8 +17,8 @@ """Interfaces for list styles.""" -from mailman import public from mailman.interfaces.errors import MailmanError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/subscriptions.py b/src/mailman/interfaces/subscriptions.py index 284261de5..dc3563def 100644 --- a/src/mailman/interfaces/subscriptions.py +++ b/src/mailman/interfaces/subscriptions.py @@ -19,9 +19,9 @@ from collections import namedtuple from enum import Enum -from mailman import public from mailman.interfaces.errors import MailmanError from mailman.interfaces.member import DeliveryMode, MembershipError +from public import public from zope.interface import Interface diff --git a/src/mailman/interfaces/switchboard.py b/src/mailman/interfaces/switchboard.py index 4428f4b12..d9e2f9aab 100644 --- a/src/mailman/interfaces/switchboard.py +++ b/src/mailman/interfaces/switchboard.py @@ -17,7 +17,7 @@ """Interface for switchboards.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/system.py b/src/mailman/interfaces/system.py index 1b0a9a2de..440611537 100644 --- a/src/mailman/interfaces/system.py +++ b/src/mailman/interfaces/system.py @@ -17,7 +17,7 @@ """System information.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/template.py b/src/mailman/interfaces/template.py index 24f956b78..6b6bcd7a3 100644 --- a/src/mailman/interfaces/template.py +++ b/src/mailman/interfaces/template.py @@ -17,7 +17,7 @@ """Template downloader with cache.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/user.py b/src/mailman/interfaces/user.py index a6c470b6e..e103f38fd 100644 --- a/src/mailman/interfaces/user.py +++ b/src/mailman/interfaces/user.py @@ -17,8 +17,8 @@ """Interface describing the basics of a user.""" -from mailman import public from mailman.interfaces.address import AddressError +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/usermanager.py b/src/mailman/interfaces/usermanager.py index 87d4bf6e2..4cd8af7aa 100644 --- a/src/mailman/interfaces/usermanager.py +++ b/src/mailman/interfaces/usermanager.py @@ -17,7 +17,7 @@ """Interface describing the user management service.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/interfaces/workflow.py b/src/mailman/interfaces/workflow.py index 9846f4683..b0b5a23da 100644 --- a/src/mailman/interfaces/workflow.py +++ b/src/mailman/interfaces/workflow.py @@ -17,7 +17,7 @@ """Interfaces describing the state of a workflow.""" -from mailman import public +from public import public from zope.interface import Attribute, Interface diff --git a/src/mailman/languages/language.py b/src/mailman/languages/language.py index 014852c5c..afe217048 100644 --- a/src/mailman/languages/language.py +++ b/src/mailman/languages/language.py @@ -18,8 +18,8 @@ """The representation of a language.""" -from mailman import public from mailman.interfaces.languages import ILanguage +from public import public from zope.interface import implementer diff --git a/src/mailman/languages/manager.py b/src/mailman/languages/manager.py index 9832eb3eb..5e56ec0e0 100644 --- a/src/mailman/languages/manager.py +++ b/src/mailman/languages/manager.py @@ -17,10 +17,10 @@ """Language manager.""" -from mailman import public from mailman.interfaces.configuration import ConfigurationUpdatedEvent from mailman.interfaces.languages import ILanguageManager from mailman.languages.language import Language +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/model/address.py b/src/mailman/model/address.py index a31e9a429..63896c728 100644 --- a/src/mailman/model/address.py +++ b/src/mailman/model/address.py @@ -18,12 +18,12 @@ """Model for addresses.""" from email.utils import formataddr -from mailman import public from mailman.database.model import Model from mailman.database.types import SAUnicode from mailman.interfaces.address import ( AddressVerificationEvent, IAddress, IEmailValidator) from mailman.utilities.datetime import now +from public import public from sqlalchemy import Column, DateTime, ForeignKey, Integer from sqlalchemy.orm import backref, relationship from zope.component import getUtility diff --git a/src/mailman/model/autorespond.py b/src/mailman/model/autorespond.py index 20c19889f..e9509c4f8 100644 --- a/src/mailman/model/autorespond.py +++ b/src/mailman/model/autorespond.py @@ -17,13 +17,13 @@ """Autoresponder records.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import Enum from mailman.interfaces.autorespond import ( IAutoResponseRecord, IAutoResponseSet, Response) from mailman.utilities.datetime import today +from public import public from sqlalchemy import Column, Date, ForeignKey, Integer, desc from sqlalchemy.orm import relationship from zope.interface import implementer diff --git a/src/mailman/model/bans.py b/src/mailman/model/bans.py index c8d43c5ae..1c4cbde8c 100644 --- a/src/mailman/model/bans.py +++ b/src/mailman/model/bans.py @@ -19,12 +19,12 @@ import re -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode from mailman.interfaces.bans import IBan, IBanManager from mailman.utilities.queries import QuerySequence +from public import public from sqlalchemy import Column, Integer from zope.interface import implementer diff --git a/src/mailman/model/bounce.py b/src/mailman/model/bounce.py index 856d91f20..6db55a3c7 100644 --- a/src/mailman/model/bounce.py +++ b/src/mailman/model/bounce.py @@ -17,13 +17,13 @@ """Bounce support.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import Enum, SAUnicode from mailman.interfaces.bounce import ( BounceContext, IBounceEvent, IBounceProcessor) from mailman.utilities.datetime import now +from public import public from sqlalchemy import Boolean, Column, DateTime, Integer from zope.interface import implementer diff --git a/src/mailman/model/cache.py b/src/mailman/model/cache.py index 6be5fbc9d..d1ef9f05c 100644 --- a/src/mailman/model/cache.py +++ b/src/mailman/model/cache.py @@ -22,13 +22,13 @@ import hashlib from contextlib import ExitStack from lazr.config import as_timedelta -from mailman import public from mailman.config import config from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode from mailman.interfaces.cache import ICacheManager from mailman.utilities.datetime import now +from public import public from sqlalchemy import Boolean, Column, DateTime, Integer from zope.interface import implementer diff --git a/src/mailman/model/digests.py b/src/mailman/model/digests.py index ac49249cc..a0daaebbc 100644 --- a/src/mailman/model/digests.py +++ b/src/mailman/model/digests.py @@ -17,11 +17,11 @@ """One last digest.""" -from mailman import public from mailman.database.model import Model from mailman.database.types import Enum from mailman.interfaces.digests import IOneLastDigest from mailman.interfaces.member import DeliveryMode +from public import public from sqlalchemy import Column, ForeignKey, Integer from sqlalchemy.orm import relationship from zope.interface import implementer diff --git a/src/mailman/model/domain.py b/src/mailman/model/domain.py index 5bb569585..2622ba80b 100644 --- a/src/mailman/model/domain.py +++ b/src/mailman/model/domain.py @@ -17,7 +17,6 @@ """Domains.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode @@ -27,6 +26,7 @@ from mailman.interfaces.domain import ( from mailman.interfaces.user import IUser from mailman.interfaces.usermanager import IUserManager from mailman.model.mailinglist import MailingList +from public import public from sqlalchemy import Column, Integer from sqlalchemy.orm import relationship from zope.component import getUtility diff --git a/src/mailman/model/language.py b/src/mailman/model/language.py index 596e580e1..c762b9715 100644 --- a/src/mailman/model/language.py +++ b/src/mailman/model/language.py @@ -17,10 +17,10 @@ """Model for languages.""" -from mailman import public from mailman.database.model import Model from mailman.database.types import SAUnicode from mailman.interfaces.languages import ILanguage +from public import public from sqlalchemy import Column, Integer from zope.interface import implementer diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py index e2519af5b..bd07e6c27 100644 --- a/src/mailman/model/listmanager.py +++ b/src/mailman/model/listmanager.py @@ -17,7 +17,6 @@ """A mailing list manager.""" -from mailman import public from mailman.database.transaction import dbconnection from mailman.interfaces.address import InvalidEmailAddressError from mailman.interfaces.listmanager import ( @@ -30,6 +29,7 @@ from mailman.model.mailinglist import ( from mailman.model.mime import ContentFilter from mailman.utilities.datetime import now from mailman.utilities.queries import QuerySequence +from public import public from zope.event import notify from zope.interface import implementer diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index eec58ad04..bd6538aaf 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -19,7 +19,6 @@ import os -from mailman import public from mailman.config import config from mailman.database.model import Model from mailman.database.transaction import dbconnection @@ -49,6 +48,7 @@ from mailman.model.mime import ContentFilter from mailman.model.preferences import Preferences from mailman.utilities.filesystem import makedirs from mailman.utilities.string import expand +from public import public from sqlalchemy import ( Boolean, Column, DateTime, Float, ForeignKey, Integer, Interval, LargeBinary, PickleType) diff --git a/src/mailman/model/member.py b/src/mailman/model/member.py index aacaa73b6..93d0c7feb 100644 --- a/src/mailman/model/member.py +++ b/src/mailman/model/member.py @@ -17,7 +17,6 @@ """Model for members.""" -from mailman import public from mailman.core.constants import system_preferences from mailman.database.model import Model from mailman.database.transaction import dbconnection @@ -30,6 +29,7 @@ from mailman.interfaces.member import ( from mailman.interfaces.user import IUser, UnverifiedAddressError from mailman.interfaces.usermanager import IUserManager from mailman.utilities.uid import UIDFactory +from public import public from sqlalchemy import Column, ForeignKey, Integer from sqlalchemy.orm import relationship from zope.component import getUtility diff --git a/src/mailman/model/message.py b/src/mailman/model/message.py index 576baab5c..233e8b5b5 100644 --- a/src/mailman/model/message.py +++ b/src/mailman/model/message.py @@ -17,11 +17,11 @@ """Model for messages.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode from mailman.interfaces.messages import IMessage +from public import public from sqlalchemy import Column, Integer from zope.interface import implementer diff --git a/src/mailman/model/messagestore.py b/src/mailman/model/messagestore.py index 8949c56c6..dc037c44f 100644 --- a/src/mailman/model/messagestore.py +++ b/src/mailman/model/messagestore.py @@ -21,13 +21,13 @@ import os import errno import pickle -from mailman import public from mailman.config import config from mailman.database.transaction import dbconnection from mailman.interfaces.messages import IMessageStore from mailman.model.message import Message from mailman.utilities.email import add_message_hash from mailman.utilities.filesystem import makedirs, safe_remove +from public import public from zope.interface import implementer diff --git a/src/mailman/model/mime.py b/src/mailman/model/mime.py index da5f11f05..a21cfb35d 100644 --- a/src/mailman/model/mime.py +++ b/src/mailman/model/mime.py @@ -17,10 +17,10 @@ """The content filter.""" -from mailman import public from mailman.database.model import Model from mailman.database.types import Enum, SAUnicode from mailman.interfaces.mime import FilterType, IContentFilter +from public import public from sqlalchemy import Column, ForeignKey, Integer from sqlalchemy.orm import relationship from zope.interface import implementer diff --git a/src/mailman/model/pending.py b/src/mailman/model/pending.py index 7e7f0b2eb..5889f9cc1 100644 --- a/src/mailman/model/pending.py +++ b/src/mailman/model/pending.py @@ -20,7 +20,6 @@ import json from lazr.config import as_timedelta -from mailman import public from mailman.config import config from mailman.database.model import Model from mailman.database.transaction import dbconnection @@ -29,6 +28,7 @@ from mailman.interfaces.pending import ( IPendable, IPended, IPendedKeyValue, IPendings) from mailman.utilities.datetime import now from mailman.utilities.uid import TokenFactory +from public import public from sqlalchemy import Column, DateTime, ForeignKey, Integer, and_ from sqlalchemy.orm import aliased, relationship from zope.interface import implementer diff --git a/src/mailman/model/preferences.py b/src/mailman/model/preferences.py index 366ed97c2..4e57ce659 100644 --- a/src/mailman/model/preferences.py +++ b/src/mailman/model/preferences.py @@ -17,13 +17,13 @@ """Model for preferences.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import Enum, SAUnicode from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.interfaces.preferences import IPreferences +from public import public from sqlalchemy import Boolean, Column, Integer from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/model/requests.py b/src/mailman/model/requests.py index 0f0f96dfe..04717f49a 100644 --- a/src/mailman/model/requests.py +++ b/src/mailman/model/requests.py @@ -18,7 +18,6 @@ """Implementations of the pending requests interfaces.""" from datetime import timedelta -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import Enum, SAUnicode @@ -26,6 +25,7 @@ from mailman.interfaces.pending import IPendable, IPendings from mailman.interfaces.requests import IListRequests, RequestType from mailman.utilities.queries import QuerySequence from pickle import dumps, loads +from public import public from sqlalchemy import Column, ForeignKey, Integer from sqlalchemy.orm import relationship from zope.component import getUtility diff --git a/src/mailman/model/roster.py b/src/mailman/model/roster.py index 5dc0423b2..d3dc1b661 100644 --- a/src/mailman/model/roster.py +++ b/src/mailman/model/roster.py @@ -22,12 +22,12 @@ the ones that fit a particular role. These are used as the member, owner, moderator, and administrator roster filters. """ -from mailman import public from mailman.database.transaction import dbconnection from mailman.interfaces.member import DeliveryMode, MemberRole from mailman.interfaces.roster import IRoster from mailman.model.address import Address from mailman.model.member import Member +from public import public from sqlalchemy import or_ from zope.interface import implementer diff --git a/src/mailman/model/subscriptions.py b/src/mailman/model/subscriptions.py index d3fdc3a8a..485524a68 100644 --- a/src/mailman/model/subscriptions.py +++ b/src/mailman/model/subscriptions.py @@ -17,7 +17,6 @@ """Subscription services.""" -from mailman import public from mailman.app.membership import delete_member from mailman.database.transaction import dbconnection from mailman.interfaces.listmanager import IListManager, NoSuchListError @@ -30,6 +29,7 @@ from mailman.model.member import Member from mailman.model.user import User from mailman.utilities.queries import QuerySequence from operator import attrgetter +from public import public from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/model/template.py b/src/mailman/model/template.py index b09c644bb..eb776293f 100644 --- a/src/mailman/model/template.py +++ b/src/mailman/model/template.py @@ -19,7 +19,6 @@ import logging -from mailman import public from mailman.config import config from mailman.database.model import Model from mailman.database.transaction import dbconnection @@ -32,6 +31,7 @@ from mailman.interfaces.template import ( from mailman.utilities import protocols from mailman.utilities.i18n import find from mailman.utilities.string import expand +from public import public from requests import HTTPError from sqlalchemy import Column, Integer from urllib.error import URLError diff --git a/src/mailman/model/uid.py b/src/mailman/model/uid.py index 2cf61668f..9daefa318 100644 --- a/src/mailman/model/uid.py +++ b/src/mailman/model/uid.py @@ -17,10 +17,10 @@ """Unique IDs.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import UUID +from public import public from sqlalchemy import Column, Integer diff --git a/src/mailman/model/user.py b/src/mailman/model/user.py index edda2a9e8..dc9c097d5 100644 --- a/src/mailman/model/user.py +++ b/src/mailman/model/user.py @@ -17,7 +17,6 @@ """Model for users.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode, UUID @@ -31,6 +30,7 @@ from mailman.model.preferences import Preferences from mailman.model.roster import Memberships from mailman.utilities.datetime import factory as date_factory from mailman.utilities.uid import UIDFactory +from public import public from sqlalchemy import ( Boolean, Column, DateTime, ForeignKey, Integer) from sqlalchemy.orm import backref, relationship diff --git a/src/mailman/model/usermanager.py b/src/mailman/model/usermanager.py index fba8e2ec0..2a62e0cf1 100644 --- a/src/mailman/model/usermanager.py +++ b/src/mailman/model/usermanager.py @@ -17,7 +17,6 @@ """A user manager.""" -from mailman import public from mailman.database.transaction import dbconnection from mailman.interfaces.address import ExistingAddressError from mailman.interfaces.usermanager import IUserManager @@ -27,6 +26,7 @@ from mailman.model.digests import OneLastDigest from mailman.model.member import Member from mailman.model.preferences import Preferences from mailman.model.user import User +from public import public from zope.interface import implementer diff --git a/src/mailman/model/workflow.py b/src/mailman/model/workflow.py index 53763a0e8..8b782b5e0 100644 --- a/src/mailman/model/workflow.py +++ b/src/mailman/model/workflow.py @@ -17,11 +17,11 @@ """Model for workflow states.""" -from mailman import public from mailman.database.model import Model from mailman.database.transaction import dbconnection from mailman.database.types import SAUnicode from mailman.interfaces.workflow import IWorkflowState, IWorkflowStateManager +from public import public from sqlalchemy import Column from zope.interface import implementer diff --git a/src/mailman/mta/aliases.py b/src/mailman/mta/aliases.py index dc434c613..889375c04 100644 --- a/src/mailman/mta/aliases.py +++ b/src/mailman/mta/aliases.py @@ -17,8 +17,8 @@ """Utility for generating all the aliases of a mailing list.""" -from mailman import public from mailman.interfaces.mta import IMailTransportAgentAliases +from public import public from zope.interface import implementer diff --git a/src/mailman/mta/base.py b/src/mailman/mta/base.py index 679faefd5..4f5bb1d58 100644 --- a/src/mailman/mta/base.py +++ b/src/mailman/mta/base.py @@ -22,10 +22,10 @@ import socket import logging import smtplib -from mailman import public from mailman.config import config from mailman.interfaces.mta import IMailTransportAgentDelivery from mailman.mta.connection import Connection +from public import public from zope.interface import implementer diff --git a/src/mailman/mta/bulk.py b/src/mailman/mta/bulk.py index 1741e0d4c..91b04957a 100644 --- a/src/mailman/mta/bulk.py +++ b/src/mailman/mta/bulk.py @@ -17,8 +17,8 @@ """Bulk message delivery.""" -from mailman import public from mailman.mta.base import BaseDelivery +from public import public # A mapping of top-level domains to bucket numbers. The zeroth bucket is diff --git a/src/mailman/mta/connection.py b/src/mailman/mta/connection.py index 44cc31d86..318bc5e8e 100644 --- a/src/mailman/mta/connection.py +++ b/src/mailman/mta/connection.py @@ -22,8 +22,8 @@ import smtplib from contextlib import suppress from lazr.config import as_boolean -from mailman import public from mailman.config import config +from public import public log = logging.getLogger('mailman.smtp') diff --git a/src/mailman/mta/decorating.py b/src/mailman/mta/decorating.py index e9d6f5785..32db852da 100644 --- a/src/mailman/mta/decorating.py +++ b/src/mailman/mta/decorating.py @@ -17,9 +17,9 @@ """Individualized delivery with header/footer decorations.""" -from mailman import public from mailman.config import config from mailman.mta.verp import VERPDelivery +from public import public @public diff --git a/src/mailman/mta/deliver.py b/src/mailman/mta/deliver.py index a5a4e2433..7624979bf 100644 --- a/src/mailman/mta/deliver.py +++ b/src/mailman/mta/deliver.py @@ -20,7 +20,6 @@ import time import logging -from mailman import public from mailman.config import config from mailman.interfaces.mailinglist import Personalization from mailman.interfaces.mta import SomeRecipientsFailed @@ -30,6 +29,7 @@ from mailman.mta.decorating import DecoratingMixin from mailman.mta.personalized import PersonalizedMixin from mailman.mta.verp import VERPMixin from mailman.utilities.string import expand +from public import public COMMA = ',' diff --git a/src/mailman/mta/exim4.py b/src/mailman/mta/exim4.py index 7151768a8..ec2e77708 100644 --- a/src/mailman/mta/exim4.py +++ b/src/mailman/mta/exim4.py @@ -17,8 +17,8 @@ """Creation/deletion hooks for the Exim4 MTA.""" -from mailman import public from mailman.interfaces.mta import IMailTransportAgentLifecycle +from public import public from zope.interface import implementer diff --git a/src/mailman/mta/null.py b/src/mailman/mta/null.py index 165c5f0ee..e5368e689 100644 --- a/src/mailman/mta/null.py +++ b/src/mailman/mta/null.py @@ -20,8 +20,8 @@ Exim one example of an MTA that Just Works. """ -from mailman import public from mailman.interfaces.mta import IMailTransportAgentLifecycle +from public import public from zope.interface import implementer diff --git a/src/mailman/mta/personalized.py b/src/mailman/mta/personalized.py index 7cfbfff43..01ba686f3 100644 --- a/src/mailman/mta/personalized.py +++ b/src/mailman/mta/personalized.py @@ -19,10 +19,10 @@ from email.header import Header from email.utils import formataddr -from mailman import public from mailman.interfaces.mailinglist import Personalization from mailman.interfaces.usermanager import IUserManager from mailman.mta.verp import VERPDelivery +from public import public from zope.component import getUtility diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py index ff4b92117..07bf17a22 100644 --- a/src/mailman/mta/postfix.py +++ b/src/mailman/mta/postfix.py @@ -21,7 +21,6 @@ import os import logging from flufl.lock import Lock -from mailman import public from mailman.config import config from mailman.config.config import external_configuration from mailman.interfaces.listmanager import IListManager @@ -29,6 +28,7 @@ from mailman.interfaces.mta import ( IMailTransportAgentAliases, IMailTransportAgentLifecycle) from mailman.utilities.datetime import now from operator import attrgetter +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/mta/verp.py b/src/mailman/mta/verp.py index 8ede6cb67..6ce80c795 100644 --- a/src/mailman/mta/verp.py +++ b/src/mailman/mta/verp.py @@ -19,11 +19,11 @@ import logging -from mailman import public from mailman.config import config from mailman.mta.base import IndividualDelivery from mailman.utilities.email import split_email from mailman.utilities.string import expand +from public import public DOT = '.' diff --git a/src/mailman/rest/addresses.py b/src/mailman/rest/addresses.py index f0cb8edef..8e8b543b9 100644 --- a/src/mailman/rest/addresses.py +++ b/src/mailman/rest/addresses.py @@ -17,7 +17,6 @@ """REST for addresses.""" -from mailman import public from mailman.interfaces.address import ( ExistingAddressError, InvalidEmailAddressError) from mailman.interfaces.usermanager import IUserManager @@ -29,6 +28,7 @@ from mailman.rest.preferences import Preferences from mailman.rest.validator import Validator from mailman.utilities.datetime import now from operator import attrgetter +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/bans.py b/src/mailman/rest/bans.py index ce575885b..981c1b549 100644 --- a/src/mailman/rest/bans.py +++ b/src/mailman/rest/bans.py @@ -17,12 +17,12 @@ """REST for banned emails.""" -from mailman import public from mailman.interfaces.bans import IBanManager from mailman.rest.helpers import ( CollectionMixin, bad_request, child, created, etag, no_content, not_found, okay) from mailman.rest.validator import Validator +from public import public class _BannedBase: diff --git a/src/mailman/rest/docs/__init__.py b/src/mailman/rest/docs/__init__.py index 5a039ac3d..dc27a6525 100644 --- a/src/mailman/rest/docs/__init__.py +++ b/src/mailman/rest/docs/__init__.py @@ -20,9 +20,9 @@ import threading from http.server import BaseHTTPRequestHandler, HTTPServer -from mailman import public from mailman.testing.helpers import wait_for_webservice from mailman.testing.layers import RESTLayer +from public import public # New in Python 3.5. diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py index c6b8daa7c..ce96204b4 100644 --- a/src/mailman/rest/domains.py +++ b/src/mailman/rest/domains.py @@ -17,7 +17,6 @@ """REST for domains.""" -from mailman import public from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) from mailman.rest.helpers import ( @@ -27,6 +26,7 @@ from mailman.rest.lists import ListsForDomain from mailman.rest.uris import ADomainURI, AllDomainURIs from mailman.rest.users import ListOfDomainOwners, OwnersForDomain from mailman.rest.validator import Validator, list_of_strings_validator +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/header_matches.py b/src/mailman/rest/header_matches.py index 25c519ef3..13dad97ad 100644 --- a/src/mailman/rest/header_matches.py +++ b/src/mailman/rest/header_matches.py @@ -17,13 +17,13 @@ """REST API for a mailing list's header matches.""" -from mailman import public from mailman.interfaces.action import Action from mailman.interfaces.mailinglist import IHeaderMatchList from mailman.rest.helpers import ( CollectionMixin, bad_request, child, created, etag, no_content, not_found, okay) from mailman.rest.validator import Validator, enum_validator +from public import public def lowercase(value): diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index a4b072408..6b45eb78a 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -27,9 +27,9 @@ from email.header import Header from email.message import Message from enum import Enum from lazr.config import as_boolean -from mailman import public from mailman.config import config from pprint import pformat +from public import public class ExtendedEncoder(json.JSONEncoder): diff --git a/src/mailman/rest/listconf.py b/src/mailman/rest/listconf.py index 861e54dd1..94598b0ab 100644 --- a/src/mailman/rest/listconf.py +++ b/src/mailman/rest/listconf.py @@ -18,7 +18,6 @@ """Mailing list configuration via REST API.""" from lazr.config import as_boolean, as_timedelta -from mailman import public from mailman.config import config from mailman.interfaces.action import Action from mailman.interfaces.archiver import ArchivePolicy @@ -32,6 +31,7 @@ from mailman.rest.helpers import ( from mailman.rest.validator import ( PatchValidator, ReadOnlyPATCHRequestError, UnknownPATCHRequestError, Validator, enum_validator, list_of_strings_validator) +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py index 1fdf595fb..cdebdebd9 100644 --- a/src/mailman/rest/lists.py +++ b/src/mailman/rest/lists.py @@ -18,7 +18,6 @@ """REST for mailing lists.""" from lazr.config import as_boolean -from mailman import public from mailman.app.digests import ( bump_digest_number_and_volume, maybe_send_digest_now) from mailman.app.lifecycle import create_list, remove_list @@ -41,6 +40,7 @@ from mailman.rest.post_moderation import HeldMessages from mailman.rest.sub_moderation import SubscriptionRequests from mailman.rest.uris import AListURI, AllListURIs from mailman.rest.validator import Validator, list_of_strings_validator +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index b35440af4..ea7eaa394 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -17,7 +17,6 @@ """REST for members.""" -from mailman import public from mailman.app.membership import add_member, delete_member from mailman.interfaces.action import Action from mailman.interfaces.address import IAddress @@ -36,6 +35,7 @@ from mailman.rest.helpers import ( from mailman.rest.preferences import Preferences, ReadOnlyPreferences from mailman.rest.validator import ( Validator, enum_validator, subscriber_validator) +from public import public from uuid import UUID from zope.component import getUtility diff --git a/src/mailman/rest/post_moderation.py b/src/mailman/rest/post_moderation.py index 33a32de20..9a56ada00 100644 --- a/src/mailman/rest/post_moderation.py +++ b/src/mailman/rest/post_moderation.py @@ -17,7 +17,6 @@ """REST API for held message moderation.""" -from mailman import public from mailman.app.moderator import handle_message from mailman.interfaces.action import Action from mailman.interfaces.messages import IMessageStore @@ -25,6 +24,7 @@ from mailman.interfaces.requests import IListRequests, RequestType from mailman.rest.helpers import ( CollectionMixin, bad_request, child, etag, no_content, not_found, okay) from mailman.rest.validator import Validator, enum_validator +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/preferences.py b/src/mailman/rest/preferences.py index cf26380fe..549751d1e 100644 --- a/src/mailman/rest/preferences.py +++ b/src/mailman/rest/preferences.py @@ -18,12 +18,12 @@ """Preferences.""" from lazr.config import as_boolean -from mailman import public from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.rest.helpers import ( GetterSetter, bad_request, etag, no_content, not_found, okay) from mailman.rest.validator import ( Validator, enum_validator, language_validator) +from public import public PREFERENCES = ( diff --git a/src/mailman/rest/queues.py b/src/mailman/rest/queues.py index 9fa5b9dc6..27e9c698e 100644 --- a/src/mailman/rest/queues.py +++ b/src/mailman/rest/queues.py @@ -17,13 +17,13 @@ """/queues.""" -from mailman import public from mailman.app.inject import inject_text from mailman.config import config from mailman.interfaces.listmanager import IListManager from mailman.rest.helpers import ( CollectionMixin, bad_request, created, etag, no_content, not_found, okay) from mailman.rest.validator import Validator +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py index 7f6be0353..c4c0b865f 100644 --- a/src/mailman/rest/root.py +++ b/src/mailman/rest/root.py @@ -17,7 +17,6 @@ """The root of the REST API.""" -from mailman import public from mailman.config import config from mailman.core.api import API30, API31 from mailman.core.constants import system_preferences @@ -36,6 +35,7 @@ from mailman.rest.queues import AQueue, AQueueFile, AllQueues from mailman.rest.templates import TemplateFinder from mailman.rest.uris import ASiteURI, AllSiteURIs from mailman.rest.users import AUser, AllUsers, ServerOwners +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/sub_moderation.py b/src/mailman/rest/sub_moderation.py index 55b6a7609..39976826c 100644 --- a/src/mailman/rest/sub_moderation.py +++ b/src/mailman/rest/sub_moderation.py @@ -17,7 +17,6 @@ """REST API for held subscription requests.""" -from mailman import public from mailman.app.moderator import send_rejection from mailman.core.i18n import _ from mailman.interfaces.action import Action @@ -28,6 +27,7 @@ from mailman.rest.helpers import ( CollectionMixin, bad_request, child, conflict, etag, no_content, not_found, okay) from mailman.rest.validator import Validator, enum_validator +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/templates.py b/src/mailman/rest/templates.py index fe5e34a8e..7f4e5a3af 100644 --- a/src/mailman/rest/templates.py +++ b/src/mailman/rest/templates.py @@ -17,9 +17,9 @@ """Template finder.""" -from mailman import public from mailman.rest.helpers import not_found from mailman.utilities.i18n import TemplateNotFoundError, find +from public import public # Use mimetypes.guess_all_extensions()? diff --git a/src/mailman/rest/uris.py b/src/mailman/rest/uris.py index 2fc062262..d94b3b237 100644 --- a/src/mailman/rest/uris.py +++ b/src/mailman/rest/uris.py @@ -17,12 +17,12 @@ """URI templates.""" -from mailman import public from mailman.interfaces.template import ALL_TEMPLATES, ITemplateManager from mailman.rest.helpers import ( CollectionMixin, bad_request, etag, no_content, not_found, okay) from mailman.rest.validator import Validator from operator import attrgetter +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/users.py b/src/mailman/rest/users.py index f9ce9b132..c50bfe3d0 100644 --- a/src/mailman/rest/users.py +++ b/src/mailman/rest/users.py @@ -19,7 +19,6 @@ from functools import lru_cache from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.interfaces.address import ExistingAddressError from mailman.interfaces.usermanager import IUserManager @@ -32,6 +31,7 @@ from mailman.rest.validator import ( PatchValidator, ReadOnlyPATCHRequestError, UnknownPATCHRequestError, Validator, list_of_strings_validator) from passlib.utils import generate_password as generate +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/validator.py b/src/mailman/rest/validator.py index 19e8d684a..439c25b8e 100644 --- a/src/mailman/rest/validator.py +++ b/src/mailman/rest/validator.py @@ -17,10 +17,10 @@ """REST web form validation.""" -from mailman import public from mailman.interfaces.address import IEmailValidator from mailman.interfaces.errors import MailmanError from mailman.interfaces.languages import ILanguageManager +from public import public from zope.component import getUtility diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py index 3ba122c00..b2dbc7409 100644 --- a/src/mailman/rest/wsgiapp.py +++ b/src/mailman/rest/wsgiapp.py @@ -23,10 +23,10 @@ import logging from base64 import b64decode from falcon import API, HTTPUnauthorized from falcon.routing import create_http_method_map -from mailman import public from mailman.config import config from mailman.database.transaction import transactional from mailman.rest.root import Root +from public import public from wsgiref.simple_server import ( WSGIRequestHandler, WSGIServer, make_server as wsgi_server) diff --git a/src/mailman/rules/administrivia.py b/src/mailman/rules/administrivia.py index e5defee6e..6dc6c38b4 100644 --- a/src/mailman/rules/administrivia.py +++ b/src/mailman/rules/administrivia.py @@ -18,10 +18,10 @@ """The administrivia rule.""" from email.iterators import typed_subpart_iterator -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer # The list of email commands we search for in the Subject header and payload. diff --git a/src/mailman/rules/any.py b/src/mailman/rules/any.py index 466735ebe..6d3bbe21f 100644 --- a/src/mailman/rules/any.py +++ b/src/mailman/rules/any.py @@ -17,9 +17,9 @@ """Check if any previous rules have matched.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/approved.py b/src/mailman/rules/approved.py index a4ea1145e..66f21c8eb 100644 --- a/src/mailman/rules/approved.py +++ b/src/mailman/rules/approved.py @@ -20,10 +20,10 @@ import re from email.iterators import typed_subpart_iterator -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/banned_address.py b/src/mailman/rules/banned_address.py index 8ed33a5e6..850f101db 100644 --- a/src/mailman/rules/banned_address.py +++ b/src/mailman/rules/banned_address.py @@ -17,10 +17,10 @@ """Banned addresses rule.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.bans import IBanManager from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/emergency.py b/src/mailman/rules/emergency.py index 442ccf136..59c0c6a84 100644 --- a/src/mailman/rules/emergency.py +++ b/src/mailman/rules/emergency.py @@ -17,9 +17,9 @@ """The emergency hold rule.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/implicit_dest.py b/src/mailman/rules/implicit_dest.py index c0e116d1c..88429a6ac 100644 --- a/src/mailman/rules/implicit_dest.py +++ b/src/mailman/rules/implicit_dest.py @@ -21,10 +21,10 @@ import re from contextlib import suppress from email.utils import getaddresses -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.mailinglist import IAcceptableAliasSet from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/loop.py b/src/mailman/rules/loop.py index 0f8047e76..d9b7c299d 100644 --- a/src/mailman/rules/loop.py +++ b/src/mailman/rules/loop.py @@ -17,9 +17,9 @@ """Look for a posting loop.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/max_recipients.py b/src/mailman/rules/max_recipients.py index 61df613cb..1d38e28c1 100644 --- a/src/mailman/rules/max_recipients.py +++ b/src/mailman/rules/max_recipients.py @@ -18,9 +18,9 @@ """The maximum number of recipients rule.""" from email.utils import getaddresses -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/max_size.py b/src/mailman/rules/max_size.py index 8911e97fd..c5c492347 100644 --- a/src/mailman/rules/max_size.py +++ b/src/mailman/rules/max_size.py @@ -17,9 +17,9 @@ """The maximum message size rule.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/moderation.py b/src/mailman/rules/moderation.py index 20b238eab..b52ecff3e 100644 --- a/src/mailman/rules/moderation.py +++ b/src/mailman/rules/moderation.py @@ -19,13 +19,13 @@ import re -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.action import Action from mailman.interfaces.bans import IBanManager from mailman.interfaces.member import MemberRole from mailman.interfaces.rules import IRule from mailman.interfaces.usermanager import IUserManager +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/rules/news_moderation.py b/src/mailman/rules/news_moderation.py index 63a7e93b0..8d0fe3402 100644 --- a/src/mailman/rules/news_moderation.py +++ b/src/mailman/rules/news_moderation.py @@ -17,10 +17,10 @@ """The news moderation rule.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.nntp import NewsgroupModeration from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/no_subject.py b/src/mailman/rules/no_subject.py index ed020b81e..f3eba625a 100644 --- a/src/mailman/rules/no_subject.py +++ b/src/mailman/rules/no_subject.py @@ -17,9 +17,9 @@ """The no-Subject header rule.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/suspicious.py b/src/mailman/rules/suspicious.py index 679605fd6..049df0a61 100644 --- a/src/mailman/rules/suspicious.py +++ b/src/mailman/rules/suspicious.py @@ -20,9 +20,9 @@ import re import logging -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/rules/truth.py b/src/mailman/rules/truth.py index 9883a0e60..224ceeaad 100644 --- a/src/mailman/rules/truth.py +++ b/src/mailman/rules/truth.py @@ -17,9 +17,9 @@ """A rule which always matches.""" -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.rules import IRule +from public import public from zope.interface import implementer diff --git a/src/mailman/runners/archive.py b/src/mailman/runners/archive.py index 23b7b164d..073f72d52 100644 --- a/src/mailman/runners/archive.py +++ b/src/mailman/runners/archive.py @@ -23,12 +23,12 @@ import logging from datetime import datetime from email.utils import mktime_tz, parsedate_tz from lazr.config import as_timedelta -from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.archiver import ClobberDate from mailman.interfaces.mailinglist import IListArchiverSet from mailman.utilities.datetime import RFC822_DATE_FMT, now +from public import public log = logging.getLogger('mailman.archiver') diff --git a/src/mailman/runners/bounce.py b/src/mailman/runners/bounce.py index 4150dc9b5..40ea840e7 100644 --- a/src/mailman/runners/bounce.py +++ b/src/mailman/runners/bounce.py @@ -20,10 +20,10 @@ import logging from flufl.bounce import all_failures, scan_message -from mailman import public from mailman.app.bounces import ProbeVERP, StandardVERP, maybe_forward from mailman.core.runner import Runner from mailman.interfaces.bounce import BounceContext, IBounceProcessor +from public import public from zope.component import getUtility diff --git a/src/mailman/runners/command.py b/src/mailman/runners/command.py index ba10988e3..a52dd541d 100644 --- a/src/mailman/runners/command.py +++ b/src/mailman/runners/command.py @@ -30,13 +30,13 @@ from email.errors import HeaderParseError from email.header import decode_header, make_header from email.iterators import typed_subpart_iterator from io import StringIO -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.runner import Runner from mailman.email.message import UserNotification from mailman.interfaces.command import ContinueProcessing, IEmailResults from mailman.interfaces.languages import ILanguageManager +from public import public from zope.component import getUtility from zope.interface import implementer diff --git a/src/mailman/runners/digest.py b/src/mailman/runners/digest.py index 4971965fa..284056e3a 100644 --- a/src/mailman/runners/digest.py +++ b/src/mailman/runners/digest.py @@ -27,7 +27,6 @@ from email.mime.message import MIMEMessage from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, make_msgid from io import StringIO -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.runner import Runner @@ -37,6 +36,7 @@ from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.interfaces.template import ITemplateLoader from mailman.utilities.mailbox import Mailbox from mailman.utilities.string import expand, oneline, wrap +from public import public from zope.component import getUtility diff --git a/src/mailman/runners/incoming.py b/src/mailman/runners/incoming.py index 62b12dab1..9461e59bc 100644 --- a/src/mailman/runners/incoming.py +++ b/src/mailman/runners/incoming.py @@ -27,12 +27,12 @@ immediately. """ from contextlib import suppress -from mailman import public from mailman.core.chains import process from mailman.core.runner import Runner from mailman.database.transaction import transaction from mailman.interfaces.address import ExistingAddressError from mailman.interfaces.usermanager import IUserManager +from public import public from zope.component import getUtility diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py index 21fb44c5e..0fa13a611 100644 --- a/src/mailman/runners/lmtp.py +++ b/src/mailman/runners/lmtp.py @@ -43,7 +43,6 @@ import aiosmtpd.smtp from aiosmtpd.controller import Controller from aiosmtpd.lmtp import LMTP from email.utils import parseaddr -from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.database.transaction import transactional @@ -51,6 +50,7 @@ from mailman.email.message import Message from mailman.interfaces.listmanager import IListManager from mailman.utilities.datetime import now from mailman.utilities.email import add_message_hash +from public import public from zope.component import getUtility diff --git a/src/mailman/runners/nntp.py b/src/mailman/runners/nntp.py index b125fe4f9..38f67c453 100644 --- a/src/mailman/runners/nntp.py +++ b/src/mailman/runners/nntp.py @@ -24,10 +24,10 @@ import logging import nntplib from io import StringIO -from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.nntp import NewsgroupModeration +from public import public COMMA = ',' diff --git a/src/mailman/runners/outgoing.py b/src/mailman/runners/outgoing.py index 3f21e3813..61b6e0b99 100644 --- a/src/mailman/runners/outgoing.py +++ b/src/mailman/runners/outgoing.py @@ -22,7 +22,6 @@ import logging from datetime import datetime from lazr.config import as_boolean, as_timedelta -from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.bounce import BounceContext, IBounceProcessor @@ -32,6 +31,7 @@ from mailman.interfaces.pending import IPendings from mailman.interfaces.subscriptions import ISubscriptionService from mailman.utilities.datetime import now from mailman.utilities.modules import find_name +from public import public from uuid import UUID from zope.component import getUtility diff --git a/src/mailman/runners/pipeline.py b/src/mailman/runners/pipeline.py index 3ec7499f2..caa68763c 100644 --- a/src/mailman/runners/pipeline.py +++ b/src/mailman/runners/pipeline.py @@ -22,9 +22,9 @@ through the 'preparation pipeline'. This pipeline adds, deletes and modifies headers, calculates message recipients, and more. """ -from mailman import public from mailman.core.pipelines import process from mailman.core.runner import Runner +from public import public @public diff --git a/src/mailman/runners/rest.py b/src/mailman/runners/rest.py index 037b6adf8..dd7eae245 100644 --- a/src/mailman/runners/rest.py +++ b/src/mailman/runners/rest.py @@ -21,9 +21,9 @@ import signal import logging import threading -from mailman import public from mailman.core.runner import Runner from mailman.rest.wsgiapp import make_server +from public import public log = logging.getLogger('mailman.http') diff --git a/src/mailman/runners/retry.py b/src/mailman/runners/retry.py index f1af4f73c..2be89e8b0 100644 --- a/src/mailman/runners/retry.py +++ b/src/mailman/runners/retry.py @@ -19,9 +19,9 @@ import time -from mailman import public from mailman.config import config from mailman.core.runner import Runner +from public import public @public diff --git a/src/mailman/runners/virgin.py b/src/mailman/runners/virgin.py index a69d07bf7..50ef3dcce 100644 --- a/src/mailman/runners/virgin.py +++ b/src/mailman/runners/virgin.py @@ -23,9 +23,9 @@ to go through some minimal processing before they can be sent out to the recipient. """ -from mailman import public from mailman.core.pipelines import process from mailman.core.runner import Runner +from public import public @public diff --git a/src/mailman/styles/base.py b/src/mailman/styles/base.py index 7226d762a..02a17d54d 100644 --- a/src/mailman/styles/base.py +++ b/src/mailman/styles/base.py @@ -24,7 +24,6 @@ methods in your compositional derived class. from datetime import timedelta -from mailman import public from mailman.core.i18n import _ from mailman.interfaces.action import Action, FilterAction from mailman.interfaces.archiver import ArchivePolicy @@ -34,6 +33,7 @@ from mailman.interfaces.digests import DigestFrequency from mailman.interfaces.mailinglist import ( Personalization, ReplyToMunging, SubscriptionPolicy) from mailman.interfaces.nntp import NewsgroupModeration +from public import public @public diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py index 2df075a6f..c7632fe8e 100644 --- a/src/mailman/styles/default.py +++ b/src/mailman/styles/default.py @@ -17,11 +17,11 @@ """Application of list styles to new and existing lists.""" -from mailman import public from mailman.interfaces.styles import IStyle from mailman.styles.base import ( Announcement, BasicOperation, Bounces, Discussion, Identity, Moderation, Public) +from public import public from zope.interface import implementer diff --git a/src/mailman/styles/manager.py b/src/mailman/styles/manager.py index 1b3130581..ae60dc3c6 100644 --- a/src/mailman/styles/manager.py +++ b/src/mailman/styles/manager.py @@ -17,11 +17,11 @@ """Style manager.""" -from mailman import public from mailman.interfaces.configuration import ConfigurationUpdatedEvent from mailman.interfaces.styles import ( DuplicateStyleError, IStyle, IStyleManager) from mailman.utilities.modules import find_components +from public import public from zope.component import getUtility from zope.interface import implementer from zope.interface.verify import verifyObject diff --git a/src/mailman/testing/documentation.py b/src/mailman/testing/documentation.py index 29629fe1b..97e30e900 100644 --- a/src/mailman/testing/documentation.py +++ b/src/mailman/testing/documentation.py @@ -22,12 +22,12 @@ distributions. doctest discovery currently requires file system traversal. """ from inspect import isfunction, ismethod -from mailman import public from mailman.app.lifecycle import create_list from mailman.config import config from mailman.testing.helpers import ( call_api, get_queue_messages, specialized_message_from_string, subscribe) from mailman.testing.layers import SMTPLayer +from public import public DOT = '.' diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index 2ce6956b7..01b362192 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -35,7 +35,6 @@ from contextlib import contextmanager, suppress from email import message_from_string from httplib2 import Http from lazr.config import as_timedelta -from mailman import public from mailman.bin.master import Loop as Master from mailman.config import config from mailman.database.transaction import transaction @@ -46,6 +45,7 @@ from mailman.interfaces.styles import IStyleManager from mailman.interfaces.usermanager import IUserManager from mailman.runners.digest import DigestRunner from mailman.utilities.mailbox import Mailbox +from public import public from unittest import mock from urllib.error import HTTPError from urllib.parse import urlencode diff --git a/src/mailman/testing/i18n.py b/src/mailman/testing/i18n.py index 2031be307..ade8584b1 100644 --- a/src/mailman/testing/i18n.py +++ b/src/mailman/testing/i18n.py @@ -20,8 +20,8 @@ from contextlib import closing from flufl.i18n import registry from gettext import GNUTranslations, NullTranslations -from mailman import public from pkg_resources import resource_stream +from public import public class TestingStrategy: diff --git a/src/mailman/testing/layers.py b/src/mailman/testing/layers.py index 3157809e6..67fb4f5e1 100644 --- a/src/mailman/testing/layers.py +++ b/src/mailman/testing/layers.py @@ -32,7 +32,6 @@ import datetime import tempfile from lazr.config import as_boolean -from mailman import public from mailman.config import config from mailman.core import initialize from mailman.core.initialize import INHIBIT_CONFIG_FILE @@ -44,6 +43,7 @@ from mailman.testing.helpers import ( from mailman.testing.mta import ConnectionCountingController from mailman.utilities.string import expand from pkg_resources import resource_string as resource_bytes +from public import public from textwrap import dedent from zope.component import getUtility diff --git a/src/mailman/testing/mta.py b/src/mailman/testing/mta.py index 81e4b8a62..d94466428 100644 --- a/src/mailman/testing/mta.py +++ b/src/mailman/testing/mta.py @@ -24,8 +24,8 @@ import smtplib from aiosmtpd.controller import Controller from aiosmtpd.handlers import Message as MessageHandler from aiosmtpd.smtp import SMTP -from mailman import public from mailman.interfaces.mta import IMailTransportAgentLifecycle +from public import public from queue import Empty, Queue from zope.interface import implementer diff --git a/src/mailman/testing/nose.py b/src/mailman/testing/nose.py index bbd361390..1a9830da5 100644 --- a/src/mailman/testing/nose.py +++ b/src/mailman/testing/nose.py @@ -22,11 +22,11 @@ import re import doctest import importlib -from mailman import public from mailman.testing.documentation import setup, teardown from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer, SMTPLayer from nose2.events import Plugin from pkg_resources import resource_filename +from public import public DOT = '.' diff --git a/src/mailman/utilities/datetime.py b/src/mailman/utilities/datetime.py index 9bb772b3f..2915080e8 100644 --- a/src/mailman/utilities/datetime.py +++ b/src/mailman/utilities/datetime.py @@ -24,8 +24,8 @@ instrumented for testing purposes. import datetime -from mailman import public from mailman.testing import layers +from public import public # Python always sets the locale to 'C' locale unless the user explicitly calls diff --git a/src/mailman/utilities/email.py b/src/mailman/utilities/email.py index e870117ac..546a7de61 100644 --- a/src/mailman/utilities/email.py +++ b/src/mailman/utilities/email.py @@ -19,7 +19,7 @@ from base64 import b32encode from hashlib import sha1 -from mailman import public +from public import public @public diff --git a/src/mailman/utilities/filesystem.py b/src/mailman/utilities/filesystem.py index e89f2abb8..7dcf2bb80 100644 --- a/src/mailman/utilities/filesystem.py +++ b/src/mailman/utilities/filesystem.py @@ -20,7 +20,7 @@ import os from contextlib import suppress -from mailman import public +from public import public @public diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py index 1df8ede7e..a658c231b 100644 --- a/src/mailman/utilities/i18n.py +++ b/src/mailman/utilities/i18n.py @@ -21,11 +21,11 @@ import os import sys from itertools import product -from mailman import public from mailman.config import config from mailman.core.constants import system_preferences from mailman.interfaces.errors import MailmanError from pkg_resources import resource_filename +from public import public @public diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py index cf14fa73a..c8348a681 100644 --- a/src/mailman/utilities/importer.py +++ b/src/mailman/utilities/importer.py @@ -23,7 +23,6 @@ import sys import logging import datetime -from mailman import public from mailman.config import config from mailman.handlers.decorate import decorate_template from mailman.interfaces.action import Action, FilterAction @@ -44,6 +43,7 @@ from mailman.interfaces.template import ITemplateManager from mailman.interfaces.usermanager import IUserManager from mailman.utilities.filesystem import makedirs from mailman.utilities.i18n import search +from public import public from sqlalchemy import Boolean from zope.component import getUtility diff --git a/src/mailman/utilities/interact.py b/src/mailman/utilities/interact.py index ac1612156..48f3ae358 100644 --- a/src/mailman/utilities/interact.py +++ b/src/mailman/utilities/interact.py @@ -23,7 +23,7 @@ import code from contextlib import suppress from inspect import signature -from mailman import public +from public import public DEFAULT_BANNER = object() diff --git a/src/mailman/utilities/mailbox.py b/src/mailman/utilities/mailbox.py index b799babea..19146e036 100644 --- a/src/mailman/utilities/mailbox.py +++ b/src/mailman/utilities/mailbox.py @@ -23,8 +23,9 @@ # get its size. MMDF is slightly more sane than mbox; it's primary advantage # for us is that it does no 'From' mangling. # mangling. + from mailbox import MMDF -from mailman import public +from public import public @public diff --git a/src/mailman/utilities/modules.py b/src/mailman/utilities/modules.py index b16aa45e5..83063a3f0 100644 --- a/src/mailman/utilities/modules.py +++ b/src/mailman/utilities/modules.py @@ -20,8 +20,8 @@ import os import sys -from mailman import public from pkg_resources import resource_filename, resource_listdir +from public import public @public diff --git a/src/mailman/utilities/options.py b/src/mailman/utilities/options.py index 1c0064260..9e1e698a7 100644 --- a/src/mailman/utilities/options.py +++ b/src/mailman/utilities/options.py @@ -21,12 +21,12 @@ import os import sys from copy import copy -from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.initialize import initialize from mailman.version import MAILMAN_VERSION from optparse import Option, OptionParser, OptionValueError +from public import public def check_unicode(option, opt, value): diff --git a/src/mailman/utilities/passwords.py b/src/mailman/utilities/passwords.py index 5597e2556..7bf18b93a 100644 --- a/src/mailman/utilities/passwords.py +++ b/src/mailman/utilities/passwords.py @@ -17,10 +17,10 @@ """A wrapper around passlib.""" -from mailman import public from mailman.config.config import load_external from mailman.interfaces.configuration import ConfigurationUpdatedEvent from passlib.context import CryptContext +from public import public class PasswordContext: diff --git a/src/mailman/utilities/protocols.py b/src/mailman/utilities/protocols.py index 5f447c465..43d43a8bc 100644 --- a/src/mailman/utilities/protocols.py +++ b/src/mailman/utilities/protocols.py @@ -19,10 +19,10 @@ import requests -from mailman import public from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.listmanager import IListManager from mailman.utilities.i18n import TemplateNotFoundError, find +from public import public from urllib.error import URLError from urllib.parse import urlparse from zope.component import getUtility diff --git a/src/mailman/utilities/queries.py b/src/mailman/utilities/queries.py index e27ae9a17..cd6542270 100644 --- a/src/mailman/utilities/queries.py +++ b/src/mailman/utilities/queries.py @@ -18,7 +18,7 @@ """Some helpers for queries.""" from collections.abc import Sequence -from mailman import public +from public import public @public diff --git a/src/mailman/utilities/string.py b/src/mailman/utilities/string.py index 2694877ee..fecadc444 100644 --- a/src/mailman/utilities/string.py +++ b/src/mailman/utilities/string.py @@ -21,8 +21,8 @@ import logging from email.errors import HeaderParseError from email.header import decode_header, make_header -from mailman import public from mailman.config import config +from public import public from string import Template, whitespace from textwrap import TextWrapper, dedent diff --git a/src/mailman/utilities/tests/test_modules.py b/src/mailman/utilities/tests/test_modules.py index 8e144e60b..d34a99910 100644 --- a/src/mailman/utilities/tests/test_modules.py +++ b/src/mailman/utilities/tests/test_modules.py @@ -67,7 +67,7 @@ class TestModuleImports(unittest.TestCase): Path(init_file).touch() with open(good_file, 'w', encoding='utf-8') as fp: print("""\ -from mailman import public +from public import public from mailman.interfaces.styles import IStyle from zope.interface import implementer @@ -80,7 +80,7 @@ class GoodStyle: """, file=fp) with open(bad_file, 'w', encoding='utf-8') as fp: print("""\ -from mailman import public +from public import public from mailman.interfaces.styles import IStyle from zope.interface import implementer diff --git a/src/mailman/utilities/uid.py b/src/mailman/utilities/uid.py index 4389bcd92..9abf92e90 100644 --- a/src/mailman/utilities/uid.py +++ b/src/mailman/utilities/uid.py @@ -29,10 +29,10 @@ import hashlib from contextlib import suppress from flufl.lock import Lock -from mailman import public from mailman.config import config from mailman.model.uid import UID from mailman.testing import layers +from public import public class _PredictableIDGenerator: -- cgit v1.3.1 From c44c48e1447b54f2f8673a930b343767f0b917fb Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 29 Nov 2016 19:19:13 -0500 Subject: Use flufl.testing's flake8 plugin. --- setup.py | 1 - src/mailman/testing/flake8.py | 141 ------------------------------------------ tox.ini | 2 + 3 files changed, 2 insertions(+), 142 deletions(-) delete mode 100644 src/mailman/testing/flake8.py diff --git a/setup.py b/setup.py index 080c83925..378bc989a 100644 --- a/setup.py +++ b/setup.py @@ -101,7 +101,6 @@ case second `m'. Any other spelling is incorrect.""", include_package_data = True, entry_points = { 'console_scripts' : list(scripts), - 'flake8.extension': ['B4 = mailman.testing.flake8:ImportOrder'], }, install_requires = [ 'aiosmtpd', diff --git a/src/mailman/testing/flake8.py b/src/mailman/testing/flake8.py deleted file mode 100644 index 68bd37761..000000000 --- a/src/mailman/testing/flake8.py +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (C) 2016 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# GNU Mailman. If not, see . - -"""Flake8 extensions for Mailman coding style.""" - - -from ast import NodeVisitor -from collections import namedtuple -from enum import Enum - - -class ImportType(Enum): - non_from = 0 - from_import = 1 - - -ImportRecord = namedtuple('ImportRecord', 'itype lineno colno, module, names') - - -NONFROM_FOLLOWS_FROM = 'B401 Non-from import follows from-import' -NONFROM_MULTIPLE_NAMES = 'B402 Multiple names on non-from import' -NONFROM_SHORTER_FOLLOWS = 'B403 Shorter non-from import follows longer' -NONFROM_ALPHA_UNSORTED = ( - 'B404 Same-length non-from imports not sorted alphabetically') -NONFROM_EXTRA_BLANK_LINE = ( - 'B405 Unexpected blank line since last non-from import') -NONFROM_DOTTED_UNSORTED = ( - 'B406 Dotted non-from import not sorted alphabetically') - -FROMIMPORT_MISSING_BLANK_LINE = ( - 'B411 Expected one blank line since last non-from import') -FROMIMPORT_ALPHA_UNSORTED = 'B412 from-import not sorted alphabetically' -FROMIMPORT_MULTIPLE = 'B413 Multiple from-imports of same module' -FROMIMPORT_NAMES_UNSORTED = ( - 'B414 from-imported names are not sorted alphabetically') - - -class ImportVisitor(NodeVisitor): - def __init__(self): - self.imports = [] - - def visit_Import(self, node): - if node.col_offset != 0: - # Ignore nested imports. - return - names = [alias.name for alias in node.names] - self.imports.append( - ImportRecord(ImportType.non_from, node.lineno, node.col_offset, - None, names)) - - def visit_ImportFrom(self, node): - if node.col_offset != 0: - # Ignore nested imports. - return - names = [alias.name for alias in node.names] - self.imports.append( - ImportRecord(ImportType.from_import, node.lineno, node.col_offset, - node.module, names)) - - -class ImportOrder: - name = 'flufl-import-order' - version = '0.1' - - def __init__(self, tree, filename): - self.tree = tree - self.filename = filename - - def _error(self, record, error): - code, space, text = error.partition(' ') - return (record.lineno, record.colno, - '{} {}'.format(code, text), ImportOrder) - - def run(self): - visitor = ImportVisitor() - visitor.visit(self.tree) - last_import = None - for record in visitor.imports: - if last_import is None: - last_import = record - continue - if record.itype is ImportType.non_from: - if len(record.names) != 1: - yield self._error(record, NONFROM_MULTIPLE_NAMES) - if last_import.itype is ImportType.from_import: - yield self._error(record, NONFROM_FOLLOWS_FROM) - # Shorter imports should always precede longer import *except* - # when they are dotted imports and everything but the last - # path component are the same. In that case, they should be - # sorted alphabetically. - last_name = last_import.names[0] - this_name = record.names[0] - if '.' in last_name and '.' in this_name: - last_parts = last_name.split('.') - this_parts = this_name.split('.') - if (last_parts[:-1] == this_parts[:-1] and - last_parts[-1] > this_parts[-1]): - yield self._error(record, NONFROM_DOTTED_UNSORTED) - elif len(last_name) > len(this_name): - yield self._error(record, NONFROM_SHORTER_FOLLOWS) - # It's also possible that the imports are the same length, in - # which case they must be sorted alphabetically. - if (len(last_import.names[0]) == len(record.names[0]) and - last_import.names[0] > record.names[0]): - yield self._error(record, NONFROM_ALPHA_UNSORTED) - if last_import.lineno + 1 != record.lineno: - yield self._error(record, NONFROM_DOTTED_UNSORTED) - else: - assert record.itype is ImportType.from_import - if (last_import.itype is ImportType.non_from and - record.lineno != last_import.lineno + 2): - yield self._error(record, FROMIMPORT_MISSING_BLANK_LINE) - if last_import.itype is ImportType.non_from: - last_import = record - continue - if last_import.module > record.module: - yield self._error(record, FROMIMPORT_ALPHA_UNSORTED) - # All imports from the same module should show up in the same - # multiline import. - if last_import.module == record.module: - yield self._error(record, FROMIMPORT_MULTIPLE) - # Check the sort order of the imported names. - if sorted(record.names) != record.names: - yield self._error(record, FROMIMPORT_NAMES_UNSORTED) - # How to check for no blank lines between from imports? - # Update the last import. - last_import = record diff --git a/tox.ini b/tox.ini index 7892b557a..34bd367d1 100644 --- a/tox.ini +++ b/tox.ini @@ -35,6 +35,7 @@ commands = python -m flake8 src deps = flake8>3.0 + flufl.testing [testenv:docs] basepython = python3 @@ -51,3 +52,4 @@ rc = --rcfile={[coverage]rcfile} max-line-length = 79 exclude = src/mailman/compat/*.py jobs = 1 +enable-extensions = U4 -- cgit v1.3.1 From 5d73d057854191637b248da0875cf7ce005bbffb Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 29 Nov 2016 19:25:25 -0500 Subject: Fix an import. --- src/mailman/config/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py index 1f4384eb7..a274aa3b9 100644 --- a/src/mailman/config/config.py +++ b/src/mailman/config/config.py @@ -24,13 +24,14 @@ import mailman.templates from configparser import ConfigParser from flufl.lock import Lock from lazr.config import ConfigSchema, as_boolean +from mailman import version from mailman.interfaces.configuration import ( ConfigurationUpdatedEvent, IConfiguration, MissingConfigurationFileError) from mailman.interfaces.languages import ILanguageManager from mailman.utilities.filesystem import makedirs from mailman.utilities.modules import call_name, expand_path from pkg_resources import resource_filename, resource_string as resource_bytes -from public import public, version +from public import public from string import Template from zope.component import getUtility from zope.event import notify -- cgit v1.3.1 From cdd24f88bd36aa2bd87252618e98b80aa7cc1bf1 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 29 Nov 2016 19:58:16 -0500 Subject: More fixes & flufl.testing. --- setup.py | 1 + src/mailman/core/system.py | 3 +- src/mailman/testing/nose.py | 118 -------------------------------------------- unittest.cfg | 5 +- 4 files changed, 7 insertions(+), 120 deletions(-) delete mode 100644 src/mailman/testing/nose.py diff --git a/setup.py b/setup.py index 378bc989a..c31817b9a 100644 --- a/setup.py +++ b/setup.py @@ -110,6 +110,7 @@ case second `m'. Any other spelling is incorrect.""", 'flufl.bounce', 'flufl.i18n', 'flufl.lock', + 'flufl.testing', 'httplib2', 'lazr.config', 'nose2', diff --git a/src/mailman/core/system.py b/src/mailman/core/system.py index 2d76f0c97..41ddced95 100644 --- a/src/mailman/core/system.py +++ b/src/mailman/core/system.py @@ -19,8 +19,9 @@ import sys +from mailman import version from mailman.interfaces.system import ISystem -from public import public, version +from public import public from zope.interface import implementer diff --git a/src/mailman/testing/nose.py b/src/mailman/testing/nose.py deleted file mode 100644 index 1a9830da5..000000000 --- a/src/mailman/testing/nose.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (C) 2013-2016 by the Free Software Foundation, Inc. -# -# This file is part of GNU Mailman. -# -# GNU Mailman is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# GNU Mailman. If not, see . - -"""nose2 test infrastructure.""" - -import os -import re -import doctest -import importlib - -from mailman.testing.documentation import setup, teardown -from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer, SMTPLayer -from nose2.events import Plugin -from pkg_resources import resource_filename -from public import public - - -DOT = '.' -FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF -TOPDIR = os.path.dirname(resource_filename('mailman', '__init__.py')) - - -@public -class NosePlugin(Plugin): - configSection = 'mailman' - - def __init__(self): - super().__init__() - self.patterns = [] - self.stderr = False - def set_stderr(ignore): # noqa: E306 - self.stderr = True - self.addArgument(self.patterns, 'P', 'pattern', - 'Add a test matching pattern') - self.addFlag(set_stderr, 'E', 'stderr', - 'Enable stderr logging to sub-runners') - - def startTestRun(self, event): - MockAndMonkeyLayer.testing_mode = True - if (self.stderr or - len(os.environ.get('MM_VERBOSE_TESTLOG', '').strip()) > 0): - ConfigLayer.stderr = True - - def getTestCaseNames(self, event): - if len(self.patterns) == 0: - # No filter patterns, so everything should be tested. - return - # Does the pattern match the fully qualified class name? - for pattern in self.patterns: - full_class_name = '{}.{}'.format( - event.testCase.__module__, event.testCase.__name__) - if re.search(pattern, full_class_name): - # Don't suppress this test class. - return - names = filter(event.isTestMethod, dir(event.testCase)) - for name in names: - full_test_name = '{}.{}.{}'.format( - event.testCase.__module__, - event.testCase.__name__, - name) - for pattern in self.patterns: - if re.search(pattern, full_test_name): - break - else: - event.excludedNames.append(name) - - def handleFile(self, event): - path = event.path[len(TOPDIR)+1:] - if len(self.patterns) > 0: - for pattern in self.patterns: - if re.search(pattern, path): - break - else: - # Skip this doctest. - return - base, ext = os.path.splitext(path) - if ext != '.rst': - return - # Look to see if the package defines a test layer, otherwise use the - # default layer. First turn the file system path into a dotted Python - # module path. - parent = os.path.dirname(path) - dotted = 'mailman.' + DOT.join(parent.split(os.path.sep)) - try: - module = importlib.import_module(dotted) - except ImportError: - layer = SMTPLayer - else: - layer = getattr(module, 'layer', SMTPLayer) - test = doctest.DocFileTest( - path, package='mailman', - optionflags=FLAGS, - setUp=setup, - tearDown=teardown) - test.layer = layer - # Suppress the extra "Doctest: ..." line. - test.shortDescription = lambda: None - event.extraTests.append(test) - - # def startTest(self, event): - # import sys; print('vvvvv', event.test, file=sys.stderr) - - # def stopTest(self, event): - # import sys; print('^^^^^', event.test, file=sys.stderr) diff --git a/unittest.cfg b/unittest.cfg index d639a8ae3..4b080f22e 100644 --- a/unittest.cfg +++ b/unittest.cfg @@ -1,6 +1,6 @@ [unittest] verbose = 2 -plugins = mailman.testing.nose +plugins = flufl.testing.nose nose2.plugins.layers [mailman] @@ -8,3 +8,6 @@ always-on = True [log-capture] always-on = False + +[flufl.testing] +package = mailman -- cgit v1.3.1 From 7d172db85b7bee4731853471528a612980be5611 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Tue, 29 Nov 2016 22:24:22 -0500 Subject: Enable the flufl.testing extension. --- unittest.cfg | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/unittest.cfg b/unittest.cfg index 4b080f22e..9fc0912a9 100644 --- a/unittest.cfg +++ b/unittest.cfg @@ -3,11 +3,9 @@ verbose = 2 plugins = flufl.testing.nose nose2.plugins.layers -[mailman] -always-on = True - [log-capture] always-on = False [flufl.testing] +always-on = True package = mailman -- cgit v1.3.1 From b0f5e43046c6b4be473e1d98623e3157221719af Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Wed, 30 Nov 2016 15:03:35 -0500 Subject: Finish configuring flufl.testing. Also, use the better way to set the LMTP ident. --- src/mailman/runners/lmtp.py | 7 +++---- src/mailman/testing/helpers.py | 8 ++++++++ unittest.cfg | 4 ++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py index 0fa13a611..b0f473c0b 100644 --- a/src/mailman/runners/lmtp.py +++ b/src/mailman/runners/lmtp.py @@ -93,9 +93,6 @@ ERR_502 = '502 Error: command HELO not implemented' ERR_550 = '550 Requested action not taken: mailbox unavailable' ERR_550_MID = '550 No Message-ID header provided' -# XXX Blech -aiosmtpd.smtp.__version__ = 'GNU Mailman LMTP runner 2.0' - def split_recipient(address): """Split an address into listname, subaddress and domain parts. @@ -218,7 +215,9 @@ class LMTPHandler: class LMTPController(Controller): def factory(self): - return LMTP(self.handler) + server = LMTP(self.handler) + server.__ident__ = 'GNU Mailman LMTP runner 2.0' + return server def make_socket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index 01b362192..233b03cf8 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -568,3 +568,11 @@ def hackenv(envar, new_value): del os.environ[envar] else: os.environ[envar] = old_value + + +def nose2_start_test_run_callback(plugin): + from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer + MockAndMonkeyLayer.testing_mode = True + if (plugin.stderr or + len(os.environ.get('MM_VERBOSE_TESTLOG', '').strip()) > 0): + ConfigLayer.stderr = True diff --git a/unittest.cfg b/unittest.cfg index 9fc0912a9..ba479fdf8 100644 --- a/unittest.cfg +++ b/unittest.cfg @@ -9,3 +9,7 @@ always-on = False [flufl.testing] always-on = True package = mailman +start_run = mailman.testing.helpers.nose2_start_test_run_callback +default_layer = mailman.testing.layers.SMTPLayer +setup = mailman.testing.documentation.setup +teardown = mailman.testing.documentation.teardown -- cgit v1.3.1 From 4a8b154e92acc76cdb437f2dc57543f67e1390a3 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Wed, 30 Nov 2016 15:12:01 -0500 Subject: Remove some unused imports. --- src/mailman/runners/lmtp.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py index b0f473c0b..25d531da4 100644 --- a/src/mailman/runners/lmtp.py +++ b/src/mailman/runners/lmtp.py @@ -37,8 +37,6 @@ so that the peer mail server can provide better diagnostics. import email import socket import logging -import aiosmtpd -import aiosmtpd.smtp from aiosmtpd.controller import Controller from aiosmtpd.lmtp import LMTP -- cgit v1.3.1 From a30bbdf0d483150dc4259b8d149679d38b6030f1 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Sat, 3 Dec 2016 11:08:18 -0500 Subject: Prevent the occasional CI/testsuite hang. This doesn't solve the underlying problem of why child processes (both runners and master) occasionally don't exit, but it prevents ugly timeouts in the CI infrastructure when that happens. --- src/mailman/commands/tests/test_control.py | 58 ++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/mailman/commands/tests/test_control.py b/src/mailman/commands/tests/test_control.py index 7377c4666..4425b3411 100644 --- a/src/mailman/commands/tests/test_control.py +++ b/src/mailman/commands/tests/test_control.py @@ -64,6 +64,59 @@ def find_master(): return None +def kill_with_extreme_prejudice(pid=None): + # 2016-12-03 barry: We have intermittent hangs during both local and CI + # test suite runs where killing a runner or master process doesn't + # terminate the process. In those cases, wait()ing on the child can + # suspend the test process indefinitely. Locally, you have to C-c the + # test process, but that still doesn't kill it; the process continues to + # run in the background. If you then search for the process's pid and + # SIGTERM it, it will usually exit, which is why I don't understand why + # the above SIGTERM doesn't kill it sometimes. However, when run under + # CI, the test suite will just hang until the CI runner times it out. It + # would be better to figure out the underlying cause, because we have + # definitely seen other situations where a runner process won't exit, but + # for testing purposes we're just trying to clean up some resources so + # after a brief attempt at SIGTERMing it, let's SIGKILL it and warn. + if pid is not None: + os.kill(pid, signal.SIGTERM) + until = timedelta(seconds=10) + datetime.now() + while datetime.now() < until: + try: + if pid is None: + os.wait3(os.WNOHANG) + else: + os.waitpid(pid, os.WNOHANG) + except ChildProcessError: + # This basically means we went one too many times around the + # loop. The previous iteration successfully reaped the child. + # Because the return status of wait3() and waitpid() are different + # in those cases, it's easier just to catch the exception for + # either call and exit. + return + time.sleep(0.1) + else: + if pid is None: + # There's really not much more we can do because we have no pid to + # SIGKILL. Just report the problem and continue. + print('WARNING: NO CHANGE IN CHILD PROCESS STATES', + file=sys.stderr) + return + print('WARNING: SIGTERM DID NOT EXIT PROCESS; SIGKILLing', + file=sys.stderr) + if pid is not None: + os.kill(pid, signal.SIGKILL) + until = timedelta(seconds=10) + datetime.now() + while datetime.now() < until: + status = os.waitpid(pid, os.WNOHANG) + if status == (0, 0): + # The child was reaped. + return + time.sleep(0.1) + else: + print('WARNING: SIGKILL DID NOT EXIT PROCESS!', file=sys.stderr) + + class FakeArgs: force = None run_as_user = None @@ -171,7 +224,7 @@ class TestBinDir(unittest.TestCase): args_config = Configuration() args_config.load(self.args.config) self.assertFalse(os.path.exists(args_config.PID_FILE)) - os.wait() + kill_with_extreme_prejudice() def test_master_is_elsewhere_and_findable(self): with ExitStack() as resources: @@ -188,5 +241,4 @@ class TestBinDir(unittest.TestCase): # killable. We might have to wait until the process has started. master_pid = find_master() self.assertIsNotNone(master_pid, 'master did not start') - os.kill(master_pid, signal.SIGTERM) - os.waitpid(master_pid, 0) + kill_with_extreme_prejudice(master_pid) -- cgit v1.3.1