Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you set conditional dependencies for Python 2 and 3 in setuptools?

Tags:

When releasing a Python egg with support for both Python 2 and 3, can you specify dependencies that change depending on which version you're using? For example, if you use dnspython for Python 2, there is a Python 3 version that is called dnspython3.

Can you write your setuptools.setup() function in such a way that your egg is useable to both versions if that is the only roadblock, i.e., if you have run 2to3 to ensure that the rest of your library is compatible with both versions.

I have looked through these documents and can't seem to find the answer this question:

  • Porting Python 2 Code to Python 3
  • setuptools' Declaring Dependencies
  • Travis CI Python documentation
  • pip Requirements Files
like image 746
Michael Herold Avatar asked Oct 30 '13 02:10

Michael Herold


People also ask

Does pip depend on setuptools?

In Fedora, our pip package Recommends setuptools. Practically that means: Majority of users who install pip will get setuptools by default. Users can explicitly uninstall setuptools after installing pip or exclude setuptools when installing pip.

What does setuptools do Python?

Setuptools is a package development process library designed to facilitate packaging Python projects by enhancing the Python standard library distutils (distribution utilities). It includes: Python package and module definitions. Distribution package metadata.

Does Python come with setuptools?

Usually, Yes. the setuptools is not part of the python vanilla codebase, hence not a vanilla modules. python.org installers or mac homebrew will install it for you, but if someone compile the python by himself or install it on some linux distribution he may not get it and will need to install it by himself.


2 Answers

Bogdan's comment helped point me on my way. I thought I'd post what I did in case anyone else has my problem.

For the example in the question, I did exactly what Bogdan suggested:

setup.py

import sys  if sys.version_info[0] == 2:     dnspython = "dnspython" elif sys.version_info[0] == 3:     dnspython = "dnspython3"  setup(     ... <snip> ...     install_requires=[         "%s >= 1.10.0" % dnspython,     ] ) 

However, this still has the issue of pip-style dependencies for Travis and tox (I'm not sure why, given Bogdan's second comment). To work around this problem, I created two extra requirements files, as shown below:

requirements-py2.txt

dnspython>=1.10.0 

requirements-py3.txt

dnspython3>=1.10.0 

Then for Travis, I made use of some environment variables that I gleaned from the tornado .travis.yml:

.travis.yml

install:   - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install -r requirements-py2.txt --use-mirrors; fi   - if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install -r requirements-py3.txt --use-mirrors; fi 

Lastly, for tox, I had to use a rather hackish method of using these multiple requirements files.

tox.ini

[testenv:py27] deps = -rrequirements-py2.txt  [testenv:py33] deps = -rrequirements-py3.txt 
like image 176
Michael Herold Avatar answered Oct 25 '22 12:10

Michael Herold


The setup.py portion of the answer by @Harold did not work for me: pip install distribution.whl still installs the dependency that the if code says it shouldn't. I will further update this answer in a few days when I have this issue resolved.

Here are some links that may provide additional ways to deal with this ():

  • Wheel docs section explaining conditional dependencies: not completely clear but gives a hint of what to do
  • Example on github
  • Blog post
like image 30
Oliver Avatar answered Oct 25 '22 11:10

Oliver