Skip to content
This repository was archived by the owner on Jan 13, 2026. It is now read-only.

Commit 5402378

Browse files
committed
Add example visit method to SpacesVisitor
1 parent 6cfab68 commit 5402378

4 files changed

Lines changed: 39 additions & 5 deletions

File tree

rewrite/rewrite/python/format/auto_format.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Optional
22

33
from rewrite import Recipe, Tree, Cursor
4-
from rewrite.java import JavaSourceFile
4+
from rewrite.java import JavaSourceFile, MethodDeclaration, J, Space
55
from rewrite.python import PythonVisitor, SpacesStyle, IntelliJ
66
from rewrite.visitor import P, T
77

@@ -27,3 +27,8 @@ class SpacesVisitor(PythonVisitor):
2727
def __init__(self, style: SpacesStyle, stop_after: Tree = None):
2828
self._style = style
2929
self._stop_after = stop_after
30+
31+
def visit_method_declaration(self, method_declaration: MethodDeclaration, p: P) -> J:
32+
return method_declaration.padding.with_parameters(
33+
method_declaration.padding.parameters.with_before(Space.SINGLE_SPACE if self._style.beforeParentheses.method_parentheses else Space.EMPTY)
34+
)

rewrite/rewrite/python/parser.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
import ast
22
import logging
3+
from dataclasses import dataclass
34
from pathlib import Path
45
from typing import Iterable, Optional
56

6-
from rewrite import Parser, ParserInput, ExecutionContext, SourceFile, ParseError
7+
from rewrite import Parser, ParserInput, ExecutionContext, SourceFile, ParseError, NamedStyles, Markers, Tree, random_id
78
from rewrite.parser import require_print_equals_input, ParserBuilder
89
from ._parser_visitor import ParserVisitor
910
from .tree import CompilationUnit
1011

1112
logging.basicConfig(level=logging.ERROR)
1213

1314

15+
@dataclass(frozen=True)
1416
class PythonParser(Parser):
17+
_styles: Optional[Iterable[NamedStyles]]
18+
1519
def parse_inputs(self, sources: Iterable[ParserInput], relative_to: Optional[Path],
1620
ctx: ExecutionContext) -> Iterable[SourceFile]:
1721
accepted = (source for source in sources if self.accept(source.path))
@@ -20,6 +24,7 @@ def parse_inputs(self, sources: Iterable[ParserInput], relative_to: Optional[Pat
2024
source_str = source.source().read()
2125
tree = ast.parse(source_str, source.path)
2226
cu = ParserVisitor(source_str).visit(tree).with_source_path(source.path)
27+
cu = cu.with_markers(Markers.build(random_id(), self._styles)) if self._styles else cu
2328
cu = require_print_equals_input(self, cu, source, relative_to, ctx)
2429
except Exception as e:
2530
logging.error(f"An error was encountered while parsing {source.path}: {str(e)}", exc_info=True)
@@ -37,6 +42,11 @@ class PythonParserBuilder(ParserBuilder):
3742
def __init__(self):
3843
self._source_file_type = type(CompilationUnit)
3944
self._dsl_name = 'python'
45+
self._styles = None
46+
47+
def styles(self, styles: Iterable[NamedStyles]):
48+
self._styles = styles
49+
return self
4050

4151
def build(self) -> Parser:
42-
return PythonParser()
52+
return PythonParser(self._styles)

rewrite/rewrite/visitor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def first_enclosing(self, type: Type[P]) -> P:
4040
return None
4141

4242
def fork(self) -> Cursor:
43-
return Cursor(self.parent.fork(), self.value)
43+
return Cursor(self.parent.fork(), self.value) if self.parent else self
4444

4545

4646
class TreeVisitor(Protocol[T, P]):

rewrite/tests/python/all/format/demo_test.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Optional
22

33
from rewrite.java import Space, P
4-
from rewrite.python import PythonVisitor
4+
from rewrite.python import PythonVisitor, AutoFormat
55
from rewrite.test import rewrite_run, python, from_visitor
66

77

@@ -18,6 +18,25 @@ def getter(self, row):
1818
recipe=from_visitor(NoSpaces())
1919
)
2020

21+
22+
def test_spaces_before_method_parentheses():
23+
rewrite_run(
24+
# language=python
25+
python(
26+
"""
27+
class Foo:
28+
def getter (self, row):
29+
pass
30+
""",
31+
"""
32+
class Foo:
33+
def getter(self, row):
34+
pass
35+
"""
36+
),
37+
recipe=AutoFormat()
38+
)
39+
2140
class NoSpaces(PythonVisitor):
2241
def visit_space(self, space: Optional[Space], loc: Optional[Space.Location], p: P) -> Optional[Space]:
2342
return Space.EMPTY if space else None

0 commit comments

Comments
 (0)