Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6eb438c

Browse files
committed
Minor formatting changes, add tests, bump version to 1.0.1
1 parent a904123 commit 6eb438c

6 files changed

Lines changed: 126 additions & 70 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ dependencies = [
4141
version = {attr = "idlemypyextension.__init__.__version__"}
4242

4343
[project.optional-dependencies]
44-
user = ["idleuserextend~=0.0.0"]
44+
user = ["idleuserextend~=0.0.1"]
4545

4646
[project.urls]
4747
"Source" = "https://github.com/CoolCat467/idlemypyextension"

src/idlemypyextension/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
__title__ = "idlemypyextension"
2323
__author__ = "CoolCat467"
2424
__license__ = "GNU General Public License Version 3"
25-
__version__ = "1.0.0"
25+
__version__ = "1.0.1"
2626

2727

2828
from idlemypyextension import utils

src/idlemypyextension/extension.py

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,64 @@ def debug(message: object) -> None:
5151
print(f"\n[{__title__}] DEBUG: {message}")
5252

5353

54+
def parse_comments(
55+
mypy_output: str,
56+
default_file: str,
57+
default_line: int,
58+
) -> dict[str, list[utils.Comment]]:
59+
"""Parse mypy output, return mapping of filenames to lists of comments."""
60+
error_type = re.compile(r" \[[a-z\-]+\]\s*$")
61+
62+
files: dict[str, list[utils.Comment]] = {}
63+
for output_line in mypy_output.splitlines():
64+
if not output_line.strip():
65+
continue
66+
filename = default_file
67+
line = default_line
68+
line_end = default_line
69+
col = 0
70+
col_end = 0
71+
msg_type = "unrecognized"
72+
73+
if output_line.count(": ") < 2:
74+
text = output_line
75+
else:
76+
where, msg_type, text = output_line.split(": ", 2)
77+
78+
position = where.split(":")
79+
80+
filename = position[0]
81+
if len(position) > 1:
82+
line = int(position[1])
83+
line_end = line
84+
if len(position) > 2:
85+
col = int(position[2])
86+
col_end = col
87+
if len(position) > 4:
88+
line_end = int(position[3])
89+
if line_end == line:
90+
col_end = int(position[4])
91+
else:
92+
line_end = line
93+
comment_type = error_type.search(text)
94+
if comment_type is not None:
95+
text = text[: comment_type.start()]
96+
msg_type = f"{comment_type.group(0)[3:-1]} {msg_type}"
97+
98+
comment = utils.Comment(
99+
file=filename,
100+
line=line,
101+
contents=f"{msg_type}: {text}",
102+
column=col,
103+
line_end=line_end,
104+
column_end=col_end,
105+
)
106+
107+
files.setdefault(filename, [])
108+
files[filename].append(comment)
109+
return files
110+
111+
54112
# Important weird: If event handler function returns 'break',
55113
# then it prevents other bindings of same event type from running.
56114
# If returns None, normal and others are also run.
@@ -211,64 +269,6 @@ def typecomment_only_current_file(self) -> bool:
211269
"""Should only add type comments for currently open file?."""
212270
return True
213271

214-
@staticmethod
215-
def parse_comments(
216-
mypy_output: str,
217-
default_file: str,
218-
default_line: int,
219-
) -> dict[str, list[utils.Comment]]:
220-
"""Parse mypy output, return mapping of filenames to lists of comments."""
221-
error_type = re.compile(r" \[[a-z\-]+\]\s*$")
222-
223-
files: dict[str, list[utils.Comment]] = {}
224-
for output_line in mypy_output.splitlines():
225-
if not output_line.strip():
226-
continue
227-
filename = default_file
228-
line = default_line
229-
line_end = default_line
230-
col = 0
231-
col_end = 0
232-
msg_type = "unrecognized"
233-
234-
if output_line.count(": ") < 2:
235-
text = output_line
236-
else:
237-
where, msg_type, text = output_line.split(": ", 2)
238-
239-
position = where.split(":")
240-
241-
filename = position[0]
242-
if len(position) > 1:
243-
line = int(position[1])
244-
line_end = line
245-
if len(position) > 2:
246-
col = int(position[2])
247-
col_end = col
248-
if len(position) > 4:
249-
line_end = int(position[3])
250-
if line_end == line:
251-
col_end = int(position[4])
252-
else:
253-
line_end = line
254-
comment_type = error_type.search(text)
255-
if comment_type is not None:
256-
text = text[: comment_type.start()]
257-
msg_type = f"{comment_type.group(0)[3:-1]} {msg_type}"
258-
259-
comment = utils.Comment(
260-
file=filename,
261-
line=line,
262-
contents=f"{msg_type}: {text}",
263-
column=col,
264-
line_end=line_end,
265-
column_end=col_end,
266-
)
267-
268-
files.setdefault(filename, [])
269-
files[filename].append(comment)
270-
return files
271-
272272
def add_type_comments_for_file(
273273
self,
274274
target_filename: str,
@@ -308,7 +308,7 @@ def add_mypy_messages(
308308
"""
309309
assert self.files.filename is not None
310310

311-
files = self.parse_comments(
311+
files = parse_comments(
312312
mypy_output,
313313
os.path.abspath(self.files.filename),
314314
start_line,
@@ -368,7 +368,7 @@ def add_extra_data(
368368
Tuple of:
369369
- Number of lines attempted to add
370370
- List of line numbers added that were not already there
371-
otherwise None because no content.
371+
otherwise empty because no content.
372372
373373
"""
374374
if not data:

src/idlemypyextension/utils.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ def check_installed(
131131
return False
132132

133133

134-
def get_line_selection(line: int) -> tuple[str, str]:
135-
"""Get selection strings for given line."""
136-
return f"{line}.0", f"{line+1}.0"
134+
def get_line_selection(line: int, length: int = 1) -> tuple[str, str]:
135+
"""Get selection strings for given line(s)."""
136+
return f"{line}.0", f"{line+length}.0"
137137

138138

139139
# Stolen from idlelib.searchengine
@@ -421,7 +421,11 @@ def reload(cls) -> None:
421421
)
422422
setattr(cls, key, value)
423423

424-
def get_line(self, line: int, text_win: Text | None = None) -> str:
424+
def get_line(
425+
self,
426+
line: int,
427+
text_win: Text | None = None,
428+
) -> str:
425429
"""Get the characters from the given line in currently open file."""
426430
if text_win is None:
427431
text_win = self.text

tests/test_annotate.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,27 @@ def test_invalid_tokenize() -> None:
203203
annotate.End(),
204204
],
205205
),
206+
(
207+
"""def potato(
208+
get_line = lambda lno: GLOBAL_LINES[lno]
209+
):""",
210+
[
211+
annotate.Definition("def"),
212+
annotate.FunctionName("potato"),
213+
annotate.EndSeparator("("),
214+
annotate.EndSeparator(text="\n"),
215+
annotate.EndSeparator(text=" "),
216+
annotate.ArgumentName("get_line"),
217+
annotate.DefaultDef("="),
218+
annotate.ArgumentDefault(text="lambda"),
219+
annotate.LambdaBody("lno: GLOBAL_LINES[lno]"),
220+
annotate.EndSeparator(text="\n"),
221+
annotate.EndSeparator(text=""),
222+
annotate.EndSeparator(")"),
223+
annotate.EndDefinition(":"),
224+
annotate.End(),
225+
],
226+
),
206227
],
207228
)
208229
def test_tokenize_definition(text: str, tokens: list[annotate.Token]) -> None:
@@ -500,6 +521,17 @@ def get_line(line_no: int) -> str:
500521
"""def potato(
501522
get_line: Callable[[int, str], str] = lambda lno, default: (default),
502523
lines: int = 0,
524+
) -> bool:""",
525+
None,
526+
),
527+
(
528+
"""def potato(
529+
get_line = lambda lno, default: (default, GLOBAL), lines = 0,
530+
):""",
531+
["Callable[[int, str], str]", "int"],
532+
"bool",
533+
"""def potato(
534+
get_line: Callable[[int, str], str] = lambda lno, default: (default, GLOBAL), lines: int = 0,
503535
) -> bool:""",
504536
None,
505537
),
@@ -676,6 +708,17 @@ def test_read_lambda_over_read_detection() -> None:
676708
assert over_read_error
677709

