Skip to content

Commit 3aafe47

Browse files
added type hints
1 parent 5db8d60 commit 3aafe47

9 files changed

Lines changed: 71 additions & 41 deletions

File tree

sifter/grammar/comparator.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from typing import (
2+
Optional,
3+
Text
4+
)
5+
16
import re
27
import sifter.comparator
38

@@ -7,6 +12,8 @@
712
# The official definition of comparators is in RFC 4790
813
class Comparator(object):
914

15+
COMPARATOR_ID: Optional[Text] = None
16+
1017
@classmethod
1118
def register(cls) -> None:
1219
try:

sifter/grammar/grammar.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# Parser based on RFC 5228, especially the grammar as defined in section 8. All
22
# references are to sections in RFC 5228 unless stated otherwise.
33

4-
import ply.yacc
4+
from typing import (
5+
TYPE_CHECKING,
6+
Any
7+
)
8+
9+
import ply.yacc # type: ignore
510

611
import sifter.grammar
712
from sifter.grammar.tag import Tag
@@ -10,14 +15,17 @@
1015
from sifter.grammar.string import String
1116
import sifter.handler
1217

18+
if TYPE_CHECKING:
19+
from py.yacc import LRParser, YaccProduction # type: ignore
20+
1321
__all__ = ('parser',)
1422

1523

16-
def parser(**kwargs):
24+
def parser(**kwargs: Any) -> 'LRParser':
1725
return ply.yacc.yacc(**kwargs)
1826

1927

20-
def p_commands_list(p):
28+
def p_commands_list(p: 'YaccProduction') -> None:
2129
"""commands : commands command"""
2230
p[0] = p[1]
2331

@@ -39,12 +47,12 @@ def p_commands_list(p):
3947
p[0].commands.append(p[2])
4048

4149

42-
def p_commands_empty(p):
50+
def p_commands_empty(p: 'YaccProduction') -> None:
4351
"""commands : """
4452
p[0] = CommandList()
4553

4654

47-
def p_command(p):
55+
def p_command(p: 'YaccProduction') -> None:
4856
"""command : IDENTIFIER arguments ';'
4957
| IDENTIFIER arguments block"""
5058
# print("COMMAND:", p[1], p[2], p[3])
@@ -59,14 +67,14 @@ def p_command(p):
5967
p[0] = handler(arguments=p[2]['args'], tests=tests, block=block)
6068

6169

62-
def p_command_error(p):
70+
def p_command_error(p: 'YaccProduction') -> None:
6371
"""command : IDENTIFIER error ';'
6472
| IDENTIFIER error block"""
6573
print("Syntax error in command definition after %s on line %d" % (p[1], p.lineno(1)))
6674
raise SyntaxError
6775

6876

69-
def p_block(p):
77+
def p_block(p: 'YaccProduction') -> None:
7078
"""block : '{' commands '}' """
7179
# section 3.2: REQUIRE command must come before any other commands,
7280
# which means it can't be in the block of another command
@@ -77,13 +85,13 @@ def p_block(p):
7785
p[0] = p[2]
7886

7987

80-
def p_block_error(p):
88+
def p_block_error(p: 'YaccProduction') -> None:
8189
"""block : '{' error '}'"""
8290
print("Syntax error in command block that starts on line %d" % (p.lineno(1),))
8391
raise SyntaxError
8492

8593

86-
def p_arguments(p):
94+
def p_arguments(p: 'YaccProduction') -> None:
8795
"""arguments : argumentlist
8896
| argumentlist test
8997
| argumentlist '(' testlist ')'"""
@@ -95,24 +103,24 @@ def p_arguments(p):
95103
p[0]['tests'] = [p[2]]
96104

97105

98-
def p_testlist_error(p):
106+
def p_testlist_error(p: 'YaccProduction') -> None:
99107
"""arguments : argumentlist '(' error ')'"""
100108
print("Syntax error in test list that starts on line %d" % p.lineno(2))
101109
raise SyntaxError
102110

103111

104-
def p_argumentlist_list(p):
112+
def p_argumentlist_list(p: 'YaccProduction') -> None:
105113
"""argumentlist : argumentlist argument"""
106114
p[0] = p[1]
107115
p[0].append(p[2])
108116

109117

110-
def p_argumentlist_empty(p):
118+
def p_argumentlist_empty(p: 'YaccProduction') -> None:
111119
"""argumentlist : """
112120
p[0] = []
113121

114122

115-
def p_test(p):
123+
def p_test(p: 'YaccProduction') -> None:
116124
"""test : IDENTIFIER arguments"""
117125
# print("TEST:", p[1], p[2])
118126
tests = p[2].get('tests')
@@ -123,55 +131,55 @@ def p_test(p):
123131
p[0] = handler(arguments=p[2]['args'], tests=tests)
124132

125133

126-
def p_testlist_list(p):
134+
def p_testlist_list(p: 'YaccProduction') -> None:
127135
"""testlist : test ',' testlist"""
128136
p[0] = p[3]
129137
p[0].insert(0, p[1])
130138

131139

132-
def p_testlist_single(p):
140+
def p_testlist_single(p: 'YaccProduction') -> None:
133141
"""testlist : test"""
134142
p[0] = [p[1]]
135143

136144

137-
def p_argument_stringlist(p):
145+
def p_argument_stringlist(p: 'YaccProduction') -> None:
138146
"""argument : '[' stringlist ']'"""
139147
p[0] = p[2]
140148

141149

142-
def p_argument_string(p):
150+
def p_argument_string(p: 'YaccProduction') -> None:
143151
"""argument : string"""
144152
# for simplicity, we treat all single strings as a string list
145153
p[0] = [p[1]]
146154

147155

