Reputation: 1021
I work on a project where two of the dependencies require conflicting dependencies. In particular the project requires eli5==0.8
which requires tabulate>=0.7.7
and invocations==1.4.0
which requires tabulate==0.7.5
.
I can still install the project, import the module and run the code, however when I try to create an entry point via setup.py
and run it I encounter the following failure:
Traceback (most recent call last):
File "/Users/user/.pyenv/versions/3.6.6/envs/repro/lib/python3.6/site-packages/pkg_resources/__init__.py", line 574, in _build_master
ws.require(__requires__)
File "/Users/user/.pyenv/versions/3.6.6/envs/repro/lib/python3.6/site-packages/pkg_resources/__init__.py", line 892, in require
needed = self.resolve(parse_requirements(requirements))
File "/Users/user/.pyenv/versions/3.6.6/envs/repro/lib/python3.6/site-packages/pkg_resources/__init__.py", line 783, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (tabulate 0.8.2 (/Users/user/.pyenv/versions/3.6.6/envs/repro/lib/python3.6/site-packages), Requirement.parse('tabulate==0.7.5'), {'invocations'})
Even if I try to pin the version of tabulate
directly in my setup.py
I get the same failure.
How are situations like this resolved?
As extra information. I'm using Python 3.6.6 and the following minimal python module and setup.py
can be used to reproduce the problem.
a_script.py
:
def cli():
print('Hello world')
if __name__ == '__main__':
cli()
setup.py
:
from setuptools import setup
setup(
name='repro',
version='0.1',
py_modules=['a_script'],
install_requires=[
'eli5==0.8',
'invocations==1.4.0',
# 'tabulate==0.8.2'
],
entry_points='''
[console_scripts]
repro=a_script:cli
''',
)
Upvotes: 1
Views: 629
Reputation: 1344
I recently resolved a situation like this by patching the package's METADATA
file using a unified diff, made using git diff
, and GNU patch.
This is an effective solution if you are trying to deploy an application, but if you are writing a library, then only effective solution is to go bother the maintainers and tell them to relax their constraints, or eliminate your reliance on their work.
Upvotes: 1
Reputation: 149075
Welcome to the world of dependencies hell!
I know no clean way to solve this. Some hints for a simple workaround:
If none of the above worked, you will have to build a custom version of one of the conflicting projects (assuming at least one is open source). Ideally you should clone the oldest (here invocation
), set its version to a local version identifier (here for example 1.4.0+tab0-7) and change its own requirement to accept a tabulate>=0.7.7
. then use that special version and again throughly test that all your use cases pass with that.
If all the tests of the modified project still pass, you could try to propose its maintainer to change their version requirement for a future release, for example by proposing a patch / pull request based on the current development tree.
Upvotes: 1