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

Add note about dict indentation style to docs #925

Closed
strokirk opened this issue Jul 11, 2019 · 9 comments
Closed

Add note about dict indentation style to docs #925

strokirk opened this issue Jul 11, 2019 · 9 comments
Labels
F: linebreak How should we split up lines? T: style What do we want Blackened code to look like?

Comments

@strokirk
Copy link

strokirk commented Jul 11, 2019

Hi!

I've been searching a bit on why this code containing a single inline-dict is expanded into multiple lines with hanging braces by black, but couldn't find anything about configuring it, if it's expected, or a bug.

# In
func({
	# expand me
    'a':37,
    'b':42,
    'c':927,
})

# Out
func(
    {
		# expand me
        "a": 37,
        "b": 42,
        "c": 927,
    }
)

I personally would prefer the dict to keep it's original formatting for better readability, and lose the extra indentation and Allman-style hanging bracket. Essentially we would keep the input formatting in this example.

This pattern is also much more common in the python code I regularly read, including the standard library, django and a couple of other codebases. Grepping \({$ vs \(\n\s*{$ shows usages.

However, I expect this pattern might be fairly set in stone by now and would maybe cause a lot of unnecessary diffs for existing black users. What do you think?

Either way, I think something like this would be a useful example to add to the Black code style. That way people like me who are wondering why the function call is expanded can find out that it is to be expected.
(I'm opening this issue partly to be able to google for it myself in coming years.)

Hopefully the feedback is somewhat useful!

@zsol zsol added the T: style What do we want Blackened code to look like? label Jul 30, 2019
@Jma353
Copy link
Contributor

Jma353 commented Aug 4, 2019

If the inline dict was actually large and had to be split over several lines, it would be re-formatted in the above way as well, e.g.

# In
func({"a": 37, "b": 42, "c": 927, "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111})

# Out
func(
    {
        "a": 37,
        "b": 42,
        "c": 927,
        "aaaaaaaaaaaaaaaaaaaaaaaaa": 11111111111111111111111111,
    }
)

I believe changing this would likely cause some diff-based churn. In your above example, I believe the comment causes the inline dict to be restructured in this way; omitting the comment results in the dict fitting on one line:

# In
func({
    'a':37,
    'b':42,
    'c':927,
})

# Out
func({"a": 37, "b": 42, "c": 927})

This kinda is captured in the above linked documentation:

As for vertical whitespace, Black tries to render one full expression or simple statement per line. If this fits the allotted line length, great. If not, Black will look at the contents of the first outer matching brackets and put that in a separate indented line. If that still doesn’t fit the bill, it will decompose the internal expression further using the same rule, indenting matching brackets every time. If the contents of the matching brackets pair are comma-separated (like an argument list, or a dict literal, and so on) then Black will first try to keep them on the same line with the matching brackets. If that doesn’t work, it will put all of them in separate lines.

I guess the formatter isn't smart enough to move the comment to the end of the line, but if it tried to keep the code all on one line, it would be invalid Python since the rest of the line would be commented out.

@pradyunsg
Copy link
Contributor

@ambv would a PR reducing the indentation for lists+dicts, when they're the only argument in a call be acceptable?

@strokirk
Copy link
Author

Ping @ambv @cooperlees @ichard26 regarding the question of @pradyunsg above. Reducing the indentation for trailing list/dicts would vastly improve readability of black-formatted django code, for example.

Compare:

# Desired

def view_1(request):
	return render(request, "template.html", {
		"var_1": foo,
		"var_2": bar,
		...
	})

def view_2(request):
	return JsonResponse({
		"var_1": foo,
		"var_2": bar,
		...
	})

with

# Current

def view_1(request):
	return render(
		request, 
		"template.html", 
		{
			"context_var_1": foo,
			"context_var_2": bar,
			...
		}
	)

def view_2(request):
	return JsonResponse(
		{
			"var_1": foo,
			"var_2": bar,
			...
		}
	)

@strokirk strokirk reopened this Apr 15, 2021
@JelleZijlstra JelleZijlstra added the F: linebreak How should we split up lines? label May 30, 2021
@richardk53
Copy link

any news on this? Blackening function calls with dictionaries currently leads to more 'vertical coding', which reduces readability (in my opinion). Any chance that two brackets will be allowed in one line? At least for the special case, where both the opening brackets and closing brackets are directly next to each other, without additional arguments between. In other cases (with additional arguments), I agree that starting a new line improves readability.

@thinkwelltwd
Copy link

I've periodically tested Black, liking so much about its styple, but ultimately avoided it not wanting to "ruin" my codebase by changing brackets from:

fields.extend([
    (name_keys, 'name'),
])

to

fields.extend(
    [
        (name_keys, 'name'),
    ]
)

And now, with #3992 landed, I want to express my thanks and appreciation; thanks so much! 🙇‍♂️ 💯

@henriholopainen
Copy link
Contributor

I think this can now be closed, as the formatting has been changed and the docs now include a section about what to expect.

@spagh-eddie
Copy link
Contributor

spagh-eddie commented Nov 11, 2023

Is there a rationale for not treating tuples the same as their cousins the lists and dicts? e.g. hash(("long", "tuple", ...)).

I'd be happy to extend this if no reasons against

@JelleZijlstra
Copy link
Collaborator

I think the adjacent parentheses make this look more confusing for tuples than for dicts and lists, but we can consider making the change anyway for consistency. Should do it in a new issue though.

@spagh-eddie
Copy link
Contributor

spagh-eddie commented Nov 19, 2023

we can consider making the change anyway

I started to take a look this weekend after work, but my concerns have already been addressed in #4012 c:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F: linebreak How should we split up lines? T: style What do we want Blackened code to look like?
Projects
None yet
Development

No branches or pull requests

10 participants