-
-
Save AlexRiina/d8dfd39d2c6c4b121c8776070a2272dc to your computer and use it in GitHub Desktop.
| """ | |
| Add `# noqa: FXXX` comments to all lines with violations from flake8 | |
| """ | |
| # MIT License | |
| # | |
| # Copyright (c) 2022 Alex Riina | |
| # | |
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| # copies of the Software, and to permit persons to whom the Software is | |
| # furnished to do so, subject to the following conditions: | |
| # | |
| # The above copyright notice and this permission notice shall be included in all | |
| # copies or substantial portions of the Software. | |
| # | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| # SOFTWARE. | |
| import sys | |
| import argparse | |
| import fileinput | |
| from itertools import groupby | |
| from collections import defaultdict | |
| parser = argparse.ArgumentParser( | |
| description=__doc__, | |
| usage="flake8 $(git ls-files **/*.py) | noqaer.py - [--dry-run]", | |
| epilog=""" | |
| Intended to be used once in lieu of manually fixing all flake8 violatios so | |
| flake8 passes 100% and can be added to a build.""", | |
| ) | |
| parser.add_argument("errors", type=argparse.FileType("r"), help="errors from flake8") | |
| parser.add_argument("--dry-run", action="store_true") | |
| args = parser.parse_args() | |
| def parse_flake8_errors(error_lines): | |
| for error_line in error_lines: | |
| filename, line_number, col, message = error_line.strip().split(":", 3) | |
| error_code, message = message.strip().split(" ", 1) | |
| yield filename, int(line_number), error_code | |
| for filename, error_tuples in groupby( | |
| parse_flake8_errors(args.errors), key=lambda error_tuple: error_tuple[0] | |
| ): | |
| errors = defaultdict(set) | |
| for _, line_number, code in error_tuples: | |
| errors[line_number].add(code) | |
| with fileinput.input(files=[filename], inplace=not args.dry_run) as fp: | |
| for line_number, line in enumerate(fp, start=1): | |
| if line_number not in errors: | |
| # line already has a newline, so don't add an extra | |
| print(line, end="") | |
| elif "noqa" in line or line.strip().endswith("\\"): | |
| print("skipping {}:{}".format(filename, line_number), file=sys.stderr) | |
| print(line, end="") | |
| else: | |
| # note the fileinput inplace captures output and writes back to the file | |
| print(line.rstrip("\n") + " # noqa: " + ", ".join(errors[line_number])) |
@sigmavirus24 I hadn't heard of that project but my inclination is to avoid adding any external dependencies so this can be audited and run very easily. I do like the idea of reducing the split and strips though and think the script could be rewritten to use an explicit flake8 --format ....
With something like flake8 --format '%(path)s:%(row)d:%(col)d:%(code)s' some of the strips can go away and this could even use csv.reader (if someone is dealing with a gnarly error message that breaks this script and reads this: '%(path)s:%(row)d:%(col)d:%(code)s x' looks like be good enough).
I'm not planning to change this gist since I've run the code on my repo and we're unlikely to declare a "jubilee" for any other flake8 errors but please feel free to fork this repo and make any changes you like (just added a license).
@AlexRiina have you considered suggesting folks use
flake8-jsonso you have structured data that you can parse more easily?