678710

711+
def test_read_lambda_over_read_parens() -> None:
712+
text = """ line_no, default: f'{line_no}: {default}'):"""
713+
714+
with StringIO(text) as file:
715+
content, over_read_error = annotate.read_lambda(
716+
generate_tokens(file.readline),
717+
)
718+
assert content == " line_no, default: f'{line_no}: {default}'"
719+
assert over_read_error
720+
721+
679722
@pytest.mark.parametrize(
680723
"end",
681724
[

tests/test_utils.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ def test_get_required_config() -> None:
3030
)
3131

3232

33+
def test_get_line_selection() -> None:
34+
assert utils.get_line_selection(3) == ("3.0", "4.0")
35+
assert utils.get_line_selection(3, 3) == ("3.0", "6.0")
36+
37+
3338
@pytest.mark.parametrize(
3439
("line", "expected"),
3540
[
@@ -44,10 +49,6 @@ def test_get_line_col_success(line: str, expected: tuple[int, int]) -> None:
4449
assert utils.get_line_col(line) == expected
4550

4651

47-
def test_get_line_selection() -> None:
48-
assert utils.get_line_selection(3) == ("3.0", "4.0")
49-
50-
5152
@pytest.mark.parametrize(
5253
"line",
5354
[
@@ -65,6 +66,14 @@ def test_get_line_col_failure(line: str) -> None:
6566
utils.get_line_col(line)
6667

6768

69+
@pytest.mark.parametrize(
70+
("index", "offset", "expect"),
71+
[("3.14", 0, "3.0"), ("3.14", 1, "4.0"), ("2981.23", -1, "2980.0")],
72+
)
73+
def test_get_whole_line(index: str, offset: int, expect: str) -> None:
74+
assert utils.get_whole_line(index, offset) == expect
75+
76+
6877
@pytest.mark.parametrize(
6978
("text", "expect"),
7079
[(" waf", 2), ("cat", 0), (" fish", 5), (" ", 3), ("", 0)],

0 commit comments

Comments
 (0)