Некорректно работает exclude при вызове mypy
Есть тестовая структура проекта:
├── app
| └── db
| └── postgres.py
| └── postgres.py
└── postgres.py
Если не устанавливать конфигурацию, то вызов poetry run mypy . | grep postgres дает следующее:
postgres.py:2: error: Unsupported operand types for + ("str" and
"float") [operator]
app/postgres.py:2: error: Unsupported operand types for + ("str"
and "float") [operator]
app/db/postgres.py:11: error: "Constraint" has no attribute
"columns" [attr-defined]
Однако моя цель исключить директорию db или хотя бы файл app/db/postgres.py, поэтому в pyproject.toml добавляю:
[tool.mypy]
exclude = ["postgres.py", "db", "app/db", "db/postgres.py", "app/db/postgres.py"]
И вызываю poetry run mypy . | grep postgres. Вывод:
app/db/postgres.py:11: error: "Constraint" has no attribute "columns" [attr-defined]
Почему-то на втором уровне вложенности mypy никак не хочет респектить exclude. Кажется, проблема даже не в этом параметре. Кто-нибудь может помочь?
Ответы (2 шт):
Параметр exclude — это строка с регулярным выражением:
#pyproject.toml
[tool.mypy]
exclude = "^app/db/.*$"
В .toml можно использовать список, но важно учесть, что это должен быть список регулярных выражений.
Пример из документации:
[tool.mypy]
exclude = [
"^one\\.py$", # TOML's double-quoted strings require escaping backslashes
'two\.pyi$', # but TOML's single-quoted strings do not
'^three\.',
]
Эквивалентен выражению в одну строчку:
^one\.py$|two\.pyi$|^three\.
#mypy.ini
[mypy]
exclude = ^app/db/.*$
Такая регулярка исключает:
- app/db/all_file.py
- Все подкаталоги внутри app/db
Если использовать просто имена файлов или директорий, это может рано или поздно выйти боком.
Благодарю за ответы. Проблема оказалась в следующем: https://mypy.readthedocs.io/en/stable/running_mypy.html#following-imports
Mypy по умолчанию проверяет все встреченные в импортах модули, даже если они подходят под заданный exclude. Данное поведение можно изменить, но это не является рекомендуемой практикой.
Таким образом, при вызове mypy из корня проекта, исключить app/db можно следующими способами:
Задать в
excludeрегулярку и вызыватьmypyбез проверки встреченных импортов (не рекомендутеся)poetry run mypy . --follow-imports silentОтключить проверку импортируемого модуля в overrides
[[tool.mypy.overrides]]
module = "app.db.*"
ignore_errors = true
- Явно указывать проверяемые модули, с учетом того, что
mypyбудет проверять импорты рекурсивно.