google / yapf

A formatter for Python files
Apache License 2.0
13.78k stars 892 forks source link

Adding more properties to style #295

Open b5y opened 8 years ago

b5y commented 8 years ago

I am actively contributing RedBaron project. It has list of formattings for every node which is based on Baron project.

My suggestion is to add more properties for every node which can help to distinct style of unique developer. It is useful if developer's style guide is based on some of 4 style guides in Python with minor changes. For instance, some developers like to have one indent (I know that it sounds crazy, but it is just example) instead of two or four.

bwendling commented 8 years ago

I'm perfectly fine with having more style properties in yapf. They just need to have a proper meaning that cannot be achieved by current properties.

Question, though. Are you suggesting that RedBaron may change the style for each node in the AST? E.g., a statement on line 4 would use style foo while a statement on line 5 would use style bar?

b5y commented 8 years ago

RedBaron can do anything you want with code except minor changes (there are some restrictions which I am trying to remove). This tool is the best tool to manipulate with code in Python.

Just show you some example. Say, you have this code (test_google.py):

def foo(a, b):
    c = a
    d = b + c
    return d

And you want to change formatting for def and assignments:

from redbaron import RedBaron, ProxyList, NodeList, Node, EndlNode, SpaceNode

def change_style(sub_tree, formatting=None):
    if not isinstance(sub_tree, (ProxyList, NodeList, Node)):
        return sub_tree
    for node in sub_tree:
        if isinstance(node, EndlNode):
            continue
        for kind, key, _ in node._render():
            if kind == "formatting" and key != "formatting":
                attr = getattr(node, key)
                if not isinstance(attr, (ProxyList, NodeList)):
                    getattr(attr.parent, key).replace(formatting)
                else:
                    attr.append(SpaceNode({"value": formatting, "type": "space"}))

with open("test_google.py", 'rb') as fd:
    source = fd.read()
red = RedBaron(source)

methods = red.find_all('DefNode')
assignments = red.find_all('AssignmentNode')
change_style(methods, formatting='\\\n')
change_style(assignments, formatting='   ')

with open('res_google.py', 'w+') as fd:
    fd.write(red.dumps())

The output will be:

def \
foo\
(\
a, b\
)\
:\

    c    =    a
    d    =    b + c
    return d

And of course, this code is valid. All I want is to make yapf perfect to format every node in AST.