Я столкнулся с ошибкой при попытке установить и протестировать мой пакет.
Ошибка была вызвана конфликтующими версиями транзитивных зависимостей двух пакетов - одного в setup_requires
(twine
) и другого в install_requires
(tensorflow
).
Оба транзитивно зависят от bleach
, каждый со своей версией.
Установка пакета с pip install -e .
или python setup.py develop
работает как положено.
При запуске python setup.py test
возникает ошибка (примечание: это происходит только при запуске тестов после установки . Если пакет не был установлен первым, ошибки нет).
Traceback (most recent call last):
File "setup.py", line 3, in <module>
setup()
File "/usr/local/lib/python3.6/site-packages/setuptools/__init__.py", line 145, in setup
return distutils.core.setup(**attrs)
File "/usr/local/lib/python3.6/distutils/core.py", line 148, in setup
dist.run_commands()
File "/usr/local/lib/python3.6/distutils/dist.py", line 955, in run_commands
self.run_command(cmd)
File "/usr/local/lib/python3.6/distutils/dist.py", line 974, in run_command
cmd_obj.run()
File "/root/test/.eggs/pytest_runner-4.4-py3.6.egg/ptr.py", line 189, in run
with self.project_on_sys_path():
File "/usr/local/lib/python3.6/contextlib.py", line 81, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.6/site-packages/setuptools/command/test.py", line 166, in project_on_sys_path
require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 900, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 791, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (bleach 3.1.0 (/root/test/.eggs/bleach-3.1.0-py3.6.egg), Requirement.parse('bleach==1.5.0'), {'tensorboard'})
Шаги для воспроизведения
Я получаю сообщение об ошибке с этой минимальной структурой пакета:
my-package
|-- src/
| |-- module.py (empty)
|-- setup.py
|-- setup.cfg
setup.cfg выглядит так:
[metadata]
name = test
version = 0.0.1
[options]
package_dir=
= src
packages=find:
setup_requires =
setuptools >= 40.0.0
pip >= 10
pytest-runner >= 2.0
twine >= 1.0.0
install_requires =
tensorflow == 1.6.0
tests_require =
pytest >=3.0, <4.0
[options.packages.find]
where=src
[aliases]
test=pytest
setup.py выглядит так:
from setuptools import setup
setup()
Шаги:
- Пробег
pip install -e .
- Выполнить
python setup.py test
Окружающая среда:
python:3.6
Изображение Docker
Что я думаю, что происходит
Насколько я могу судить, при запуске команд (как установка, так и тестирование) устанавливаются пакеты из setup_requires
, а файлы egg помещаются в каталог .eggs.
При запуске python setup.py test
setuptools устанавливает все пакеты из install_requires
, но видит, что уже существует яйцо для одной из зависимостей, и использует его.
Я не уверен, каков точный механизм.
Возможные решения
- Использовать более новую версию tenorflow. Это решило конфликт
- Или: удалить
twine
из setup_requires
- я понял, что это не требуется для установки
- Или: не устанавливайте пакет локально. Только запустить
python setup.py test
Вопросы
Хотя мне удалось решить проблему в этом конкретном случае, я все же хотел бы узнать больше о том, что вызвало ее в первую очередь.
- В какой момент создается каталог .eggs?
- Почему установка работает нормально, но тесты не пройдены?
- Почему тесты дают сбой только после установки?
- Есть ли способ предотвратить конфликт?