Issue #141 open

setup_requires feature does not handle multiple versions

Martin Scherer
created an issue

This seems somehow related to issue323 in distribute.

Why is a not met requirement not simply installed local as an egg and then inserted to path, if it is required via setup_requires?

Scenario: system wide installation of package A, version 1.0 (which can not be upgraded as non administrative user) setup_requires=[('A > 1.0')]

Instead of building A > 1.0 before the build process starts, pkg_resources throws a VersionConflict:

 File "build/bdist.linux-x86_64/egg/pkg_resources.py", line 576, in resolve
    dist = best[req.key] = env.best_match(req, self, installer)
pkg_resources.VersionConflict: (numpy 1.6.2 (/usr/lib/pymodules/python2.7), Requirement.parse('numpy>=1.8'))

Is this behaviour intended? And if that is the case it should be somehow documented, because it is not intuitive.

Comments (22)

  1. Erik Bray

    Wow, totally forgot about this issue, but was led back to it today due to a new, related issue. I will open a new issue for this, but in short if two versions of the same package belonging to a namespace package are on two different sys.path entries, for example

    sys.path = [
        ...,
        custom/path/to/foo.bar-0.1.egg,
        ...,
        site-packages/foo.bar-0.1.egg
    ]
    

    if I import foo.bar this can sometimes result in the version in site-packages being imported rather than the version earlier in sys.path.

  2. Erik Bray

    That reminds me, I still need to submit my fix for #207. I've been busy with work and got completely distracted from that. I'll see if I can resolve this.

    I'm a little surprised though, since this fix resolved the issue for me.

  3. Erik Bray

    Do you think it would fix it to use a different environment, in that while loop, for each distribution in the requirements? (at least if env=None was passed in to the function--otherwise it should look for all requirements in the same Environment, I think).

  4. Jason R. Coombs

    I apologize I haven't had a chance to look at this. I did look at it briefly a few days ago, and my instinct was to do the same - use an empty environment for each iteration. I'm yet unsure about the other consequences of that approach, but I'll look into that more later.

  5. Erik Bray

    I've never not been a bit confused about the different roles of Environment and WorkingSet. But if I understand correctly the Environment is mostly just for locating distributions, while the WorkingSet is a collection of currently active distributions. The same WorkingSet is being reused throughout, which I think is more important insofar as keeping track of which distributions are currently found.

  6. Laurent Mazuel

    Hi,

    This bug is really annoying :(. I used 2 hours this morning to figure out why my jenkins did not want to compile but my personal laptop did... In my case, if I wrote:

    install_requires=["requests >= 2.4.1", "Flask >= 0.10.1"],
    

    If Flask is installed on the system, it works (my laptop). If Flask is not (my jenkins), it fails with:

    pkg_resources.VersionConflict: (requests 2.2.1 (/usr/lib/python3/dist-packages), Requirement.parse('requests>=2.4.1'))
    

    In a debugger, I saw that resolve begins with "Flask" and depending of its presence (or not) in the system, set the env and ws the way requests install will fail or not...

    I can pass through the bug using

    install_requires=["Flask >= 0.10.1", "requests >= 2.4.1"],
    

    Actually, puts the conflicting libs at the end makes resolve works since env and ws are None when needed.

    Tested with setuptools 3.3 (ubuntu 14.04) and 6.0.2 (currently last from pip)

  7. Jason R. Coombs

    I'm raising the priority on this one. Would someone be willing to present the submitted patch as a pull request? Due to their high visibility in the UI, a PR almost always forces a first-look when I find time to work on setuptools.

  8. Log in to comment