Skip to content

Commit 264ebd3

Browse files
added more type hints
1 parent 5fb8c11 commit 264ebd3

9 files changed

Lines changed: 69 additions & 27 deletions

File tree

sifter/commands/fileinto.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1-
import sifter.grammar
2-
import sifter.validators
1+
from email.message import Message
2+
3+
from sifter.grammar.command import Command
4+
from sifter.validators.stringlist import StringList
5+
from sifter.grammar.state import EvaluationState
6+
37

48
__all__ = ('CommandFileInto',)
59

610

711
# section 4.1
8-
class CommandFileInto(sifter.grammar.Command):
12+
class CommandFileInto(Command):
913

1014
RULE_IDENTIFIER = 'FILEINTO'
1115

12-
def __init__(self, arguments=None, tests=None, block=None):
16+
def __init__(self, arguments=None, tests=None, block=None) -> None:
1317
super(CommandFileInto, self).__init__(arguments, tests, block)
1418
_, positional_args = self.validate_arguments(
1519
{},
16-
[sifter.validators.StringList(length=1), ],
20+
[StringList(length=1), ],
1721
)
1822
self.validate_tests_size(0)
1923
self.validate_block_size(0)
2024
self.file_dest = positional_args[0]
2125

22-
def evaluate(self, message, state):
26+
def evaluate(self, message: Message, state: EvaluationState) -> None:
2327
state.check_required_extension('fileinto', 'FILEINTO')
2428
state.actions.append('fileinto', self.file_dest)
2529
state.actions.cancel_implicit_keep()

sifter/commands/require.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from typing import (
2+
Text
3+
)
4+
5+
from sifter.grammar.command import Command
16
import sifter.grammar
27
import sifter.handler
38
import sifter.validators
@@ -6,11 +11,11 @@
611

712

813
# section 3.2
9-
class CommandRequire(sifter.grammar.Command):
14+
class CommandRequire(Command):
1015

11-
RULE_IDENTIFIER = 'REQUIRE'
16+
RULE_IDENTIFIER: Text = 'REQUIRE'
1217

