setup: make ez_setup.py work to upgrade setuptools even if there is already a setuptools installed which is too old

This works only if setup.py is invoked as "./setup.py install" (or 
"python ./setup.py install" or whatever).  It doesn't work if it is invoked by 
easy_install.  On the other hand, I don't know why easy_install would execute 
ez_setup.py anyway -- I thought that it didn't execute the setup.py scripts.  
See this mailing list thread for details:

http://mail.python.org/pipermail/distutils-sig/2007-October/008339.html
This commit is contained in:
Zooko O'Whielacronx 2007-10-12 22:59:37 -07:00
parent aba57d9a4c
commit c9653af82a

View File

@ -13,7 +13,7 @@ the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools. This file can also be run as a script to install or upgrade setuptools.
""" """
import subprocess, sys import os, sys
DEFAULT_VERSION = "0.6c7" DEFAULT_VERSION = "0.6c7"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
@ -23,8 +23,6 @@ md5_data = {
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
} }
import sys, os
def _validate_md5(egg_name, data): def _validate_md5(egg_name, data):
if egg_name in md5_data: if egg_name in md5_data:
from md5 import md5 from md5 import md5
@ -37,28 +35,43 @@ def _validate_md5(egg_name, data):
sys.exit(2) sys.exit(2)
return data return data
def setuptools_is_loaded(): # The following code to parse versions is copied from pkg_resources.py so that
return 'pkg_resources' in sys.modules or 'setuptools' in sys.modules # we can parse versions without importing that module.
import re
component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get
def get_setuptools_version(): def _parse_version_parts(s):
sub = subprocess.Popen([sys.executable, "-c", "import setuptools;print setuptools.__version__"], stdout=subprocess.PIPE) for part in component_re.split(s):
return sub.stdout.read().strip() part = replace(part,part)
if not part or part=='.':
continue
if part[:1] in '0123456789':
yield part.zfill(8) # pad for numeric comparison
else:
yield '*'+part
yield '*final' # ensure that alpha/beta/candidate are before final
def parse_version(s):
parts = []
for part in _parse_version_parts(s.lower()):
if part.startswith('*'):
if part<'*final': # remove '-' before a prerelease tag
while parts and parts[-1]=='*final-': parts.pop()
# remove trailing zeros from each series of numeric parts
while parts and parts[-1]=='00000000':
parts.pop()
parts.append(part)
return tuple(parts)
def setuptools_is_new_enough(required_version): def setuptools_is_new_enough(required_version):
"""Return True if setuptools is already installed and has a version """Return True if setuptools is already installed and has a version
number >= required_version.""" number >= required_version."""
verstr = get_setuptools_version() (cin, cout, cerr,) = os.popen3("%s -c \"import setuptools;print setuptools.__version__\"" % (sys.executable,))
try: verstr = cout.read().strip()
import pkg_resources ver = parse_version(verstr)
except ImportError: return ver and ver >= parse_version(required_version)
# Well then I guess it is definitely not new enough.
return False
try:
ver = pkg_resources.parse_version(verstr)
newenough = ver and ver >= pkg_resources.parse_version(required_version)
finally:
del sys.modules['pkg_resources']
return newenough
def use_setuptools( def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
@ -77,18 +90,6 @@ def use_setuptools(
""" """
if min_version is None: if min_version is None:
min_version = version min_version = version
if setuptools_is_loaded():
# setuptools is installed, but can't be upgraded, so just version
# check (using pkg_resources) and exit if it's not a good enough
# version.
if not setuptools_is_new_enough(min_version):
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not installed, and\n"
"can't be installed while this script is running. Please install\n"
"a more recent version first.\n\n(Currently using %r)"
) % (min_version, get_setuptools_version())
sys.exit(2)
else:
if not setuptools_is_new_enough(min_version): if not setuptools_is_new_enough(min_version):
egg = download_setuptools(version, download_base, to_dir, download_delay) egg = download_setuptools(version, download_base, to_dir, download_delay)
sys.path.insert(0, egg) sys.path.insert(0, egg)
@ -144,18 +145,6 @@ and place it in this directory before rerunning this script.)
def main(argv, version=DEFAULT_VERSION): def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall""" """Install or upgrade setuptools and EasyInstall"""
if setuptools_is_loaded():
# setuptools is installed, but can't be upgraded, so just version
# check (using pkg_resources) and exit if it's not a good enough
# version.
if not setuptools_is_new_enough(version):
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not installed, and\n"
"can't be installed while this script is running. Please install\n"
"a more recent version first.\n\n(Currently using %r)"
) % (version, get_setuptools_version())
sys.exit(2)
else:
if setuptools_is_new_enough(version): if setuptools_is_new_enough(version):
if argv: if argv:
from setuptools.command.easy_install import main from setuptools.command.easy_install import main