1#!python 2"""Bootstrap setuptools installation 3 4If you want to use setuptools in your package's setup.py, just include this 5file in the same directory with it, and add this to the top of your setup.py:: 6 7 from ez_setup import use_setuptools 8 use_setuptools() 9 10If you want to require a specific version of setuptools, set a download 11mirror, or use an alternate download directory, you can do so by supplying 12the appropriate options to ``use_setuptools()``. 13 14This file can also be run as a script to install or upgrade setuptools. 15""" 16import sys 17DEFAULT_VERSION = "0.6c11" 18DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] 19 20md5_data = { 21 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 22 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 23 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 24 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 25 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 26 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 27 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 28 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 29 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 30 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 31 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090', 32 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4', 33 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7', 34 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5', 35 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de', 36 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b', 37 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2', 38 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086', 39 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 40 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 41 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 42 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 43 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 44 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 45 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 46 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 47 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 48 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 49 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 50 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 51 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 52 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 53 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 54 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 55 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 56 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 57 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 58 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 59 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 60 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 61 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 62 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', 63} 64 65import sys, os 66try: from hashlib import md5 67except ImportError: from md5 import md5 68 69def _validate_md5(egg_name, data): 70 if egg_name in md5_data: 71 digest = md5(data).hexdigest() 72 if digest != md5_data[egg_name]: 73 print >>sys.stderr, ( 74 "md5 validation of %s failed! (Possible download problem?)" 75 % egg_name 76 ) 77 sys.exit(2) 78 return data 79 80def use_setuptools( 81 version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 82 download_delay=15 83): 84 """Automatically find/download setuptools and make it available on sys.path 85 86 `version` should be a valid setuptools version number that is available 87 as an egg for download under the `download_base` URL (which should end with 88 a '/'). `to_dir` is the directory where setuptools will be downloaded, if 89 it is not already available. If `download_delay` is specified, it should 90 be the number of seconds that will be paused before initiating a download, 91 should one be required. If an older version of setuptools is installed, 92 this routine will print a message to ``sys.stderr`` and raise SystemExit in 93 an attempt to abort the calling script. 94 """ 95 was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules 96 def do_download(): 97 egg = download_setuptools(version, download_base, to_dir, download_delay) 98 sys.path.insert(0, egg) 99 import setuptools; setuptools.bootstrap_install_from = egg 100 try: 101 import pkg_resources 102 except ImportError: 103 return do_download() 104 try: 105 pkg_resources.require("setuptools>="+version); return 106 except pkg_resources.VersionConflict, e: 107 if was_imported: 108 print >>sys.stderr, ( 109 "The required version of setuptools (>=%s) is not available, and\n" 110 "can't be installed while this script is running. Please install\n" 111 " a more recent version first, using 'easy_install -U setuptools'." 112 "\n\n(Currently using %r)" 113 ) % (version, e.args[0]) 114 sys.exit(2) 115 else: 116 del pkg_resources, sys.modules['pkg_resources'] # reload ok 117 return do_download() 118 except pkg_resources.DistributionNotFound: 119 return do_download() 120 121def download_setuptools( 122 version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 123 delay = 15 124): 125 """Download setuptools from a specified location and return its filename 126 127 `version` should be a valid setuptools version number that is available 128 as an egg for download under the `download_base` URL (which should end 129 with a '/'). `to_dir` is the directory where the egg will be downloaded. 130 `delay` is the number of seconds to pause before an actual download attempt. 131 """ 132 import urllib2, shutil 133 egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) 134 url = download_base + egg_name 135 saveto = os.path.join(to_dir, egg_name) 136 src = dst = None 137 if not os.path.exists(saveto): # Avoid repeated downloads 138 try: 139 from distutils import log 140 if delay: 141 log.warn(""" 142--------------------------------------------------------------------------- 143This script requires setuptools version %s to run (even to display 144help). I will attempt to download it for you (from 145%s), but 146you may need to enable firewall access for this script first. 147I will start the download in %d seconds. 148 149(Note: if this machine does not have network access, please obtain the file 150 151 %s 152 153and place it in this directory before rerunning this script.) 154---------------------------------------------------------------------------""", 155 version, download_base, delay, url 156 ); from time import sleep; sleep(delay) 157 log.warn("Downloading %s", url) 158 src = urllib2.urlopen(url) 159 # Read/write all in one block, so we don't create a corrupt file 160 # if the download is interrupted. 161 data = _validate_md5(egg_name, src.read()) 162 dst = open(saveto,"wb"); dst.write(data) 163 finally: 164 if src: src.close() 165 if dst: dst.close() 166 return os.path.realpath(saveto) 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203def main(argv, version=DEFAULT_VERSION): 204 """Install or upgrade setuptools and EasyInstall""" 205 try: 206 import setuptools 207 except ImportError: 208 egg = None 209 try: 210 egg = download_setuptools(version, delay=0) 211 sys.path.insert(0,egg) 212 from setuptools.command.easy_install import main 213 return main(list(argv)+[egg]) # we're done here 214 finally: 215 if egg and os.path.exists(egg): 216 os.unlink(egg) 217 else: 218 if setuptools.__version__ == '0.0.1': 219 print >>sys.stderr, ( 220 "You have an obsolete version of setuptools installed. Please\n" 221 "remove it from your system entirely before rerunning this script." 222 ) 223 sys.exit(2) 224 225 req = "setuptools>="+version 226 import pkg_resources 227 try: 228 pkg_resources.require(req) 229 except pkg_resources.VersionConflict: 230 try: 231 from setuptools.command.easy_install import main 232 except ImportError: 233 from easy_install import main 234 main(list(argv)+[download_setuptools(delay=0)]) 235 sys.exit(0) # try to force an exit 236 else: 237 if argv: 238 from setuptools.command.easy_install import main 239 main(argv) 240 else: 241 print "Setuptools version",version,"or greater has been installed." 242 print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' 243 244def update_md5(filenames): 245 """Update our built-in md5 registry""" 246 247 import re 248 249 for name in filenames: 250 base = os.path.basename(name) 251 f = open(name,'rb') 252 md5_data[base] = md5(f.read()).hexdigest() 253 f.close() 254 255 data = [" %r: %r,\n" % it for it in md5_data.items()] 256 data.sort() 257 repl = "".join(data) 258 259 import inspect 260 srcfile = inspect.getsourcefile(sys.modules[__name__]) 261 f = open(srcfile, 'rb'); src = f.read(); f.close() 262 263 match = re.search("\nmd5_data = {\n([^}]+)}", src) 264 if not match: 265 print >>sys.stderr, "Internal error!" 266 sys.exit(2) 267 268 src = src[:match.start(1)] + repl + src[match.end(1):] 269 f = open(srcfile,'w') 270 f.write(src) 271 f.close() 272 273 274if __name__=='__main__': 275 if len(sys.argv)>2 and sys.argv[1]=='--md5update': 276 update_md5(sys.argv[2:]) 277 else: 278 main(sys.argv[1:]) 279 280 281 282 283 284 285