Skip to content

Commit 7ca8044

Browse files
committed
Python: Address review feedback on template parenthesization
Remove dead `coordinates` and `cursor` params from `apply_substitutions`, extend `_get_precedence` to handle `not` unary (precedence 3), fix test calling renamed `apply_coordinates`, and add clarifying docstring for the outer/inner parenthesization boundary.
1 parent 28c5490 commit 7ca8044

4 files changed

Lines changed: 12 additions & 16 deletions

File tree

rewrite-python/rewrite/src/rewrite/python/template/engine.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,13 @@ def apply_substitutions(
116116
cls,
117117
template_tree: J,
118118
values: Dict[str, J],
119-
cursor: 'Cursor',
120-
coordinates: Optional[PythonCoordinates] = None
121119
) -> Optional[J]:
122120
"""
123121
Substitute placeholder identifiers with actual values.
124122
125123
Args:
126124
template_tree: The parsed template AST.
127125
values: Dict mapping capture names to their AST values.
128-
cursor: Current cursor position.
129-
coordinates: Where/how to apply the template.
130126
131127
Returns:
132128
The template with placeholders replaced by actual values.
@@ -135,13 +131,7 @@ def apply_substitutions(
135131

136132
# Replace placeholders with actual values
137133
visitor = PlaceholderReplacementVisitor(values)
138-
result = visitor.visit(template_tree, None)
139-
140-
# Apply coordinates (wrap in statement if needed, etc.)
141-
if coordinates and result is not None:
142-
result = cls.apply_coordinates(result, cursor, coordinates)
143-
144-
return result
134+
return visitor.visit(template_tree, None)
145135

146136
@classmethod
147137
def _make_cache_key(

rewrite-python/rewrite/src/rewrite/python/template/replacement.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,13 @@
6767

6868

6969
def _get_precedence(expr: J) -> Optional[int]:
70-
"""Return the precedence of an expression, or None if not a binary op."""
70+
"""Return the precedence of an expression, or None if not an operator node."""
7171
if isinstance(expr, j.Binary):
7272
return _BINARY_PRECEDENCE.get(expr.operator)
7373
if isinstance(expr, py.Binary):
7474
return _BINARY_PRECEDENCE.get(expr.operator)
75+
if isinstance(expr, j.Unary) and expr.operator == j.Unary.Type.Not:
76+
return 3 # `not` sits between `and` (2) and comparisons (4)
7577
return None
7678

7779

@@ -111,6 +113,11 @@ def maybe_parenthesize(result: J, cursor: 'Cursor') -> J:
111113
"""Wrap *result* in parentheses when its precedence is lower than the
112114
surrounding context (the cursor's parent tree node).
113115
116+
This handles the *outer* boundary: whether the template result as a whole
117+
needs parentheses relative to where it is being inserted in the tree.
118+
The *inner* operand parenthesization (within the template result itself)
119+
is handled by ``PlaceholderReplacementVisitor.visit_binary`` / ``visit_unary``.
120+
114121
This mirrors ``ParenthesizeVisitor.maybeParenthesize`` in the Java
115122
``JavaTemplate`` implementation.
116123
"""

rewrite-python/rewrite/src/rewrite/python/template/template.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,14 @@ def apply(
143143
result = TemplateEngine.apply_substitutions(
144144
template_tree,
145145
values_dict,
146-
cursor,
147146
)
148147
else:
149148
result = template_tree
150149

151150
# Phase 2: parenthesize the result if it has lower precedence than
152151
# the surrounding context, mirroring JavaTemplate.doApply().
153152
# This must happen before coordinates are applied, because
154-
# _apply_coordinates may wrap the expression in ExpressionStatement.
153+
# apply_coordinates may wrap the expression in ExpressionStatement.
155154
if result is not None and cursor is not None:
156155
from .replacement import maybe_parenthesize
157156
result = maybe_parenthesize(result, cursor)

rewrite-python/rewrite/tests/python/template/test_engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def bar(self):
329329
)
330330

331331
def test_apply_coordinates_no_cu_context_does_not_crash(self):
332-
"""_apply_coordinates with cursor lacking CU context doesn't crash."""
332+
"""apply_coordinates with cursor lacking CU context doesn't crash."""
333333
from rewrite.visitor import Cursor
334334
from rewrite.python.template.coordinates import PythonCoordinates
335335

@@ -340,5 +340,5 @@ def test_apply_coordinates_no_cu_context_does_not_crash(self):
340340
coordinates = PythonCoordinates.replace(original)
341341
cursor = Cursor(parent=Cursor(None, Cursor.ROOT_VALUE), value=original)
342342

343-
out = TemplateEngine._apply_coordinates(result, cursor, coordinates)
343+
out = TemplateEngine.apply_coordinates(result, cursor, coordinates)
344344
assert out is not None

0 commit comments

Comments
 (0)