Skip to content

Commit c3f5c0d

Browse files
added type hints
1 parent 244e219 commit c3f5c0d

34 files changed

Lines changed: 512 additions & 126 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ parser.out
55
parsetab.py
66
*.pyc
77
*.egg-info/
8+
.mypy_cache

sifter/commands/discard.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1+
from email.message import Message
2+
from typing import (
3+
TYPE_CHECKING,
4+
Optional,
5+
List,
6+
Union,
7+
SupportsInt,
8+
Text
9+
)
10+
11+
from sifter.grammar.actions import Actions
12+
from sifter.grammar.state import EvaluationState
113
from sifter.grammar.command import Command
14+
from sifter.grammar.command_list import CommandList
15+
16+
if TYPE_CHECKING:
17+
from sifter.grammar.tag import Tag as TagGrammar
18+
from sifter.grammar.string import String
19+
from sifter.grammar.test import Test
220

321
__all__ = ('CommandDiscard',)
422

@@ -8,14 +26,15 @@ class CommandDiscard(Command):
826

927
RULE_IDENTIFIER = 'DISCARD'
1028

11-
def __init__(self, arguments=None, tests=None, block=None):
29+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1230
super(CommandDiscard, self).__init__(arguments, tests, block)
1331
self.validate_arguments()
1432
self.validate_tests_size(0)
1533
self.validate_block_size(0)
1634

17-
def evaluate(self, message, state):
35+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
1836
state.actions.cancel_implicit_keep()
37+
return None
1938

2039

2140
CommandDiscard.register()

sifter/commands/fileinto.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
from email.message import Message
2+
from typing import (
3+
TYPE_CHECKING,
4+
List,
5+
Optional,
6+
Union,
7+
SupportsInt,
8+
Text
9+
)
210

311
from sifter.grammar.command import Command
12+
from sifter.grammar.command_list import CommandList
413
from sifter.validators.stringlist import StringList
514
from sifter.grammar.state import EvaluationState
15+
from sifter.grammar.actions import Actions
616

17+
if TYPE_CHECKING:
18+
from sifter.grammar.tag import Tag as TagGrammar
19+
from sifter.grammar.string import String
20+
from sifter.grammar.test import Test
721

822
__all__ = ('CommandFileInto',)
923

@@ -13,7 +27,7 @@ class CommandFileInto(Command):
1327

1428
RULE_IDENTIFIER = 'FILEINTO'
1529

