Skip to content

Commit 2a452f8

Browse files
author
MomIsBestFriend
committed
TST: Added test case
for spaces at the beggining of concatneted strings
1 parent 4206fd4 commit 2a452f8

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python
2+
"""
3+
Test case for leading spaces in concated strings.
4+
5+
For example:
6+
7+
# Good
8+
foo = (
9+
"bar "
10+
"baz"
11+
)
12+
13+
14+
# Bad
15+
foo = (
16+
"bar"
17+
" baz"
18+
)
19+
"""
20+
21+
import argparse
22+
import os
23+
import sys
24+
import token
25+
import tokenize
26+
from typing import Generator, List, Tuple
27+
28+
FILE_EXTENSIONS_TO_CHECK = (".py", ".pyx", ".pyx.ini", ".pxd")
29+
30+
MSG = "String have a space at the beggining instead, at the end of the previos string."
31+
32+
33+
def main(source_path: str, output_format: str) -> bool:
34+
"""
35+
Main entry point of the script.
36+
37+
Parameters
38+
----------
39+
source_path : str
40+
Source path representing path to a file/directory.
41+
output_format : str
42+
Output format of the script.
43+
44+
Returns
45+
-------
46+
bool
47+
True if found any strings that have a leading space in the wrong line.
48+
49+
Raises
50+
------
51+
ValueError
52+
If the `source_path` is not pointing to existing file/directory.
53+
"""
54+
if not os.path.exists(source_path):
55+
raise ValueError(
56+
"Please enter a valid path, pointing to a valid file/directory."
57+
)
58+
59+
is_failed: bool = False
60+
61+
if os.path.isfile(source_path):
62+
for source_path, line_number in strings_with_wrong_space(source_path):
63+
is_failed = True
64+
print(
65+
output_format.format(
66+
source_path=source_path, line_number=line_number, msg=MSG
67+
)
68+
)
69+
70+
for subdir, _, files in os.walk(source_path):
71+
for file_name in files:
72+
if any(
73+
file_name.endswith(extension) for extension in FILE_EXTENSIONS_TO_CHECK
74+
):
75+
for source_path, line_number in strings_with_wrong_space(
76+
os.path.join(subdir, file_name)
77+
):
78+
is_failed = True
79+
print(
80+
output_format.format(
81+
source_path=source_path, line_number=line_number, msg=MSG
82+
)
83+
)
84+
return is_failed
85+
86+
87+
def strings_with_wrong_space(
88+
source_path: str,
89+
) -> Generator[Tuple[str, int], None, None]:
90+
"""
91+
Yielding the file path and the line number of the string to fix.
92+
93+
Parameters
94+
----------
95+
source_path : str
96+
File path pointing to a single file.
97+
98+
Yields
99+
------
100+
source_path : str
101+
Source file path.
102+
line_number : int
103+
Line number of the wrong placed space.
104+
"""
105+
with open(source_path, "r") as file_name:
106+
tokens: List = list(tokenize.generate_tokens(file_name.readline))
107+
108+
for first_token, second_token, third_token in zip(tokens, tokens[1:], tokens[2:]):
109+
if (
110+
first_token[0] == third_token[0] == token.STRING
111+
and second_token[0] == token.NL
112+
):
113+
# Means we are in a block of concated string
114+
115+
# Striping the quotes
116+
first_string = first_token[1][1:-1]
117+
second_string = third_token[1][1:-1]
118+
119+
if (not first_string.endswith(" ")) and (second_string.startswith(" ")):
120+
yield source_path, third_token[2][0]
121+
122+
123+
if __name__ == "__main__":
124+
parser = argparse.ArgumentParser(
125+
description="Validate spaces over concated strings"
126+
)
127+
128+
parser.add_argument(
129+
"path", nargs="?", default=".", help="Source path of file/directory to check."
130+
)
131+
parser.add_argument(
132+
"--format",
133+
"-f",
134+
default="{source_path}:{line_number}:{msg}",
135+
help="Output format of the error message.",
136+
)
137+
138+
args = parser.parse_args()
139+
140+
sys.exit(main(source_path=args.path, output_format=args.format))

0 commit comments

Comments
 (0)