Commit b2382a4e authored by PJ Eby's avatar PJ Eby

Simplify non-root install process and improve Mac OS docs for it. Support

.pth files and legacy packages possibly being symlinks, and ensure that
overwrites don't follow the symlink.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041229
parent b577c941
...@@ -673,15 +673,22 @@ Non-Root Installation ...@@ -673,15 +673,22 @@ Non-Root Installation
If you want to use EasyInstall on a computer where you do not have write access If you want to use EasyInstall on a computer where you do not have write access
to Python's main ``site-packages`` directory, you may need to set up an to Python's main ``site-packages`` directory, you may need to set up an
alternate ``PYTHONHOME`` location, which allows Python to read a second alternate "home" location for Python, so that it uses a personal
``site-packages`` directory. ``site-packages`` directory instead of the system-wide ``site-packages``.
If you are on a Mac OS X machine, you should just use the If you are on a Mac OS X machine, you should just use the
``~/Library/Python2.x/site-packages`` directory (replacing the ``x`` with the ``~/Library/Python2.x/site-packages`` directory (replacing the ``x`` with the
appropriate number). Just make sure the directory exists, and use it as your appropriate number). Just make sure the directory exists, and use it as your
installation location for all packages (including EasyInstall itself). You installation location for all packages (including EasyInstall itself). To
do not need to set up a ``PYTHONHOME``, so you can skip the rest of this make the distutils install to this personal ``site-packages`` directory by
section, unless you want to be able to override system-installed packages. default, you should create a ``~/.pydistutils.cfg`` file with the following
contents::
[install]
install_lib = ~/Library/Python$py_version_short/site-packages
This will tell the distutils (and EasyInstall) to always install packages in
the appropriate personal ``site-packages`` directory.
If you are on a Linux, BSD, Cygwin, or other similar Unix-like operating If you are on a Linux, BSD, Cygwin, or other similar Unix-like operating
system, you should create a ``~/lib/python2.x/site-packages`` directory system, you should create a ``~/lib/python2.x/site-packages`` directory
...@@ -694,39 +701,40 @@ instead. You will need to know your Python version's ``sys.prefix`` and ...@@ -694,39 +701,40 @@ instead. You will need to know your Python version's ``sys.prefix`` and
Assuming your ``sys.prefix`` is ``/usr/local``, and you are working with Assuming your ``sys.prefix`` is ``/usr/local``, and you are working with
Python 2.4, you need to then perform the following steps (possibly making Python 2.4, you need to then perform the following steps (possibly making
adjustments for the tools available on your platform):: adjustments for the tools available on your platform). First, you need
to set up the local library directories, by symlinking to the system Python's
libraries::
mkdir -p ~/lib/python2.4
ln -s /usr/local/lib/python2.4/* ~/lib/python2.4/
rm ~/lib/python2.4/site-packages
mkdir ~/lib/python2.4/site-packages
ln -s /usr/local/lib/python2.4/site-packages/* ~/lib/python2.4/site-packages
cd /usr/local/lib/python2.4 If your ``sys.exec_prefix`` was different from your ``sys.prefix``, you will
find . -name lib-dynload -prune -o -name site-packages -prune -o \ also need to do this::
-print >~/pyfiles
zip -r ~/lib/python24.zip . -i@$HOME/pyfiles
rm ~/pyfiles
mkdir -p ~/lib/python2.4/site-packages
ln -s /usr/local/lib/python2.4/lib-* ~/lib/python2.4/
echo "[install]" >>~/.pydistutils.cfg ln -s /execprefix/lib/python2.4/* ~/lib/python2.4/
echo "prefix=$HOME" >>~/.pydistutils.cfg
echo "exec_prefix=$HOME" >>~/.pydistutils.cfg
Note that all of the paths above should be based on ``sys.prefix``, not replacing ``execprefix`` in the above with the value of ``sys.exec_prefix``.
``sys.exec_prefix`` (unless they're the same). Once these one-time steps are
completed, you can set your ``PYTHONHOME`` with::
export PYTHONHOME=$HOME:/old_exec_prefix Finally, you will also need a private ``python`` executable, e.g.::
replacing ``/old_exec_prefix`` with the original value of ``sys.exec_prefix``. mkdir -p ~/bin
ln /usr/local/bin/python2.4 ~/bin/python
The downside to this setup is that it can take up as much as 10 megabytes of Note that if hardlinking as shown doesn't work (e.g. because the system Python
disk space to store the zipped standard library. The upside, however, is that is on a different filesystem), you should use ``copy -p`` instead of ``ln``.
Python usually starts much faster with a zipped standard library! And of Do NOT use a symlink; the Python binary must be copied or hardlinked, otherwise
course, you'll effectively have complete control over your own Python it will use the system ``site-packages`` directory and not yours.
installation, without needing to convince a system administrator to install
packages for you.
Note that if you were previously setting a ``PYTHONPATH`` and/or had other Note that if you were previously setting a ``PYTHONPATH`` and/or had other
special configuration options in your ``~/.pydistutils.cfg``, you may need to special configuration options in your ``~/.pydistutils.cfg``, you may need to
remove these settings, after relocating any older installed modules to your remove these settings, after relocating any older installed modules to your
new ``~/lib/python2.x`` directory. new ``~/lib/python2.x/site-packages`` directory. Also note that you must now
make sure to use the ``~/bin/python`` executable instead of the system Python,
and ideally you should put ``~/bin`` first on your ``PATH`` as well, because
that is where EasyInstall will install new Python scripts.
Release Notes/Change History Release Notes/Change History
......
...@@ -10,7 +10,7 @@ Packages built and distributed using ``setuptools`` look to the user like ...@@ -10,7 +10,7 @@ Packages built and distributed using ``setuptools`` look to the user like
ordinary Python packages based on the ``distutils``. Your users don't need to ordinary Python packages based on the ``distutils``. Your users don't need to
install or even know about setuptools in order to use them, and you don't install or even know about setuptools in order to use them, and you don't
have to include the entire setuptools package in your distributions. By have to include the entire setuptools package in your distributions. By
including just a single `bootstrap module`_ (a 5K .py file), your package will including just a single `bootstrap module`_ (a 7K .py file), your package will
automatically download and install ``setuptools`` if the user is building your automatically download and install ``setuptools`` if the user is building your
package from source and doesn't have a suitable version already installed. package from source and doesn't have a suitable version already installed.
......
...@@ -168,14 +168,11 @@ class bdist_egg(Command): ...@@ -168,14 +168,11 @@ class bdist_egg(Command):
# We run install_lib before install_data, because some data hacks # We run install_lib before install_data, because some data hacks
# pull their data path from the install_lib command. # pull their data path from the install_lib command.
log.info("installing library code to %s" % self.bdist_dir) log.info("installing library code to %s" % self.bdist_dir)
instcmd = self.get_finalized_command('install') instcmd = self.get_finalized_command('install')
old_root = instcmd.root old_root = instcmd.root; instcmd.root = None
instcmd.root = None
cmd = self.call_command('install_lib', warn_dir=0) cmd = self.call_command('install_lib', warn_dir=0)
instcmd.root = old_root instcmd.root = old_root
ext_outputs = cmd._mutate_outputs( ext_outputs = cmd._mutate_outputs(
self.distribution.has_ext_modules(), 'build_ext', 'build_lib', '' self.distribution.has_ext_modules(), 'build_ext', 'build_lib', ''
) )
...@@ -201,7 +198,6 @@ class bdist_egg(Command): ...@@ -201,7 +198,6 @@ class bdist_egg(Command):
archive_root = self.bdist_dir archive_root = self.bdist_dir
egg_info = os.path.join(archive_root,'EGG-INFO') egg_info = os.path.join(archive_root,'EGG-INFO')
self.mkpath(egg_info) self.mkpath(egg_info)
if self.distribution.scripts: if self.distribution.scripts:
script_dir = os.path.join(egg_info, 'scripts') script_dir = os.path.join(egg_info, 'scripts')
log.info("installing scripts to %s" % script_dir) log.info("installing scripts to %s" % script_dir)
......
...@@ -104,8 +104,10 @@ class easy_install(Command): ...@@ -104,8 +104,10 @@ class easy_install(Command):
for filename in blockers: for filename in blockers:
log.info("Deleting %s", filename) log.info("Deleting %s", filename)
if not self.dry_run: if not self.dry_run:
if os.path.isdir(filename): if hasattr(os.path,'islink') and os.path.islink(filename):
shutil.rmtree(filename) os.unlink(filename)
elif os.path.isdir(filename):
shutil.rmtree(filename)
else: else:
os.unlink(filename) os.unlink(filename)
...@@ -119,8 +121,6 @@ class easy_install(Command): ...@@ -119,8 +121,6 @@ class easy_install(Command):
def finalize_options(self): def finalize_options(self):
# If a non-default installation directory was specified, default the # If a non-default installation directory was specified, default the
# script directory to match it. # script directory to match it.
...@@ -846,7 +846,9 @@ See the setuptools documentation for the "develop" command for more info. ...@@ -846,7 +846,9 @@ See the setuptools documentation for the "develop" command for more info.
if dist.key=='setuptools': if dist.key=='setuptools':
# Ensure that setuptools itself never becomes unavailable! # Ensure that setuptools itself never becomes unavailable!
# XXX should this check for latest version? # XXX should this check for latest version?
f = open(os.path.join(self.install_dir,'setuptools.pth'), 'wt') filename = os.path.join(self.install_dir,'setuptools.pth')
unlink_if_symlink(filename)
f = open(filename, 'wt')
f.write(dist.location+'\n') f.write(dist.location+'\n')
f.close() f.close()
...@@ -857,8 +859,6 @@ See the setuptools documentation for the "develop" command for more info. ...@@ -857,8 +859,6 @@ See the setuptools documentation for the "develop" command for more info.
return dst # only unpack-and-compile skips files for dry run return dst # only unpack-and-compile skips files for dry run
def unpack_and_compile(self, egg_path, destination): def unpack_and_compile(self, egg_path, destination):
to_compile = [] to_compile = []
...@@ -1017,9 +1017,9 @@ def extract_wininst_cfg(dist_filename): ...@@ -1017,9 +1017,9 @@ def extract_wininst_cfg(dist_filename):
f.close() f.close()
def unlink_if_symlink(filename):
if hasattr(os.path,'islink') and os.path.islink(filename):
os.unlink(filename)
...@@ -1100,11 +1100,11 @@ class PthDistributions(Environment): ...@@ -1100,11 +1100,11 @@ class PthDistributions(Environment):
if self.dirty: if self.dirty:
log.debug("Saving %s", self.filename) log.debug("Saving %s", self.filename)
data = '\n'.join(self.paths+['']) data = '\n'.join(self.paths+[''])
unlink_if_symlink(self.filename)
f = open(self.filename,'wt'); f.write(data); f.close() f = open(self.filename,'wt'); f.write(data); f.close()
self.dirty = False self.dirty = False
def add(self,dist): def add(self,dist):
"""Add `dist` to the distribution map""" """Add `dist` to the distribution map"""
if dist.location not in self.paths: if dist.location not in self.paths:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment