Перейти к содержимому

Flake8 isort как установить

  • автор:

flake8-isort 6.1.1

Use isort to check if the imports on your python files are sorted the way you expect.

Add an .isort.cfg to define how you want your imports sorted and run flake8 as you usually do.

See isort documentation for .isort.cfg available options.

Install

Install with pip:

$ pip install flake8-isort

Install with conda:

$ conda install -c conda-forge flake8-isort

Configuration

If using the select option from flake8 be sure to enable the I category as well, see below for the specific error codes reported by flake8-isort .

See flake8 —help for available flake8-isort options.

Error codes

Requirements

  • Python 3.8, 3.9, 3.10, 3.11 and pypy3
  • flake8
  • isort

Relation to flake8-import-order

As an alternative to this flake8 plugin, there’s flake8-import-order that could be worth checking out. In contrast to this plugin that defers all logic to isort, the flake8-import-order comes bundled with it’s own logic.

flake8-import-order comes with a few predefined set of styles meanwhile this plugin can be customized a bit more. But the biggest difference could lie in that flake8-isort actually has the corresponding sorting engine isort that can sort the import orders of your existing python files. Meanwhile flake8-import-order has no such corresponding tool, hence big existing projects who want to adopt either would get a more automized experience choosing flake8-isort.

License

Подробности проекта

Ссылки проекта

Статистика

Метаданные

Лицензия: GNU General Public License v2 (GPLv2) (GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, . )

Метки flake8, imports, isort, pep8, python

Требует: Python >=3.8

Сопровождающие

Классификаторы

  • Development Status
    • 5 — Production/Stable
    • Console
    • Flake8
    • Plone
    • Developers
    • OSI Approved :: GNU General Public License v2 (GPLv2)
    • OS Independent
    • Python
    • Python :: 3
    • Python :: 3 :: Only
    • Python :: 3.8
    • Python :: 3.9
    • Python :: 3.10
    • Python :: 3.11
    • Python :: 3.12
    • Python :: Implementation :: CPython
    • Python :: Implementation :: PyPy
    • Software Development
    • Software Development :: Quality Assurance

    PEP8 — линтеры и правила оформления кода

    Любой код должен быть оформлен по установленным правилам, ведь работать с ним придётся не только вам, но и вашим коллегам.Даже код, написанный для себя, лучше оформлять как следует: в какой-то момент вы обязательно захотите показать его кому-то ещё — и попадёте в неловкую ситуацию: «А ты точно разработчик?». В Python принят стандарт оформления кода PEP8.

    Оформляйте код правильно

    Без соблюдений этих правил, проект не будет принят.Основные правила PEP8:

    • Длина строки — не более 79 символов.
    • Отступы — 4 пробела.
    • Стили имён должны соответствовать PEP8: Naming Conventions.
    • Переносы строк делаются с правильными отступами.
    • Бэкслеши \ для переносов не применяются.
    • В коде нет неиспользуемых импортов.
    • Импорты отсортированы в таком порядке:
      • импорты стандартной библиотеки,
      • импорты сторонних библиотек,
      • импорты модулей текущего проекта.

      Для отслеживания правил оформления кода есть специальные программы: линтеры. Изначально linter (или lint remover) — это ролик для чистки одежды.

      Всё изменилось в 1979 году, когда вышла программа lint для статического анализа кода на языке C. Она предупреждала разработчика об использовании непортабельных на другие архитектуры языковых конструкций. Сейчас линтерами принято называть любые статические анализаторы, которые помогают находить распространённые ошибки и дают рекомендации по улучшению кода.

      Как включить нужный линтер в VS Code

      Когда в VSC вы открываете файл с расширением .py, в правом нижнем углу интерфейса появляется всплывающее окно с предложением инсталлировать рекомендуемые расширения для Python. Установите их, там много полезного. В этом пакете будут и линтеры.Если вы случайно закрыли это окошко — не беда, этот набор расширений доступен в разделе «Рекомендуемые» в панели маркетплейса VSC (она открывается с помощью горячих клавиш Ctrl+Shift+X). Выбрать и активировать нужный линтер можно с помощью командной строки VSC (Command Palette, вызывается через Ctrl+Shift+P). Введите в командную строку Python: Select Linter и нажмите Enter.

    Возможно, в вашем редакторе уже включён какой-нибудь линтер. Или нет.

Выберите в списке flake8, именно его мы рекомендуем установить на время обучения. flake8 — это утилита, объединяющая в себе несколько анализаторов кода (pycodestyle, pyflakes и mccabe). Сейчас это самый популярный линтер для Python. После включения flake8 панель будет выглядеть так:

В нижней части интерфейса может появиться окошко с предложением установить линтер. Соглашайтесь.

После этого линтер должен заработать.

package installer for Python

Иногда не получается включить нужный линтер через графический интерфейс VSC (могут, например, возникнуть проблемы с правами доступа). В таком случае придётся действовать через консоль.Модули и пакеты для Python устанавливают посредством специальной программы, менеджера пакетов. Для Python написано много разных менеджеров, но пока ещё ни один не стал более популярен, чем pip, package installer for Python.У вас установлен Python 3.7, pip был автоматически установлен вместе с ним.Установите flake8 с помощью pip. Выполните в консоли команду:

# В macOS или Linux: $ sudo pip3 install flake8 
# В Windows, в командной строке с правами администратора: $ pip3 install flake8 

Если что-то пошло не так — почитайте документацию VSC в части подключения линтеров, скорее всего, вы найдёте там решение проблем.Проверьте, выполнена ли установка: запросите через консоль данные о программе flake8:

$ flake8 --version 

Если всё в порядке — вы увидите в консоли примерно такой ответ:

$ flake8 --version 3.8.4 (mccabe: 0.6.1, pycodestyle: 2.6.0, pyflakes: 2.2.0) CPython 3.8.5 on Linux 

