Installation problem when using as a dependency with setuptools
postlund opened this issue · comments
I'm using srptools (great project btw) as a dependency in my library (pyatv) but currently I'm experiencing some issues during installation. The stack trace looks like this:
pyatv$ python setup.py develop
running develop
...
Searching for srptools>=0.1.1
Reading https://pypi.python.org/simple/srptools/
Downloading https://pypi.python.org/packages/d2/19/4d9beec46e82d17249517291d0564c9eb6773c51015c278fef97312e63e3/srptools-0.1.1.tar.gz#md5=811c38f3e45039a8973cc6820d3ce94f
Best match: srptools 0.1.1
Processing srptools-0.1.1.tar.gz
Writing /tmp/easy_install-7pdx2q5r/srptools-0.1.1/setup.cfg
Running srptools-0.1.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-7pdx2q5r/srptools-0.1.1/egg-dist-tmp-dzq732f7
Traceback (most recent call last):
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 158, in save_modules
yield saved
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 199, in setup_context
yield
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 254, in run_setup
_execfile(setup_script, ns)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 48, in _execfile
exec(code, globals, locals)
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/setup.py", line 6, in <module>
# Read in version without importing pyatv
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/srptools/__init__.py", line 1, in <module>
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/srptools/context.py", line 4, in <module>
ImportError: No module named 'six'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "setup.py", line 48, in <module>
'Topic :: Home Automation',
File "/usr/lib/python3.5/distutils/core.py", line 148, in setup
dist.run_commands()
File "/usr/lib/python3.5/distutils/dist.py", line 955, in run_commands
self.run_command(cmd)
File "/usr/lib/python3.5/distutils/dist.py", line 974, in run_command
cmd_obj.run()
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/develop.py", line 36, in run
self.install_for_development()
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/develop.py", line 150, in install_for_development
self.process_distribution(None, self.dist, not self.no_deps)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 746, in process_distribution
[requirement], self.local_index, self.easy_install
File "/home/pista/git/pyatv/lib/python3.5/site-packages/pkg_resources/__init__.py", line 826, in resolve
dist = best[req.key] = env.best_match(req, ws, installer)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1092, in best_match
return self.obtain(req, installer)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1104, in obtain
return installer(requirement)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 673, in easy_install
return self.install_item(spec, dist.location, tmpdir, deps)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 699, in install_item
dists = self.install_eggs(spec, download, tmpdir)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 880, in install_eggs
return self.build_and_install(setup_script, setup_base)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 1119, in build_and_install
self.run_setup(setup_script, setup_base, args)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/command/easy_install.py", line 1105, in run_setup
run_setup(setup_script, args)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 257, in run_setup
raise
File "/usr/lib/python3.5/contextlib.py", line 77, in __exit__
self.gen.throw(type, value, traceback)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 199, in setup_context
yield
File "/usr/lib/python3.5/contextlib.py", line 77, in __exit__
self.gen.throw(type, value, traceback)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 170, in save_modules
saved_exc.resume()
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 145, in resume
six.reraise(type, exc, self._tb)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/pkg_resources/_vendor/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 158, in save_modules
yield saved
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 199, in setup_context
yield
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 254, in run_setup
_execfile(setup_script, ns)
File "/home/pista/git/pyatv/lib/python3.5/site-packages/setuptools/sandbox.py", line 48, in _execfile
exec(code, globals, locals)
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/setup.py", line 6, in <module>
# Read in version without importing pyatv
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/srptools/__init__.py", line 1, in <module>
File "/tmp/easy_install-7pdx2q5r/srptools-0.1.1/srptools/context.py", line 4, in <module>
ImportError: No module named 'six'
The problem itself is quite simple. Since you are importing VERSION from srptools in setup.py, that will basically evaluate everything in that module. So context will be pulled in which in turn requires "six". Since this package is not part of setup_requires, it will not yet have been installed at this stage. A suggestion to work-around this is to place version in a separate file (that does not depend on anything) and just pull that one in. I have done a similar thing in my library:
https://github.com/postlund/pyatv/blob/master/setup.py
https://github.com/postlund/pyatv/blob/master/pyatv/const.py
I assume adding six to setup_requires might work as well, but I have not tried that myself. Is this anything that can be fixed soon? It's a bit of a usage blocker.
Thank you for the report.
Six is added into setup_requires
.
Thanks for the quick reply! As I said, I'm not 100% sure that setup_requires works that way as I have not used it. I suspect it is for other things. Some logically reasoning about the issue concludes that the import-line that causes an issue here must still be evaluated before setuptools is configured. So I do not think it will work and AFAIK it's only possible to test it out once it's on pypi. It must be downloadable by pip.
Just tried it out in a clean venv and it doesn't work (setup.py cannot be evaluated):
$ git clone https://github.com/idlesign/srptools/
$ cd srptools
$virtualenv -p python3.5 .
Running virtualenv with interpreter /usr/bin/python3.5
Using base prefix '/usr'
New python executable in /home/pista/git/srptools/bin/python3.5
Also creating executable in /home/pista/git/srptools/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
$ source bin/activate
$ python setup.py develop
Traceback (most recent call last):
File "setup.py", line 6, in <module>
from srptools import VERSION
File "/home/pista/git/srptools/srptools/__init__.py", line 1, in <module>
from .context import SRPContext
File "/home/pista/git/srptools/srptools/context.py", line 4, in <module>
from six import integer_types, PY3
ImportError: No module named 'six'
So unless a system wide installation of python is used and six is installed there, it gives this issue.
I see. Let's make it a separate module.
It's still the same issue I'm afraid:
$ python setup.py develop
Traceback (most recent call last):
File "setup.py", line 6, in <module>
from srptools.version import VERSION
File "/home/pista/git/srptools/srptools/__init__.py", line 1, in <module>
from .context import SRPContext
File "/home/pista/git/srptools/srptools/context.py", line 4, in <module>
from six import integer_types, PY3
ImportError: No module named 'six'
When you import anything from your library, even a specific module, the __init__.py
file will be loaded as well. So it's basically the same situation as before. That's why I do this hack:
# Read in version without importing pyatv
# http://stackoverflow.com/questions/6357361/alternative-to-execfile-in-python-3
exec(compile(open('pyatv/const.py', "rb").read(), 'pyatv/const.py', 'exec'))
The details are on SO.
Sorry, I'm kind of in a rush for last three days.
I shall see what exactly is going on there in a day or two.
No worries, take the time you need! Personal life comes first!
We'll do it in a slightly different manner with re
, since:
exec
seems to be an overkill;- I'd like to keep compatibility with
release
command ofmakeapp
.
Should work now.
Sure, you do it as you please 😄 I can confirm that it works now! Would be really good if you could make a release to pypi as well, so it's possible to use srptools as a dependency in other projects.
0.2.0 is out.
Thank you. Closing this.
Top notch, thank you very much!