LoginSignup
3
1

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_optionsparse_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',
        ],
    },
...
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1