Skip to content

Commit 28a9e88

Browse files
committed
Add hook to remove newlines after equals signs.
1 parent 6eed652 commit 28a9e88

File tree

6 files changed

+82
-2
lines changed

6 files changed

+82
-2
lines changed

formate/mini_hooks.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,19 @@
2929
# stdlib
3030
import ast
3131
import re
32+
from collections import deque
3233
from typing import List
3334

3435
# 3rd party
36+
import tokenize_rt # type: ignore[import-untyped]
3537
from domdf_python_tools.paths import PathPlus
3638
from domdf_python_tools.stringlist import StringList
3739
from domdf_python_tools.typing import PathLike
3840

3941
# this package
4042
from formate.config import wants_filename
4143

42-
__all__ = ("noqa_reformat", "check_ast", "squish_stubs")
44+
__all__ = ("check_ast", "newline_after_equals", "noqa_reformat", "squish_stubs")
4345

4446

4547
def noqa_reformat(source: str) -> str:
@@ -246,3 +248,40 @@ def _reformat_blocks(blocks: List[List[str]]) -> StringList:
246248
output.blankline(ensure_single=True)
247249

248250
return output
251+
252+
253+
def newline_after_equals(source: str) -> str:
254+
"""
255+
Removes newlines immediately after equals signs.
256+
257+
.. versionadded:: 1.2.0
258+
259+
:param source: The source to check.
260+
261+
:return: The reformatted source.
262+
"""
263+
264+
original_tokens = deque(tokenize_rt.src_to_tokens(source))
265+
tokens = []
266+
267+
while original_tokens:
268+
token = original_tokens.popleft()
269+
270+
if token.name == "OP" and token.src == '=':
271+
while True:
272+
273+
# TODO: handle spaces around equals (e.g. in function signature)
274+
# Look ahead until there's a non-whitespace token.
275+
next_token = original_tokens.popleft()
276+
if next_token.name in {"UNIMPORTANT_WS", "NL"}:
277+
pass
278+
else:
279+
break
280+
281+
tokens.append(token)
282+
tokens.append(next_token)
283+
284+
else:
285+
tokens.append(token)
286+
287+
return tokenize_rt.tokens_to_src(tokens)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ reformat-generics = "formate.reformat_generics:reformat_generics"
3131
dynamic_quotes = "formate.dynamic_quotes:dynamic_quotes"
3232
noqa_reformat = "formate.mini_hooks:noqa_reformat"
3333
squish_stubs = "formate.mini_hooks:squish_stubs"
34+
newline_after_equals = "formate.mini_hooks:newline_after_equals"
3435
ellipsis_reformat = "formate.ellipses:ellipsis_reformat"
3536
collections-import-rewrite = "formate.imports:rewrite_collections_abc_imports"
3637
isort = "formate:isort_hook"

repo_helper.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ entry_points:
6868
- "dynamic_quotes=formate.dynamic_quotes:dynamic_quotes"
6969
- "noqa_reformat=formate.mini_hooks:noqa_reformat"
7070
- "squish_stubs=formate.mini_hooks:squish_stubs"
71+
- "newline_after_equals=formate.mini_hooks:newline_after_equals"
7172
- "ellipsis_reformat=formate.ellipses:ellipsis_reformat"
7273
- "collections-import-rewrite=formate.imports:rewrite_collections_abc_imports"
7374
- "isort=formate:isort_hook"

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ dom-toml>=2.2.0
88
domdf-python-tools>=2.5.0
99
isort>=5.5.2
1010
prettyprinter>=0.18.0
11+
tokenize-rt>=5.0.0
1112
typing-extensions>=3.7.4.3
1213
yapf<0.43.0,>=0.30.0

tests/test_mini_hooks.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from coincidence.regressions import AdvancedFileRegressionFixture
77

88
# this package
9-
from formate.mini_hooks import check_ast, noqa_reformat, squish_stubs
9+
from formate.mini_hooks import check_ast, newline_after_equals, noqa_reformat, squish_stubs
1010

1111

1212
def test_noqa_reformat():
@@ -254,3 +254,33 @@ def foo():
254254

255255
new_code = squish_stubs(code, formate_filename="code.py")
256256
assert new_code == code
257+
258+
259+
newline_after_equals_src = """
260+
def foo():
261+
262+
with pytest.raises(
263+
ValueError,
264+
match=
265+
"This is a really long error message that exceeds the line length limit so gets pushed down!!!!!!",
266+
):
267+
pass
268+
269+
"""
270+
271+
no_newline_after_equals_src = """
272+
def foo():
273+
274+
with pytest.raises(
275+
ValueError,
276+
match="This is a shorter error message that's still too long to fit on one line.",
277+
):
278+
pass
279+
280+
"""
281+
282+
283+
def test_newline_after_equals(advanced_file_regression: AdvancedFileRegressionFixture):
284+
285+
advanced_file_regression.check(newline_after_equals(newline_after_equals_src))
286+
assert newline_after_equals(no_newline_after_equals_src) == no_newline_after_equals_src
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
def foo():
3+
4+
with pytest.raises(
5+
ValueError,
6+
match="This is a really long error message that exceeds the line length limit so gets pushed down!!!!!!",
7+
):
8+
pass

0 commit comments

Comments
 (0)