-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
flake8 #noqa comments get moved a place where they're ignored #195
Comments
You can work around this by doing
|
Shish, Black doesn't understand how What @zsol is suggesting will work, but you can also say what you suggested and Black will keep it:
|
Yeah, I can see why this would be a very tricky special case - in my own code I manually moved the comment once, and black now keeps it in the correct place; it's just when I did the original one-off bulk-reformat of my project that a bunch of flake8 errors suddenly became un-silenced :) |
I ran into a similar issue with |
@JelleZijlstra, were you able to move |
I wonder if "when reformatting a one-line statement with a comment into a multi-line statement with a comment, put the comment at the end of the first line instead of at the end of the last line" would be a good approach? Running through some examples in my head I think that that should be equally consistent as the current behaviour, but it would Just Work more in more cases (and it feels more intuitive IMO - if I'm commenting a block of code, I put the comment at the start of the block) |
I think what I can do for |
Maybe consider handling |
This also affects coverage.py |
IMO, this can very easily devolve into "my tool requires these comments to be untouched, and black messes them up, can we special case them?" On the other hand, practically every company needs to special case something. At my workplace, it's the type ignore comments. Why not let us specify in a config the kind of comments we want to special case? That way it's easy for organizations to onboard onto Black without needing a fork/request new functionality. I'm not sure how it would be implemented, so it's just a thought. |
I mentioned this over in #379, but I'll add it again here: I think a policy of leaving comments pinned to the start of the line they started on, rather than the end of the line they started on, would fix many/most of these problems. |
That wouldn’t be enough for mypy value = (
checked()
+ ignored() + ignored() # type: ignore
+ checked()
) Here’s a proposal that doesn’t require understanding whether each magic comment applies to the entire statement or some specific part. Could Black guarantee to apply only horizontal reformatting to lines with a comment matching a configurable set of prefixes ( In other words, Black would disable the length limit for that line to avoid breaking it into multiple lines, and if the line is part of a longer statement, Black would preserve the line breaks preceding and succeeding the line. So it would not reformat the above to value = (
checked()
+ ignored()
+ ignored() # type: ignore
+ checked()
) nor to value = checked() + ignored() + ignored() + checked() # type: ignore either of which would change the comment’s semantics. |
Why only apply this for certain prefixes? If a multi-line statement has a comment in a middle line, surely the author meant for it to apply to that line for a reason? |
Perhaps the easier rule is to just not have black expand or collapse any lines with trailing comments? |
I think we still want Black to expand an overlong single-line statement with a normal comment at the end, even though that transformation is unsound for Of course, if the horizontal-only behavior is configurable with prefixes, then you can configure the empty prefix to get it on all comments. (I should mention where I'm coming from: I'm a big fan of Black, but this issue is a blocker for considering its use in Zulip, which was one of the early adopters of mypy and has hundreds of |
I am also having issues with black re-formatting my imports that I want ignored: import os
from typing import Optional
import matplotlib # noqa isort:skip fmt: off
matplotlib.use("agg") # noqa isort:skip fmt: off
from matplotlib import pyplot as plt
from gwpy.signal import filter_design
from gwpy.timeseries import TimeSeries After blacking: import os
from typing import Optional
import matplotlib # noqa isort:skip fmt: off
matplotlib.use("agg") # noqa isort:skip fmt: off
from matplotlib import pyplot as plt
from gwpy.signal import filter_design
from gwpy.timeseries import TimeSeries |
@avivajpeyi I think that is unrelated and is expected behaviour. See https://github.com/psf/black/blob/master/README.md#the-black-code-style There may be an existing issue for ignoring single lines, or please open a new design issue. |
Here's another example, repro with Black 243230 Options
Inputargs = (
(3, 3),
# fmt: off
(-1, -1, 0,
-1, 0, 1,
0, 1, 1), # noqa: E127
# fmt: on
0.3,
) Outputargs = (
(3, 3),
# fmt: off
(-1, -1, 0,
-1, 0, 1,
0, 1, 1),
# noqa: E127
# fmt: on
0.3,
) ExpectedNo change from input. It's also a little surprising Black moves comments inside This is more of a problem with the new Flake8 3.8. In Flake8 3.7, you could mark the whole block as args = ( # noqa: E127
(3, 3),
# fmt: off
(-1, -1, 0,
-1, 0, 1,
0, 1, 1),
# fmt: on
0.3,
) But in Flake8 3.8 you need to mark the specific line and Black moves the comment rendering it ineffective. |
This issue affected me also, where I started with:
which failed mypy due to the lack of
but that failed flake8 checks due to long line, so I replaced it with:
Which failed black, so I ran black, which generated:
Which failed mypy because the ignore was on the wrong line. 😭 |
@jaraco Good example, although Black will preserve filterfalse = (
getattr(itertools, "filterfalse", None) or itertools.ifilterfalse # type: ignore
) (Might I suggest |
I hope it's not overkill to add another example here, but I just ran into this as well I think. Before: from obspy.clients.fdsn.header import ( # type: ignore
FDSNNoDataException as _FDSNNoDataException,
) After: from obspy.clients.fdsn.header import (
FDSNNoDataException as _FDSNNoDataException,
) # type: ignore It's in parentheses because the line was more than 88 chars. In general this would be a problem for any very long import lines that need a @andersk Your idea of configurable ignore rules gets my vote, and to combine with what the other comments suggest maybe some of the most common things like |
We now have some code (in comments.py) that attempts to keep magical comments like |
Shouldn't this work for these two cases? def foo(parameter1: str, parameter2: str) -> None: # pylint: disable=missing-return-doc,missing-function-docstring
pass
def foo(parameter1: str, parameter2: str, parameter3: str, parameter4: str, parameter5: str, parameter6) -> None: # noqa
pass After running black 22.3.0, the comments are still in the wrong place: def foo(
parameter1: str, parameter2: str
) -> None: # pylint: disable=missing-return-doc,missing-function-docstring
pass
def foo(
parameter1: str,
parameter2: str,
parameter3: str,
parameter4: str,
parameter5: str,
parameter6,
) -> None: # noqa
pass |
Operating system: Linux
Python version: 3.6
Black version: 18.4a5
Does also happen on master: ?
Using a long list of
typing
imports with #noqa because my code is py2 compatible so I'm using the comment syntax for type hintsoriginal code
becomes
but flake8 wants
The text was updated successfully, but these errors were encountered: