Skip to content

Commit 6e6601e

Browse files
Merge branch 'develop'
2 parents c7e9e5d + 36fba3b commit 6e6601e

46 files changed

Lines changed: 351 additions & 263 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

setup.py

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,41 @@
66
long_description = file.read()
77

88
setup(
9-
name = "sifter",
10-
version = "0.1",
11-
author = "Gary Peck",
12-
author_email = "gary@realify.com",
13-
url = "https://github.com/garyp/sifter",
14-
license = "BSD",
15-
description = "Parser/evaluator for the Sieve filtering language (RFC 5228)",
16-
long_description = long_description,
17-
install_requires=[
18-
"ply",
19-
],
20-
classifiers = [
21-
"Programming Language :: Python",
22-
"Programming Language :: Python :: 2",
23-
"Programming Language :: Python :: 3",
24-
"License :: OSI Approved :: BSD License",
25-
"Development Status :: 4 - Beta",
26-
"Intended Audience :: Developers",
27-
"Intended Audience :: System Administrators",
28-
"Operating System :: OS Independent",
29-
"Topic :: Communications :: Email :: Filters",
30-
"Topic :: Software Development :: Interpreters",
31-
"Topic :: Software Development :: Libraries :: Python Modules",
32-
],
33-
packages = [
34-
"sifter",
35-
"sifter.commands",
36-
"sifter.comparators",
37-
"sifter.extensions",
38-
"sifter.grammar",
39-
"sifter.t",
40-
"sifter.tests",
41-
"sifter.validators",
42-
],
43-
package_data = {
44-
"sifter.t" : ["*.in", "*.out", "*.msg", "*.rules"],
45-
},
46-
)
47-
9+
name="sifter",
10+
version="0.1",
11+
author="Gary Peck",
12+
author_email="gary@realify.com",
13+
url="https://github.com/garyp/sifter",
14+
license="BSD",
15+
description="Parser/evaluator for the Sieve filtering language (RFC 5228)",
16+
long_description=long_description,
17+
install_requires=[
18+
"ply",
19+
],
20+
classifiers=[
21+
"Programming Language :: Python",
22+
"Programming Language :: Python :: 2",
23+
"Programming Language :: Python :: 3",
24+
"License :: OSI Approved :: BSD License",
25+
"Development Status :: 4 - Beta",
26+
"Intended Audience :: Developers",
27+
"Intended Audience :: System Administrators",
28+
"Operating System :: OS Independent",
29+
"Topic :: Communications :: Email :: Filters",
30+
"Topic :: Software Development :: Interpreters",
31+
"Topic :: Software Development :: Libraries :: Python Modules",
32+
],
33+
packages=[
34+
"sifter",
35+
"sifter.commands",
36+
"sifter.comparators",
37+
"sifter.extensions",
38+
"sifter.grammar",
39+
"sifter.t",
40+
"sifter.tests",
41+
"sifter.validators",
42+
],
43+
package_data={
44+
"sifter.t": ["*.in", "*.out", "*.msg", "*.rules"],
45+
},
46+
)

sifter/commands/discard.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
__all__ = ('CommandDiscard',)
44

5+
56
# section 4.4
67
class CommandDiscard(sifter.grammar.Command):
78

@@ -16,4 +17,5 @@ def __init__(self, arguments=None, tests=None, block=None):
1617
def evaluate(self, message, state):
1718
state.actions.cancel_implicit_keep()
1819

20+
1921
CommandDiscard.register()

sifter/commands/fileinto.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
__all__ = ('CommandFileInto',)
55

6+
67
# section 4.1
78
class CommandFileInto(sifter.grammar.Command):
89

@@ -11,9 +12,9 @@ class CommandFileInto(sifter.grammar.Command):
1112
def __init__(self, arguments=None, tests=None, block=None):
1213
super(CommandFileInto, self).__init__(arguments, tests, block)
1314
_, positional_args = self.validate_arguments(
14-
{},
15-
[ sifter.validators.StringList(length=1), ],
16-
)
15+
{},
16+
[sifter.validators.StringList(length=1), ],
17+
)
1718
self.validate_tests_size(0)
1819
self.validate_block_size(0)
1920
self.file_dest = positional_args[0]
@@ -23,4 +24,5 @@ def evaluate(self, message, state):
2324
state.actions.append('fileinto', self.file_dest)
2425
state.actions.cancel_implicit_keep()
2526

27+
2628
CommandFileInto.register()

sifter/commands/if_cmd.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
__all__ = ('CommandIf', 'CommandElsIf', 'CommandElse',)
44

5+
56
# section 3.1
67
class CommandIfBase(sifter.grammar.Command):
78

@@ -24,6 +25,7 @@ class CommandIf(CommandIfBase):
2425

2526
RULE_IDENTIFIER = 'IF'
2627

28+
2729
CommandIf.register()
2830

2931

@@ -37,6 +39,7 @@ def evaluate(self, message, state):
3739
else:
3840
return super(CommandElsIf, self).evaluate(message, state)
3941

42+
4043
CommandElsIf.register()
4144

4245

@@ -55,4 +58,5 @@ def evaluate(self, message, state):
5558
else:
5659
return self.block.evaluate(message, state)
5760

61+
5862
CommandElse.register()

sifter/commands/keep.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
__all__ = ('CommandKeep',)
44

5+
56
# section 4.3
67
class CommandKeep(sifter.grammar.Command):
78

@@ -16,4 +17,5 @@ def __init__(self, arguments=None, tests=None, block=None):
1617
def evaluate(self, message, state):
1718
state.actions.append('keep').cancel_implicit_keep()
1819

20+
1921
CommandKeep.register()

sifter/commands/redirect.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
__all__ = ('CommandRedirect',)
77

8+
89
# section 4.2
910
class CommandRedirect(sifter.grammar.Command):
1011

@@ -13,9 +14,9 @@ class CommandRedirect(sifter.grammar.Command):
1314
def __init__(self, arguments=None, tests=None, block=None):
1415
super(CommandRedirect, self).__init__(arguments, tests, block)
1516
_, positional_args = self.validate_arguments(
16-
{},
17-
[ sifter.validators.StringList(length=1), ],
18-
)
17+
{},
18+
[sifter.validators.StringList(length=1), ],
19+
)
1920
self.validate_tests_size(0)
2021
self.validate_block_size(0)
2122
self.email_address = positional_args[0][0]
@@ -26,12 +27,13 @@ def __init__(self, arguments=None, tests=None, block=None):
2627
realname, emailaddr = email.utils.parseaddr(self.email_address)
2728
if emailaddr == "":
2829
raise sifter.grammar.RuleSyntaxError(
29-
"REDIRECT destination not a valid email address: %s"
30-
% self.email_address
31-
)
30+
"REDIRECT destination not a valid email address: %s"
31+
% self.email_address
32+
)
3233

3334
def evaluate(self, message, state):
3435
state.actions.append('redirect', self.email_address)
3536
state.actions.cancel_implicit_keep()
3637

38+
3739
CommandRedirect.register()

sifter/commands/require.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
__all__ = ('CommandRequire',)
66

7+
78
# section 3.2
89
class CommandRequire(sifter.grammar.Command):
910

@@ -12,18 +13,21 @@ class CommandRequire(sifter.grammar.Command):
1213
def __init__(self, arguments=None, tests=None, block=None):
1314
super(CommandRequire, self).__init__(arguments, tests, block)
1415
_, positional_args = self.validate_arguments(
15-
{},
16-
[ sifter.validators.StringList(), ],
17-
)
16+
{},
17+
[sifter.validators.StringList(), ],
18+
)
1819
self.validate_tests_size(0)
1920
self.validate_block_size(0)
2021
self.ext_names = positional_args[0]
2122

2223
def evaluate(self, message, state):
2324
for ext_name in self.ext_names:
2425
if not sifter.handler.get('extension', ext_name):
25-
raise RuntimeError("Required extension '%s' not supported"
26-
% ext_name)
26+
raise RuntimeError(
27+
"Required extension '%s' not supported"
28+
% ext_name
29+
)
2730
state.require_extension(ext_name)
2831

32+
2933
CommandRequire.register()

sifter/commands/stop.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
__all__ = ('CommandStop',)
44

5+
56
# section 3.3
67
class CommandStop(sifter.grammar.Command):
78

@@ -16,4 +17,5 @@ def __init__(self, arguments=None, tests=None, block=None):
1617
def evaluate(self, message, state):
1718
state.actions.append('stop')
1819

20+
1921
CommandStop.register()

sifter/comparator.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22

33
__all__ = ('register', 'get_match_fn',)
44

5+
56
def register(comparator_name, comparator_cls):
67
sifter.handler.register('comparator', comparator_name, comparator_cls)
78

9+
810
def get_match_fn(comparator, match_type):
911
# section 2.7.3: default comparator is 'i;ascii-casemap'
10-
if comparator is None: comparator = 'i;ascii-casemap'
12+
if comparator is None:
13+
comparator = 'i;ascii-casemap'
1114
# RFC 4790, section 3.1: the special identifier 'default' refers to the
1215
# implementation-defined default comparator
13-
elif comparator == 'default': comparator = 'i;ascii-casemap'
16+
elif comparator == 'default':
17+
comparator = 'i;ascii-casemap'
1418

1519
# section 2.7.1: default match type is ":is"
16-
if match_type is None: match_type = 'IS'
20+
if match_type is None:
21+
match_type = 'IS'
1722

1823
# TODO: support wildcard matching in comparator names (RFC 4790)
1924
cmp_handler = sifter.handler.get('comparator', comparator)
@@ -24,9 +29,8 @@ def get_match_fn(comparator, match_type):
2429
cmp_fn = getattr(cmp_handler, 'cmp_%s' % match_type.lower())
2530
except AttributeError:
2631
raise RuntimeError(
27-
"':%s' matching not supported by comparator '%s'"
28-
% (match_type, comparator)
29-
)
32+
"':%s' matching not supported by comparator '%s'"
33+
% (match_type, comparator)
34+
)
3035

3136
return (cmp_fn, comparator, match_type)
32-
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import string
2-
try:
3-
# Python 3
4-
maketrans = str.maketrans
5-
except AttributeError:
6-
# Python 2
7-
maketrans = string.maketrans
8-
91
from sifter.comparators.octet import ComparatorOctet
102

3+
maketrans = str.maketrans
4+
115
__all__ = ('ComparatorASCIICasemap',)
126

7+
138
class ComparatorASCIICasemap(ComparatorOctet):
149

1510
COMPARATOR_ID = 'i;ascii-casemap'
@@ -18,4 +13,5 @@ class ComparatorASCIICasemap(ComparatorOctet):
1813
def sort_key(cls, s):
1914
return s.upper()
2015

16+
2117
ComparatorASCIICasemap.register()

0 commit comments

Comments
 (0)