запуск pytest как перехвата перед фиксацией // нет такой проблемы с файлом или каталогом

#python #pytest #pre-commit-hook #pre-commit #pre-commit.com

#python #pytest #перехват предварительной фиксации #предварительная фиксация #pre-commit.com

Вопрос:

в моем проекте Python я использую pytest в качестве pre-commit перехвата. Некоторые тесты создают и удаляют временные файлы, при запуске все работает нормально pytest <test directory> . Однако, когда я запускаю git commit и pre-commit подключаю триггеры pytest , некоторые тесты завершаются неудачей из-за FileNotFoundError: [Errno 2] No such file or directory: '<file name>' . У меня такое впечатление, что это происходит, когда многие файлы были изменены и находятся в промежуточной области (с 1-2 файлами я не наблюдаю эту проблему). Вот мой pytest раздел из .pre-commit-config.yaml :

   - repo: local
    hooks:
      - id: pytest-check
        name: pytest-check
        entry: bash -c 'pytest'
        language: system
  

вывод выглядит следующим образом:

 pytest-check.............................................................Failed
- hook id: pytest-check
- exit code: 1

tests/utils/test_application.py F                                        [ 91%]
tests/utils/test_image_io.py .FFF.........                               [100%]

==================================== ERRORS ====================================
_ ERROR at teardown of test_calling_with_nonexisting_parameter[--non_existing 1337-hm] _

    def teardown_module() -> None:
>       os.remove(OUTPUT_FILE)
E       FileNotFoundError: [Errno 2] No such file or directory: 'output.png'

tests/bdd/step_defs/test_runner_steps.py:98: FileNotFoundError
  

этого не происходит, когда я запускаю pytest с консоли.

с pass_filenames: false помощью и always_run: true ошибка больше не отображается:

   - repo: local
    hooks:
      - id: pytest-check
        name: pytest-check
        entry: pytest
        language: system
        pass_filenames: false
        always_run: true
  

что касается переноса вещей в bash, я все еще делаю это для pylint :

   - repo: local
    hooks:
      - id: pylint-check
        name: pylint-check
        entry: bash -c 'find . -name "*.py" | xargs pylint'
        language: system
        types: [python]
        pass_filenames: false
        always_run: true
  

есть ли лучшее решение для этого? pylint не поддерживает рекурсию неограниченной глубины, поэтому мне нужна команда bash.

Спасибо!

С наилучшими пожеланиями, Алексей

Ответ №1:

покажите свой вывод, иначе мы можем только догадываться о проблеме

тем не менее, вы, вероятно, хотите использовать always_run: true and pass_filenames: false — также ваш entry фиктивный, не нужно оборачивать вещи в bash, просто вызывайте исполняемый файл напрямую. Собрать все это вместе:

   - repo: local
    hooks:
      - id: pytest-check
        name: pytest-check
        entry: pytest
        language: system
        pass_filenames: false
        always_run: true
  

отказ от ответственности: я являюсь автором предварительной фиксации

Комментарии:

1. спасибо за быстрый ответ! Я опубликую свой вывод ниже. Кстати, когда требуется перенос в bash? Например, mypy и pylint не работают должным образом как перехватчики предварительной фиксации при вызове без оболочки bash.

2. пожалуйста, посмотрите мой вывод на этой странице.

3. «не работает» не является полезным сообщением об ошибке, покажите, что вы видите — вам никогда не понадобится bash. не публикуйте в качестве ответа, отредактируйте свой исходный вопрос

Ответ №2:

Если вы запускаете различные типы файлов через pre-commit или используете перехваты перед фиксацией, вам нужно добавить .pre-commit-config.yaml в файл другой параметр, иначе произойдет сбой с кодом выхода 5 (тесты не выполнялись):

     - repo: local
      hooks:
      - id: pytest-check
        name: pytest-check
        stages: [commit]
        types: [python]
        entry: pytest
        language: system
        pass_filenames: false
        always_run: true
  

Добавление types параметра позволит вам пройти pre-commit , даже если тесты не выполнялись или нет файлов Python.