I'm trying to make a setup script for a python package. For an easy setup, I would like that all the dependencies be installed using setuptools. However, I found some difficulties when installing these packages this way: numpy
, matplotlib
, scipy
, netcdf4
, pandas
and pymatgen
. The numpy problem was already asked in this SO post, matplotlib here, pandas here and scipy here. So it seems it is a recurring problem though I have found a workaround for each of these packages which is to use pip
in the setup script:
from setuptools import pip
import pip
for package in ("numpy", "matplotlib", "scipy", "netcdf4", "pandas",
"pymatgen"):
pip.main(["install", package])
setup(name="package_name",
...)
The problem is that when another package requires this package, the fact that pip is called to install the dependencies, setuptools raises a weird SandBoxViolation Error which prevent the use of the pip.main function. Here's an example traceback:
Traceback (most recent call last):
File ".../lib/python3.6/site-packages/pip/basecommand.py", line 215,
in main
status = self.run(options, args)
File ".../lib/python3.6/site-packages/pip/commands/install.py", line 335, in run
wb.build(autobuilding=True)
File ".../lib/python3.6/site-packages/pip/wheel.py", line 749, in build
self.requirement_set.prepare_files(self.finder)
File ".../lib/python3.6/site-packages/pip/req/req_set.py", line 380, in prepare_files
ignore_dependencies=self.ignore_dependencies))
File ".../lib/python3.6/site-packages/pip/req/req_set.py", line 554, in _prepare_file
require_hashes
File ".../lib/python3.6/site-packages/pip/req/req_install.py", line 278, in populate_link
self.link = finder.find_requirement(self, upgrade)
File ".../lib/python3.6/site-packages/pip/index.py", line 465, in find_requirement
all_candidates = self.find_all_candidates(req.name)
File ".../lib/python3.6/site-packages/pip/index.py", line 423, in find_all_candidates
for page in self._get_pages(url_locations, project_name):
File ".../lib/python3.6/site-packages/pip/index.py", line 568, in _get_pages
page = self._get_page(location)
File ".../lib/python3.6/site-packages/pip/index.py", line 683, in _get_page
return HTMLPage.get_page(link, session=self.session)
File ".../lib/python3.6/site-packages/pip/index.py", line 792, in get_page
"Cache-Control": "max-age=600",
File ".../lib/python3.6/site-packages/pip/_vendor/requests/sessions.py", line 488, in get
return self.request('GET', url, **kwargs)
File ".../lib/python3.6/site-packages/pip/download.py", line 386, in request
return super(PipSession, self).request(method, url, *args, **kwargs)
File ".../lib/python3.6/site-packages/pip/_vendor/requests/sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File ".../lib/python3.6/site-packages/pip/_vendor/requests/sessions.py", line 596, in send
r = adapter.send(request, **kwargs)
File ".../lib/python3.6/site-packages/pip/_vendor/cachecontrol/adapter.py", line 37, in send
cached_response = self.controller.cached_request(request)
File ".../lib/python3.6/site-packages/pip/_vendor/cachecontrol/controller.py", line 202, in cached_request
self.cache.delete(cache_url)
File ".../lib/python3.6/site-packages/pip/download.py", line 302, in delete
return super(SafeFileCache, self).delete(*args, **kwargs)
File ".../lib/python3.6/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py", line 107, in delete
os.remove(name)
File ".../lib/python3.6/site-packages/setuptools/sandbox.py", line 314, in wrap
path = self._remap_input(name, path, *args, **kw)
File ".../lib/python3.6/site-packages/setuptools/sandbox.py", line 456, in _remap_input
self._violation(operation, os.path.realpath(path), *args, **kw)
File ".../lib/python3.6/site-packages/setuptools/sandbox.py", line 411, in _violation
raise SandboxViolation(operation, args, kw)
setuptools.sandbox.SandboxViolation: SandboxViolation:
remove('/.../Library/Caches/pip/http/8/f/4/a/1/8f4a19894a92f9
63886c9b755abcf90542da3c3c8283d3bebe3650b2',) {}
The package setup script has attempted to modify files on your system
that are not within the EasyInstall build area, and has been aborted.
This package cannot be safely installed by EasyInstall, and may not
support alternate installation locations even if you run its setup
script by hand. Please inform the package's author and the EasyInstall
maintainers to find out if a fix or workaround is available.
A workaround for this is to use the pip.main
method for this package also...
So I conclude that the use of the pip.main
function should be avoided but I don't know an easy way to install the problematic dependencies. So my question is: how should the problematic dependencies like numpy
, scipy
, pymatgen
, etc. be handled in order to install them automatically (without pip
, just with setuptools for instance)? If it is not possible to avoid the usage of pip
, how should the package calling pip
in it's setup should be installed (in order to avoid the SandboxViolation errors)?