7

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').)

Dan Gittik
  • 3,460
  • 3
  • 17
  • 24
  • By default `tox` runs in the same directory where `tox.ini` (and hence your README and VERSION) reside so there should be no problems. Can we see your `tox.ini`? – phd Dec 21 '17 at 15:40

2 Answers2

11

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.

Dan Gittik
  • 3,460
  • 3
  • 17
  • 24
3

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.