Skip to content

setup_requires and install_requires don't play nicely together #209

@ghost

Description

Originally reported by: msabramo (Bitbucket: msabramo, GitHub: msabramo)


What's the latest thinking on how to deal with a package that has setup_requires=['foo'] and install_requires=['foo']?

My observation is that this causes setuptools to download a foo.egg file to the current directory, install_requires then decides it doesn't need to install the package, and then the software craps out when it tries to import it because it can't import from the egg :-(

For example, I work on a project that uses pbr. The setup.py looks like this:

import setuptools

setuptools.setup(
    setup_requires=['pbr'],
    install_requires=['pbr'],
    pbr=True)

Now starting with a clean virtualenv and no .egg files in the current directory, here's what I see (with pip 1.5.5 and setuptools 3.4.4):

$ python setup.py install

Installed /Users/marca/dev/git-repos/jenkins-job-builder/pbr-0.8.0-py2.7.egg
running install
...
Requirement already satisfied (use --upgrade to upgrade): pbr>=0.5.21,<1.0 in ./pbr-0.8.0-py2.7.egg
...

$ ls -ld *.egg
drwxr-xr-x  4 marca  staff  136 May 23 08:56 pbr-0.8.0-py2.7.egg/

OK, fine. pbr wasn't available in the virtualenv so setuptools downloaded a .egg so that it could use it to do setupy things.

Not so fine is that because the .egg file was already present because it was downloaded in the setup_requires phase, the setuptools install_requires logic decided that it didn't have to install pbr in the virtualenv (I guess at this point the .egg file is on the PYTHONPATH so it can be imported?). This is not good because code outside of setuptools doesn't know how to do anything with that .egg:

$ python -c 'import jenkins_jobs.version'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "jenkins_jobs/version.py", line 18, in <module>
    from pbr.version import VersionInfo
ImportError: No module named pbr.version

So this is not good.

Ideas:

  1. Maybe setuptools puts the .egg file on the PYTHONPATH so that it can use it while creating metadata and such. Maybe when it's done, it can remove the .egg from the PYTHONPATH so that the install_requires code doesn't see the package as importable and then it would install the package in the virtualenv? A variation on the idea is to leave the PYTHONPATH but delete the .egg file (or download the egg into a temp directory that gets cleaned up as soon as it's not needed). Drawback here is that we download the package twice -- once for setup_requires and once for install_requires.
  2. Have a special case in the setup_requires logic so that if install_requires of the same dependency is present, instead of downloading the .egg, it simply installs the package in a more "permanent" place on the PYTHONPATH (site-packages)?

@jaraco: What do you think?


Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions