Black formatter - Ignore specific multi-line code
Asked Answered
S

4

245

I would like to ignore a specific multi-line code by black python formatter. Particularly, this is used for np.array or matrix construction which turned ugly when formatted. Below is the example.

np.array(
    [
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1],
    ]
)
# Will be formatted to
np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]])

I found this issue in black github, but that only works for inline command, which is not what I have here.

Is there anything I can do to achieve this for a multi-line code?

Semiotics answered 27/10, 2019 at 23:59 Comment(1)
Doesn't the issue say that you can just add # fmt: off before it and # fmt: on after it?Teamster
M
435

You can use #fmt: on/off (docs) as explained in the issue linked. Here, it would look like:

# fmt: off
np.array(
    [
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1],
    ]
)
# fmt: on

# fmt: off disables formatting for all following lines until re-activated with # fmt: on.

Muskogee answered 28/10, 2019 at 0:29 Comment(8)
Ah, thanks! This works as expected! I tried it as header but didn't turned it on again, that's why it didn't work.Semiotics
Can this be done by configuring exclude in pyproject.toml file? Rather than adding #fmt: on/off in each file, I would want to set it for my project.Swede
I don't know much about pyproject.toml, maybe you can open a new question?Muskogee
After some digging through the docs I have also found you can also use # fmt: skip to skip individual lines.Vitalis
Note that if you try to minimize the lines you disable formatting for and put # fmt: off inside the statement, black gives you an error.Naphtha
I'm trying this and still getting black complaining about e.g. long lines. Not sure why it doesn't seem to work.Iives
This tricks works well but not if I want to use black in my pre commit. This leads to an error since file failed to reformat. "cannot format file : Cannot parse : line_skipped_number"Hentrich
Relevant docs seem to be here now.Christchurch
K
46

If you're willing to change your code slightly, then Black leaves either of the following alone:

contents = [
    [1, 0, 0, 0],
    [0, -1, 0, 0],
    [0, 0, 1, 0],
    [0, 0, 0, -1],
]

np.array(contents)

This is because the trailing comma in the multi-line list is magic. Black takes it to mean that you plan to extend the list in future, although in this case it just means Black's style isn't very readable. Unfortunately the trailing comma isn't magic enough to work when the list is wrapped in that extra function call.

np.array(
    [
        # just say anything
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1],
    ]
)

This is because Black cannot outwit Python's lack of inline comments!

Kalgan answered 13/7, 2020 at 22:19 Comment(0)
S
22

The latest version of black ( >= 21.0) takes into account the comma after the last element.

So:

np.array(
    [
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1]
    ]
)

will be formatted to:

np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]])

(note no last comma)

Instead

np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1],])

will be formatted to:

np.array(
    [
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1],
    ]
)

(note last comma)

Sarina answered 28/1, 2022 at 16:43 Comment(3)
On my computer, black is keeping the single or multi-line style as it is, regardless of the size of the array, and regardless of whether there is a last comma or not. I'm using black 22.1.0.Niobic
@Niobic it may be a problem of IDE settings. Is the python interpreter where black is installed "visible" by the IDE?Sarina
I use black directly on the terminal, and Python 3.8.11 is visible. Perhaps it's not a problem though, they may have decided to keep the single/multi-line as it is to keep the developer's choice.Niobic
V
0

This is the idiomatic way:

np.array(
    [
        [1, 0, 0, 0],
        [0, -1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, -1],
    ],
)

Putting , at the end of lines causes black to reformat to a separate line.

I recommend against switching off formatting, it clutters the code and negates the advantages of using black.

Putting commas at the end of each line (including the last), is nice because if you want to move lines using IDE shortcuts or add new parameters, you don't need to add commas on other lines, which is also nice for having clean diffs.

People that ever edited JSON by hand know how nice it is to be able to add commas to the end of each line including the last.

Actually in this case even your original code stays formatted properly in recent black version, as @SeF says.

Vinasse answered 12/3, 2024 at 16:47 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.