148-
def p_argument_number(p):
156+
def p_argument_number(p: 'YaccProduction') -> None:
149157
"""argument : NUMBER"""
150158
p[0] = p[1]
151159

152160

153-
def p_argument_tag(p):
161+
def p_argument_tag(p: 'YaccProduction') -> None:
154162
"""argument : TAG"""
155163
p[0] = Tag(p[1])
156164

157165

158-
def p_stringlist_error(p):
166+
def p_stringlist_error(p: 'YaccProduction') -> None:
159167
"""argument : '[' error ']'"""
160168
print("Syntax error in string list that starts on line %d" % p.lineno(1))
161169
raise SyntaxError
162170

163171

164-
def p_stringlist_list(p):
172+
def p_stringlist_list(p: 'YaccProduction') -> None:
165173
"""stringlist : string ',' stringlist"""
166174
p[0] = p[3]
167175
p[0].insert(0, p[1])
168176

169177

170-
def p_stringlist_single(p):
178+
def p_stringlist_single(p: 'YaccProduction') -> None:
171179
"""stringlist : string"""
172180
p[0] = [p[1]]
173181

174182

175-
def p_string(p):
183+
def p_string(p: 'YaccProduction') -> None:
176184
"""string : QUOTED_STRING"""
177185
p[0] = String(p[1])

sifter/grammar/lexer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# references are to sections in RFC 5228 unless stated otherwise.
33

44
import math
5-
import ply.lex
5+
import ply.lex # type: ignore
66

77
__all__ = ('lexer', 'tokens',)
88

sifter/t/run_tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# type: ignore
2+
13
import unittest
24

35
if __name__ == '__main__':

sifter/t/test_comparators.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# type: ignore
2+
13
import unittest
24

35
import sifter.comparator

sifter/t/test_evaluation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# type: ignore
2+
13
import email
24
import os.path
35
import unittest

sifter/t/test_grammar.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
# type: ignore
2+
13
import unittest
24

35
import sifter.extension
4-
import sifter.grammar
6+
from sifter.grammar.state import EvaluationState
57

68

79
class TestEvaluationState(unittest.TestCase):
810

911
def setUp(self) -> None:
1012
sifter.extension.register('ext1')
1113
sifter.extension.register('ext2')
12-
self.state = sifter.grammar.EvaluationState()
14+
self.state = EvaluationState()
1315

1416
def test_require_extension(self) -> None:
1517
self.state.require_extension('ext1')

sifter/t/test_parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# type: ignore
2+
13
import os.path
24
import unittest
35
import codecs

sifter/t/test_validators.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
# type: ignore
2+
13
import unittest
24

3-
from sifter.grammar.rule import Rule
4-
import sifter.validators
5+
from sifter.grammar.tag import Tag as GrammarTag
6+
from sifter.grammar.rule import Rule, RuleSyntaxError
7+
from sifter.validators.number import Number
8+
from sifter.validators.stringlist import StringList
9+
from sifter.validators.tag import Tag as TagValidator
510

611

712
class MockRule(Rule):
@@ -16,54 +21,54 @@ def __init__(self, arguments=None, tests=None):
1621
class TestValidationFn(unittest.TestCase):
1722

1823
def test_too_many_args(self) -> None:
19-
mock_rule = MockRule([sifter.grammar.Tag('IS'), 13, ])
24+
mock_rule = MockRule([GrammarTag('IS'), 13, ])
2025
self.assertRaises(
21-
sifter.grammar.RuleSyntaxError,
26+
RuleSyntaxError,
2227
mock_rule.validate_arguments,
2328
)
2429

2530
def test_not_enough_args(self) -> None:
2631
mock_rule = MockRule([13, ])
2732
self.assertRaises(
28-
sifter.grammar.RuleSyntaxError,
33+
RuleSyntaxError,
2934
mock_rule.validate_arguments,
3035
[
31-
sifter.validators.Number(),
32-
sifter.validators.StringList(),
36+
Number(),
37+
StringList(),
3338
],
3439
)
3540

3641

3742
class TestTagValidator(unittest.TestCase):
3843

3944
def test_allowed_tag(self) -> None:
40-
mock_validator = sifter.validators.Tag(['MOCK', 'IS', ])
45+
mock_validator = TagValidator(['MOCK', 'IS', ])
4146
self.assertEqual(
42-
mock_validator.validate([sifter.grammar.Tag('IS')], 0),
47+
mock_validator.validate([GrammarTag('IS')], 0),
4348
1
4449
)
4550

4651
def test_allowed_single_tag(self) -> None:
4752
# test the case for a non-list single tag name
48-
mock_validator = sifter.validators.Tag('IS')
53+
mock_validator = TagValidator('IS')
4954
self.assertEqual(
50-
mock_validator.validate([sifter.grammar.Tag('IS')], 0),
55+
mock_validator.validate([GrammarTag('IS')], 0),
5156
1
5257
)
5358

5459
def test_not_allowed_tag(self) -> None:
55-
mock_validator = sifter.validators.Tag(['MOCK', 'FOO', ])
60+
mock_validator = TagValidator(['MOCK', 'FOO', ])
5661
self.assertEqual(
57-
mock_validator.validate([sifter.grammar.Tag('IS')], 0),
62+
mock_validator.validate([GrammarTag('IS')], 0),
5863
0
5964
)
6065

6166
def test_not_allowed_single_tag(self) -> None:
6267
# test the case for a non-list single tag name. test when the tag is a
6368
# substring of the allowed tag.
64-
mock_validator = sifter.validators.Tag('ISFOO')
69+
mock_validator = TagValidator('ISFOO')
6570
self.assertEqual(
66-
mock_validator.validate([sifter.grammar.Tag('IS')], 0),
71+
mock_validator.validate([GrammarTag('IS')], 0),
6772
0
6873
)
6974

0 commit comments

Comments
 (0)