Skip to content

Multiline strings get indented #74

Open
@alexmojaki

Description

@alexmojaki

This refactoring, similar to what I actually used:

import ast
import refactor

class WrapF(refactor.Rule):
    def match(self, node: ast.AST) -> refactor.BaseAction:
        assert isinstance(node, ast.Constant)

        # Prevent wrapping F-strings that are already wrapped in F()
        # Otherwise you get infinite F(F(F(F(...))))
        parent = self.context.ancestry.get_parent(node)
        assert not (isinstance(parent, ast.Call) and isinstance(parent.func, ast.Name) and parent.func.id == 'F')

        return refactor.Replace(node, ast.Call(func=ast.Name(id="F"), args=[node], keywords=[]))


refactor.run(rules=[WrapF])

produces this:

 def f():
-    return """
-a
-"""
+    return F("""
+    a
+    """)

This changes the value of the string.

Possibly related is #12, but I couldn't reproduce an equivalent problem with just ast.unparse:

import ast

source = '''
def f():
    return """
a
"""
'''

tree = ast.parse(source)
node = tree.body[0].body[0].value
call = ast.Call(func=ast.Name(id="F"), args=[node], keywords=[])
ast.copy_location(call, node)
ast.fix_missing_locations(call)
print(ast.unparse(node))  # '\na\n'
print(ast.unparse(call))  # F('\na\n')

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions