1

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)?

fgoudra
  • 751
  • 8
  • 23

0 Answers0