Первоначально опубликовано на мой блог .
Это короткий пост, описывающий, как я снимаю свой код Python. Вы увидите, что это немного больше, чем просто установить несколько плагинов в IDE, вместо этого это немного кода сценариев.
Linting – это процесс запуска программы, которая будет анализировать код для потенциальных ошибок.
Вы даете ему путь своих источников, и он выводит список сообщений.
Ничего! Просто я предпочитаю иметь свободу запускать линтер только тогда, когда они мне нужны, и что наличие сценариев полезно, когда вы выполняете непрерывную интеграцию.
Я использую несколько из них, потому что все они хорошо дополняют друг друга:
Pycodestyle
Для проверки стиля 1Pyflakes
Для быстрого статического анализа.МакКейб
найти код, который слишком сложный и нуждается рефакторингPylint
для всего остального.
Первое, о чем вам нужно позаботиться, – это получить список файлов, на которых вы хотите запустить свои Linters.
Это не так просто, потому что у каждого Линтера есть свой собственный синтаксис, и есть некоторые части вашего кода, вы знаю Вы не хотите, чтобы Linters работали.
Для этого я пишу немного кода Python, используя path.py
# in ci/utils.py import path def collect_sources(ignore_func): top_path = path.Path(".") for py_path in top_path.walkfiles("*.py"): py_path = py_path.normpath() # get rid of the leading '.' if not ignore_func(py_path): yield py_path
collect_sources
Функция принимает обратный вызов как параметр, который позволяет игнорировать некоторые файлы.
На самом деле вам, вероятно, не понадобится collect_sources
функция запуска Pycodestyle
Анкет Просто беги:
$ pycodestyle .
от корня проекта.
Он найдет каждое .py
Файл в проект и проверьте стиль для каждого из них.
Если вам нужно исключить каталоги, вы можете добавить [Pycodestyle]
раздел в любом setup.cfg
или tox.ini
Файлы конфигурации:
[pycodestyle] exclude=
# in ci/run-pyflakes import subprocess from .utils import collect_sources def ignore(p): """ Ignore hidden and test files """ parts = p.splitall() if any(x.startswith(".") for x in parts): return True if 'test' in parts: return True return False def run_pyflakes(): cmd = ["pyflakes"] cmd.extend(collect_sources(ignore_func=ignore) return subprocess.call(cmd) if __name__ == "__main__": rc = run_pyflakes() sys.exit(rc)
Здесь я должен убедиться, что Pyflakes
не запускается в тестовых файлах, потому что иногда он запутался pytest
магистраль магии.
МакКейб
Поставляется с main ()
функция, но его можно запустить только на одном файле.
Поэтому мне пришлось переписать основную функцию, использующую collect_sources
написано ранее. Пока я был в этом, я немного настроил выход.
# In ci/run-mccabe.py import ast import mccabe def process(py_source, max_complexity): code = py_source.text() tree = compile(code, py_source, "exec", ast.PyCF_ONLY_AST) visitor = mccabe.PathGraphingAstVisitor() visitor.preorder(tree, visitor) for graph in visitor.graphs.values(): if graph.complexity() > max_complexity: text = "{}:{}:{} {} {}" return text.format(py_source, graph.lineno, graph.column, graph.entity, graph.complexity()) def main(): max_complexity = int(sys.argv[1]) ok = True for py_source in collect_sources(): error = process(py_source, max_complexity) if error: ok = False print(error) if not ok: sys.exit(1) if __name__ == "__main__": main()
Обратите внимание, как порог сложности передается непосредственно в качестве аргумента командной строки.
Это позволит вам точно настроить этот параметр. Для меня 10 – хорошее значение, но в зависимости от вашей базы кода, вам может потребоваться снизить или увеличить ее.
# before $ python -m mccabe foo/bar.py -m 10 4:0: 'complex_fun' 12 # after $ ./ci/lint.sh $ bad.py:4:0 complex_fun 12
Я уже написал Пост о Pylint Анкет Короче говоря, вы должны тщательно отредактировать свой .pylintrc
Фад и обязательно собирайте свои пакеты Python.
Просто простой сценарий Bash:
#!/bin/bash -xe pycodestyle . python bin/run-pyflakes.py python bin/run-mccabe.py 10 pylint mymodule
Вы можете задаться вопросом, почему я не использую такие инструменты, как Flake8
или Проспект
Анкет
Ну, Flake8
не работает Pylint
Анкет
Проспект
С другой стороны, это приятно, но заставляет вас использовать конкретные версии всех других линтеров, и его не так легко настроить. Кроме того, я обнаружил его только существование после Написание сценария:)
Кроме того, я остановил Tyring, чтобы использовать такие инструменты, как Токс
или вызвать
. Мне не нужно проверять несколько версий Python (это главная причина использования tox
) и дополнительную сложность определения команд в вызвать
просто не стоит.
Наконец, даже в Windows я в основном запускаю команды в git-bash
, так что я не возражаю против сценария, написанного в Bash.
Просто используйте:
set makeprg=ci/lint.sh
А затем беги : сделать
Анкет
Все проблемы появятся в окне QuickFix.
Как я уже сказал, мне не нравятся, что мои Линтеры работают во время редактирования, поэтому я в порядке с синхронно, но мне нужен плагин, который вы можете использовать для этого.
Ваше здоровье!
Этот инструмент раньше назывался
PEP8
Анкет Он был переименован после проблема открыл сам Гвидо. ↩
Оригинал: “https://dev.to/dmerejkowsky/how-i-lint-my-python”