Pytests не работает в Teamcity из-за бэкэнда Matplotlib

Я пытаюсь запустить несколько модульных тестов Python на удаленном сервере сборки с помощью Teamcity. Они терпят неудачу при попытке выполнить некоторый код matplotlib. Я получаю следующий вывод в журналах сборки Teamcity, который, похоже, указывает на бэкэнд matplotlib как на виновника.

    XXXXX\stats.py:144: in PerformHypothesisTest
        fig, ax = plt.subplots(1, 1, figsize=(10, 6))
    .venv\lib\site-packages\matplotlib\pyplot.py:1702: in subplots
        fig = figure(**fig_kw)
    .venv\lib\site-packages\matplotlib\pyplot.py:1022: in figure
        manager = new_figure_manager(
    .venv\lib\site-packages\matplotlib\pyplot.py:545: in new_figure_manager
        return _get_backend_mod().new_figure_manager(*args, **kwargs)
    .venv\lib\site-packages\matplotlib\backend_bases.py:3521: in new_figure_manager
        return cls.new_figure_manager_given_figure(num, fig)
    .venv\lib\site-packages\matplotlib\backend_bases.py:3526: in new_figure_manager_given_figure
        return cls.FigureCanvas.new_manager(figure, num)
    .venv\lib\site-packages\matplotlib\backend_bases.py:1811: in new_manager
        return cls.manager_class.create_with_canvas(cls, figure, num)
    .venv\lib\site-packages\matplotlib\backends\_backend_tk.py:479: in create_with_canvas
        with _restore_foreground_window_at_end():
    C:\Python310\lib\contextlib.py:135: in __enter__
        return next(self.gen)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
        @contextmanager
        def _restore_foreground_window_at_end():
    >       foreground = _c_internal_utils.Win32_GetForegroundWindow()
    E       ValueError: PyCapsule_New called with null pointer
    
    .venv\lib\site-packages\matplotlib\backends\_backend_tk.py:43: ValueError

Тесты проходят нормально оба:

  • Локально на моем компьютере из Pycharm
  • На сервере сборки при выполнении из командной строки, т. е. при запуске python -m pytest

Я не очень хорошо знаком с тем, как работает Teamcity и как его отлаживать, поэтому буду признателен за любые идеи относительно того, что здесь может быть не так.

На сервере сборки работают следующие версии:

  • Питон 3.10.0
  • Матплотлиб 3.9.0
  • Питест 8.2.1

Если это полезно, сервер сборки использует бэкэнд «tkagg» (из matplotlib.get_backend()).

Обновлять: Спасибо за ответы. Как говорит Снарк, проблема, по-видимому, связана с ошибкой в ​​самой последней версии Matplotlib (3.9.0). Пока это не исправлено, я решал эту проблему, явно устанавливая для бэкэнда Matplotlib значение «Agg», как предложили BadCaffe и Lemmy. Я сделал это программно через файл pytest conftest.py.

Это может быть эта ошибка в matplotlib 3.9.0 с серверной частью tkagg в Windows: github.com/matplotlib/matplotlib/issues/28267. Поэтому попробуйте использовать matplotlib < 3.9.0 до выхода версии 3.9.1.

snark 31.05.2024 13:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
197
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У меня аналогичная проблема. Мой скрипт Python перестал работать самопроизвольно (исходный код не менялся). Скрипт отлично работает локально, но не удаленно (сервер). Локальная и удаленная среды Python кажутся одинаковыми. Установка бэкэнда на «Agg» решила проблему для меня. Вот что я сделал:

import matplotlib
matplotlib.use('Agg')
# now do the funny stuff

Надеюсь, это поможет!

Ответ принят как подходящий

У меня была такая же проблема, она как-то связана с отсутствующим физическим видеовыходом (на сервере с ночной сборкой монитор обычно не подключен). Вот почему он работает на вашей личной машине.

matplotlib.use('Agg')

должно работать, но если у вас полностью автоматические ночные сборки, которые сносят какой-то репозиторий и вы не можете изменить код, посмотрите здесь: https://matplotlib.org/stable/users/explain/customizing.html# файл-matplotlibrc

Вы можете поместить файл «matplotlibrc» в папку пользователя (в зависимости от вашей ОС) и просто поместить туда «backend: Agg». Это делает то же самое, что и matplotlib.use('Agg') при изменении используемого бэкэнда, но вы можете сделать это, не меняя код.

Другие вопросы по теме