200

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?

Darren Christopher
  • 3,893
  • 4
  • 20
  • 37
  • 4
    Doesn't the issue say that you can just add `# fmt: off` before it and `# fmt: on` after it? – Eric Oct 28 '19 at 00:15

3 Answers3

357

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.

Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
OriolAbril
  • 7,315
  • 4
  • 29
  • 40
  • 2
    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. – Darren Christopher Oct 28 '19 at 00:33
  • 4
    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. – Abhishek Upadhyaya Jan 16 '20 at 16:13
  • 1
    I don't know much about `pyproject.toml`, maybe you can open a new question? – OriolAbril Jan 22 '20 at 17:51
  • 28
    After some digging through the docs I have also found you can also use `# fmt: skip` to skip individual lines. – GammaGames Oct 25 '21 at 19:03
  • 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. – Troy Daniels Dec 18 '21 at 19:48
  • I'm trying this and still getting black complaining about e.g. long lines. Not sure why it doesn't seem to work. – szeitlin Jan 18 '22 at 23:52
  • 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" – Ermite Dec 13 '22 at 14:55
42

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!

S.A.
  • 1,819
  • 1
  • 24
  • 39
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
17

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)

SeF
  • 3,864
  • 2
  • 28
  • 41
  • 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. – Codoscope Mar 11 '22 at 14:15
  • @Codoscope it may be a problem of IDE settings. Is the python interpreter where black is installed "visible" by the IDE? – SeF Mar 16 '22 at 15:40
  • 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. – Codoscope Mar 16 '22 at 16:04