diff options
Diffstat (limited to '')
| -rw-r--r-- | Mailman/app/rules.py | 4 | ||||
| -rw-r--r-- | Mailman/interfaces/rules.py | 21 | ||||
| -rw-r--r-- | Mailman/rules/__init__.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/administrivia.py | 7 | ||||
| -rw-r--r-- | Mailman/rules/approved.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/docs/administrivia.txt (renamed from Mailman/docs/administrivia.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/approve.txt (renamed from Mailman/docs/approve.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/implicit-dest.txt (renamed from Mailman/docs/implicit-dest.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/loop.txt (renamed from Mailman/docs/loop.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/max-size.txt (renamed from Mailman/docs/max-size.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/moderation.txt (renamed from Mailman/docs/moderation.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/news-moderation.txt (renamed from Mailman/docs/news-moderation.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/no-subject.txt (renamed from Mailman/docs/no-subject.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/recipients.txt (renamed from Mailman/docs/recipients.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/docs/rules.txt (renamed from Mailman/docs/rules.txt) | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/suspicious.txt (renamed from Mailman/docs/suspicious.txt) | 0 | ||||
| -rw-r--r-- | Mailman/rules/emergency.py | 5 | ||||
| -rw-r--r-- | Mailman/rules/implicit_dest.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/loop.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/max_recipients.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/max_size.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/moderation.py | 9 | ||||
| -rw-r--r-- | Mailman/rules/news_moderation.py (renamed from Mailman/rules/new_moderation.py) | 6 | ||||
| -rw-r--r-- | Mailman/rules/no_subject.py | 6 | ||||
| -rw-r--r-- | Mailman/rules/suspicious.py | 6 | ||||
| -rw-r--r-- | Mailman/tests/test_documentation.py | 28 |
26 files changed, 57 insertions, 74 deletions
diff --git a/Mailman/app/rules.py b/Mailman/app/rules.py index 37f5d9af4..e4c3c8c40 100644 --- a/Mailman/app/rules.py +++ b/Mailman/app/rules.py @@ -45,7 +45,7 @@ def process(mlist, msg, msgdata, rule_set=None): # Now process all rules, returning the set of rules that match. rule_matches = set() for rule in rules: - if rule.check(mlist, msg, msgdata): + if rule().check(mlist, msg, msgdata): rule_matches.add(rule.name) return rule_matches @@ -60,5 +60,5 @@ def find_rule(rule_name): for rule_set_class in get_plugins('mailman.rules'): rule = rule_set_class().get(rule_name) if rule is not None: - return rule + return rule() return None diff --git a/Mailman/interfaces/rules.py b/Mailman/interfaces/rules.py index 13edcf481..c023acf6b 100644 --- a/Mailman/interfaces/rules.py +++ b/Mailman/interfaces/rules.py @@ -17,10 +17,25 @@ """Interface describing the basics of rules.""" +from munepy import Enum from zope.interface import Interface, Attribute +class ChainJump(Enum): + # Allow the next rule in the chain to be run. + defer = 0 + # Jump to the 'accept' chain. + accept = 1 + # Jump to the 'hold' chain. + hold = 2 + # Jump to the 'reject' chain. + reject = 3 + # Jump to the 'discard' chain. + discard = 4 + + + class DuplicateRuleError(Exception): """A rule or rule name is added to a processor more than once.""" @@ -35,10 +50,14 @@ class IRule(Interface): def check(mlist, msg, msgdata): """Run the rule. + The effects of running the rule can be as simple as appending the rule + name to `msgdata['rules']` when the rule matches. The rule is allowed + to do other things, such as modify the message or metadata. + :param mlist: The mailing list object. :param msg: The message object. :param msgdata: The message metadata. - :return: A boolean specifying whether the rule was matched or not. + :return: A chain to jump to, i.e. an ChainJump enum. """ diff --git a/Mailman/rules/__init__.py b/Mailman/rules/__init__.py index 2d2f5d0a8..2a1e2ec2b 100644 --- a/Mailman/rules/__init__.py +++ b/Mailman/rules/__init__.py @@ -44,11 +44,11 @@ class BuiltinRules: if extension <> '.py': continue module_name = mypackage + '.' + basename - __import__(module_name) + __import__(module_name, fromlist='*') module = sys.modules[module_name] - for name in dir(module): + for name in module.__all__: rule = getattr(module, name) - if IRule.providedBy(rule): + if IRule.implementedBy(rule): if rule.name in self._rules or rule in rule_set: raise DuplicateRuleError(rule.name) self._rules[rule.name] = rule diff --git a/Mailman/rules/administrivia.py b/Mailman/rules/administrivia.py index 422503c71..589c4a56b 100644 --- a/Mailman/rules/administrivia.py +++ b/Mailman/rules/administrivia.py @@ -17,7 +17,7 @@ """The administrivia rule.""" -__all__ = ['administrivia_rule'] +__all__ = ['Administrivia'] __metaclass__ = type @@ -95,8 +95,3 @@ class Administrivia: if minargs <= len(words) - 1 <= maxargs: return True return False - - - -administrivia_rule = Administrivia() - diff --git a/Mailman/rules/approved.py b/Mailman/rules/approved.py index b9b041c2e..98b158dd9 100644 --- a/Mailman/rules/approved.py +++ b/Mailman/rules/approved.py @@ -17,7 +17,7 @@ """Look for moderator pre-approval.""" -__all__ = ['approve_rule'] +__all__ = ['Approved'] __metaclass__ = type @@ -114,7 +114,3 @@ def reset_payload(part, payload): part.set_param('Format', format) if delsp: part.set_param('DelSp', delsp) - - - -approve_rule = Approved() diff --git a/Mailman/docs/administrivia.txt b/Mailman/rules/docs/administrivia.txt index 0e48fdd1b..0e48fdd1b 100644 --- a/Mailman/docs/administrivia.txt +++ b/Mailman/rules/docs/administrivia.txt diff --git a/Mailman/docs/approve.txt b/Mailman/rules/docs/approve.txt index ea07058f8..ea07058f8 100644 --- a/Mailman/docs/approve.txt +++ b/Mailman/rules/docs/approve.txt diff --git a/Mailman/docs/implicit-dest.txt b/Mailman/rules/docs/implicit-dest.txt index b6fed2769..b6fed2769 100644 --- a/Mailman/docs/implicit-dest.txt +++ b/Mailman/rules/docs/implicit-dest.txt diff --git a/Mailman/docs/loop.txt b/Mailman/rules/docs/loop.txt index 3174805b9..3174805b9 100644 --- a/Mailman/docs/loop.txt +++ b/Mailman/rules/docs/loop.txt diff --git a/Mailman/docs/max-size.txt b/Mailman/rules/docs/max-size.txt index b477ecd2b..b477ecd2b 100644 --- a/Mailman/docs/max-size.txt +++ b/Mailman/rules/docs/max-size.txt diff --git a/Mailman/docs/moderation.txt b/Mailman/rules/docs/moderation.txt index 0ce6bee6e..0ce6bee6e 100644 --- a/Mailman/docs/moderation.txt +++ b/Mailman/rules/docs/moderation.txt diff --git a/Mailman/docs/news-moderation.txt b/Mailman/rules/docs/news-moderation.txt index f69fbb33d..f69fbb33d 100644 --- a/Mailman/docs/news-moderation.txt +++ b/Mailman/rules/docs/news-moderation.txt diff --git a/Mailman/docs/no-subject.txt b/Mailman/rules/docs/no-subject.txt index 3c6dc88bf..3c6dc88bf 100644 --- a/Mailman/docs/no-subject.txt +++ b/Mailman/rules/docs/no-subject.txt diff --git a/Mailman/docs/recipients.txt b/Mailman/rules/docs/recipients.txt index 98176c8bb..98176c8bb 100644 --- a/Mailman/docs/recipients.txt +++ b/Mailman/rules/docs/recipients.txt diff --git a/Mailman/docs/rules.txt b/Mailman/rules/docs/rules.txt index dbf009eeb..4e5db7012 100644 --- a/Mailman/docs/rules.txt +++ b/Mailman/rules/docs/rules.txt @@ -32,6 +32,7 @@ You can iterator over all the rules in a rule set. >>> rule = None >>> for rule in rule_set.rules: ... if rule.name == 'emergency': + ... rule = rule() ... break >>> verifyObject(IRule, rule) True @@ -80,7 +81,7 @@ For example, the emergency rule just checks to see if the emergency flag is set on the mailing list, and the message has not been pre-approved by the list administrator. - >>> rule = rule_set['emergency'] + >>> rule = rule_set['emergency']() >>> rule.name 'emergency' >>> mlist.emergency = False diff --git a/Mailman/docs/suspicious.txt b/Mailman/rules/docs/suspicious.txt index 8646e1b81..8646e1b81 100644 --- a/Mailman/docs/suspicious.txt +++ b/Mailman/rules/docs/suspicious.txt diff --git a/Mailman/rules/emergency.py b/Mailman/rules/emergency.py index 989e4fff7..e51612940 100644 --- a/Mailman/rules/emergency.py +++ b/Mailman/rules/emergency.py @@ -17,7 +17,7 @@ """The emergency hold rule.""" -__all__ = ['emergency_rule'] +__all__ = ['Emergency'] __metaclass__ = type @@ -40,6 +40,3 @@ the list administrator.""") def check(self, mlist, msg, msgdata): """See `IRule`.""" return mlist.emergency and not msgdata.get('adminapproved') - - -emergency_rule = Emergency() diff --git a/Mailman/rules/implicit_dest.py b/Mailman/rules/implicit_dest.py index e056a2e9e..19a096aa5 100644 --- a/Mailman/rules/implicit_dest.py +++ b/Mailman/rules/implicit_dest.py @@ -17,7 +17,7 @@ """The implicit destination rule.""" -__all__ = ['implicit_dest'] +__all__ = ['ImplicitDestination'] __metaclass__ = type @@ -92,7 +92,3 @@ class ImplicitDestination: pass # Nothing matched. return True - - - -implicit_dest = ImplicitDestination() diff --git a/Mailman/rules/loop.py b/Mailman/rules/loop.py index 77cedb0a6..a88858d6a 100644 --- a/Mailman/rules/loop.py +++ b/Mailman/rules/loop.py @@ -17,7 +17,7 @@ """Look for a posting loop.""" -__all__ = ['loop_rule'] +__all__ = ['Loop'] __metaclass__ = type @@ -41,7 +41,3 @@ class Loop: been_theres = [value.strip().lower() for value in msg.get_all('x-beenthere', [])] return mlist.posting_address in been_theres - - - -loop_rule = Loop() diff --git a/Mailman/rules/max_recipients.py b/Mailman/rules/max_recipients.py index 6e3451e4e..dfa23f659 100644 --- a/Mailman/rules/max_recipients.py +++ b/Mailman/rules/max_recipients.py @@ -17,7 +17,7 @@ """The maximum number of recipients rule.""" -__all__ = ['max_recipients_rule'] +__all__ = ['MaximumRecipients'] __metaclass__ = type @@ -45,7 +45,3 @@ class MaximumRecipients: recipients = getaddresses(msg.get_all('to', []) + msg.get_all('cc', [])) return len(recipients) >= mlist.max_num_recipients - - - -max_recipients_rule = MaximumRecipients() diff --git a/Mailman/rules/max_size.py b/Mailman/rules/max_size.py index 1e62b2ad8..b723fbf07 100644 --- a/Mailman/rules/max_size.py +++ b/Mailman/rules/max_size.py @@ -17,7 +17,7 @@ """The maximum message size rule.""" -__all__ = ['max_size'] +__all__ = ['MaximumSize'] __metaclass__ = type @@ -43,7 +43,3 @@ class MaximumSize: 'Message was not sized on initial parsing.') # The maximum size is specified in 1024 bytes. return msg.original_size / 1024.0 > mlist.max_message_size - - - -max_size = MaximumSize() diff --git a/Mailman/rules/moderation.py b/Mailman/rules/moderation.py index 5b0820426..9fa7cd34d 100644 --- a/Mailman/rules/moderation.py +++ b/Mailman/rules/moderation.py @@ -18,8 +18,8 @@ """Membership related rules.""" __all__ = [ - 'moderation_rule', - 'nonmember_rule', + 'Moderation', + 'NonMember', ] __metaclass__ = type @@ -62,8 +62,3 @@ class NonMember: # The sender is a member of the mailing list. return False return True - - - -moderation_rule = Moderation() -nonmember_rule = NonMember() diff --git a/Mailman/rules/new_moderation.py b/Mailman/rules/news_moderation.py index dc42dcbb7..9caf8fb4a 100644 --- a/Mailman/rules/new_moderation.py +++ b/Mailman/rules/news_moderation.py @@ -17,7 +17,7 @@ """The news moderation rule.""" -__all__ = ['news_moderation'] +__all__ = ['ModeratedNewsgroup'] __metaclass__ = type @@ -40,7 +40,3 @@ newsgroup.""") def check(self, mlist, msg, msgdata): """See `IRule`.""" return mlist.news_moderation == NewsModeration.moderated - - - -news_moderation = ModeratedNewsgroup() diff --git a/Mailman/rules/no_subject.py b/Mailman/rules/no_subject.py index ca7cbd9d2..c36d742b8 100644 --- a/Mailman/rules/no_subject.py +++ b/Mailman/rules/no_subject.py @@ -17,7 +17,7 @@ """The no-Subject header rule.""" -__all__ = ['no_subject_rule'] +__all__ = ['NoSubject'] __metaclass__ = type @@ -39,7 +39,3 @@ class NoSubject: """See `IRule`.""" subject = msg.get('subject', '').strip() return subject == '' - - - -no_subject_rule = NoSubject() diff --git a/Mailman/rules/suspicious.py b/Mailman/rules/suspicious.py index 6384f8b9e..0464a6336 100644 --- a/Mailman/rules/suspicious.py +++ b/Mailman/rules/suspicious.py @@ -17,7 +17,7 @@ """The historical 'suspicious header' rule.""" -__all__ = ['suspicious_header'] +__all__ = ['SuspiciousHeader'] __metaclass__ = type @@ -90,7 +90,3 @@ def has_matching_bounce_header(mlist, msg): if cre.search(value): return True return False - - - -suspicious_header = SuspiciousHeader() diff --git a/Mailman/tests/test_documentation.py b/Mailman/tests/test_documentation.py index 36b3c7ecb..9faf1d588 100644 --- a/Mailman/tests/test_documentation.py +++ b/Mailman/tests/test_documentation.py @@ -31,6 +31,7 @@ from Mailman.app.styles import style_manager from Mailman.configuration import config +DOT = '.' COMMASPACE = ', ' @@ -78,7 +79,12 @@ def cleaning_teardown(testobj): def test_suite(): suite = unittest.TestSuite() - docsdir = os.path.join(os.path.dirname(Mailman.__file__), 'docs') + topdir = os.path.dirname(Mailman.__file__) + packages = [] + for dirpath, dirnames, filenames in os.walk(topdir): + if 'docs' in dirnames: + docsdir = os.path.join(dirpath, 'docs')[len(topdir)+1:] + packages.append(docsdir) # Under higher verbosity settings, report all doctest errors, not just the # first one. flags = (doctest.ELLIPSIS | @@ -86,13 +92,15 @@ def test_suite(): doctest.REPORT_NDIFF) if config.opts.verbosity <= 2: flags |= doctest.REPORT_ONLY_FIRST_FAILURE - for filename in os.listdir(docsdir): - if os.path.splitext(filename)[1] == '.txt': - test = doctest.DocFileSuite( - 'docs/' + filename, - package=Mailman, - optionflags=flags, - setUp=setup, - tearDown=cleaning_teardown) - suite.addTest(test) + # Add all the doctests in all subpackages. + for docsdir in packages: + for filename in os.listdir(os.path.join('Mailman', docsdir)): + if os.path.splitext(filename)[1] == '.txt': + test = doctest.DocFileSuite( + os.path.join(docsdir, filename), + package='Mailman', + optionflags=flags, + setUp=setup, + tearDown=cleaning_teardown) + suite.addTest(test) return suite |