16-
def __init__(self, arguments=None, tests=None, block=None) -> None:
30+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1731
super(CommandFileInto, self).__init__(arguments, tests, block)
1832
_, positional_args = self.validate_arguments(
1933
{},
@@ -23,10 +37,11 @@ def __init__(self, arguments=None, tests=None, block=None) -> None:
2337
self.validate_block_size(0)
2438
self.file_dest = positional_args[0]
2539

26-
def evaluate(self, message: Message, state: EvaluationState) -> None:
40+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
2741
state.check_required_extension('fileinto', 'FILEINTO')
28-
state.actions.append('fileinto', self.file_dest)
42+
state.actions.append('fileinto', self.file_dest) # type: ignore
2943
state.actions.cancel_implicit_keep()
44+
return None
3045

3146

3247
CommandFileInto.register()

sifter/commands/if_cmd.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
1+
from email.message import Message
2+
from typing import (
3+
TYPE_CHECKING,
4+
List,
5+
Optional,
6+
Union,
7+
SupportsInt,
8+
Text
9+
)
10+
111
from sifter.grammar.command import Command
12+
from sifter.grammar.command_list import CommandList
13+
from sifter.grammar.state import EvaluationState
14+
from sifter.grammar.actions import Actions
15+
16+
if TYPE_CHECKING:
17+
from sifter.grammar.tag import Tag as TagGrammar
18+
from sifter.grammar.string import String
19+
from sifter.grammar.test import Test
220

321
__all__ = ('CommandIf', 'CommandElsIf', 'CommandElse',)
422

523

624
# section 3.1
725
class CommandIfBase(Command):
826

9-
def __init__(self, arguments=None, tests=None, block=None):
27+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1028
super(CommandIfBase, self).__init__(arguments, tests, block)
1129
self.validate_arguments()
1230
self.validate_tests_size(1)
1331

14-
def evaluate(self, message, state):
32+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
1533
if self.tests[0].evaluate(message, state):
1634
result = self.block.evaluate(message, state)
1735
state.last_if = True
@@ -32,7 +50,7 @@ class CommandElsIf(CommandIfBase):
3250

3351
RULE_IDENTIFIER = 'ELSIF'
3452

35-
def evaluate(self, message, state):
53+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
3654
if state.last_if:
3755
return None
3856
return super(CommandElsIf, self).evaluate(message, state)
@@ -45,12 +63,12 @@ class CommandElse(Command):
4563

4664
RULE_IDENTIFIER = 'ELSE'
4765

48-
def __init__(self, arguments=None, tests=None, block=None):
66+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
4967
super(CommandElse, self).__init__(arguments, tests, block)
5068
self.validate_arguments()
5169
self.validate_tests_size(0)
5270

53-
def evaluate(self, message, state):
71+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
5472
if state.last_if:
5573
return None
5674
return self.block.evaluate(message, state)

sifter/commands/keep.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
1+
from email.message import Message
2+
from typing import (
3+
TYPE_CHECKING,
4+
List,
5+
Optional,
6+
Union,
7+
SupportsInt,
8+
Text
9+
)
10+
111
from sifter.grammar.command import Command
12+
from sifter.grammar.command_list import CommandList
13+
from sifter.grammar.state import EvaluationState
14+
from sifter.grammar.actions import Actions
15+
16+
if TYPE_CHECKING:
17+
from sifter.grammar.tag import Tag as TagGrammar
18+
from sifter.grammar.string import String
19+
from sifter.grammar.test import Test
20+
221

322
__all__ = ('CommandKeep',)
423

@@ -8,14 +27,16 @@ class CommandKeep(Command):
827

928
RULE_IDENTIFIER = 'KEEP'
1029

11-
def __init__(self, arguments=None, tests=None, block=None):
30+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1231
super(CommandKeep, self).__init__(arguments, tests, block)
1332
self.validate_arguments()
1433
self.validate_tests_size(0)
1534
self.validate_block_size(0)
1635

17-
def evaluate(self, message, state):
18-
state.actions.append('keep').cancel_implicit_keep()
36+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
37+
state.actions.append('keep')
38+
state.actions.cancel_implicit_keep()
39+
return None
1940

2041

2142
CommandKeep.register()

sifter/commands/redirect.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
import email.utils
2+
from email.message import Message
3+
from typing import (
4+
TYPE_CHECKING,
5+
List,
6+
Optional,
7+
Union,
8+
SupportsInt,
9+
Text
10+
)
211

312
from sifter.grammar.command import Command
4-
import sifter.validators
13+
from sifter.grammar.command_list import CommandList
514
from sifter.grammar.rule import RuleSyntaxError
615
from sifter.validators.stringlist import StringList
16+
from sifter.grammar.state import EvaluationState
17+
from sifter.grammar.actions import Actions
18+
19+
if TYPE_CHECKING:
20+
from sifter.grammar.tag import Tag as TagGrammar
21+
from sifter.grammar.string import String
22+
from sifter.grammar.test import Test
723

824
__all__ = ('CommandRedirect',)
925

@@ -13,14 +29,18 @@ class CommandRedirect(Command):
1329

1430
RULE_IDENTIFIER = 'REDIRECT'
1531

16-
def __init__(self, arguments=None, tests=None, block=None):
32+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1733
super(CommandRedirect, self).__init__(arguments, tests, block)
1834
_, positional_args = self.validate_arguments(
1935
{},
2036
[StringList(length=1), ],
2137
)
2238
self.validate_tests_size(0)
2339
self.validate_block_size(0)
40+
if not isinstance(positional_args, list):
41+
raise ValueError("CommandRedirect positional argument error")
42+
if not isinstance(positional_args[0], list):
43+
raise ValueError("CommandRedirect positional argument error")
2444
self.email_address = positional_args[0][0]
2545
# TODO: section 2.4.2.3 constrains the email address to a limited
2646
# subset of valid address formats. need to check if python's
@@ -33,9 +53,10 @@ def __init__(self, arguments=None, tests=None, block=None):
3353
% self.email_address
3454
)
3555

36-
def evaluate(self, message, state):
56+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
3757
state.actions.append('redirect', self.email_address)
3858
state.actions.cancel_implicit_keep()
59+
return None
3960

4061

4162
CommandRedirect.register()

sifter/commands/require.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1+
from email.message import Message
12
from typing import (
2-
Text
3+
TYPE_CHECKING,
4+
Text,
5+
List,
6+
Optional,
7+
Union,
8+
SupportsInt
39
)
410