Линтер немедленно сообщит вам о проблемах в файле: даст описание ошибок в закладке Problems

и подчеркнёт проблемные места прямо в коде:

Одно из преимуществ flake8 — это большое количество дополнений, которые можно к нему подключить; они помогут избежать ошибок при оформлении кода. Дополнения устанавливаются из консоли через pip, точно так же, как flake8:

$ sudo pip3 install имя_пакета # Linux/MacOS # или $ pip3 install имя_пакета # Windows 

Мы рекомендуем установить следующие дополнения:

  • pep8-naming — проверяет имена классов, функций и переменных на соответствие PEP8;
  • flake8-broken-line отслеживает применение устаревших переносов (через обратный слеш \ );
  • flake8-return проверяет значения, возвращаемые функциями;
  • flake8-isort проверяет правильность порядка импортов.
Похожие записи:
  1. Окружение Django-проекта: Git
  2. Библиотека python-telegram-bot
  3. Unittest в Django и Coverage-тестомерка
  4. Unittest в Django: тестирование моделей

Как создать виртуальное окружение из командной строки (инструкция)

Чтобы создать виртуальное окружение python перейдите в папку, в которую хотите его поместить (развернуть) и выполните команду:

python -m venv myvenv

где myvenv — имя виртуального окружения. (по факту, после успешного создания виртуального окружения в текущей папке появится подпапка myvenv.

Кстати, обычно виртуальное окружение называют не myvenv, как в примере выше, а просто venv.

Как запустить виртуальное окружение?

Для запуска виртуального окружения из примера выше вводим команду:

myvenv\scripts\activate

Если всё успешно, то в командной строке, в скобочках перед курсором, появится название виртуально окружения (myvenv)

Как отключить(остановить) виртуальное окружение?

Для остановки текущего виртуального окружения выполните в командной строке команду:

deactivate

Как устанавливать пакеты в виртуальное окружение Python?

В общем случае установку можно делать через через python или через пакетный менеджер pip. Команды идентичны:

python install pytest flake8 isort pip install pytest flake8 isort

Как установить в виртуальное окружение из файла requirements.txt?

Нужно перейти в папку, в которой находится файл с зависимостями и выполнить команду:

pip install -r requirements.txt

Кстати, файл не обязательно должен называться requirements.txt. Если у вас другое название, то вводить нужно именно его.

Как создать requirements.txt?

pip freeze > requirements.txt

Как посмотреть установленные в виртуальном окружении пакеты?

Есть несколько вариантов:

pip freeze pip list

Делаем все правильно: проект на Python в 2021

Цель данного Руководства – описать экосистему разработчика Python в 2021 году. Оно будет полезно любому, кто пришел в Python, зная другой язык программирования.

Они говорят, что ты должен вызубрить алгоритмы и структуры данных, что ты можешь выучить язык программирования за пару недель, ну, просто узнаешь синтаксис. Полностью согласен: алгоритмы и структуры данных – экстремально важны для разработчика, но когда говорим о языке программирования, то уточнить синтаксис – мало. Вокруг языка, как правило складывается, целая экосистема из инструментов, и “эталонных практик” – способов делать то-то и то-то наилучшим образом. Для кого-то пришедшего из другого языка, может быть утомительно изучать одновременно всю экосистему, особенно если учесть, что чаще всего ценнейшие данные по крупицам рассредоточены по разным местам.

Это моя, очень субъективная, попытка собрать в одном месте лучшие практики по настройке Python для локальной разработки. Также будут советы по интеграции этих тулзов с Visual Studio Code (однако не так уж обязательно работать именно в этом IDE). Гайд получился весьма большим, поскольку я подробно объясняю работу всех инструментов. В конечном итоге у тебя должно выйти – восхитительно настроенное окружение для Python.

Управление версиями Python в pyenv

Почему pyenv?

Видел десятки туториалов, начинающиеся с того же тупого совета: иди на python.org и скачай последнюю версию Python для своей платформы. Не делай так. Можно лучше, и вот почему.

Понятно, что версий Python – сильно больше одной, и тебе понадобится переключаться между ними, работая в разных проектах.

Возможно, есть версии Python, идущие в комплекте с операционкой. Например в Mac сейчас ставят по умолчанию версию 2.7, а некоторые дистрибутивы Windows поставляются с версией 3.х. Далее, в пакет Anaconda включена своя версия Python. Нужно учесть: никогда неизвестно, какая версия появится в ответе на введенную команду “python” в командной строке.

На каком-то этапе может возникнуть бардак с разными версиями ехе-файлов Python на твоем компьютере, и надо уметь управляться с ними. Если есть средство для этого, было бы отлично.

Да, такое есть. По ссылке –

Как ставится pyenv?

Установка на Mac:

brew update brew install pyenv

На Linux установка здесь:

curl https://pyenv.run | bash

Но все-таки лучше работать в Windows Subsystem for Linux (WSL), а затем установить “как правильно в Linux”.

Как работать с pyenv?

Сначала посмотрим на список всех ехе-шников Python, если они есть на компьютере. (По крайней мере, те которые pyenv может найти):

pyenv versions
* system (set by /Users/alex/.python-version)

Здесь показан вывод на моем компьютере. Звездочка-астериск обозначает текущую версию установленного Python. Если ввести команду:

python -V

то выведет сообщение, говорящее, что MacOS на моем компьютере все еще с Python 2.7.

Python 2.7.16

Теперь посмотрим, какие версии Python доступны:

pyenv install --list

Появится большой список, ты даже будешь удивлен, насколько большой. Имплементации CPython будут иметь версии типа 3.8.5, другие имплементации – что-то типа pypy 3.6-7.3.1.

Чтобы посмотреть только С-шные версии Питона, надо запустить следующую команду:

pyenv install --list | grep " 3\."

Если pyenv уже долго используется, и новых версий Питона как-то не выводится в pyenv, то вероятно, надо обновить сам pyenv:

brew upgrade pyenv
pyenv update

Как должно быть понятно, версии с приставкой -dev девелоперские.

Итак, я установил самый новый Питон и при этом самую стабильную версию (на момент написания поста):

pyenv install 3.8.5

Команда загружает исходник и компилирует его:

python-build: use openssl@1.1 from homebrew python-build: use readline from homebrew Downloading Python-3.8.5.tar.xz. -> https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tar.xz Installing Python-3.8.5. python-build: use readline from homebrew python-build: use zlib from xcode sdk Installed Python-3.8.5 to /Users/alex/.pyenv/versions/3.8.5

Если запустить команду pyenv versions еще раз, то увидим нашу выбранную версию в списке, но она еще не активирована:

* system (set by /Users/alex/.python-version) 3.8.5

Надо верифицировать ее командой. Все еще нет:

Python 2.7.16

pyenv дает возможности установки любой версии Python как глобального Python-интерпретатора, но мы сейчас делать так не будем. У нас уже есть скрипты или другие инструменты, работающие на дефолтном интерпретаторе, поэтому давайте не менять эти настройки. Вместо этого, давайте настроим Python для каждого проекта отдельно. Итак, создадим проект в следующем разделе.

Есть и альтернативный инструмент для описанного выше – asdf, по ссылке.

Управление зависимостями в Poetry

Зачем мне нужен Poetry?

По умолчанию, пакеты Python ставятся командой pip install. В реальности никто так не делает. Эта команда приводит все зависимости к одному интерпретатору Python, что создает бардак.

Хорошей практикой является проставлять зависимости по-проектно. Таким образом проект имеет зависимости только нужные, и никаких других. Не возникают конфликты с другими питон-пакетами, позарез нужными в другим проектах.

Для этой проблемы придумано решение – виртуальные окружения. В них каждый проект имеет собственное виртуальное окружение с приписанной ему питон-версией, и фиксированными зависимостями, в каждом проекте своя.

Виртуальные окружения, которые возникли из старых venv, virtualenv, virtualenvwrapper – очень популярны и давно работают. Но есть некая неразбериха с pipenv, если очень надо, то можешь почитать здесь: Pipenv: promises a lot, delivers very little. Одной из видимых проблем pipenv является задержка релизов – например с 2018 года не было новых. Но в середине 2020 года проект pipenv внезапно “проснулся” и выпустил пару апдейтов. Poetry тоже применяется, к тому же заявляют что он лучше работает чем pipenv. Poetry может быть полезен в опенсорсных проектах, особенно в публикации пакетов.

Как ставится Poetry

Рекомендую ставить Poetry на системном уровне.

В MacOS, Linux и WSL вот так:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python

Если работаешь в Windows Powershell, есть специальный скрипт на официальном сайте. Но видимо лучше просто сделать в WSL.

Чтобы применить изменения для текущей версии оболочки, команда:

source $HOME/.poetry/env

Можно добавить это в авторан-скрипт типа .bashrc или .zshrc, если Poetry все еще нет в новой сессии:

export PATH="$HOME/.poetry/bin:$PATH"

Можно тут же включить Tab-автодополнение в оболочке. Описано тут.

Как создать проект в Poetry?

Poetry создает отдельные папки и переходит туда, поэтому надо убедиться, что выполнен переход из текущей папки в папку Python-проекта, и там запустить команду:

poetry new my-project

где my-project это имя твоего проекта.

Дальше посмотрим, что там создал Poetry:

cd my-project; ls
Как настроить версию Python по-проектно

Мы все еще находимся на версии 2.7, помнишь? В новом проекте мы будем работать в новой версии, поэтому перейдем в pyenv. Мы сейчас находимся в проектной папке, и мы задаем версию Python локально, для этой папки, командой:

pyenv local 3.8.5

Если мы запустим pyenv versions сейчас, то увидим что 3.8.5 обозначено звездочкой, как активная для этой папки. Учти, что вне этой папки версия Python остается не измененной, той же “по умолчанию”.

system * 3.8.5 (set by /Users/alex/iCloud/dev/projects/my-project/.python-version)

Можно проверить наверняка, командой python -V.

Python 3.8.5

Теперь заставим Poetry “подхватить” текущую версию:

poetry env use python
Creating virtualenv my-project-PSaGJAu6-py3.8 in /Users/alex/Library/Caches/pypoetry/virtualenvs Using virtualenv: /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8

На последнем шаге настройки версий, давай-ка обновим pyproject.toml . [tool.poetry.dependencies] . Должно ответить, что поддерживается версия 3.8 или выше:

[tool.poetry] name = "my-project" version = "0.1.0" description = "" authors = ["Alex"] [tool.poetry.dependencies] python = "^3.8" [tool.poetry.dev-dependencies] pytest = "^5.2" [build-system] requires = ["poetry-core>=1.0.0a5"] build-backend = "poetry.core.masonry.api"
Как работать в Poetry

На этом этапе надо будет установить первую зависимость: какую-то библиотеку или фреймворк, “поверх” того что планировалось в проекте. Например:

poetry add aiohttp

где aiohttp – фреймворк который ставится.

Если надо подтянуть существующий проект и установить его зависимости для локальной разработки, вводим команду:

poetry install

Обновить все зависимости к последним версиям:

poetry update
Как связать Poetry с VS Code

VS Code к сожалению не подхватывает Poetry автоматически. Но есть и хорошие новости, можно заставить VS Code находить и подхватывать виртуальное окружение, прописанное в Poetry.

Скачала активируем виртуальное окружение:

poetry shell
Spawning shell within /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8 ➜ my-project . /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.8/bin/activate (my-project-PSaGJAu6-py3.8) ➜ my-project

Теперь мы вошли в виртуальное окружение, и можем вызывать VS Code из него:

code .

Надо будет также установить Pylance – питон-сервер для VS Code.

При открытии любого питон-файла, VS Code тут же спросит, какой интерпретатор задействовать?

Итак, выберем. Мы вызывали VS Code из виртуальной среды, поэтому нужный интерпретатор покажется в списке, и мы выберем его.

Заметь, что есть две опции для 3.8.5, мы должны выбрать одну, которая относится к виртуальному окружению (это видно по пути к файлу, там должно быть virtualenv).

Вообще, можно подписаться на соответствующую issue на Гитхабе, по связке VS Code с Python. А Брет Кэннон говорит, что разработчики VS Code уже переписывают код связки, и когда-нибудь, говорили они, Poetry будет полностью поддерживаться в VS Code.

Обновление Poetry

Просто запускай poetry self update, и получишь последнюю версию Poetry.

Если выплыла ошибка:

ImportError: No module named cleo

То надо переустановить Poetry. Сначала удалить:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py > get-poetry.py python get-poetry.py --uninstall python get-poetry.py rm get-poetry.py
Как обновить версию Python в Poetry и pyenv?

Новые версии Python выходят регулярно, там новые функции и фиксы, и мы хотим обновить Python у себя. Это сделать достаточно просто.

Сначала мы загружаем, компилируем, и настраиваем новый Python-интерпретатор. Убедись, что запускаешь эти команды не из виртуального окружения, а откуда положено – из корневой папки проекта. В моем случае, надо было обновиться к CPython 3.9.2 (которая была новейшей на момент написания основной части этого текста), но в принципе ничего особо не отличается в любой другой версии CPython.

pyenv install 3.9.2 pyenv local 3.9.2 pyenv versions
my-project pyenv versions system 3.8.5 * 3.9.2 (set by /Users/alex/iCloud/dev/projects/my-project/.python-version)

Дальше мы в Poetry передаем этот интерпретатор как “рабочий” для виртуальных окружений.

poetry env use python
Creating virtualenv my-project-PSaGJAu6-py3.9 in /Users/alex.mitelman/Library/Caches/pypoetry/virtualenvs Using virtualenv: /Users/alex/Library/Caches/pypoetry/virtualenvs/my-project-PSaGJAu6-py3.9

Хэш проекта остается неизменным, а версия Python изменилась на 3.9.

Имеем новое окружение, и надо теперь переустановить все зависимости:

poetry install

На следующем этапе надо активировать виртуальное окружение и внимательно проверить, что выбрана правильная версия Python. Итак, запускаем VS Code из виртуального окружения, и VS Code теперь может найти новое окружение (надо еще не забыть закрыть VS Code перед этим).

poetry shell python -V code .

И последний этап, в левом нижнем углу нажми на версии Python, и выбери нужную версию в списке. Проверь, что выбрал версию именно виртуального окружения.

Не забывай обновлять отдел [tool.poetry.dependencies] в файле pyproject.toml, чтобы корректно отображалась поддержка версий Python.

VS Code предложит выбрать линтер, форматировщик кода и прочее. Игнорируй. Сначала настрой описанное выше, остальное – потом (далее я опишу, как и что).

Можно все это сделать и альтернативным путем, командой venv.

Как тестировать код при помощи pytest

Зачем нужен pytest

Тесты нужны, тесты важны, поэтому первым делом после создания проекта позаботимся о тестах.

pytest – популярный фреймворк, широко одобряемый в Python-сообществе. Он так популярен, что идет в комплекте с Poetry как средство тестирования. Итак, открываем раздел [tool.poetry.dev-dependencies] в pyproject.toml, и видим, что pytest уже в списке зависимостей.

Poetry прописывает за нас структуру тестовых папок.

cd tests; ls
__init__.py __pycache__ test_my_project.py
Как работать с pytest в VS Code

Очень простой пример. Создаем и протестируем функцию, умножающую два числа. В соответствии с TDD сначала создаем тест.

Откроем test_my_project.py и добавляем импорт функции, а также простой тест:

from my_project.math import multiply_two_numbers def test_multiply_two_numbers(): result = multiply_two_numbers(2, 3) assert result == 6

Вместо запуска наших тестов из терминала, сделаем все в редакторе (на примере MacOS). Нажимаем комбинацию ⇧⌘P, далее начинаем вводить “Python: Discover Tests” и выбираем нужное в списке.

Тестовый фреймворк появился в правом нижнем углу. Нажимаем его:

и выбираем pytest в выпадающем списке:

На последнем этапе, надо задать папку, где будут наши тесты:

VS Code нашел наши тесты, и добавил кнопки для запуска и дебага тестов.

Так как мы работаем в VS Code, редактор выделит их красным, потому что эти функции еще не прописаны.

Итак, создаем файл math.py в папке my_project и далее пропишем нашу простую функцию:

def multiply_two_numbers(a, b): return a * b

Когда запустим тесты снова, они будут уже зелеными:

Альтернативный путь: запустить тесты из командной стройки:

poetry run pytest

или из активированного виртуального окружения, командой:

pytest

Или так: unittest – инструментом, включенным в стандартный дистрибутив Python. Но есть минусы: “не питоновский” camelcase API, неудобный синтаксис.

Как оценить покрытие тестами при помощи pytest-cov

Если есть тесты, надо знать покрытие ими кода. Можно поставить плагин pytest-cov для pytest :

poetry add --dev pytest-cov

Теперь запуск тестов с дополнительным параметром будет генерировать отчет по покрытию кода тестированием:

pytest --cov=my_project tests/
================================================= test session starts ============= platform darwin -- Python 3.9.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 rootdir: /Users/alex/iCloud/dev/projects/my-project plugins: cov-2.10.1 collected 2 items tests/test_my_project.py .. [100%] ----------- coverage: platform darwin, python 3.9.2 ----------- Name Stmts Miss Cover -------------------------------------------- my_project/__init__.py 1 0 100% my_project/math.py 4 0 100% -------------------------------------------- TOTAL 5 0 100% ================================================== 2 passed in 0.08s ===============

Также сгенерируется файл .coverage, которого мы не хотим видеть в нашем контроле версий, поэтому не забудь добавить его в соответствующий списочек .gitignore :

echo '.coverage' > .gitignore
Как провести проверку до отправки на предварительный коммит
В Git

Мы еще не затрагивали здесь контроль версий, а теперь займемся этим. Конечно, в 2021 году все работают в Git. Установить последнюю версию (или обновить) в MacOS:

brew install git

Если в проекте еще нет репозитория, надо его создать. Github создает новый репозиторий по умолчанию с веткой main и делаем это:

git init -b main

Сначала уточним, мы должны иметь у себя файл .gitignore , и он не даст невпопад коммитить “временные” файлы или бинарники в наш Git-репозиторий. Можно вручную скопипейстить отсюда или просто запустить команду создающую .gitignore, и загрузить контент из указанной ссылки. При этом надо находиться в корневой папке проекта.

curl -s https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore >> .gitignore

Можно исключить папку настроек VS Code из контроля версий. Также можно исключить папку настроек PyCharm, если кто-то в проекте работает в этом IDE.

echo '.vscode/\n.idea/' >> .gitignore

Теперь добавим все нужное в контроль версий:

git add .
Зачем запускать проверку перед коммитами?

Как ты уже понял (и еще увидишь дальше), объем проекта большой. Легко что-то упустить перед тем как отправить код в репозиторий. В результате, код не проходит автоматическую проверку качества непрерывной интеграции кода (CI), твои коллеги или тестировщики могут заставлять корректировать код. Иногда все тормозится из-за того, что кто-то не поставил пробел или символ конца строки, а ведь это тоже входит в стандарт качества POSIX например, в чем можно убедиться по ссылке. Даже если помнишь все мелкие стандарты, это ни от чего не спасает, все равно легко ошибиться. Но есть удобный инструмент избежать “залипания” в этих легко автоматизируемых мелочах.

Для этого и существует pre-commit . Это средство автоматической проверки каждого git-коммита. Оно простое и не требует рут-доступа. Написано на Python, но разумеется может работать в проектах с другими языками.

Установка и работа pre-commit

pre-commit может ставиться на системном уровне, но мы так делать не будем, именно потому, почему применяем pyenv – у нас много разных версий Python, и наши зависимости надо хранить в порядке. Мы ставим pre-commit как зависимость:

poetry add pre-commit --dev

Далее мы “прикрепим” все наши “проверяльщики” (линты) и подобные инструменты для предварительной проверки кода. Создаем простой конфиг для проверки на наличие в положенном месте – символа конца строки (EoF, newline), о котором речь шла выше.

Есть команда в pre-commit для быстрого создания такого конфига. В корневой папке вводим:

pre-commit sample-config > .pre-commit-config.yaml

Создан небольшой файл конфигурации, содержащий такие строки:

# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files

Здесь видно, что наш pre-commit уже сам прописал некоторые удобные хуки. Теперь смотрим, как оно работает. Запуск проверки вручную:

pre-commit run --all-files

После запуска pre-commit, становится понятно, что даже в файлах, автоматически создаваемых в VS Code, нет в конце этого символа (newline), между прочим требуемого стандартом!

Trim Trailing Whitespace. Passed Fix End of Files. Failed - hook id: end-of-file-fixer - exit code: 1 - files were modified by this hook Fixing my_project/math.py Fixing .vscode/settings.json Fixing tests/test_my_project.py Check Yaml. Passed Check for added large files. Passed

А pre-commit пофиксил эту проблему за тебя, так что если запустить ту же команду еще раз, все проверки покажут ОК.

Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed

Самая важная часть тут – правильно “связать” Git с этими хуками, и запускать их перед каждым коммитом.

pre-commit install
pre-commit installed at .git/hooks/pre-commit

Теперь мы выполняем коммиты (то есть передаем свои правки на Git):

git commit -m 'Initial commit'
Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed [master (root-commit) 7dc335f] Initial commit 11 files changed, 559 insertions(+) create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .python-version create mode 100644 .vscode/settings.json create mode 100644 README.rst create mode 100644 my_project/__init__.py create mode 100644 my_project/math.py create mode 100644 poetry.lock create mode 100644 pyproject.toml create mode 100644 tests/__init__.py create mode 100644 tests/test_my_project.py

Хуки запускаются перед коммитом, как положено.

И последнее, можно заставить pre-commit периодически обновлять конфиги к последней версии:

pre-commit autoupdate

И он немедленно обновил хук, в моем случае:

Updating https://github.com/pre-commit/pre-commit-hooks . updating v2.4.0 -> v3.2.0.
Анализ кода в линтере Flake8

Почему линтеры нужны в проектах на Python

Линтеры – твой заслон от багов и тупых ошибок-опечаток. Они сигнализируют об ошибках заблаговременно, до передачи кода на выполнение. Конечно же, все IDE-редакторы поддерживают в себе линтеры, и их не нужно запускать отдельно. Редактор с подключенным линтером подсвечивает некорректный код прямо после ввода.

В “Мире Python’а” существует много линтеров, основных два – Flake8 и Pylint.

Начнем с Pylint, это строгий и дотошный линтер. С ним работают люди в Google, в их Python-проектах, и это предусмотрено в их гугловских гайдлайнах. Из-за дотошности этого линтера, возможно, придется тратить время на разбор всех подробностей, и настройку срабатывания. Что, в принципе, неплохо – учишься писать удобочитаемый правильный код сразу же, “не отходя от кассы”. Безопасный код, однако, учиться писать намного дольше, как показывает опыт.

Популярнейший линтер с открытыми исходниками – Flake8. Но перед тем как начать, надо обсудить одну вещь.

Python Style Guide- PEP8

Гайдлайн по Питону, известен по номеру “Предложений по Улучшению №8” – PEP8. Все программисты на Питоне попросту обязаны ознакомиться с PEP8, и понятно, с Дзеном тоже (РЕР20).

После прочтения РЕР8, достаточно утомительного документа, возникает вопрос, а есть ли “тулз” автоматической проверки, и приведения в действие всех этих указаний? Это делает Flake8, и не только это. Он работает сразу после установки, и может настраиваться на специфические правила у каждого разработчика.

Flake8 не такой строгий как Pylint, и вполне сносно “несет службу на первом краю”, где твоя безалаберность обычно наивысшая.

Поэтому советую все-таки работать с Flake8. Можно иметь в запасе и Pylint как запасной вариант, но в Flake8 работать обязательно.

Как ставится Flake8

VS Code обязательно спросит при установке, оп, а какой будет линтер? На Маке нажимаем ⇧⌘P, дальше вводим “linter”, выбираем в списке “Python: Select Linter”.

И выбираем “flake8”

VS Code подхватит виртуальное окружение и установит Flake8 как зависимость.

Если так не получилось, или если хочется поставить Flake из командной строки:

poetry add flake8 --dev
Как работать в Flake8

Итак, вернемся к коду в предыдущей главе. VS Code подсвечивает красным ошибки, с точки зрения линтера. Подводим мышку к ошибке, видим сообщение с номером и описанием ошибки (можно тут же посмотреть в интернете, о чем это), и название линтера.

Можно запускать Flake8 вручную:

flake8 .
./tests/test_my_project.py:4:1: E302 expected 2 blank lines, found 1 ./tests/test_my_project.py:7:1: E302 expected 2 blank lines, found 1
Как “подвязать” Flake8 к хукам Git?

О красной подсветке ошибок в IDE иногда забывают, так же как о запуске команды flake8 перед отправкой кода в репозиторий. Поэтому существуют хуки. Добавим Flake8 в список хуков, и ко будет проверяться автоматически.

Для этого откроем файл .pre-commit-config.yaml и добавляем следующее:

- repo: https://gitlab.com/pycqa/flake8 rev: 3.8.3 hooks: - id: flake8

Теперь внимательно – на строчку с rev. Здесь не обязательно версия 3.8.3. Узнать текущую версию Flake8 можно, открыв pyproject.toml, там найти версию Flake8, и скопировать-вставить ее в конфиг-файл пре-коммита, как показано выше.

Помни: мы раньше заставили pre-commit обновлять версии, поэтому Flake8 будет постоянно обновляться к последней версии. Но мы уже используем самую новую версию линтера, и ничего не будет происходить. pre-commit загрузит эту версию Flake8, потому что он проводит свои проверки в отдельном окружении. Это значит, что у нас получится две разных версии Flake8, и надо убедиться, что сейчас работает правильная. Обычно обновление к последней версии не составляет проблем,но если они возникают, советую отключить автоматическое обновление для pre-commit.

После редактирования конфиг-файла делаем так:

git add .pre-commit-config.yaml
git commit -m 'Add Flake8 to git hooks'
Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. (no files to check)Skipped [master 1d25c9f] Add Flake8 to git hooks 1 file changed, 4 insertions(+)

Давайте попробуем вручную запустить pre-commit еще раз, чтобы проверить, как работает Flake8 в связке с Git:

pre-commit run --all-files
Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. Failed - hook id: flake8 - exit code: 1 tests/test_my_project.py:4:1: E302 expected 2 blank lines, found 1 tests/test_my_project.py:7:1: E302 expected 2 blank lines, found 1

Не спеши фиксить эту ошибку, чтобы “снять” ее из линтера. Надо пробовать фиксить ее в автоматическом режиме.

Форматирование кода в Black

Каждый программист обладает собственным стилем. Даже на Питоне, который принудительно заставляет делать отступы, можно писать код по своему.

Иногда, глядя на кусок кода, я могу сказать, кто из моей команды писал его. Когда код пишут одновременно несколько человек, он становится “лоскутным”.

Как этого избежать: по идее, перед написанием кода надо посоветоваться, иначе дело замедлится. Вообще же, пререкания насчет стиля – есть дело личного вкуса. В конце рабочего дня люди ссорятся о мелочах, о том как внешне выглядит код, а не о том как он работает.

Круто, когда код одинаково выглядит во всем проекте, как если бы его писал один человек. Есть такое решение, такой инструмент, он называется Black.

Этот софт форматирует код “в одном ключе”, и код по крайней мере внешне – выглядит однообразно. В Black можно настраивать мало что, но здесь не тот случай, когда есть выбор. Просто поставь его, и пользуйся без претензий. В конце концов, РЕР8 и Black создавались для “причесывания” всего под единый образец, и тут уж ничего не поделать, претензии излишни.

Сразу заметно, что сам Black игнорирует правило из РЕР8 о длине строки. Вообще, в РЕР8 сказано, что строка может быть максимально длиной в 79 символов. Это имеет исторические корни, удивительно, от перфокарт IBM и первых UNIX-терминалов. РЕР8 писали в далеком 2001 году, с того времени много чего изменилось. Люди начали ставить под сомнение это правило. “Не читаю код на UNIX-терминале”, говорят они. “У меня 27-дюймовый IPX-монитор”, говорят они. Однако, есть и люди, которые пишут код на маленьком 13-дюймовом лэптопе. И, например, искать глазами разницу между двумя текстовыми файлами, с длиной строки всего 79 символов – им довольно удобно. Представить только, горизонтальную перемотку огромного файла с большой длиной строки на таком экране. Поэтому “правило 79 символов” сохранено.

И да, хотя РЕР8 составлен в 2001, он неоднократно обновлялся (список новшеств), и все-таки правило, еще раз обсудив, не трогали.

И это правило Black дает нам настроить.

Как поставить Black

В VS Code открываем Python-файл в нашем новом проекте. Например test_my_project.py, о котором так беспокоится наш Flake8. Нажимаем и вводим “format”, дальше выбираем “Format Document”.

Всплывает диалог выбора форматировщика.

Выбираем форматировщик: “Use Black”.

VS Code обнаружит, что уже есть Poetry, и автоматически поставит Black.

Или же можно поставить вручную, командой:

poetry add --dev black --allow-prereleases

Опция –allow-prereleases присутствует, потому что Black все еще бета (весной-летом 2021 по крайней мере). Когда-то в 2019 думали, что закончат с бетами в том же году, но как говорится. Впрочем, многие серьезные продакшены и опенсорсные проекты “причесывают” свой код с Black, поэтому можно считать, что этот “дефолтный” форматировщик – в достаточной мере стабилен и надежен.

Чтобы настроить Black, открываем pyproject.toml и вставляем следующий раздел:

[tool.black] line-length = 79 target-version = ['py38'] include = '\.pyi?$' exclude = ''' ( /( \.eggs # exclude a few common directories in the | \.git # root of the project | \.hg | \.mypy_cache | \.tox | \.venv | _build | buck-out | build | dist )/ | foo.py # also separately exclude a file named foo.py in # the root of the project ) '''

Самая важная часть здесь – установить, что максимальная длина строки равна 79.

Если работаешь и в других версиях Python, то обновляй их тоже, но убедись, что они поддерживаются в Black.

Также понадобится “притушить” некоторые ошибки в Flake8, чтобы Flake8 нормально работал с Black. Для этого создаем конфиг-файл setup.cfg (то есть файл конфигурации Flake8), и вставляем там это:

[flake8] extend-ignore = E203
Как работает Black

Очень просто он работает. Запускается и форматирует код:

black .
reformatted /projects/my-project/my_project/__init__.py reformatted /projects/my-project/tests/test_my_project.py All done! ✨ �� ✨ 2 files reformatted, 2 files left unchanged.

Flake8 жаловался на отсутствие символов перевода строки? (об этом шла речь выше.) Запускаем Git-хук, и видим что все ОК.

pre-commit run --all-files
Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. Passed
Как добавить Black в git-хуки?

Так же как Flake8, работа Black отлично автоматизируется, так что не волнуемся. Вставляем в конфиг .pre-commit-config.yaml следующий кусок:

- repo: https://github.com/psf/black rev: 20.8b1 hooks: - id: black

Опять запускаем pre-commit run –all-files. Видим что загружается Black, и работает:

[INFO] Initializing environment for https://github.com/psf/black. [INFO] Installing environment for https://github.com/psf/black. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes. Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. Passed black. Passed

Сохранение изменений в Git описывать не буду, это одинаковое с Flake8.

Есть еще альтернатива – yapf.

Бонус!

Можно сделать в VS Code вертикальную линейку (ruler), показывающую тот самый лимит 79 символов. Открываем settings.json в папке .vscode и вставляем туда:

«[python]»:

Линейка будет видна только в питон-коде. В docstrings будет только 72 символа.

Статические типы в Mypy

Применение проверки статических типов в Python

Споры о типах полыхали еще в 1970-е. IBM со своим Smalltalk – против Sun с их Java. Как мы знаем, выиграла Java и концепция “strong-type”, однако и Smalltalk не исчез со своим динамическим типированием; это рассматривалось как преимущество, по крайней мере в некоторых крупных компаниях, так как этим обеспечивалась быстрота разработки. Конечно, строгое типирование хранит от многих багов и runtime-исключений; но от них можно уберечься и 100%-ным покрытием тестами (как считает Uncle Bob, это и есть главная причина успешности Python). Но давайте также не забывать, что не все проекты можно 100% покрыть тестами.

А можно заиметь лучшее из обеих концепций. Можно соединить безопасные типы, и быстроту разработки. И в этом поможет Mypy – инструмент анализа статического кода, на предмет его безопасности (type-safe check). Проект превратился в такой ценный, что на него обратил внимание сам Его Величество творец Python Гвидо ван Россум, и добавил аннотации по типам в Python, и присоединился к разработке Mypy. Аннотации типов делают код удобочитаемым, а также удобным для IDE в плане быстроты авто-дополнения кода.

Как установить mypy

В VS Code открываем файл settings.json в папке .vscode. Устанавливаем параметр “python.linting.mypyEnabled”: в положение :true. Затем открываем любой питон-файл из проекта, например тот же math.py. VS Code сразу сообщает, что линтер Mypy еще не установлен.

Нажимаем “Install”, и Mypy поставится автоматически вместе с Poetry.

Или же, можно поставить Mypy вручную:

poetry add --dev mypy
Как работает Mypy

Теперь надо опробовать этот “тулз” в своем проекте.

mypy .
Success: no issues found in 4 source files

Вроде как все хорошо, у нас даже не надо ничего корректировать, Mypy автоматически проверяет типы.

Как упоминалось выше, аннотации типов помогают лучше читать код и понимать его, и IDE лучше авто-дополняет код, так что давайте пробовать. Открываем конфиг-файл setup.cfg и вставляем туда этот кусок:

[mypy] follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True

Тут самая важная строчка – disallow_untyped_defs = True. Она заставляет тебя “описывать функции типами”, то есть принудительное присвоение типов. В существующих старых проектах это можно отключить, но у нас новый проект, поэтому будет полезно убедиться, что аннотации типов не пропущены.

Может понадобиться временно отключить Mуpу для тестирования, для этого вставляем следующий кусок в настройки:

[mypy-tests.*] ignore_errors = True

Еще лучшую совместимость дают плагины для Mypy. К примеру, если нужно применять pydantic для валидации данных или их сериализации, конфиг-файл будет содержать такие строчки:

[mypy] plugins = pydantic.mypy follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True [pydantic-mypy] init_forbid_extra = True init_typed = True warn_required_dynamic_aliases = True warn_untyped_fields = True

После вставки такого куска, на выводе получим:

my_project/math.py:1: error: Function is missing a type annotation Found 1 errors in 1 files (checked 4 source files)

Помимо этого, в VS Code Mypy работает в качестве линтера, подчеркивая ошибки:

Чтобы пофиксить их, вставляем аннотации типов в нашу функцию:

from numbers import Real from typing import Union def multiply_two_numbers(a: Union[int, Real], b: Union[int, Real]) -> Union[int, Real]: return a * b

Как видишь, описание функции слишком длинное. Нажимаем ⇧⌥F, и VS Code отформатирует код при помощи Black, сократив длину строки до 79 символов:

from numbers import Real from typing import Union def multiply_two_numbers( a: Union[int, Real], b: Union[int, Real] ) -> Union[int, Real]: return a * b

Коммитим внесенные правки:

git commit -m 'Add Mypy'
Как добавить mypy в список git-хуков

Надо проверить, что Mypy запускается до коммита кода. Вставляем в файл .pre-commit-config.yaml следующий кусок:

- repo: https://github.com/pre-commit/mirrors-mypy rev: v0.782 hooks: - id: mypy additional_dependencies: [pydantic] # add if use pydantic

Вводим команду pre-commit run –all-files, она устанавливает запуск Mypy для предварительных коммитов и проводит проверки:

[INFO] Installing environment for https://github.com/pre-commit/mirrors-mypy. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes. Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. Passed black. Passed mypy. Passed
Сортирование импортов при помощи isort

Ну и последнее. Импорты.

Зачем вообще сортировать импорты?

РЕР8 говорит, что импорты должны быть отсортированы, причем в следующем порядке: стандартная библиотека, third party библиотека, локальная библиотека. Кроме того, импорты должны быть “красивыми, хорошо читаемыми”.

Есть и такой инструмент! Называется isort, как бы сокращение от “import sort”. Здесь по ссылке описание.

До сортировки импорты выглядят так:

from my_lib import Object import os from my_lib import Object3 from my_lib import Object2 import sys from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14 import sys from __future__ import absolute_import from third_party import lib3
from __future__ import absolute_import import os import sys from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14, lib15) from my_lib import Object, Object2, Object3
Как поставить isort, добавить в список git-хуков и работать с ним

