#20218: Use pip to install Python depedencies
---------------------------+-----------------------
Reporter: embray | Owner:
Type: enhancement | Status: new
Priority: minor | Milestone:
Component: build | Keywords:
Merged in: | Authors:
Reviewers: | Report Upstream: N/A
Work issues: | Branch:
Commit: | Dependencies:
Stopgaps: |
---------------------------+-----------------------
Work has already been done--for example in #19187--on using `pip` for
`sage -i` where appropriate. However, a normal build of sage does not use
`pip` for installing any Python spkgs; rather, they run `python setup.py
install` which until recently has always been *the* way to install Python
packages.
I can suggest several reasons why `pip` should be used instead of this
method. To be clear--as many people think of `pip` as a tool for
installing packages from the internet--this is not strictly the case.
`pip` can be used to install an already downloaded tarball, or even
straight from a source tree unpacked from a tarball or checked out from
VCS. The typical way to do this is to change directories to the directory
containing the `setup.py` script and running `pip install .`. This still
ultimately calls `setup.py install`, among other `setup.py` commands, but
with the right incantations to perform a pip-style flat install. Now, why
is this preferable?
1. Future-compatibility. One of the goals that the Python packaging
community has been working toward over the past several years has been to
decouple Python package installation from build system. Traditionally
`setup.py` provided both a build program and an installation program. At
best it will still stick around as a build program, but its use for
installation is being discouraged. There is now finally a PEP
(http://legacy.python.org/dev/peps/pep-0516/), still very much in draft
state, specifically concerning this decoupling. Under this new regime
`pip` will not likely be the *only* software for installing Python
packages, but the assumption can no longer be that there is a `setup.py`
script at all.
2. `pip` avoids using `easy_install`. `easy_install` is an older
installation program for Python packages that was bundled with setuptools
--when a Python project uses setuptools in its `setup.py`, the `setup.py
install` command invokes `easy_install` *by default*. The behavior of
`easy_install` is to install the package as an egg archive/directory.
`easy_install` has several disadvantages, of which this is just one, but
there are a couple reasons that this alone is a problem:[[br]][[br]]
a. Every .egg requires a `sys.path` entry, hence difficult to debug
paths that look like this:
{{{
#!python
>>> pprint(sys.path)
['',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/setuptools-18.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Cython-0.23.3-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/MarkupSafe-0.23-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Jinja2-2.7.3-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/six-1.10.0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Pygments-2.0.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Sphinx-1.2.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/zope.interface-4.1.3-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Twisted-15.5.0-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-packages
/pytz-2013b0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Babel-2.1.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Werkzeug-0.11.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/speaklater-1.3-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/python_openid-2.2.5-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/itsdangerous-0.24-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask-0.10.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask_Silk-0.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask_AutoIndex-0.5-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask_Babel-0.9-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask_OpenID-1.2.5-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/Flask_OldSessions-0.10-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/webassets-0.11.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/sagenb-0.11.6.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/backports.ssl_match_hostname-3.4.0.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/certifi-14.5.14-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/tornado-4.1-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/setuptools_scm-1.7.0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/path.py-7.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/pickleshare-0.5-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/simplegeneric-0.8.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/decorator-4.0.6-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/networkx-1.10-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/python_dateutil-2.2-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/cycler-0.9.0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/matplotlib-1.5.0-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/jsonschema-2.4.0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/mistune-0.5.1-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/pip-6.1.1-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/pkgconfig-1.1.0-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/singledispatch-3.4.0.3-py2.7.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-
packages/rpy2-2.7.5-py2.7-linux-x86_64.egg',
'/home/iguananaut/src/sagemath/sage/local/lib/python',
'/home/iguananaut/src/sagemath/sage/local/lib/python/site_packages',
'/home/iguananaut/src/sagemath/sage/local/lib/python27.zip',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/plat-linux2',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-tk',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-old',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-dynload',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-packages']
}}}
With the flat install style used by `pip`, and now more generally
favored, the `sys.path`, with no eggs, would be simply:
{{{
#!python
>>> pprint(sys.path)
['',
'/home/iguananaut/src/sagemath/sage/local/lib/python',
'/home/iguananaut/src/sagemath/sage/local/lib/python27.zip',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/plat-linux2',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-tk',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-old',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/lib-dynload',
'/home/iguananaut/src/sagemath/sage/local/lib/python2.7/site-packages']
}}}
which is certainly easier to read and reason about.[[br]][[br]]
b. The egg import mechanism requires writing to a common file during egg
installation--easy-install.pth. This causes problems in parallel
installations, requiring patches to setuptools. The flat install style
used by pip has no such problems--there is a no single common file written
to by pip during installation of packages (other than maybe the log file,
which is only for debugging purposes).
As I explained in
[http://trac.sagemath.org/timeline?from=2016-02-25T10%3A23%3A37-08%3A00&precision=second
this comment], when a Python package is installed with `pip`, `pip`
actually slips setuptools into the installation process, whether the
package uses it explicitly or not. There are reasons for this not worth
going into now. This is no problem for the vast majority of cases. The
only exception I know of is that setuptools doesn't handle the
`data_files` option well when `--prefix` is changed. As far as I can tell
this is only a problem for sage itself and possibly for sagetex, but these
don't even use `setuptools` in the first place, so until we have a
workaround for that it does no harm if we keep using `setup.py install`
for those packages, if nothing else works.
Most of the rest of the Python packages included by default in a Sage
build (I haven't checked all of -optional yet) already use setuptools. I
checked the setup.py of all the rest that don't explicitly use setuptools
--these include `docutils`, `mpmath`, `pexpect`, `ptyprocess`, `Pycrypto`,
`pyparsing`, `pyzmq`, `scipy`, and all packages from the Jupyter team
(`ip*`, `jupyter*`, `np*`, `notebook`, `traitlets`).
Most of these packages are known by me (from personal experience) to work
fine with pip. Looking at the setup.py scripts of the rest of them, most
of them are fairly trivial and should work fine.
TL;DR, with the exceptions of sage and sagetex (pending work like #20108),
as well as pip itself the `spkg-install` scripts for Python packages
should change `setup.py install` commands to `pip install .`. Their
dependencies would also have to be updated to require pip to be installed
first.
At the same time the "uninstall" commands in those scripts can be changed
to use `pip uninstall`.
--
Ticket URL: <http://trac.sagemath.org/ticket/20218>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.