Wrap walrus expressions in parens in as_string output#3045
Conversation
DanielNoord
left a comment
There was a problem hiding this comment.
Code LGTM, but you'll need to move the import to the top level.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3045 +/- ##
=======================================
Coverage 93.42% 93.42%
=======================================
Files 92 92
Lines 11314 11314
=======================================
Hits 10570 10570
Misses 744 744
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Moved the import to module-level. Thanks! |
|
@SAY-5 Could you resolve the conflict? :) |
23ad24f to
2c99114
Compare
|
Pushed 35b011b. The follow-up keeps compare output parenthesized while rendering walrus operands bare when the parent node already manages precedence parens, which fixes the extra wrapping caught by the downstream pylint workflow.\n\nLocal checks I reran:\n- PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q tests/test_nodes.py\n- PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q tests/test_nodes.py -k 'assignment_expression'\n- in a local pylint checkout with this astroid branch installed: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest -q tests/test_functional.py -k 'consider_refactoring_into_while_condition_py38' |
| return child.accept(self) | ||
|
|
||
| @staticmethod | ||
| def _namedexpr_renders_bare(node: nodes.NamedExpr) -> bool: |
There was a problem hiding this comment.
This feels quite brittle. Did you explore other ways to compute this condition?
|
Switched to unconditional wrapping in visit_namedexpr (matching CPython's ast.unparse) and removed the NamedExpr precedence entry so parents do not double-wrap. The parent-type list is gone; tests still pass. Pushed in e01d829. |
|
@SAY-5 Sorry to ask, but are you AI? Anyway, the CI shows you're back to the previous failure now. |
|
Naa! @DanielNoord I've been trying something, due to that the ci failures |
e01d829 to
7db5c11
Compare
|
Rebased onto current main (resolved the ChangeLog conflict) and squashed to a single commit: as_string now always parenthesizes the walrus expression, matching CPython's ast.unparse. The pylint-with-astroid-sha job's consider_refactoring_into_while_condition_py38 functional output will need the matching update on the pylint side. Local tests/test_nodes.py walrus/namedexpr tests pass. |
| target = node.target.accept(self) | ||
| value = node.value.accept(self) | ||
| return f"{target} := {value}" | ||
| if isinstance(getattr(node, "parent", None), nodes.Compare): |
There was a problem hiding this comment.
Can we do this without a getattr?
Pierre-Sassoulas
left a comment
There was a problem hiding this comment.
Agree with Daniel's comment, otherwise LGTM
Type of Changes
Description
Closes #2668
AsStringVisitor.visit_namedexprrendereda := valuewithout surrounding parentheses, producing invalid Python whenever the walrus appeared inside another expression. For example,if x != (size := (1, 2, 3)):round-tripped toif x != size := (1, 2, 3):, which is a SyntaxError.The fix always emits
(target := value), matching CPython'sast.unparsebehavior. Existingtest_assignment_expressionwas updated to expect the parenthesized form, and a regression test rebuilds the issue's example and asserts the rendered output is valid Python viacompile(...).