VS Code (с установленным Python-расширением) запускает isort “автоматически”, так что не надо какой-то дополнительной настройки. Если ты не будешь работать с isort из командной строки, то даже не надо отдельно устанавливать его, потому что pre-commit автоматически устанавливает все зависимости в окружениях.

Но, если понадобится работать с isort вне VS Code и pre-commit, то устанавливать надо так:

poetry add --dev isort

Чтобы isort корректно “сотрудничал” с Black, в pyproject.toml надо добавить строчки:

[tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 79

В VS Code на Маке нажимаем ⇧⌘P, вводим “sort imports”, и увидим:

Или же, если isort уже установлен, вводим, находясь в корневой папке проекта:

isort .
Skipped 2 files

Ну и добавляем isort в список хуков в конфиг-файле .pre-commit-config.yaml:

- repo: https://github.com/PyCQA/isort rev: 5.4.2 hooks: - id: isort

Вот как оно работает например с pre-commit run –all-files:

Trim Trailing Whitespace. Passed Fix End of Files. Passed Check Yaml. Passed Check for added large files. Passed flake8. Passed black. Passed mypy. Passed isort. Passed
Fast Track

Вот как можно создать полностью сконфигурированный проект за пару минут (если pyenv и poetry уже установлены):

poetry new my-project; cd my-project; ls pyenv local 3.9.2 poetry env use python poetry add --dev pytest-cov pre-commit flake8 mypy isort poetry add --dev --allow-prereleases black poetry shell code .

Добавляем настройки в pyproject.toml:

[tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 79 [tool.black] line-length = 79 target-version = ['py38'] include = '\.pyi?$' exclude = ''' ( /( \.eggs # exclude a few common directories in the | \.git # root of the project | \.hg | \.mypy_cache | \.tox | \.venv | _build | buck-out | build | dist )/ | foo.py # also separately exclude a file named foo.py in # the root of the project ) '''

Создаем setup.cfg:

[flake8] extend-ignore = E203 [mypy] follow_imports = silent strict_optional = True warn_redundant_casts = True warn_unused_ignores = True disallow_any_generics = True check_untyped_defs = True no_implicit_reexport = True disallow_untyped_defs = True ignore_missing_imports = True [mypy-tests.*] ignore_errors = True

Создаем .pre-commit-config.yaml:

repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://gitlab.com/pycqa/flake8 rev: 3.8.4 hooks: - id: flake8 - repo: https://github.com/psf/black rev: 20.8b1 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.812 hooks: - id: mypy additional_dependencies: [pydantic] # add if use pydantic - repo: https://github.com/PyCQA/isort rev: 5.7.0 hooks: - id: isort
echo '.coverage' > .gitignore echo '.vscode/\n.idea/' >> .gitignore curl -s https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore >> .gitignore git init -b main git add . git commit -m 'Initial commit' pre-commit install pre-commit autoupdate pre-commit run --all-files pre-commit run --all-files

Итоги

Сегодня ты потрудился на славу, можно поздравить, если добрался сюда. Конечно, это было утомительно. Перед нами стояла цель: настроить свой IDE и Python так, чтобы создание нового проекта требовало несколько минут. Если все сделать как описано выше, так и будет.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *