Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying setup.py Dependencies with Tox

setup.py often depends on a couple external files, most notably README.md for long_description, and maybe VERSION for version. e.g.

root = os.path.dirname(os.path.abspath(__file__))
setuptools.setup(
    name             = 'package',
    version          = open(os.path.join(root, 'VERSION')).read().strip(),
    description      = 'A Simple Package',
    long_description = open(os.path.join(root, 'README.md')).read().strip(),
    # ...
)

However, when trying to run tests with tox on such a package, I get the following error:

ERROR: invocation failed (exit code 1), logfile: 
.tox/py36/log/py36-6.log
ERROR: actionid: py36
msg: installpkg
cmdargs: 
['.tox/py36/bin/pip', 'install', '-U', '--no-deps', '.tox/dist/package-0.1.0.zip']

Processing ./.tox/dist/package-0.1.0.zip
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "setup.py", line 10, in <module>
        version          = open(os.path.join(root, 'VERSION')).read().strip(),
    FileNotFoundError: [Errno 2] No such file or directory: 'VERSION'

(Or a similar message with README.md). Obviously, tox only copies setup.py, and when it tries to run it, its dependencies are missing and it doesn't work.

I went over the documentation, but I can't seem to find a way to tell tox to copy these files. Is there a way to do it?

EDIT

Here's my directory structure and relevant files:

$ ls
package/   tests/   README.md    VERSION   setup.py    tox.ini

$ cat tox.ini
[tox]
envlist = py36
[testenv]
deps     = pytest
commands = pytest tests

$ cat setup.py
import os
import setuptools
root = os.path.dirname(os.path.abspath(__file__))
setuptools.setup(
    name             = 'package',
    version          = open(os.path.join(root, 'VERSION')).read().strip(),
    description      = 'A Simple Package',
    long_description = open(os.path.join(root, 'README.md')).read().strip(),
    packages         = setuptools.find_packages(),
)

(The same happens if I use a relative path, e.g. open('README.md').)

like image 949
Dan Gittik Avatar asked Dec 21 '17 12:12

Dan Gittik


2 Answers

Turns out it's not a tox problem, but a setuptools one (or rather, me not using it correctly). I'm posting the answer here just in case somebody else runs into similar problems in the future.

tox creates a source distribution (i.e. python setup.py sdist), and then installs it in a virtual environment, where it then runs the tests. It's this distribution that's missing the VERSION and README.md files, because setuptools doesn't include any non-standard files by default. To wit:

# create a source distribution
$ python setup.py sdist

# extract it
$ cd dist/
$ tar xfz package-0.1.0.tar.gz

# check it out
$ ls package-0.1.0
package    package.egg-info   PKG-INFO   setup.cfg   setup.py

# no VERSION or README.md :(

To include non-standard files, add a MANIFEST.in file like this:

include VERSION
include README.md

Which tells setuptools to include these files in the distribution, and makes tox work as expected.

like image 70
Dan Gittik Avatar answered Sep 22 '22 18:09

Dan Gittik


What version of setuptools were you using?

I had a similar issue and upgrading setuptools fixed it.

It seems that including README.md is done automatically as of version 36.4.0. However the VERSION file would have to be included in the MANIFEST.in file.

like image 36
Hagalín Ásgrímur Guðmundsson Avatar answered Sep 23 '22 18:09

Hagalín Ásgrímur Guðmundsson