Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aligning Equal Signs #1480

Closed
mlucool opened this issue Jun 5, 2020 · 8 comments
Closed

Aligning Equal Signs #1480

mlucool opened this issue Jun 5, 2020 · 8 comments
Labels
T: enhancement New feature or request

Comments

@mlucool
Copy link

mlucool commented Jun 5, 2020

Is your feature request related to a problem? Please describe.

If a developer chooses to align equal signs, black should respect this formatting. It improves readability in some situations. This choice could be considered similar to the magic trailing comma. For example:

a_var       = 4
another_var = 5

Describe the solution you'd like

If two lines in a row have aligned equal signs, black formats the lines with all normal rules, but keeps the equals sign in place. This has the downside of picking up aligned equals when it was unintended, but that seems like a reasonable trade-off for simplicity.

Describe alternatives you've considered A clear and concise description of any
alternative solutions or features you've considered.

Status quo, which does not implement this feature and ignores alignment.

@mlucool mlucool added the T: enhancement New feature or request label Jun 5, 2020
@dalleyg
Copy link

dalleyg commented Jun 5, 2020

+1 for this feature. This is the main thing preventing myself and (I suspect) several colleagues from using Black more.

@williamfzc
Copy link
Contributor

williamfzc commented Jun 11, 2020

Not a easy job I think. Besides, what about:

one_var = "abcd"
another_really_really_really_really_really_really_really_really_really_really_really_really_really_really_long_var = "abcd"
another_thing = another_another = "abcd"

@mlucool
Copy link
Author

mlucool commented Jun 11, 2020

In the case you bring up, I am not suggesting to align equals signs. I am only proposing that it is aligned when a developer already did it. For example, imagine we format the following code:

# Black will not change equal alignment
one_var     = 'bar'
another_var = 'baz'
# These are not aligned to start so will work as it does today (the intentional extra spaces to make a point)
one_var = 'foo'
another_var        =   'baz'

That is to say, I propose this to be the output of the above code:

# Black will not change equal alignment
one_var     = "bar"
another_var = "baz"
# These are not aligned to start so will work as it does today (the intentional extra spaces to make a point)
one_var = "foo"
another_var = "baz"

You're third case would not be changed from status quo by this proposal.

# Always reformatted
foo = bar = "baz"

Hopefully I have interpreted you case correctly @williamfzc

@williamfzc
Copy link
Contributor

I got your idea and fully agree with your proposal. Something like gofmt.

type Member struct {
    id     int
    name   string
    email  string
    gender int
    age    int
}

It's cool, but still not that easy to implement this in black:

Fortunately, whitespace info did not be dropped after parsing:

This is a very concrete parse tree; we need to keep every token and

@JelleZijlstra
Copy link
Collaborator

This would be a radical change to Black's existing style, which we're unlikely to implement.

@ianstokesrees-gamma
Copy link

For people who end up here: if you need to use Black to enforce automated code formatting then you need to have totally standardized code format. "Black" comes from "Black and White", so there is no debate, no configuration, no optionality. This is good if you have Python developers who don't know how to naturally write good, readable, consistent code -- and under these circumstances you should definitely use black. In any other situation the issue of code readability is so important that I would suggest you should never consider using Black and instead make sure your team of experienced/professional software engineers understand the importance of readability and comment, document, organize the code in smart & readable ways. Black won't solve the problem of bad semantics, bad code organization, bad commenting, bad style. For all those you need coding standards and code reviews. Configurable linters are nice to pick up warnings and to check that some testable features of coding standards are adhered to, or at least how much they are violated. But with an experienced team I would never suggest the use of Black.

@sjlongland
Copy link

I was about to ask about this and saw this issue… looking around, I found the easiest way is to let black do its thing, and where you have a specific format in mind, use # fmt: off / # fmt: on.

e.g. sjlongland/aioax25@3faae6f#diff-6c156a0037bc218f8b82a5d1cbe6051d3b3670deb24a3ac5f90e2efe974b9be0L1567-R1600

99% of the time, black's formatting is quite good… I wouldn't toss a very useful tool just because of this edge case where you probably want a human to drive the formatting.

@JosephSBoyle
Copy link

For anybody from the future stumbling across this now; here's a script ChatGPT wrote when I asked it to align equals signs on adjacent lines:

def align_equals(code):
    # Split the code into lines
    lines = code.split("\n")

    # Find all variable assignments
    assignments = []
    for line in lines:
        match = re.match(r"^(?P<var>\w+)\s*:\s*(?P<type>\w+)\s*=\s*(?P<value>.+)?$", line)
        if match:
            var, type_, value = match.groups()
            assignments.append((var, type_, value))

    # Determine the maximum lengths of the variable names and types
    max_var_len = max(len(var) for var, _, _ in assignments)
    max_type_len = max(len(type_) for _, type_, _ in assignments)

    # Generate the new lines with the aligned equals sign
    new_lines = []
    for var, type_, value in assignments:
        var_pad = " " * (max_var_len - len(var))
        type_pad = " " * (max_type_len - len(type_))
        new_lines.append(f"{var}{var_pad}: {type_}{type_pad} = {value}")

    # Combine the new lines with the original lines
    new_code = "\n".join(new_lines)
    return new_code

I imagine that running this script after black would achieve what you want. How best to set that up I do not know.
Hope this helps and sorry for necroposting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants