ESLintにはファイルの最大行を設定することができる。
Flake8にはない!!!
頑張って探してもなかった。だから作った。
Pythonは何もしないとコード肥大化しがち。こういうの使って減らしていかないと。
使い方
他のFlake8プラグインのように使える。
pip install flake8 flake8_max_lines
flake8 {任意のpythonファイル}
--max-lines
で最大行を変えることができる。
デフォルトはESLintにあわせて300。
flake8 --max-lines 500 {任意のpythonファイル}
import ast
from typing import Generator, List, Tuple
MSG = "MXL001 File has too many lines ({actual}). Maximum allowed is {max}."
DEFAULT_MAX_LINES = 300
作ってみて感じたこと
Flake8のプラグインを作るにはクラスを作ってsetup.pyに渡してあげればいい。
そのクラスに色々実装してあげるだけで良さそう。
__init__
とrun
メソッドは必須で、--max-lines
みたいな引数を渡してあげたいときはadd_options
やparse_options
をクラスメソッドとして実装すれば良さそう。
オプションのところはここを見れば良さそう。
情報が少なすぎるのであちこちの取り組みを参考。
flake8_max_lines.py
class MaxLinesPlugin:
name = "flake8_max_lines"
version = "0.0.2"
@classmethod
def add_options(cls, option_manager):
option_manager.add_option(
"--max-lines",
type=int,
metavar="n",
default=DEFAULT_MAX_LINES,
parse_from_config=True,
help="enforces a maximum number of lines in a file"
"For example, ``--max-lines=500``. (Default: %(DEFAULT_MAX_LINES))"
)
@classmethod
def parse_options(cls, options):
cls.max_lines = options.max_lines
def __init__(self, lines: List[str], total_lines: int, tree: ast.AST):
self.lines = lines
self.total_lines = total_lines
def get_file_length(self) -> int:
# [this logic to check newline at end of file](./test_plugin.py#L27)
physical_line = self.lines[-1]
stripped_last_line = physical_line.rstrip("\r\n")
return (
self.total_lines
if stripped_last_line == physical_line
else self.total_lines + 1
)
def run(self) -> Generator[Tuple[int, int, str, None], None, None]:
actual_lines = self.get_file_length()
max_lines = self.max_lines
if actual_lines > max_lines:
message = MSG.format(actual=actual_lines, max=max_lines)
yield actual_lines, 0, message, None
setup.pyでentry_pointsに作ったクラスをを指定しないと認識してもらえない。
setup.py
...
entry_points={
'flake8.extension': [
'MXL = flake8_max_lines:MaxLinesPlugin',
],
},
...