511
from sifter.grammar.command import Command
12+
from sifter.grammar.command_list import CommandList
613
import sifter.grammar
714
import sifter.handler
815
from sifter.validators.stringlist import StringList
16+
from sifter.grammar.state import EvaluationState
17+
from sifter.grammar.actions import Actions
18+
19+
if TYPE_CHECKING:
20+
from sifter.grammar.tag import Tag as TagGrammar
21+
from sifter.grammar.string import String
22+
from sifter.grammar.test import Test
923

1024
__all__ = ('CommandRequire',)
1125

@@ -15,7 +29,7 @@ class CommandRequire(Command):
1529

1630
RULE_IDENTIFIER: Text = 'REQUIRE'
1731

18-
def __init__(self, arguments=None, tests=None, block=None) -> None:
32+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1933
super(CommandRequire, self).__init__(arguments, tests, block)
2034
_, positional_args = self.validate_arguments(
2135
{},
@@ -25,14 +39,17 @@ def __init__(self, arguments=None, tests=None, block=None) -> None:
2539
self.validate_block_size(0)
2640
self.ext_names = positional_args[0]
2741

28-
def evaluate(self, message, state):
42+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
43+
if not isinstance(self.ext_names, list):
44+
raise ValueError("CommandRequire.ext_names must be a list!")
2945
for ext_name in self.ext_names:
3046
if not sifter.handler.get('extension', ext_name):
3147
raise RuntimeError(
3248
"Required extension '%s' not supported"
3349
% ext_name
3450
)
3551
state.require_extension(ext_name)
52+
return None
3653

3754

3855
CommandRequire.register()

sifter/commands/stop.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1+
from email.message import Message
2+
from typing import (
3+
TYPE_CHECKING,
4+
Optional,
5+
List,
6+
Union,
7+
SupportsInt,
8+
Text
9+
)
10+
111
from sifter.grammar.command import Command
12+
from sifter.grammar.command_list import CommandList
13+
from sifter.grammar.state import EvaluationState
14+
from sifter.grammar.actions import Actions
15+
16+
if TYPE_CHECKING:
17+
from sifter.grammar.tag import Tag as TagGrammar
18+
from sifter.grammar.string import String
19+
from sifter.grammar.test import Test
220

321
__all__ = ('CommandStop',)
422

@@ -8,14 +26,15 @@ class CommandStop(Command):
826

927
RULE_IDENTIFIER = 'STOP'
1028

11-
def __init__(self, arguments=None, tests=None, block=None):
29+
def __init__(self, arguments: Optional[List[Union['TagGrammar', SupportsInt, List[Union[Text, 'String']]]]] = None, tests: Optional[List['Test']] = None, block: Optional[CommandList] = None) -> None:
1230
super(CommandStop, self).__init__(arguments, tests, block)
1331
self.validate_arguments()
1432
self.validate_tests_size(0)
1533
self.validate_block_size(0)
1634

17-
def evaluate(self, message, state):
35+
def evaluate(self, message: Message, state: EvaluationState) -> Optional[Actions]:
1836
state.actions.append('stop')
37+
return None
1938

2039

2140
CommandStop.register()

sifter/comparator.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
from typing import (
22
TYPE_CHECKING,
3-
Any,
43
Callable,
54
Text,
65
Optional,
76
Tuple,
8-
Type
7+
Type,
8+
Union
99
)
1010

1111
import sifter.handler
1212

1313
if TYPE_CHECKING:
1414
from sifter.grammar.comparator import Comparator
15+
from sifter.grammar.tag import Tag
16+
from sifter.grammar.state import EvaluationState
1517

1618
__all__ = ('register', 'get_match_fn',)
1719

1820

19-
def register(comparator_name: Text, comparator_cls: Type['Comparator']) -> None:
21+
def register(comparator_name: Optional[Text], comparator_cls: Type['Comparator']) -> None:
2022
sifter.handler.register('comparator', comparator_name, comparator_cls)
2123

2224

23-
def get_match_fn(comparator: Optional[Text], match_type: Optional[Text]) -> Tuple[Callable[[Text, Text, Any], bool], Text, Text]: # TODO: Change Any from Callable
25+
def get_match_fn(comparator: Optional[Union[Text, 'Tag']], match_type: Optional[Union[Text, 'Tag']]) -> Tuple[Callable[[Text, Text, 'EvaluationState'], bool], Union[Text, 'Tag'], Union[Text, 'Tag']]:
2426
# section 2.7.3: default comparator is 'i;ascii-casemap'
2527
if comparator is None:
2628
comparator = 'i;ascii-casemap'

0 commit comments

Comments
 (0)