refactor icon indicating copy to clipboard operation
refactor copied to clipboard

Properly indent new statements

Open isidentical opened this issue 4 years ago • 2 comments

Problem

The indentation for the statements are not preserved, since ast.unparse() uses 4 spaces by default. We should infer the common indentation level (even in some blocks it might be different), and smartly use it for the ast.unparse;

Rule

import ast
import refactor
from refactor import Rule, Action

class MakeAsyncWith(Action):
    def build(self):
        new_node = self.branch()
        new_node.__class__ = ast.AsyncWith
        return new_node

class ReplaceToAsync(Rule):
    def match(self, node):
        assert isinstance(node, ast.With)
        return MakeAsyncWith(node)

if __name__ == "__main__":
    refactor.run(rules=[ReplaceToAsync])

Input

if something: # comment
  with something: # comment2
    a = 1 # comment3
    b = 2 # comment4
  # comment5
  c()

Diff

--- t1.py

+++ t1.py

@@ -1,6 +1,6 @@

 if something: # comment
-  with something: # comment2
-    a = 1 # comment3
-    b = 2 # comment4
+  async with something:
+      a = 1
+      b = 2 # comment4
   # comment5
   c()

Expected Difff

--- t1.py

+++ t1.py

@@ -1,6 +1,6 @@

 if something: # comment
-  with something: # comment2
-    a = 1 # comment3
-    b = 2 # comment4
+  async with something:
+    a = 1
+    b = 2 # comment4
   # comment5
   c()

isidentical avatar Aug 14 '21 20:08 isidentical

PR: #66 should address this. See the added passing case to test_ast.py:

    source = """def func():
    if something:
        # Comments are retrieved
        with something: # comment2
             a = 1 # Non-standard indent
             b = 2 # Non-standard indent becomes standard
"""

    expected_src = """def func():
    if something:
        # Comments are retrieved
        async with something:
            a = 1
            b = 2 # Non-standard indent becomes standard
"""

Note the non-standard indent becomes standard

MementoRC avatar Dec 29 '22 21:12 MementoRC

Now would we want to have something like this (keeping the comments when possible):

    expected_src = """def func():
    if something:
        # Comments are retrieved
        async with something:  # comment2
            a = 1  # Non-standard indent
            b = 2  # Non-standard indent becomes standard

MementoRC avatar Dec 29 '22 22:12 MementoRC