13-
def __init__(self, arguments=None, tests=None, block=None):
18+
def __init__(self, arguments=None, tests=None, block=None) -> None:
1419
super(CommandRequire, self).__init__(arguments, tests, block)
1520
_, positional_args = self.validate_arguments(
1621
{},

sifter/grammar/command.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from typing import (
2+
Text
3+
)
4+
15
import sifter.grammar
26
from . import rule
37
import sifter.utils
@@ -7,16 +11,16 @@
711

812
class Command(rule.Rule):
913

10-
RULE_TYPE = 'command'
14+
RULE_TYPE: Text = 'command'
1115

12-
def __init__(self, arguments=None, tests=None, block=None):
16+
def __init__(self, arguments=None, tests=None, block=None) -> None:
1317
super(Command, self).__init__(arguments, tests)
1418
if block is None:
1519
self.block = sifter.grammar.CommandList()
1620
else:
1721
self.block = block
1822

19-
def __str__(self):
23+
def __str__(self) -> Text:
2024
s = [super(Command, self).__str__(), ]
2125
if len(self.block.commands) > 0:
2226
s.append("{\n")
@@ -25,7 +29,7 @@ def __str__(self):
2529
s.append("}\n")
2630
return ''.join(s)
2731

28-
def validate_block_size(self, max_commands):
32+
def validate_block_size(self, max_commands: int) -> None:
2933
if len(self.block.commands) > max_commands:
3034
raise sifter.grammar.RuleSyntaxError(
3135
"%s takes no more than %d commands" % (self.RULE_IDENTIFIER, max_commands)

sifter/grammar/grammar.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ply.yacc
55

66
import sifter.grammar
7+
from sifter.grammar.tag import Tag
78
from sifter.grammar.lexer import tokens
89
import sifter.handler
910

@@ -149,7 +150,7 @@ def p_argument_number(p):
149150

150151
def p_argument_tag(p):
151152
"""argument : TAG"""
152-
p[0] = sifter.grammar.Tag(p[1])
153+
p[0] = Tag(p[1])
153154

154155

155156
def p_stringlist_error(p):

sifter/grammar/rule.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
from email.message import Message
2+
from typing import (
3+
Any,
4+
Dict,
5+
Text,
6+
Optional,
7+
List,
8+
Tuple
9+
)
10+
11+
from sifter.grammar.tag import Tag
12+
from sifter.grammar.state import EvaluationState
13+
from sifter.grammar.validator import Validator
114
import sifter.grammar
215
import sifter.handler
316
import sifter.utils
@@ -11,6 +24,9 @@ class RuleSyntaxError(Exception):
1124

1225
class Rule(object):
1326

27+
RULE_TYPE: Optional[Text] = None
28+
RULE_IDENTIFIER: Optional[Text] = None
29+
1430
@classmethod
1531
def register(cls) -> None:
1632
try:
@@ -20,7 +36,7 @@ def register(cls) -> None:
2036
# only on subclasses that implement specific rules
2137
raise NotImplementedError
2238

23-
def __init__(self, arguments=None, tests=None):
39+
def __init__(self, arguments: Optional[List[Any]] = None, tests: Optional[List[Any]] = None) -> None:
2440
if arguments is None:
2541
self.arguments = []
2642
else:
@@ -30,7 +46,7 @@ def __init__(self, arguments=None, tests=None):
3046
else:
3147
self.tests = tests
3248

33-
def __str__(self):
49+
def __str__(self) -> Text:
3450
s = ["%s" % self.RULE_IDENTIFIER, ]
3551
for arg in self.arguments:
3652
s.append(" %s" % arg)
@@ -39,7 +55,11 @@ def __str__(self):
3955
s.append("(\n%s)\n" % sifter.utils.indent_string(str(test), 2))
4056
return ''.join(s)
4157

42-
def validate_arguments(self, tagged_args=None, positional_args=None):
58+
def validate_arguments(
59+
self,
60+
tagged_args: Optional[Dict[Any, Any]] = None,
61+
positional_args: Optional[List[Validator]] = None
62+
) -> Tuple[Dict[Any, Any], List[Any]]:
4363
if tagged_args is None:
4464
tagged_args = {}
4565
if positional_args is None:
@@ -48,7 +68,7 @@ def validate_arguments(self, tagged_args=None, positional_args=None):
4868
seen_args = {}
4969
i, n = 0, len(self.arguments)
5070
while i < n:
51-
if not isinstance(self.arguments[i], sifter.grammar.Tag):
71+
if not isinstance(self.arguments[i], Tag):
5272
break
5373
num_valid_args = 0
5474
for arg_name, arg_validator in tagged_args.items():
@@ -82,7 +102,7 @@ def validate_arguments(self, tagged_args=None, positional_args=None):
82102

83103
return (seen_args, self.arguments[i:])
84104

85-
def validate_tests_size(self, min_tests, max_tests=None):
105+
def validate_tests_size(self, min_tests: int, max_tests: Optional[int] = None) -> None:
86106
if max_tests is None:
87107
max_tests = min_tests
88108
if len(self.tests) < min_tests or len(self.tests) > max_tests:
@@ -93,5 +113,5 @@ def validate_tests_size(self, min_tests, max_tests=None):
93113
raise RuleSyntaxError("%s takes %s tests" % (
94114
self.RULE_IDENTIFIER, msg))
95115

96-
def evaluate(self, message, state):
116+
def evaluate(self, message: Message, state: EvaluationState) -> None:
97117
raise NotImplementedError

sifter/grammar/state.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from typing import (
2+
Text
3+
)
14
import sifter.grammar
25

36
__all__ = ('EvaluationState',)
@@ -17,7 +20,7 @@ def __init__(self) -> None:
1720
def require_extension(self, extension):
1821
self.required_extensions[extension] = True
1922

20-
def check_required_extension(self, extension, feature_string):
23+
def check_required_extension(self, extension: Text, feature_string: Text) -> Text:
2124
if extension not in self.required_extensions:
2225
raise RuntimeError(
2326
"REQUIRE '%s' must happen before %s can be used."

sifter/handler.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
from typing import (
22
Any,
33
Dict,
4-
Text
4+
Text,
5+
Optional
56
)
67

78

89
_HANDLERS_MAP: Dict[Text, Dict[Text, Any]] = {}
910

1011

11-
def register(handler_type: Text, handler_id: Text, value: Any) -> None:
12+
def register(handler_type: Optional[Text], handler_id: Optional[Text], value: Any) -> None:
13+
if not handler_type or not handler_id:
14+
raise ValueError("handler_type and handler_id must not be None!")
1215
_HANDLERS_MAP.setdefault(handler_type, {})[handler_id] = value
1316

1417

sifter/tests/address.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Text
44
)
55

6+
from sifter.validators.tag import Tag
67
import sifter.grammar
78
import sifter.grammar.string
89
import sifter.validators
@@ -21,7 +22,7 @@ def __init__(self, arguments=None, tests=None) -> None:
2122
{
2223
'comparator': sifter.validators.Comparator(),
2324
'match_type': sifter.validators.MatchType(),
24-
'address_part': sifter.validators.Tag(('LOCALPART', 'DOMAIN', 'ALL')),
25+
'address_part': Tag(('LOCALPART', 'DOMAIN', 'ALL')),
2526
},
2627
[
2728
sifter.validators.StringList(),

sifter/tests/size.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import operator
22

33
import sifter.grammar
4-
import sifter.validators
4+
from sifter.validators.tag import Tag
5+
from sifter.validators.number import Number
56

67
__all__ = ('TestSize',)
78

@@ -20,9 +21,9 @@ def __init__(self, arguments=None, tests=None):
2021
super(TestSize, self).__init__(arguments, tests)
2122
tagged_args, positional_args = self.validate_arguments(
2223
{
23-
'size': sifter.validators.Tag(
24+
'size': Tag(
2425
('OVER', 'UNDER'),
25-
(sifter.validators.Number(),)
26+
(Number(),)
2627
),
2728
}
2829
)

0 commit comments

Comments
 (0)