|
8 | 8 |
|
9 | 9 | whitespace_rules = [
|
10 | 10 | # This linter should be first since bash_rules depends on it.
|
11 |
| - {'pattern': r'\s+$', 'strip': '\n', 'description': 'Fix trailing whitespace'}, |
12 |
| - {'pattern': '\t', 'strip': '\n', 'description': 'Fix tab-based whitespace'}, |
| 11 | + {"pattern": r"\s+$", "strip": "\n", "description": "Fix trailing whitespace"}, |
| 12 | + {"pattern": "\t", "strip": "\n", "description": "Fix tab-based whitespace"}, |
13 | 13 | ] # type: List[Rule]
|
14 | 14 |
|
15 | 15 | markdown_whitespace_rules = list(
|
16 |
| - [rule for rule in whitespace_rules if rule['pattern'] != r'\s+$'] |
| 16 | + [rule for rule in whitespace_rules if rule["pattern"] != r"\s+$"] |
17 | 17 | ) + [
|
18 | 18 | # Two spaces trailing a line with other content is okay--it's a markdown line break.
|
19 | 19 | # This rule finds one space trailing a non-space, three or more trailing spaces, and
|
20 | 20 | # spaces on an empty line.
|
21 | 21 | {
|
22 |
| - 'pattern': r'((?<!\s)\s$)|(\s\s\s+$)|(^\s+$)', |
23 |
| - 'strip': '\n', |
24 |
| - 'description': 'Fix trailing whitespace', |
| 22 | + "pattern": r"((?<!\s)\s$)|(\s\s\s+$)|(^\s+$)", |
| 23 | + "strip": "\n", |
| 24 | + "description": "Fix trailing whitespace", |
25 | 25 | },
|
26 | 26 | {
|
27 |
| - 'pattern': r'^#+[A-Za-z0-9]', |
28 |
| - 'strip': '\n', |
29 |
| - 'description': 'Missing space after # in heading', |
| 27 | + "pattern": r"^#+[A-Za-z0-9]", |
| 28 | + "strip": "\n", |
| 29 | + "description": "Missing space after # in heading", |
30 | 30 | },
|
31 | 31 | ]
|
32 | 32 |
|
33 | 33 | python_rules = RuleList(
|
34 |
| - langs=['py'], |
| 34 | + langs=["py"], |
35 | 35 | rules=[
|
36 |
| - {'pattern': r'".*"%\([a-z_].*\)?$', 'description': 'Missing space around "%"'}, |
37 |
| - {'pattern': r"'.*'%\([a-z_].*\)?$", 'description': 'Missing space around "%"'}, |
| 36 | + {"pattern": r'".*"%\([a-z_].*\)?$', "description": 'Missing space around "%"'}, |
| 37 | + {"pattern": r"'.*'%\([a-z_].*\)?$", "description": 'Missing space around "%"'}, |
38 | 38 | # This rule is constructed with + to avoid triggering on itself
|
39 |
| - {'pattern': r" =" + r'[^ =>~"]', 'description': 'Missing whitespace after "="'}, |
40 |
| - {'pattern': r'":\w[^"]*$', 'description': 'Missing whitespace after ":"'}, |
41 |
| - {'pattern': r"':\w[^']*$", 'description': 'Missing whitespace after ":"'}, |
42 |
| - {'pattern': r"^\s+[#]\w", 'strip': '\n', 'description': 'Missing whitespace after "#"'}, |
| 39 | + {"pattern": r" =" + r'[^ =>~"]', "description": 'Missing whitespace after "="'}, |
| 40 | + {"pattern": r'":\w[^"]*$', "description": 'Missing whitespace after ":"'}, |
| 41 | + {"pattern": r"':\w[^']*$", "description": 'Missing whitespace after ":"'}, |
| 42 | + {"pattern": r"^\s+[#]\w", "strip": "\n", "description": 'Missing whitespace after "#"'}, |
43 | 43 | {
|
44 |
| - 'pattern': r"assertEquals[(]", |
45 |
| - 'description': 'Use assertEqual, not assertEquals (which is deprecated).', |
| 44 | + "pattern": r"assertEquals[(]", |
| 45 | + "description": "Use assertEqual, not assertEquals (which is deprecated).", |
46 | 46 | },
|
47 | 47 | {
|
48 |
| - 'pattern': r'self: Any', |
49 |
| - 'description': 'you can omit Any annotation for self', |
50 |
| - 'good_lines': ['def foo (self):'], |
51 |
| - 'bad_lines': ['def foo(self: Any):'], |
| 48 | + "pattern": r"self: Any", |
| 49 | + "description": "you can omit Any annotation for self", |
| 50 | + "good_lines": ["def foo (self):"], |
| 51 | + "bad_lines": ["def foo(self: Any):"], |
52 | 52 | },
|
53 |
| - {'pattern': r"== None", 'description': 'Use `is None` to check whether something is None'}, |
54 |
| - {'pattern': r"type:[(]", 'description': 'Missing whitespace after ":" in type annotation'}, |
55 |
| - {'pattern': r"# type [(]", 'description': 'Missing : after type in type annotation'}, |
56 |
| - {'pattern': r"#type", 'description': 'Missing whitespace after "#" in type annotation'}, |
57 |
| - {'pattern': r'if[(]', 'description': 'Missing space between if and ('}, |
58 |
| - {'pattern': r", [)]", 'description': 'Unnecessary whitespace between "," and ")"'}, |
59 |
| - {'pattern': r"% [(]", 'description': 'Unnecessary whitespace between "%" and "("'}, |
| 53 | + {"pattern": r"== None", "description": "Use `is None` to check whether something is None"}, |
| 54 | + {"pattern": r"type:[(]", "description": 'Missing whitespace after ":" in type annotation'}, |
| 55 | + {"pattern": r"# type [(]", "description": "Missing : after type in type annotation"}, |
| 56 | + {"pattern": r"#type", "description": 'Missing whitespace after "#" in type annotation'}, |
| 57 | + {"pattern": r"if[(]", "description": "Missing space between if and ("}, |
| 58 | + {"pattern": r", [)]", "description": 'Unnecessary whitespace between "," and ")"'}, |
| 59 | + {"pattern": r"% [(]", "description": 'Unnecessary whitespace between "%" and "("'}, |
60 | 60 | # This next check could have false positives, but it seems pretty
|
61 | 61 | # rare; if we find any, they can be added to the exclude list for
|
62 | 62 | # this rule.
|
63 | 63 | {
|
64 |
| - 'pattern': r' % [a-zA-Z0-9_.]*\)?$', |
65 |
| - 'description': 'Used % comprehension without a tuple', |
| 64 | + "pattern": r" % [a-zA-Z0-9_.]*\)?$", |
| 65 | + "description": "Used % comprehension without a tuple", |
66 | 66 | },
|
67 | 67 | {
|
68 |
| - 'pattern': r'.*%s.* % \([a-zA-Z0-9_.]*\)$', |
69 |
| - 'description': 'Used % comprehension without a tuple', |
| 68 | + "pattern": r".*%s.* % \([a-zA-Z0-9_.]*\)$", |
| 69 | + "description": "Used % comprehension without a tuple", |
70 | 70 | },
|
71 | 71 | {
|
72 |
| - 'pattern': r'__future__', |
73 |
| - 'include_only': {'zulip_bots/zulip_bots/bots/'}, |
74 |
| - 'description': 'Bots no longer need __future__ imports.', |
| 72 | + "pattern": r"__future__", |
| 73 | + "include_only": {"zulip_bots/zulip_bots/bots/"}, |
| 74 | + "description": "Bots no longer need __future__ imports.", |
75 | 75 | },
|
76 | 76 | {
|
77 |
| - 'pattern': r'#!/usr/bin/env python$', |
78 |
| - 'include_only': {'zulip_bots/'}, |
79 |
| - 'description': 'Python shebangs must be python3', |
| 77 | + "pattern": r"#!/usr/bin/env python$", |
| 78 | + "include_only": {"zulip_bots/"}, |
| 79 | + "description": "Python shebangs must be python3", |
80 | 80 | },
|
81 | 81 | {
|
82 |
| - 'pattern': r'(^|\s)open\s*\(', |
83 |
| - 'description': 'open() should not be used in Zulip\'s bots. Use functions' |
84 |
| - ' provided by the bots framework to access the filesystem.', |
85 |
| - 'include_only': {'zulip_bots/zulip_bots/bots/'}, |
| 82 | + "pattern": r"(^|\s)open\s*\(", |
| 83 | + "description": "open() should not be used in Zulip's bots. Use functions" |
| 84 | + " provided by the bots framework to access the filesystem.", |
| 85 | + "include_only": {"zulip_bots/zulip_bots/bots/"}, |
86 | 86 | },
|
87 | 87 | {
|
88 |
| - 'pattern': r'pprint', |
89 |
| - 'description': 'Used pprint, which is most likely a debugging leftover. For user output, use print().', |
| 88 | + "pattern": r"pprint", |
| 89 | + "description": "Used pprint, which is most likely a debugging leftover. For user output, use print().", |
90 | 90 | },
|
91 | 91 | {
|
92 |
| - 'pattern': r'\(BotTestCase\)', |
93 |
| - 'bad_lines': ['class TestSomeBot(BotTestCase):'], |
94 |
| - 'description': 'Bot test cases should directly inherit from BotTestCase *and* DefaultTests.', |
| 92 | + "pattern": r"\(BotTestCase\)", |
| 93 | + "bad_lines": ["class TestSomeBot(BotTestCase):"], |
| 94 | + "description": "Bot test cases should directly inherit from BotTestCase *and* DefaultTests.", |
95 | 95 | },
|
96 | 96 | {
|
97 |
| - 'pattern': r'\(DefaultTests, BotTestCase\)', |
98 |
| - 'bad_lines': ['class TestSomeBot(DefaultTests, BotTestCase):'], |
99 |
| - 'good_lines': ['class TestSomeBot(BotTestCase, DefaultTests):'], |
100 |
| - 'description': 'Bot test cases should inherit from BotTestCase before DefaultTests.', |
| 97 | + "pattern": r"\(DefaultTests, BotTestCase\)", |
| 98 | + "bad_lines": ["class TestSomeBot(DefaultTests, BotTestCase):"], |
| 99 | + "good_lines": ["class TestSomeBot(BotTestCase, DefaultTests):"], |
| 100 | + "description": "Bot test cases should inherit from BotTestCase before DefaultTests.", |
101 | 101 | },
|
102 | 102 | *whitespace_rules,
|
103 | 103 | ],
|
104 | 104 | max_length=140,
|
105 | 105 | )
|
106 | 106 |
|
107 | 107 | bash_rules = RuleList(
|
108 |
| - langs=['sh'], |
| 108 | + langs=["sh"], |
109 | 109 | rules=[
|
110 | 110 | {
|
111 |
| - 'pattern': r'#!.*sh [-xe]', |
112 |
| - 'description': 'Fix shebang line with proper call to /usr/bin/env for Bash path, change -x|-e switches' |
113 |
| - ' to set -x|set -e', |
| 111 | + "pattern": r"#!.*sh [-xe]", |
| 112 | + "description": "Fix shebang line with proper call to /usr/bin/env for Bash path, change -x|-e switches" |
| 113 | + " to set -x|set -e", |
114 | 114 | },
|
115 | 115 | *whitespace_rules[0:1],
|
116 | 116 | ],
|
117 | 117 | )
|
118 | 118 |
|
119 | 119 |
|
120 | 120 | json_rules = RuleList(
|
121 |
| - langs=['json'], |
| 121 | + langs=["json"], |
122 | 122 | # Here, we don't check tab-based whitespace, because the tab-based
|
123 | 123 | # whitespace rule flags a lot of third-party JSON fixtures
|
124 | 124 | # under zerver/webhooks that we want preserved verbatim. So
|
|
131 | 131 |
|
132 | 132 | prose_style_rules = [
|
133 | 133 | {
|
134 |
| - 'pattern': r'[^\/\#\-"]([jJ]avascript)', # exclude usage in hrefs/divs |
135 |
| - 'description': "javascript should be spelled JavaScript", |
| 134 | + "pattern": r'[^\/\#\-"]([jJ]avascript)', # exclude usage in hrefs/divs |
| 135 | + "description": "javascript should be spelled JavaScript", |
136 | 136 | },
|
137 | 137 | {
|
138 |
| - 'pattern': r'''[^\/\-\."'\_\=\>]([gG]ithub)[^\.\-\_"\<]''', # exclude usage in hrefs/divs |
139 |
| - 'description': "github should be spelled GitHub", |
| 138 | + "pattern": r"""[^\/\-\."'\_\=\>]([gG]ithub)[^\.\-\_"\<]""", # exclude usage in hrefs/divs |
| 139 | + "description": "github should be spelled GitHub", |
140 | 140 | },
|
141 | 141 | {
|
142 |
| - 'pattern': r'[oO]rganisation', # exclude usage in hrefs/divs |
143 |
| - 'description': "Organization is spelled with a z", |
| 142 | + "pattern": r"[oO]rganisation", # exclude usage in hrefs/divs |
| 143 | + "description": "Organization is spelled with a z", |
144 | 144 | },
|
145 |
| - {'pattern': r'!!! warning', 'description': "!!! warning is invalid; it's spelled '!!! warn'"}, |
| 145 | + {"pattern": r"!!! warning", "description": "!!! warning is invalid; it's spelled '!!! warn'"}, |
146 | 146 | {
|
147 |
| - 'pattern': r'[^-_]botserver(?!rc)|bot server', |
148 |
| - 'description': "Use Botserver instead of botserver or Botserver.", |
| 147 | + "pattern": r"[^-_]botserver(?!rc)|bot server", |
| 148 | + "description": "Use Botserver instead of botserver or Botserver.", |
149 | 149 | },
|
150 | 150 | ] # type: List[Rule]
|
151 | 151 |
|
|
154 | 154 | }
|
155 | 155 |
|
156 | 156 | markdown_rules = RuleList(
|
157 |
| - langs=['md'], |
| 157 | + langs=["md"], |
158 | 158 | rules=[
|
159 | 159 | *markdown_whitespace_rules,
|
160 | 160 | *prose_style_rules,
|
161 | 161 | {
|
162 |
| - 'pattern': r'\[(?P<url>[^\]]+)\]\((?P=url)\)', |
163 |
| - 'description': 'Linkified markdown URLs should use cleaner <http://example.com> syntax.', |
| 162 | + "pattern": r"\[(?P<url>[^\]]+)\]\((?P=url)\)", |
| 163 | + "description": "Linkified markdown URLs should use cleaner <http://example.com> syntax.", |
164 | 164 | },
|
165 | 165 | ],
|
166 | 166 | max_length=120,
|
167 | 167 | length_exclude=markdown_docs_length_exclude,
|
168 | 168 | )
|
169 | 169 |
|
170 | 170 | txt_rules = RuleList(
|
171 |
| - langs=['txt'], |
| 171 | + langs=["txt"], |
172 | 172 | rules=whitespace_rules,
|
173 | 173 | )
|
174 | 174 |
|
|
0 commit comments