Day by Day, Site by Site

Open source, Some Code, Troubleshooting, Good Links

Отладка сборки Python библиотеки на Manjaro Linux

   python debug

При очередном обновлении Manjaro, обновлении двух python библиотек python-jarowinkler и python-async_generator завершилось ошибками.

Библиотеку python-async_generator я удалил, потому что она выглядела старой и уже не поддерживаемой. На библиотеке python-jarowinkler я задержался, так как она выглядела поддерживаемой.

Было интересно понять где проблема: в недавнем переход Arch(Manjaro) на новый выпуск python312 или проблема кроется где то еще.

Я использую Manjaro, но пакетная база Arch и Manjaro очень близка.

При сборке возникала проблема:

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    def find_ruff_bin() -> str:
        """Return the ruff binary path."""

        ruff_exe = "ruff" + sysconfig.get_config_var("EXE")

        path = os.path.join(sysconfig.get_path("scripts"), ruff_exe)
        if os.path.isfile(path):
            return path

        if sys.version_info >= (3, 10):
            user_scheme = sysconfig.get_preferred_scheme("user")
        elif os.name == "nt":
            user_scheme = "nt_user"
        elif sys.platform == "darwin" and sys._framework:
            user_scheme = "osx_framework_user"
        else:
            user_scheme = "posix_user"

        path = os.path.join(sysconfig.get_path("scripts", scheme=user_scheme), ruff_exe)
        if os.path.isfile(path):
            return path

>       raise FileNotFoundError(path)
E       FileNotFoundError: /home/dp/.local/bin/ruff

/usr/lib/python3.12/site-packages/ruff/__main__.py:28: FileNotFoundError

---------- coverage: platform linux, python 3.12.3-final-0 -----------
Name                        Stmts   Miss  Cover
-----------------------------------------------
jarowinkler/__init__.py        22      3    86%
tests/test_JaroWinkler.py      28      1    96%
tests/test_hypothesis.py       66      0   100%
-----------------------------------------------
TOTAL                         116      4    97%

===================== short test summary info =====================
FAILED jarowinkler/__init__.py::ruff - FileNotFoundError: /home/dp/.local/bin/ruff
FAILED jarowinkler/__init__.py::ruff::format - FileNotFoundError: /home/dp/.local/bin/ruff
FAILED tests/test_JaroWinkler.py::ruff - FileNotFoundError: /home/dp/.local/bin/ruff
FAILED tests/test_JaroWinkler.py::ruff::format - FileNotFoundError: /home/dp/.local/bin/ruff
FAILED tests/test_hypothesis.py::ruff - FileNotFoundError: /home/dp/.local/bin/ruff
FAILED tests/test_hypothesis.py::ruff::format - FileNotFoundError: /home/dp/.local/bin/ruff
==================== 6 failed, 5 passed in 7.69s ==================
==> ERROR: A failure occurred in check().
    Aborting...
 -> error making: python-jarowinkler

То есть тесты не находили утилиту ruff по пути /home/dp/.local/bin/.

Совершенно не понятно было почему брался этот путь, а не общесистемный.

Я попробовал вручную собрать пакет, воспроизведя шаги из PKGBUILD:

cat /home/dp/.cache/yay/python-jarowinkler/PKGBUILD

# Maintainer: Bao Trinh <qubidt@gmail.com>
# Contributor: Antonio Rojas <arojas@archlinux.org>
# Contributor: Pekka Ristola <pekkarr [at] protonmail [dot] com>

_name=jarowinkler
pkgname=python-$_name
pkgver=2.0.1
pkgrel=2
pkgdesc='A library for fast approximate string matching using Jaro and Jaro-Winkler similarity'
arch=(x86_64)
url='https://github.com/maxbachmann/JaroWinkler'
license=(MIT)
depends=(python python-rapidfuzz)
makedepends=(python-pip python-build python-installer python-setuptools python-scikit-build ninja)
checkdepends=(python-hypothesis python-pytest)
source=("https://files.pythonhosted.org/packages/source/${_name::1}/$_name/$_name-$pkgver.tar.gz")
sha256sums=('7640c79f8d2d5e9eed6691cb49e3018a23b2319daad9a2178df253368b5432b7')

build() {
  cd $_name-$pkgver
  JAROWINKLER_BUILD_EXTENSION=1 \
  python -m build --wheel --no-isolation
}

check() {
  cd $_name-$pkgver
  python -m venv --system-site-packages test-env
  test-env/bin/python -m installer dist/*.whl
  test-env/bin/python -m pytest
}

package() {
  cd $_name-$pkgver
  python -m installer --destdir="$pkgdir" dist/*.whl
  install -Dm644 -t "$pkgdir"/usr/share/licenses/$pkgname LICENSE

Для этого переходим в сборочный каталог и начинаем воспроизводить шаги из секций build() и check():

cd /home/dp/.cache/yay/python-jarowinkler/src/jarowinkler-2.0.1

На шаге test-env/bin/python -m pytest проблема воспроизводилась.

Начал смотреть проблемный файл /usr/lib/python3.12/site-packages/ruff/__main__.py забивая его отладочными print’ами.

В выводе все равно фигурировали /home/dp/.local/bin/.

Запустил тесты от системного python и тесты прошли (!), а в выводе не было информации из отладочных print’ов.

python -m pytest tests/test_hypothesis.py

Стало понятно, что где то есть какая то разница, но как её определить?

Использовал отладку с добавлением в файл /usr/lib/python3.12/site-packages/ruff/__main__.py точек останова:

import pdb
pdb.set_trace()

Оттуда было видно что из модуля sysconfig приходит разная информация об окружении при запуске общесистемного python и из venv окружения.

Подробно можно увидеть если запустить следующие команды:

python -m sysconfig | grep script
test-env/bin/python -m sysconfig | grep script

Я вспомнил что у меня есть тестовый стенд, и попробовал воспроизвести проблему на нём. При установке пакета python-jarowinkler проблем не было. Значит есть разница в системном окружении, понял я.

Было установленно что есть разница в пакетах ruff. К слову, ruff это очень быстрый линтер и инструмент для проверки форматирования кода python.

На проблемной системе были внешние пакеты связанные с ruff:

> yay -Qs ruff
local/python-pytest-ruff 0.3.2-1
    Pytest plugin to check ruff requirements
local/python-ruff 0.4.3-1
    An extremely fast Python linter, written in Rust
local/ruff 0.4.3-1
    An extremely fast Python linter, written in Rust

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

yay -Rnsu python-pytest-ruff python-ruff ruff

Сборка начала проходить yay -S python-jarowinkler.

Я вспомнил про первый проблемный пакет - python-async_generator. Скорее всего с ним такая же история.

При сборке данного пакета возникала следующая ошибка:

---------- coverage: platform linux, python 3.12.3-final-0 -----------
Name                                             Stmts   Miss Branch BrPart  Cover
----------------------------------------------------------------------
async_generator/__init__.py                          4      0      0      0 100.0%
async_generator/_impl.py                           205     22     64      5  87.0%
async_generator/_tests/__init__.py                   0      0      0      0 100.0%
async_generator/_tests/conftest.py                  20      0      8      0 100.0%
async_generator/_tests/test_async_generator.py     589      4    172      7  98.6%
async_generator/_tests/test_util.py                152      2     80      1  98.7%
async_generator/_util.py                            55      1     20      1  97.3%
async_generator/_version.py                          1      0      0      0 100.0%
----------------------------------------------------------------------------------
TOTAL                                             1026     29    344     14  96.3%

======================= mypy ======================
Found 9 errors in 3 files (checked 10 source files)
============== short test summary info ============
FAILED async_generator/__init__.py::mypy-status
FAILED async_generator/_impl.py::mypy
FAILED docs/source/conf.py::mypy
FAILED setup.py::mypy
==== 4 failed, 50 passed, 48 warnings in 36.01s ===
==> ERROR: A failure occurred in check().
    Aborting...
 -> error making: python-async_generator

В ошибочных строках фигурируют модули mypy-status и mypy. Ищем установленные пакеты с такими именами:

> yay -Qs mypy
local/mypy 1.10.0-1
    Optional static typing for Python 2 and 3 (PEP484)
local/python-mypy_extensions 1.0.0-4
    Experimental type system extensions for programs checked with the mypy typechecker
local/python-pytest-mypy 0.10.3-6
    Mypy static type checker plugin for Pytest

Удаляем лишние пакеты - yay -R python-pytest-mypy mypy

Пакет python-mypy_extensions являлся зависимостью другого пакета, поэтому его оставил.

После удаления сборка начала проходить - yay -S python-async_generator