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