virtual-bootstrap.py 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. ## WARNING: This file is (partly) generated
  18. """Create a "virtual" Python installation
  19. """
  20. virtualenv_version = "1.10.1"
  21. import sys
  22. import os
  23. import optparse
  24. import re
  25. import shutil
  26. import logging
  27. import distutils.sysconfig
  28. try:
  29. import subprocess
  30. except ImportError, e:
  31. if sys.version_info <= (2, 3):
  32. print 'ERROR: %s' % e
  33. print 'ERROR: this script requires Python 2.6 or greater; or at least the subprocess module.'
  34. print 'If you copy subprocess.py from a newer version of Python this script will probably work'
  35. sys.exit(101)
  36. else:
  37. raise
  38. try:
  39. set
  40. except NameError:
  41. from sets import Set as set
  42. join = os.path.join
  43. py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
  44. is_jython = sys.platform.startswith('java')
  45. expected_exe = is_jython and 'jython' or 'python'
  46. REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'ntpath', 'genericpath',
  47. 'fnmatch', 'locale', 'encodings', 'codecs',
  48. 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
  49. 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
  50. 'lib-dynload', 'config', 'zlib']
  51. if sys.version_info[:2] >= (2, 6):
  52. REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
  53. if sys.version_info[:2] == (2, 7):
  54. REQUIRED_MODULES.extend(['_weakrefset'])
  55. if sys.version_info[:2] <= (2, 3):
  56. REQUIRED_MODULES.extend(['sets', '__future__'])
  57. class Logger(object):
  58. """
  59. Logging object for use in command-line script. Allows ranges of
  60. levels, to avoid some redundancy of displayed information.
  61. """
  62. DEBUG = logging.DEBUG
  63. INFO = logging.INFO
  64. NOTIFY = (logging.INFO+logging.WARN)/2
  65. WARN = WARNING = logging.WARN
  66. ERROR = logging.ERROR
  67. FATAL = logging.FATAL
  68. LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
  69. def __init__(self, consumers):
  70. self.consumers = consumers
  71. self.indent = 0
  72. self.in_progress = None
  73. self.in_progress_hanging = False
  74. def debug(self, msg, *args, **kw):
  75. self.log(self.DEBUG, msg, *args, **kw)
  76. def info(self, msg, *args, **kw):
  77. self.log(self.INFO, msg, *args, **kw)
  78. def notify(self, msg, *args, **kw):
  79. self.log(self.NOTIFY, msg, *args, **kw)
  80. def warn(self, msg, *args, **kw):
  81. self.log(self.WARN, msg, *args, **kw)
  82. def error(self, msg, *args, **kw):
  83. self.log(self.WARN, msg, *args, **kw)
  84. def fatal(self, msg, *args, **kw):
  85. self.log(self.FATAL, msg, *args, **kw)
  86. def log(self, level, msg, *args, **kw):
  87. if args:
  88. if kw:
  89. raise TypeError(
  90. "You may give positional or keyword arguments, not both")
  91. args = args or kw
  92. rendered = None
  93. for consumer_level, consumer in self.consumers:
  94. if self.level_matches(level, consumer_level):
  95. if (self.in_progress_hanging
  96. and consumer in (sys.stdout, sys.stderr)):
  97. self.in_progress_hanging = False
  98. sys.stdout.write('\n')
  99. sys.stdout.flush()
  100. if rendered is None:
  101. if args:
  102. rendered = msg % args
  103. else:
  104. rendered = msg
  105. rendered = ' '*self.indent + rendered
  106. if hasattr(consumer, 'write'):
  107. consumer.write(rendered+'\n')
  108. else:
  109. consumer(rendered)
  110. def start_progress(self, msg):
  111. assert not self.in_progress, (
  112. "Tried to start_progress(%r) while in_progress %r"
  113. % (msg, self.in_progress))
  114. if self.level_matches(self.NOTIFY, self._stdout_level()):
  115. sys.stdout.write(msg)
  116. sys.stdout.flush()
  117. self.in_progress_hanging = True
  118. else:
  119. self.in_progress_hanging = False
  120. self.in_progress = msg
  121. def end_progress(self, msg='done.'):
  122. assert self.in_progress, (
  123. "Tried to end_progress without start_progress")
  124. if self.stdout_level_matches(self.NOTIFY):
  125. if not self.in_progress_hanging:
  126. # Some message has been printed out since start_progress
  127. sys.stdout.write('...' + self.in_progress + msg + '\n')
  128. sys.stdout.flush()
  129. else:
  130. sys.stdout.write(msg + '\n')
  131. sys.stdout.flush()
  132. self.in_progress = None
  133. self.in_progress_hanging = False
  134. def show_progress(self):
  135. """If we are in a progress scope, and no log messages have been
  136. shown, write out another '.'"""
  137. if self.in_progress_hanging:
  138. sys.stdout.write('.')
  139. sys.stdout.flush()
  140. def stdout_level_matches(self, level):
  141. """Returns true if a message at this level will go to stdout"""
  142. return self.level_matches(level, self._stdout_level())
  143. def _stdout_level(self):
  144. """Returns the level that stdout runs at"""
  145. for level, consumer in self.consumers:
  146. if consumer is sys.stdout:
  147. return level
  148. return self.FATAL
  149. def level_matches(self, level, consumer_level):
  150. """
  151. >>> l = Logger()
  152. >>> l.level_matches(3, 4)
  153. False
  154. >>> l.level_matches(3, 2)
  155. True
  156. >>> l.level_matches(slice(None, 3), 3)
  157. False
  158. >>> l.level_matches(slice(None, 3), 2)
  159. True
  160. >>> l.level_matches(slice(1, 3), 1)
  161. True
  162. >>> l.level_matches(slice(2, 3), 1)
  163. False
  164. """
  165. if isinstance(level, slice):
  166. start, stop = level.start, level.stop
  167. if start is not None and start > consumer_level:
  168. return False
  169. if stop is not None or stop <= consumer_level:
  170. return False
  171. return True
  172. else:
  173. return level >= consumer_level
  174. #@classmethod
  175. def level_for_integer(cls, level):
  176. levels = cls.LEVELS
  177. if level < 0:
  178. return levels[0]
  179. if level >= len(levels):
  180. return levels[-1]
  181. return levels[level]
  182. level_for_integer = classmethod(level_for_integer)
  183. def mkdir(path):
  184. if not os.path.exists(path):
  185. logger.info('Creating %s', path)
  186. os.makedirs(path)
  187. else:
  188. logger.info('Directory %s already exists', path)
  189. def copyfile(src, dest, symlink=True):
  190. if not os.path.exists(src):
  191. # Some bad symlink in the src
  192. logger.warn('Cannot find file %s (bad symlink)', src)
  193. return
  194. if os.path.exists(dest):
  195. logger.debug('File %s already exists', dest)
  196. return
  197. if not os.path.exists(os.path.dirname(dest)):
  198. logger.info('Creating parent directories for %s' % os.path.dirname(dest))
  199. os.makedirs(os.path.dirname(dest))
  200. if symlink and hasattr(os, 'symlink'):
  201. logger.info('Symlinking %s', dest)
  202. os.symlink(os.path.abspath(src), dest)
  203. else:
  204. logger.info('Copying to %s', dest)
  205. if os.path.isdir(src):
  206. shutil.copytree(src, dest, True)
  207. else:
  208. shutil.copy2(src, dest)
  209. def writefile(dest, content, overwrite=True):
  210. if not os.path.exists(dest):
  211. logger.info('Writing %s', dest)
  212. f = open(dest, 'wb')
  213. f.write(content)
  214. f.close()
  215. return
  216. else:
  217. f = open(dest, 'rb')
  218. c = f.read()
  219. f.close()
  220. if c != content:
  221. if not overwrite:
  222. logger.notify('File %s exists with different content; not overwriting', dest)
  223. return
  224. logger.notify('Overwriting %s with new content', dest)
  225. f = open(dest, 'wb')
  226. f.write(content)
  227. f.close()
  228. else:
  229. logger.info('Content %s already in place', dest)
  230. def rmtree(dir):
  231. if os.path.exists(dir):
  232. logger.notify('Deleting tree %s', dir)
  233. shutil.rmtree(dir)
  234. else:
  235. logger.info('Do not need to delete %s; already gone', dir)
  236. def make_exe(fn):
  237. if hasattr(os, 'chmod'):
  238. oldmode = os.stat(fn).st_mode & 07777
  239. newmode = (oldmode | 0555) & 07777
  240. os.chmod(fn, newmode)
  241. logger.info('Changed mode of %s to %s', fn, oct(newmode))
  242. def _find_file(filename, dirs):
  243. for dir in dirs:
  244. if os.path.exists(join(dir, filename)):
  245. return join(dir, filename)
  246. return filename
  247. def _install_req(py_executable, unzip=False, distribute=False):
  248. if not distribute:
  249. setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
  250. project_name = 'setuptools'
  251. bootstrap_script = EZ_SETUP_PY
  252. source = None
  253. else:
  254. setup_fn = None
  255. source = 'distribute-0.6.8.tar.gz'
  256. project_name = 'distribute'
  257. bootstrap_script = DISTRIBUTE_SETUP_PY
  258. try:
  259. # check if the global Python has distribute installed or plain
  260. # setuptools
  261. import pkg_resources
  262. if not hasattr(pkg_resources, '_distribute'):
  263. location = os.path.dirname(pkg_resources.__file__)
  264. logger.notify("A globally installed setuptools was found (in %s)" % location)
  265. logger.notify("Use the --no-site-packages option to use distribute in "
  266. "the virtualenv.")
  267. except ImportError:
  268. pass
  269. search_dirs = file_search_dirs()
  270. if setup_fn is not None:
  271. setup_fn = _find_file(setup_fn, search_dirs)
  272. if source is not None:
  273. source = _find_file(source, search_dirs)
  274. if is_jython and os._name == 'nt':
  275. # Jython's .bat sys.executable can't handle a command line
  276. # argument with newlines
  277. import tempfile
  278. fd, ez_setup = tempfile.mkstemp('.py')
  279. os.write(fd, bootstrap_script)
  280. os.close(fd)
  281. cmd = [py_executable, ez_setup]
  282. else:
  283. cmd = [py_executable, '-c', bootstrap_script]
  284. if unzip:
  285. cmd.append('--always-unzip')
  286. env = {}
  287. if logger.stdout_level_matches(logger.DEBUG):
  288. cmd.append('-v')
  289. old_chdir = os.getcwd()
  290. if setup_fn is not None and os.path.exists(setup_fn):
  291. logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
  292. cmd.append(setup_fn)
  293. if os.environ.get('PYTHONPATH'):
  294. env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
  295. else:
  296. env['PYTHONPATH'] = setup_fn
  297. else:
  298. # the source is found, let's chdir
  299. if source is not None and os.path.exists(source):
  300. os.chdir(os.path.dirname(source))
  301. else:
  302. logger.info('No %s egg found; downloading' % project_name)
  303. cmd.extend(['--always-copy', '-U', project_name])
  304. logger.start_progress('Installing %s...' % project_name)
  305. logger.indent += 2
  306. cwd = None
  307. if project_name == 'distribute':
  308. env['DONT_PATCH_SETUPTOOLS'] = 'true'
  309. def _filter_ez_setup(line):
  310. return filter_ez_setup(line, project_name)
  311. if not os.access(os.getcwd(), os.W_OK):
  312. cwd = '/tmp'
  313. if source is not None and os.path.exists(source):
  314. # the current working dir is hostile, let's copy the
  315. # tarball to /tmp
  316. target = os.path.join(cwd, os.path.split(source)[-1])
  317. shutil.copy(source, target)
  318. try:
  319. call_subprocess(cmd, show_stdout=False,
  320. filter_stdout=_filter_ez_setup,
  321. extra_env=env,
  322. cwd=cwd)
  323. finally:
  324. logger.indent -= 2
  325. logger.end_progress()
  326. if os.getcwd() != old_chdir:
  327. os.chdir(old_chdir)
  328. if is_jython and os._name == 'nt':
  329. os.remove(ez_setup)
  330. def file_search_dirs():
  331. here = os.path.dirname(os.path.abspath(__file__))
  332. dirs = ['.', here,
  333. join(here, 'virtualenv_support')]
  334. if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
  335. # Probably some boot script; just in case virtualenv is installed...
  336. try:
  337. import virtualenv
  338. except ImportError:
  339. pass
  340. else:
  341. dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
  342. return [d for d in dirs if os.path.isdir(d)]
  343. def install_setuptools(py_executable, unzip=False):
  344. try:
  345. _install_req(py_executable, unzip)
  346. except OSError, e:
  347. print """
  348. -----------------------------------------------------------------------------------------------------------------
  349. If on Ubuntu 14.04 Trusty, you might be hitting https://bugs.launchpad.net/ubuntu/+source/python2.7/+bug/1115466.
  350. Recommended workaround:
  351. sudo ln -s /usr/lib/python2.7/plat-*/_sysconfigdata_nd.py /usr/lib/python2.7/
  352. More information:
  353. http://gethue.com/how-to-build-hue-on-ubuntu-14-04-trusty/
  354. -----------------------------------------------------------------------------------------------------------------
  355. """
  356. raise e
  357. def install_distribute(py_executable, unzip=False):
  358. _install_req(py_executable, unzip, distribute=True)
  359. _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
  360. def install_pip(py_executable):
  361. filenames = []
  362. for dir in file_search_dirs():
  363. filenames.extend([join(dir, fn) for fn in os.listdir(dir)
  364. if _pip_re.search(fn)])
  365. filenames.sort(key=lambda x: os.path.basename(x).lower())
  366. if not filenames:
  367. filename = 'pip'
  368. else:
  369. filename = filenames[-1]
  370. easy_install_script = 'easy_install'
  371. if sys.platform == 'win32':
  372. easy_install_script = 'easy_install-script.py'
  373. cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
  374. if filename == 'pip':
  375. logger.info('Installing pip from network...')
  376. else:
  377. logger.info('Installing %s' % os.path.basename(filename))
  378. logger.indent += 2
  379. def _filter_setup(line):
  380. return filter_ez_setup(line, 'pip')
  381. try:
  382. call_subprocess(cmd, show_stdout=False,
  383. filter_stdout=_filter_setup)
  384. finally:
  385. logger.indent -= 2
  386. def filter_ez_setup(line, project_name='setuptools'):
  387. if not line.strip():
  388. return Logger.DEBUG
  389. if project_name == 'distribute':
  390. for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
  391. 'Scanning', 'Setuptools', 'Egg', 'Already',
  392. 'running', 'writing', 'reading', 'installing',
  393. 'creating', 'copying', 'byte-compiling', 'removing',
  394. 'Processing'):
  395. if line.startswith(prefix):
  396. return Logger.DEBUG
  397. return Logger.DEBUG
  398. for prefix in ['Reading ', 'Best match', 'Processing setuptools',
  399. 'Copying setuptools', 'Adding setuptools',
  400. 'Installing ', 'Installed ']:
  401. if line.startswith(prefix):
  402. return Logger.DEBUG
  403. return Logger.INFO
  404. def main():
  405. parser = optparse.OptionParser(
  406. version=virtualenv_version,
  407. usage="%prog [OPTIONS] DEST_DIR")
  408. parser.add_option(
  409. '-v', '--verbose',
  410. action='count',
  411. dest='verbose',
  412. default=0,
  413. help="Increase verbosity")
  414. parser.add_option(
  415. '-q', '--quiet',
  416. action='count',
  417. dest='quiet',
  418. default=0,
  419. help='Decrease verbosity')
  420. parser.add_option(
  421. '-p', '--python',
  422. dest='python',
  423. metavar='PYTHON_EXE',
  424. help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
  425. 'interpreter to create the new environment. The default is the interpreter that '
  426. 'virtualenv was installed with (%s)' % sys.executable)
  427. parser.add_option(
  428. '--clear',
  429. dest='clear',
  430. action='store_true',
  431. help="Clear out the non-root install and start from scratch")
  432. parser.add_option(
  433. '--no-site-packages',
  434. dest='no_site_packages',
  435. action='store_true',
  436. help="Don't give access to the global site-packages dir to the "
  437. "virtual environment")
  438. parser.add_option(
  439. '--unzip-setuptools',
  440. dest='unzip_setuptools',
  441. action='store_true',
  442. help="Unzip Setuptools or Distribute when installing it")
  443. parser.add_option(
  444. '--relocatable',
  445. dest='relocatable',
  446. action='store_true',
  447. help='Make an EXISTING virtualenv environment relocatable. '
  448. 'This fixes up scripts and makes all .pth files relative')
  449. parser.add_option(
  450. '--distribute',
  451. dest='use_distribute',
  452. action='store_true',
  453. help='Use Distribute instead of Setuptools. Set environ variable'
  454. 'VIRTUALENV_USE_DISTRIBUTE to make it the default ')
  455. if 'extend_parser' in globals():
  456. extend_parser(parser)
  457. options, args = parser.parse_args()
  458. global logger
  459. if 'adjust_options' in globals():
  460. adjust_options(options, args)
  461. verbosity = options.verbose - options.quiet
  462. logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
  463. if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
  464. env = os.environ.copy()
  465. interpreter = resolve_interpreter(options.python)
  466. if interpreter == sys.executable:
  467. logger.warn('Already using interpreter %s' % interpreter)
  468. else:
  469. logger.notify('Running virtualenv with interpreter %s' % interpreter)
  470. env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
  471. file = __file__
  472. if file.endswith('.pyc'):
  473. file = file[:-1]
  474. os.execvpe(interpreter, [interpreter, file] + sys.argv[1:], env)
  475. if not args:
  476. print 'You must provide a DEST_DIR'
  477. parser.print_help()
  478. sys.exit(2)
  479. if len(args) > 1:
  480. print 'There must be only one argument: DEST_DIR (you gave %s)' % (
  481. ' '.join(args))
  482. parser.print_help()
  483. sys.exit(2)
  484. home_dir = args[0]
  485. if os.environ.get('WORKING_ENV'):
  486. logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
  487. logger.fatal('Please deactivate your workingenv, then re-run this script')
  488. sys.exit(3)
  489. if os.environ.get('PYTHONHOME'):
  490. if sys.platform == 'win32':
  491. name = '%PYTHONHOME%'
  492. else:
  493. name = '$PYTHONHOME'
  494. logger.warn('%s is set; this can cause problems creating environments' % name)
  495. if options.relocatable:
  496. make_environment_relocatable(home_dir)
  497. return
  498. create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
  499. unzip_setuptools=options.unzip_setuptools,
  500. use_distribute=options.use_distribute)
  501. if 'after_install' in globals():
  502. after_install(options, home_dir)
  503. def call_subprocess(cmd, show_stdout=True,
  504. filter_stdout=None, cwd=None,
  505. raise_on_returncode=True, extra_env=None):
  506. cmd_parts = []
  507. for part in cmd:
  508. if len(part) > 40:
  509. part = part[:30]+"..."+part[-5:]
  510. if ' ' in part or '\n' in part or '"' in part or "'" in part:
  511. part = '"%s"' % part.replace('"', '\\"')
  512. cmd_parts.append(part)
  513. cmd_desc = ' '.join(cmd_parts)
  514. if show_stdout:
  515. stdout = None
  516. else:
  517. stdout = subprocess.PIPE
  518. logger.debug("Running command %s" % cmd_desc)
  519. if extra_env:
  520. env = os.environ.copy()
  521. env.update(extra_env)
  522. else:
  523. env = None
  524. try:
  525. proc = subprocess.Popen(
  526. cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
  527. cwd=cwd, env=env)
  528. except Exception, e:
  529. logger.fatal(
  530. "Error %s while executing command %s" % (e, cmd_desc))
  531. raise
  532. all_output = []
  533. if stdout is not None:
  534. stdout = proc.stdout
  535. while 1:
  536. line = stdout.readline()
  537. if not line:
  538. break
  539. line = line.rstrip()
  540. all_output.append(line)
  541. if filter_stdout:
  542. level = filter_stdout(line)
  543. if isinstance(level, tuple):
  544. level, line = level
  545. logger.log(level, line)
  546. if not logger.stdout_level_matches(level):
  547. logger.show_progress()
  548. else:
  549. logger.info(line)
  550. else:
  551. proc.communicate()
  552. proc.wait()
  553. if proc.returncode:
  554. if raise_on_returncode:
  555. if all_output:
  556. logger.notify('Complete output from command %s:' % cmd_desc)
  557. logger.notify('\n'.join(all_output) + '\n----------------------------------------')
  558. raise OSError(
  559. "Command %s failed with error code %s"
  560. % (cmd_desc, proc.returncode))
  561. else:
  562. logger.warn(
  563. "Command %s had error code %s"
  564. % (cmd_desc, proc.returncode))
  565. def create_environment(home_dir, site_packages=True, clear=False,
  566. unzip_setuptools=False, use_distribute=False):
  567. """
  568. Creates a new environment in ``home_dir``.
  569. If ``site_packages`` is true (the default) then the global
  570. ``site-packages/`` directory will be on the path.
  571. If ``clear`` is true (default False) then the environment will
  572. first be cleared.
  573. """
  574. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  575. py_executable = os.path.abspath(install_python(
  576. home_dir, lib_dir, inc_dir, bin_dir,
  577. site_packages=site_packages, clear=clear))
  578. install_distutils(lib_dir, home_dir)
  579. if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
  580. install_distribute(py_executable, unzip=unzip_setuptools)
  581. else:
  582. install_setuptools(py_executable, unzip=unzip_setuptools)
  583. install_pip(py_executable)
  584. install_activate(home_dir, bin_dir)
  585. def path_locations(home_dir):
  586. """Return the path locations for the environment (where libraries are,
  587. where scripts go, etc)"""
  588. # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  589. # prefix arg is broken: http://bugs.python.org/issue3386
  590. if sys.platform == 'win32':
  591. # Windows has lots of problems with executables with spaces in
  592. # the name; this function will remove them (using the ~1
  593. # format):
  594. mkdir(home_dir)
  595. if ' ' in home_dir:
  596. try:
  597. import win32api
  598. except ImportError:
  599. print 'Error: the path "%s" has a space in it' % home_dir
  600. print 'To handle these kinds of paths, the win32api module must be installed:'
  601. print ' http://sourceforge.net/projects/pywin32/'
  602. sys.exit(3)
  603. home_dir = win32api.GetShortPathName(home_dir)
  604. lib_dir = join(home_dir, 'Lib')
  605. inc_dir = join(home_dir, 'Include')
  606. bin_dir = join(home_dir, 'Scripts')
  607. elif is_jython:
  608. lib_dir = join(home_dir, 'Lib')
  609. inc_dir = join(home_dir, 'Include')
  610. bin_dir = join(home_dir, 'bin')
  611. else:
  612. lib_dir = join(home_dir, 'lib', py_version)
  613. inc_dir = join(home_dir, 'include', py_version)
  614. bin_dir = join(home_dir, 'bin')
  615. return home_dir, lib_dir, inc_dir, bin_dir
  616. def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
  617. """Install just the base environment, no distutils patches etc"""
  618. if sys.executable.startswith(bin_dir):
  619. print 'Please use the *system* python to run this script'
  620. return
  621. if clear:
  622. rmtree(lib_dir)
  623. ## FIXME: why not delete it?
  624. ## Maybe it should delete everything with #!/path/to/venv/python in it
  625. logger.notify('Not deleting %s', bin_dir)
  626. if hasattr(sys, 'real_prefix'):
  627. logger.notify('Using real prefix %r' % sys.real_prefix)
  628. prefix = sys.real_prefix
  629. else:
  630. prefix = sys.prefix
  631. mkdir(lib_dir)
  632. fix_lib64(lib_dir)
  633. stdlib_dirs = [os.path.dirname(os.__file__)]
  634. if sys.platform == 'win32':
  635. stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  636. elif sys.platform == 'darwin':
  637. stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  638. for stdlib_dir in stdlib_dirs:
  639. if not os.path.isdir(stdlib_dir):
  640. continue
  641. if hasattr(os, 'symlink'):
  642. logger.info('Symlinking Python bootstrap modules')
  643. else:
  644. logger.info('Copying Python bootstrap modules')
  645. logger.indent += 2
  646. try:
  647. for fn in os.listdir(stdlib_dir):
  648. if fn != 'site-packages' and os.path.splitext(fn)[0] in REQUIRED_MODULES:
  649. copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
  650. finally:
  651. logger.indent -= 2
  652. mkdir(join(lib_dir, 'site-packages'))
  653. writefile(join(lib_dir, 'site.py'), SITE_PY)
  654. writefile(join(lib_dir, 'orig-prefix.txt'), prefix)
  655. site_packages_filename = join(lib_dir, 'no-global-site-packages.txt')
  656. if not site_packages:
  657. writefile(site_packages_filename, '')
  658. else:
  659. if os.path.exists(site_packages_filename):
  660. logger.info('Deleting %s' % site_packages_filename)
  661. os.unlink(site_packages_filename)
  662. stdinc_dir = join(prefix, 'include', py_version)
  663. if os.path.exists(stdinc_dir):
  664. copyfile(stdinc_dir, inc_dir)
  665. else:
  666. logger.debug('No include dir %s' % stdinc_dir)
  667. if sys.exec_prefix != prefix:
  668. if sys.platform == 'win32':
  669. exec_dir = join(sys.exec_prefix, 'lib')
  670. elif is_jython:
  671. exec_dir = join(sys.exec_prefix, 'Lib')
  672. else:
  673. exec_dir = join(sys.exec_prefix, 'lib', py_version)
  674. for fn in os.listdir(exec_dir):
  675. copyfile(join(exec_dir, fn), join(lib_dir, fn))
  676. if is_jython:
  677. # Jython has either jython-dev.jar and javalib/ dir, or just
  678. # jython.jar
  679. for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  680. src = join(prefix, name)
  681. if os.path.exists(src):
  682. copyfile(src, join(home_dir, name))
  683. # XXX: registry should always exist after Jython 2.5rc1
  684. src = join(prefix, 'registry')
  685. if os.path.exists(src):
  686. copyfile(src, join(home_dir, 'registry'), symlink=False)
  687. copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  688. symlink=False)
  689. mkdir(bin_dir)
  690. py_executable = join(bin_dir, os.path.basename(sys.executable))
  691. if 'Python.framework' in prefix:
  692. if py_executable.endswith('/Python'):
  693. # The name of the python executable is not quite what
  694. # we want, rename it.
  695. py_executable = os.path.join(
  696. os.path.dirname(py_executable), 'python')
  697. logger.notify('New %s executable in %s', expected_exe, py_executable)
  698. if sys.executable != py_executable:
  699. ## FIXME: could I just hard link?
  700. executable = sys.executable
  701. if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
  702. # Cygwin misreports sys.executable sometimes
  703. executable += '.exe'
  704. py_executable += '.exe'
  705. logger.info('Executable actually exists in %s' % executable)
  706. shutil.copyfile(executable, py_executable)
  707. make_exe(py_executable)
  708. if sys.platform == 'win32' or sys.platform == 'cygwin':
  709. pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  710. if os.path.exists(pythonw):
  711. logger.info('Also created pythonw.exe')
  712. shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  713. if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  714. secondary_exe = os.path.join(os.path.dirname(py_executable),
  715. expected_exe)
  716. py_executable_ext = os.path.splitext(py_executable)[1]
  717. if py_executable_ext == '.exe':
  718. # python2.4 gives an extension of '.4' :P
  719. secondary_exe += py_executable_ext
  720. if os.path.exists(secondary_exe):
  721. logger.warn('Not overwriting existing %s script %s (you must use %s)'
  722. % (expected_exe, secondary_exe, py_executable))
  723. else:
  724. logger.notify('Also creating executable in %s' % secondary_exe)
  725. shutil.copyfile(sys.executable, secondary_exe)
  726. make_exe(secondary_exe)
  727. if 'Python.framework' in prefix:
  728. logger.debug('MacOSX Python framework detected')
  729. # Make sure we use the the embedded interpreter inside
  730. # the framework, even if sys.executable points to
  731. # the stub executable in ${sys.prefix}/bin
  732. # See http://groups.google.com/group/python-virtualenv/
  733. # browse_thread/thread/17cab2f85da75951
  734. shutil.copy(
  735. os.path.join(
  736. prefix, 'Resources/Python.app/Contents/MacOS/Python'),
  737. py_executable)
  738. # Copy the framework's dylib into the virtual
  739. # environment
  740. virtual_lib = os.path.join(home_dir, '.Python')
  741. if os.path.exists(virtual_lib):
  742. os.unlink(virtual_lib)
  743. copyfile(
  744. os.path.join(prefix, 'Python'),
  745. virtual_lib)
  746. # And then change the install_name of the copied python executable
  747. try:
  748. call_subprocess(
  749. ["install_name_tool", "-change",
  750. os.path.join(prefix, 'Python'),
  751. '@executable_path/../.Python',
  752. py_executable])
  753. except:
  754. logger.fatal(
  755. "Could not call install_name_tool -- you must have Apple's development tools installed")
  756. raise
  757. # Some tools depend on pythonX.Y being present
  758. py_executable_version = '%s.%s' % (
  759. sys.version_info[0], sys.version_info[1])
  760. if not py_executable.endswith(py_executable_version):
  761. # symlinking pythonX.Y > python
  762. pth = py_executable + '%s.%s' % (
  763. sys.version_info[0], sys.version_info[1])
  764. if os.path.exists(pth):
  765. os.unlink(pth)
  766. os.symlink('python', pth)
  767. else:
  768. # reverse symlinking python -> pythonX.Y (with --python)
  769. pth = join(bin_dir, 'python')
  770. if os.path.exists(pth):
  771. os.unlink(pth)
  772. os.symlink(os.path.basename(py_executable), pth)
  773. if sys.platform == 'win32' and ' ' in py_executable:
  774. # There's a bug with subprocess on Windows when using a first
  775. # argument that has a space in it. Instead we have to quote
  776. # the value:
  777. py_executable = '"%s"' % py_executable
  778. cmd = [py_executable, '-c', 'import sys; print sys.prefix']
  779. logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  780. proc = subprocess.Popen(cmd,
  781. stdout=subprocess.PIPE)
  782. proc_stdout, proc_stderr = proc.communicate()
  783. proc_stdout = os.path.normcase(os.path.abspath(proc_stdout.strip()))
  784. if proc_stdout != os.path.normcase(os.path.abspath(home_dir)):
  785. logger.fatal(
  786. 'ERROR: The executable %s is not functioning' % py_executable)
  787. logger.fatal(
  788. 'ERROR: It thinks sys.prefix is %r (should be %r)'
  789. % (proc_stdout, os.path.normcase(os.path.abspath(home_dir))))
  790. logger.fatal(
  791. 'ERROR: virtualenv is not compatible with this system or executable')
  792. if sys.platform == 'win32':
  793. logger.fatal(
  794. 'Note: some Windows users have reported this error when they installed Python for "Only this user". The problem may be resolvable if you install Python "For all users". (See https://bugs.launchpad.net/virtualenv/+bug/352844)')
  795. sys.exit(100)
  796. else:
  797. logger.info('Got sys.prefix result: %r' % proc_stdout)
  798. pydistutils = os.path.expanduser('~/.pydistutils.cfg')
  799. if os.path.exists(pydistutils):
  800. logger.notify('Please make sure you remove any previous custom paths from '
  801. 'your %s file.' % pydistutils)
  802. ## FIXME: really this should be calculated earlier
  803. return py_executable
  804. def install_activate(home_dir, bin_dir):
  805. if sys.platform == 'win32' or is_jython and os._name == 'nt':
  806. files = {'activate.bat': ACTIVATE_BAT,
  807. 'deactivate.bat': DEACTIVATE_BAT}
  808. if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin':
  809. files['activate'] = ACTIVATE_SH
  810. else:
  811. files = {'activate': ACTIVATE_SH}
  812. files['activate_this.py'] = ACTIVATE_THIS
  813. for name, content in files.items():
  814. content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir))
  815. content = content.replace('__VIRTUAL_NAME__', os.path.basename(os.path.abspath(home_dir)))
  816. content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
  817. writefile(os.path.join(bin_dir, name), content)
  818. def install_distutils(lib_dir, home_dir):
  819. distutils_path = os.path.join(lib_dir, 'distutils')
  820. mkdir(distutils_path)
  821. ## FIXME: maybe this prefix setting should only be put in place if
  822. ## there's a local distutils.cfg with a prefix setting?
  823. home_dir = os.path.abspath(home_dir)
  824. ## FIXME: this is breaking things, removing for now:
  825. #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  826. writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  827. writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  828. def fix_lib64(lib_dir):
  829. """
  830. Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  831. instead of lib/pythonX.Y. If this is such a platform we'll just create a
  832. symlink so lib64 points to lib
  833. """
  834. if [p for p in distutils.sysconfig.get_config_vars().values()
  835. if isinstance(p, basestring) and 'lib64' in p]:
  836. logger.debug('This system uses lib64; symlinking lib64 to lib')
  837. assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  838. "Unexpected python lib dir: %r" % lib_dir)
  839. lib_parent = os.path.dirname(lib_dir)
  840. assert os.path.basename(lib_parent) == 'lib', (
  841. "Unexpected parent dir: %r" % lib_parent)
  842. copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
  843. def resolve_interpreter(exe):
  844. """
  845. If the executable given isn't an absolute path, search $PATH for the interpreter
  846. """
  847. if os.path.abspath(exe) != exe:
  848. paths = os.environ.get('PATH', '').split(os.pathsep)
  849. for path in paths:
  850. if os.path.exists(os.path.join(path, exe)):
  851. exe = os.path.join(path, exe)
  852. break
  853. if not os.path.exists(exe):
  854. logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
  855. sys.exit(3)
  856. return exe
  857. ############################################################
  858. ## Relocating the environment:
  859. def make_environment_relocatable(home_dir):
  860. """
  861. Makes the already-existing environment use relative paths, and takes out
  862. the #!-based environment selection in scripts.
  863. """
  864. activate_this = os.path.join(home_dir, 'bin', 'activate_this.py')
  865. if not os.path.exists(activate_this):
  866. logger.fatal(
  867. 'The environment doesn\'t have a file %s -- please re-run virtualenv '
  868. 'on this environment to update it' % activate_this)
  869. fixup_scripts(home_dir)
  870. fixup_pth_and_egg_link(home_dir)
  871. ## FIXME: need to fix up distutils.cfg
  872. OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  873. 'activate', 'activate.bat', 'activate_this.py']
  874. def fixup_scripts(home_dir):
  875. # This is what we expect at the top of scripts:
  876. shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  877. # This is what we'll put:
  878. new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  879. activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
  880. bin_dir = os.path.join(home_dir, 'bin')
  881. for filename in os.listdir(bin_dir):
  882. filename = os.path.join(bin_dir, filename)
  883. if not os.path.isfile(filename):
  884. # ignore subdirs, e.g. .svn ones.
  885. continue
  886. f = open(filename, 'rb')
  887. lines = f.readlines()
  888. f.close()
  889. if not lines:
  890. logger.warn('Script %s is an empty file' % filename)
  891. continue
  892. if not lines[0].strip().startswith(shebang):
  893. if os.path.basename(filename) in OK_ABS_SCRIPTS:
  894. logger.debug('Cannot make script %s relative' % filename)
  895. elif lines[0].strip() == new_shebang:
  896. logger.info('Script %s has already been made relative' % filename)
  897. else:
  898. logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  899. % (filename, shebang))
  900. continue
  901. logger.notify('Making script %s relative' % filename)
  902. lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
  903. f = open(filename, 'wb')
  904. f.writelines(lines)
  905. f.close()
  906. def fixup_pth_and_egg_link(home_dir, sys_path=None):
  907. """Makes .pth and .egg-link files use relative paths"""
  908. home_dir = os.path.normcase(os.path.abspath(home_dir))
  909. if sys_path is None:
  910. sys_path = sys.path
  911. for path in sys_path:
  912. if not path:
  913. path = '.'
  914. if not os.path.isdir(path):
  915. continue
  916. path = os.path.normcase(os.path.abspath(path))
  917. if not path.startswith(home_dir):
  918. logger.debug('Skipping system (non-environment) directory %s' % path)
  919. continue
  920. for filename in os.listdir(path):
  921. filename = os.path.join(path, filename)
  922. if filename.endswith('.pth'):
  923. if not os.access(filename, os.W_OK):
  924. logger.warn('Cannot write .pth file %s, skipping' % filename)
  925. else:
  926. fixup_pth_file(filename)
  927. if filename.endswith('.egg-link'):
  928. if not os.access(filename, os.W_OK):
  929. logger.warn('Cannot write .egg-link file %s, skipping' % filename)
  930. else:
  931. fixup_egg_link(filename)
  932. def fixup_pth_file(filename):
  933. lines = []
  934. prev_lines = []
  935. f = open(filename)
  936. prev_lines = f.readlines()
  937. f.close()
  938. for line in prev_lines:
  939. line = line.strip()
  940. if (not line or line.startswith('#') or line.startswith('import ')
  941. or os.path.abspath(line) != line):
  942. lines.append(line)
  943. else:
  944. new_value = make_relative_path(filename, line)
  945. if line != new_value:
  946. logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
  947. lines.append(new_value)
  948. if lines == prev_lines:
  949. logger.info('No changes to .pth file %s' % filename)
  950. return
  951. logger.notify('Making paths in .pth file %s relative' % filename)
  952. f = open(filename, 'w')
  953. f.write('\n'.join(lines) + '\n')
  954. f.close()
  955. def fixup_egg_link(filename):
  956. f = open(filename)
  957. link = f.read().strip()
  958. f.close()
  959. if os.path.abspath(link) != link:
  960. logger.debug('Link in %s already relative' % filename)
  961. return
  962. new_link = make_relative_path(filename, link)
  963. logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
  964. f = open(filename, 'w')
  965. f.write(new_link)
  966. f.close()
  967. def make_relative_path(source, dest, dest_is_directory=True):
  968. """
  969. Make a filename relative, where the filename is dest, and it is
  970. being referred to from the filename source.
  971. >>> make_relative_path('/usr/share/something/a-file.pth',
  972. ... '/usr/share/another-place/src/Directory')
  973. '../another-place/src/Directory'
  974. >>> make_relative_path('/usr/share/something/a-file.pth',
  975. ... '/home/user/src/Directory')
  976. '../../../home/user/src/Directory'
  977. >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
  978. './'
  979. """
  980. source = os.path.dirname(source)
  981. if not dest_is_directory:
  982. dest_filename = os.path.basename(dest)
  983. dest = os.path.dirname(dest)
  984. dest = os.path.normpath(os.path.abspath(dest))
  985. source = os.path.normpath(os.path.abspath(source))
  986. dest_parts = dest.strip(os.path.sep).split(os.path.sep)
  987. source_parts = source.strip(os.path.sep).split(os.path.sep)
  988. while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
  989. dest_parts.pop(0)
  990. source_parts.pop(0)
  991. full_parts = ['..']*len(source_parts) + dest_parts
  992. if not dest_is_directory:
  993. full_parts.append(dest_filename)
  994. if not full_parts:
  995. # Special case for the current directory (otherwise it'd be '')
  996. return './'
  997. return os.path.sep.join(full_parts)
  998. ############################################################
  999. ## Bootstrap script creation:
  1000. def create_bootstrap_script(extra_text, python_version=''):
  1001. """
  1002. Creates a bootstrap script, which is like this script but with
  1003. extend_parser, adjust_options, and after_install hooks.
  1004. This returns a string that (written to disk of course) can be used
  1005. as a bootstrap script with your own customizations. The script
  1006. will be the standard virtualenv.py script, with your extra text
  1007. added (your extra text should be Python code).
  1008. If you include these functions, they will be called:
  1009. ``extend_parser(optparse_parser)``:
  1010. You can add or remove options from the parser here.
  1011. ``adjust_options(options, args)``:
  1012. You can change options here, or change the args (if you accept
  1013. different kinds of arguments, be sure you modify ``args`` so it is
  1014. only ``[DEST_DIR]``).
  1015. ``after_install(options, home_dir)``:
  1016. After everything is installed, this function is called. This
  1017. is probably the function you are most likely to use. An
  1018. example would be::
  1019. def after_install(options, home_dir):
  1020. subprocess.call([join(home_dir, 'bin', 'easy_install'),
  1021. 'MyPackage'])
  1022. subprocess.call([join(home_dir, 'bin', 'my-package-script'),
  1023. 'setup', home_dir])
  1024. This example immediately installs a package, and runs a setup
  1025. script from that package.
  1026. If you provide something like ``python_version='2.4'`` then the
  1027. script will start with ``#!/usr/bin/env python2.4`` instead of
  1028. ``#!/usr/bin/env python``. You can use this when the script must
  1029. be run with a particular Python version.
  1030. """
  1031. filename = __file__
  1032. if filename.endswith('.pyc'):
  1033. filename = filename[:-1]
  1034. f = open(filename, 'rb')
  1035. content = f.read()
  1036. f.close()
  1037. py_exe = 'python%s' % python_version
  1038. content = (('#!/usr/bin/env %s\n' % py_exe)
  1039. + '## WARNING: This file is generated\n'
  1040. + content)
  1041. return content.replace('##EXT' 'END##', extra_text)
  1042. ##file site.py
  1043. SITE_PY = """
  1044. eJzVPP1z2zaWv/OvwNKToZTKdJJ2OztO3RsncVrvuUm2Sae5dT1aSoIk1hTJEqRl7c3d337vAwAB
  1045. kvJHu/vDaTKxRAAPDw/vGw8Mw/C0LGW+EJti0WRSKJlU87Uok3qtxLKoRL1Oq8VhmVT1Dp7Or5OV
  1046. VKIuhNqpGHvFQfD0D36Cp+LTOlUGBfiWNHWxSep0nmTZTqSbsqhquRCLpkrzlUjztE6TLP0n9Cjy
  1047. WDz94xgE57mAlWeprMSNrBTAVaJYig+7el3kYtSUuObn8Z+TL8cToeZVWtbQodI4A0XWSR3kUi4A
  1048. TejZKCBlWstDVcp5ukzntuO2aLKFKLNkLsU//sFLo65RFKhiI7drWUmRAzIAUwKsEvGAr2kl5sVC
  1049. xkK8kvMEJ+DnLbEChjbBPVNIxrwQWZGvYE25nEulkmonRrOmJkCEslgUgFMKGNRplgXborpWY9hS
  1050. 2o8tPBIJs4e/GGYPWCfO3+ccwPF9HvyUp7cThg3cg+DqNbNNJZfprUgQLPyUt3I+1c9G6VIs0uUS
  1051. aJDXY+wSMAJKZOnsqKTt+Ebv0LdHhJXlygTmkIgyd+ZGGhEH57VIMgVs25RII0WYv5GzNMmBGvkN
  1052. TAcQgaTB0DyLVNV2HlqdKABAhftYg5RslBhtkjQHZv0hmRPaP6f5otiqMVEAdkuJXxtVu+sfDRAA
  1053. ejsEmAS4WWY3mzxLr2W2GwMCnwD7Sqomq1EgFmkl53VRpVIRAEBtJ+QtID0RSSU1CZkzjdxOiP5E
  1054. kzTHjUUBQ4HHRiTJMl01FUmYWKbAucAVb9//KN6cvTo/fad5zABjmV1tAGeAQhvt4AQTiKNGVUdZ
  1055. AQIdBxf4RySLBQrZCucHvNoOR/fudDCCtZdxd4yz4UB2vbl6GlhjDcqE5gpo3H/DkIlaA33+5579
  1056. DoLTfVShhfO37boAmcyTjRTrhPkLOSP4RsP5Ni7r9UvgBoVwaiCVws1BBFOEByRxaTYqcilKYLEs
  1057. zeU4AArNqK+/i8AK74r8kPa6wwkAoQpyaHSejWnGXMJC+7Beor4wnXe0Mt0lsPu8KSpSHMD/+Zx0
  1058. UZbk14SjIobibzO5SvMcEUJeCKKDiCZW1ylw4iIWF9SL9ILpJCLWXtwTRaIBXkKmA56Ut8mmzOSE
  1059. xRd1691qhCaTtTB7nTHHQc+a1CvtWrvUQd57EX/ucB2hWa8rCcCbmSd0y6KYiBnobMKmTDYsXvW2
  1060. IM4JBuSJBiFPUE8Yi9+BoqdKNRtpG5FXQLMQQwXLIsuKLZDsOAiEOMBOxij7zAmt0Ab/A1z8P5P1
  1061. fB0EzkwWsAaFyO8DhUDAJMhcc7VGwuM2zcpdJZPmrCmKaiErmuphxD5ixB/YGdcavCtqbdR4ubjL
  1062. xSatUSXNtMlM2eLlUc368SWvG5YBllsRzUzXlk4bXF5WrpOZNC7JTC5REvQmvbTbDnMGA3OSLa7F
  1063. hq0MtAFZZMoWZFixoNJZ1pKcAIDBwpfkadlk1Ekhg4kEJtqUBH+ToEkvtLME7M1mOUCFxOZ7DvYH
  1064. cPsniNF2nQJ95gABNAxqKdi+WVpX6CC0+ijwjb4Zz/MDp54vtW3iKZdJmmkrn+TBOT08qyoS37ks
  1065. cdREE0PBCvMaXbtVDnREMQ/DMAiMO7RT5mthv02nsyZFezedBnW1OwbuECjkAUMX72ChNB23LKti
  1066. g80WvY+gD0Av44jgQHwgRSHZx/WY6SVSwNXKpemK5tfhSIGqJPjw49nb889nH8WJuGy10qSrkq5g
  1067. zrM8Ac4kpQ580Zm2VUfQE3VXiupLvAULTfsKJolGkwTKpG6A/QD1T1VDzbCMudcYnL07fXVxNv3p
  1068. 49mP04/nn84AQTAVMjigJaOFa8DnUzHwNzDWQsXaRAa9EfTg1elH+yCYpmr6K7vGJyzs2g+6PP7q
  1069. SpyciOjX5CaJgmAhl8CZ1xL5d/SU3MYx7w8sF8YW2oz9WqS5aadm8GKcSVC8RjQCQE+n8yxRCjtP
  1070. pxEQgQYMfGBAzL4nMuUIBpY7d+hYo4KfSgLRchwywf8GUExmNA7RYBTdIaYTcPNmnijJvWj5MG46
  1071. RZGeTkd6QuB14kbwR1hKI2G6oEhXKbh9tKso4jNVZPgT4aOQEHNj5IFKBGmvI4v4JskaqUbOopaA
  1072. /krWCHIEFikyk0QT2sex7QjUXqJc4tNjj5xoJdK8kfbhJrao9mmz1Guu5Ka4kQsw1rijzrLFj9QC
  1073. kVyZgSqFZYEeIPvB8mr8jATjFtYlwD5oa4C1NwTFEMTQ4oCDR5kr4HoOxEgOdJTIqrOsipsUjdNs
  1074. pxtBt4JkooY1hlBDK9CL96iOKhT0LXhNOVJqKyOQvaphB4fwRpConRatFMcE7gLVwhV9vc6LbT7l
  1075. yOkEJXw0tnuJnKZ3Ezu0W3Ag3oLOAyQLCARaojEUcBEFMtshIA/Lh+UCZckXBUBgGBS59w4sExrQ
  1076. EjnKwGkRxvilIG6uJNqXGzMFueaGGA4kao3tAyM2CAkWZyXeyopmMjSCphtM7JDE57qLmEMWH0CH
  1077. ijHo6JGGxp0M/S6PQQmJC1dKnXGo/j9//sxso9YUjyNiM1w0mpwlaea43IEWT8HNNRaco3tiA4jS
  1078. cwDTKM2a4vCjKEq23rCfnDYAE/kRfMV1XZfHR0fb7TbW0WhRrY7U8ujPf/n66788YyWxWBD/wHIc
  1079. adGpmfiI2tADir8xmvZbs3MdfkxznxsJ1kiSFSfXBfH7rkkXhTg+HFuFglzc2gT839hNUCBTMylT
  1080. GWgbthg9UYdP4i9VKJ6Ikdt3NGYjqIMqq9YhOCKFBG2gkmBEXYDZASM5L5q8jhz1pcQXoO4holvI
  1081. WbOK7OSe0TA/YKkopyPLA4fPrxADnzMMXymtqKaoJYgt0nxZOKT/kdkmIVOsNQSSF3V2L9raDWsx
  1082. Q9zFw+XdOjaO0JgVpgq5AyXC7/JgAbSd+5KDH+1HfdqVrh9lPp4hMKYvMMyrvZgRCg7hgnsxcaXO
  1083. 4Wp0r0CatqyaQcG4qhEUNHgkM6a2Bkf2P0KQaO5NcMgbq3sAnTqZJhNPml2AHu48PWvXZQXHNUAe
  1084. OBHP6YkEf+y41/aMt7bJMkoAdHjUowoD9jYa7XQBfDkyACYirH4KuafelvP3nU3hPRgAVnDOABls
  1085. 2WMmbHGdovAgHGCnntXfN5ppPAQCN4n6Pww4YXzCE1QKhKkc+Yy7j8MtbTlP0kF4v8EhnjK7RBKt
  1086. 9shWV3cMytSddmmZ5qh6nT2K51kBXqJVisRHbbvvK5DPjY+HbJkWQE2GlhxOpxNy9jz5i3Q/zLas
  1087. GoxL3bAdMdqkiowbkmkN/4FXQeEw5S6AlgTNgnmokPkL+xeInF2v/rKHPSyhkSHcrvu8kJ7B0HBM
  1088. +4FAMurgHYQgBxL2ZZE8R9YGGXCYs0GebEOz3CvcBCNWIGaOASEtA7hTYzsMFwhPYkyYk4Ai5Nta
  1089. yVJ8IULYvq6kPkx1/0u51AS8I6cDeQo6Uj5xo2gngj7pRNQ+Q/uxNKXWywI4eAYej5sXdtncMK0N
  1090. 8MFX9/W2RQoUMsX84dhF9coQxs09/unE6dESy0xiGMqbyDsBMDONA7vdGjRsuAHj7Xl3Lv3YDcxx
  1091. 7Cgq1Au5uYXwL6pSNS9UNEZ72gbaA8qPuaJPG4vtRToL4Y+3AeH4yoMksy46GMgvkmqb5hGpGL3C
  1092. E594PXTsYj0rdPSR4p0jQAVTWEdvK2BhOss6AoZHWS1LCLKV9sv7YO9caWjh8vDQ82svj7+86i9/
  1093. si8nYT/DxDy7ratEIT0zJiuzLdKzb2FRLcLiknynT6P0aSX68VWhIMwT7z9+FkgITtRtk93jlt6y
  1094. JGJz75q8j0EdNM+95OqsjtgFEEG9hYxyFD2eMR+O7GMXd8fCHgHkUQxzx6YYSJpPfg+cuzYK5jhc
  1095. 7PKsSBZdocYPNH/91XQgl+ci+fVX4T2zdIgxJPajjq9mZ6ZTYjG4bDOkkklG3oAzCB0B0ImXvT7l
  1096. mFUuBWiaya4G3EL8mHaj1Fv4ve69yM58DogeEAcXs18hmlQ6AXWTpBklfAGNw0PUcyYQ5th+GB8P
  1097. 0t0oY9IIfIpnk8FYRV0+g42JOPIe95ejPZdTk60ciBjNp0xUH5UDfT7bHi94Z67u0dJ+2R+0pf8m
  1098. nfVIQN5qwgECPnAN5ujr//9KWFkxNK2sxh2tr+Tdet4Ae4A63OOI3OGG9Kfmk5KlcSZY7pR4igL6
  1099. VGzpvJOSbeCL5ABlwX7GABzcRn1q9rqpKj77IjkvZXWIh0ETgaUextOgCpI+mKN3skZMbLc5JS+d
  1100. woBiSHVGOh1pVxK1nuSwyK4Lk8SQ+U1awVjQKqPo+/c/nEV9BtDT4KBhcO4+Gi55uJ1CuI9g2kgT
  1101. J3rMGKbQY4b8fqmKPA7tKldzHmlShJpsfcL2MoMmshzeg3tyBN6RFh/yYcw2X8v59VTSwSWyKQ51
  1102. sqSvsRkxseeZfgGJSpZUBQMrmWcN0oodPSxfWjb5nBLmtQR7rmsNsfaAjiM5IbTMkpUY0eAFJiM0
  1103. N1K+4iaptLdTVgVWt4kmXRyt0oWQvzVJhoGeXC4BFzzN0E0xT085CfGGT1S56knJeVOl9Q5IkKhC
  1104. HwbR4avTcbbjhY48JDnvzwTE49hj8RGXje1MuIUhlwkX/RQ4LhIjMRxgTuuQu+g5tOfFFGedUpHg
  1105. hJHqn1zS46A7QwEAQgAK6w/HOpfjt0hqck+caM9doqKW9Ejpxp4FeRwIZTTG2Jd/00+fEV3e2oPl
  1106. aj+Wq7uxXHWxXA1iufKxXN2NpSsSuLE2jWEkYSiV0c1zD572u1kInuYsma+5HxaPYZEYQBSlCeiM
  1107. THENpZfr4AMfAkJq2zmBpIft6X3KVWlVwUlRDRK5H081dPBoql+dwVQLoAfzUozPtq+CwR97FMdU
  1108. azKj4Sxvi6ROYk8uVlkxA7G16E5aABPRLWbg7Fl+M51xvq9jqcIP//Xp+/fvsDuCCs15Nw3DTUTD
  1109. gksZPU2qlepLUxtslMCO1NMvVaBhGuDBA3MtPMsB//emwCIkZByxpSPrQpTgAVBNie3mVl5EUee5
  1110. LtHQz5nJ+fThRIR5HbaL2kOk0w8f3px+Og0pCRT+b+gKjKGtLx0uPqaH7dD339zuluI4BoRa51Ja
  1111. 4+euyaN1yxH321gDtuP2PrvqPHjxEIM9GJb6q/y3Ugq2BAgV63TgYwj14ODnD4UJPfoYRuyVHrln
  1112. Leys2DZH9hwXxRH9oUR0dwL/9AtjjCkQQLtQIxMZtMFUR+lb83oHRR2gD/T1/nAI1g29upGMT1G7
  1113. iAEH0KGs7bbf/fMy92z0lKxfnX13/u7i/NWH00/fOy4gunLvPx69EGc/fBZUMIAGjH2iBM/KayxN
  1114. AcPi3pQQiwL+NZjeWDQ1JyVh1JuLC52732CtPBZPos2J4TnXtVhonKPhrKd9qAtSEKNMB0jOpQSq
  1115. 36BLCxgvbbggXhW6wJLuOszQWW106KUvm5hLKXTQGYP0QWeXFAyCa46gicpgaxMVVnwmpC9qDCCl
  1116. bbStFMgoB9U7P3ZOREy+3UvM0WB40g7Wiv4ycnGNrmJVZilEci8jK0t6GNZLtIyjH9ojT8ZrSAM6
  1117. w2Fm3ZFXvRcLtFovI16bHj9uGe23BjBsGewNrDuXVC9ABaBY7SQi7MQnB5G8ha926/UeKNgwPPqp
  1118. cRMN06Ww+gSCa7FOIYAAnlyD9cU4ASB0dsJPQB872QFZ4HF99HqzOPxbpAni9/7ll4HudZUd/l2U
  1119. EAUJri2JBojpdn4DgU8sY3H2/u04YuSoeFH8rcH6YnBIKMvnSDsVtPCZ6nSkZLbUBQe+PsAG7SdQ
  1120. c2d4JctKDx92jSOUgCdqRF7DE2XoF2H9j4U9waWMO6CxdNpihleQ3INp8zkQH9cyy3S17fmbizPw
  1121. HbGaGyWIz3nOYDrOl+Chqq7G4itSHVB45ArNFbJxhS4sHbsvYq/bYGYWRY5Geyf1dp8o+9kf1Ut1
  1122. VkmqXLRHuGyG5dQzx8jNsB1mZ5m7+92Qzm43ojtKDjPG9ENFdY0+ZwBH09OEAyOImLBi3CSb+XQx
  1123. zWtTyJalc9CmoHhBrU5AVJDEeC2K+K/IOd1bVMrcpoCH5a5KV+saU+owOKZKbuz+w+nni/N3VBr9
  1124. 4svW9x5g0QnFAxMuLjjByjHMecAXtxoMeWs6HeJc3YQwUAfBn24TVy2c8AS9cZxexD/dJr7OcuLE
  1125. g7wCUFNN2RUSDAOcYUPS00oE42qjYfy4lWEtZj4Yykhi9bwuAHDX1+dH27NjUCj7YxofcVaxLDUN
  1126. R2awW6nU/eg1Lks8XFmMhjtB65CEmc8Mhl73WvbVRLmfnizizTrAqN/bn8NUDfW66uU4zLaPWyi4
  1127. 1Zb2l9zJmDr95jmKMhBx5A4eu0w2rIp1d+ZAr7q2B0x8o9E1kjio0MNf8lD7GR4mlti9aMUMxFJB
  1128. NgWYz5D6/kEDnhTaBVAgVBQ6ciR3Mn76wlujYxPuX6PWXWAhvwdFqEs0qRa+qIAT4ctv7D5yE6GF
  1129. qvRYRI6/ksu8sPVD+Nmu0bd87q9xUAYolYliVyX5So4Y1sTA/MIn9p5ELGlbj2Mu0061hOZu8FBv
  1130. 9zB4XyyGT08MZh0+6PW7lruuNvKpgx0GLwj4EKpkC9q9bOoR79XewwLsro9gRxEmSX6L9tDrHvQ0
  1131. LPS7fhs4w8EPE8u4l9ZedW5jRLZB+5XzCgKmWtFhiWOFjYfoGubWBp60Vji0T3XFiP09cMXFqUN1
  1132. 4TIKLlRvhaHu0An1w79yLo+uhaVUu9xefdBtC3kjswLcIoi4sDT9V1uaPo4HUx334NWiggT9Rbvj
  1133. SX5NHuLrn88n4vW7H+H/V/I9xBR47Wgi/g4IiNdFBbEVX32jO8lY1l5z0FQ0Cu8mETRK0/P1bXRW
  1134. PnjrwCMBXW/vF9pb/SCwxrDa8DsDAEVeI10Hba2jqSKH3+aaS98NMy7S0K6EuhHJsL/4Hwvmj3TP
  1135. eF1vMlSUTpKg3c7L8OL89dm7j2dxfYt8ZH6GThLBr3/BFekj0gqPgybCPpk3+OTK8Ri/l1k54DDq
  1136. mMtcJMCYS0Tglpc2zuIr6Yn1rZMKA2dR7hbFPMaewFV0E1DUW/Agx054da+F88wLwhqN9SFS68bi
  1137. Y6CG+KUr8SF0pDF6TTSSEEpmeImGH8fhsA2aCMrswp+n19uFmxjWtyFogV1M21WP/OFW6ayZzhqe
  1138. y0yE2ondCXNpLEsTtZnN3btT73OhXyoA6oQy/XKZNFktZA5RBYW5dLsbtKp73YnlhLmFdTndAaJE
  1139. RbZNdsqpNUmUCHHWkC6o4pEE5cwgCv0huWbdi/ewRMN3EQE6IUqxQ+EMVc18zXLM4YBWd72j922a
  1140. f/ki6hGZJ+UYcd46cbBOdJkYo5Ws9fr5wWh8+bw1o5SXnXu3/+YlWBiXUw5AfZZPnz4NxX/cb/kZ
  1141. lTgrimtwSQD2UEAoLqh5j83Wi7O71fdqTUsMLDlfy0t4cEX5Y/u8ySk5d8dQ2hBp/xoYEe5NZPnR
  1142. 9O/YQE5bVXzUyj34yEbbjp/ylF4dgskViSpXv4EFEy9GoIglQTdEiZqnacSBOuzHrmjwnhIm2jS/
  1143. yFvg+BTBTLAVz4g4zFyjd0Uli5Z7LDonIiTAIZUQ8Wx085Fu6gCe0w87jeb0PE/rtsb+mXt8qO/i
  1144. 1vaNIJqvRLJFyTDr6BDDufLmsWrrXRZ3sqjnrRfzSzfl1lklN9+HO7A2SFqxXBpM4aHZpHkhq7kx
  1145. qrhj6TytHTCmH8LhwfQiFDJAcTCAUggangzDwkq0bf2T3RcX0/d0knpoZtIFNLV9uQynR5K8U0cW
  1146. x+38lIixhLR8a76MYZZ3lNjV/oA3l/iTTitigbV3B9696tXk+m47VzC0F94BDr1PxSpIy46ejnBe
  1147. 4mPhM9NqR769Cu/Ug2N4SrjdpFXdJNlU37+eoss2tUfLGk97RejOy2/WZwGHugBX81AXS4PvYOpM
  1148. kJ5Y62jK1SE+1+F57F678W+olAX6ei88PY5J32d82dvR4NjzC3Nx4yEq31wf6FXeu1hOqKonGndr
  1149. FXu98AQh0jVflJYd8rAfNaWB5brCDwWQAQD4w45f9EXnFMgpTeO60X2p/x7Qr7+6C6yrZAaLZinf
  1150. 7isefXHJrWJtE/4sy8bnW4NbiZKxMFdNteDxrTyUElb59iaxqXXoXoiA5ocv+Y4FP+A0LcLJDp+o
  1151. SLvZhiPvopXF7y5StZ2C30UlPWqYVujmYZnhOuEWFNemPLbBEF/VyilFO3KLT/BTXw+WZSf4UhYk
  1152. 6GF9Hd21fB5/19p1j8Cu3Jy99NbuX79waaDH7ueXIRqwC6oJ8aCKTovR9F8juhN9LDic3tCfpX09
  1153. HGc5iAc1ahPNkptk7n7Hw+lDfrtcWx/oXI5wd72zpr3Xhg079zm5z818EIfP7f03Ol1daPZig0Xv
  1154. Gplyvc5UrlZqmuCraqbk5dDZcs98Gbv5ll5TIhO1M+YOb9QDCMMqugrILfSDXQdPil+Zx0ezztVp
  1155. QVNTAZNTEaXSBUev2rYCuJijVhpvkiJc0hRmEvMNqqnKCtyRUL9Yjc8Mh8qsWqAmgtok6tqgbkZM
  1156. 9Hu2cAo+qDbXbzhWZhfHow4Qgqvynfd2cI3gdGrbgF+etRcB04llCJk3G4iP6/YOvH82kYpvnRno
  1157. 0hVusBMjtWLX4RQXsdTyh4MURin2+xfa/HvezR23/8ZWpT2crWiEDr8fc7HQkXLDzemtfSmM++6F
  1158. Bb2vjyIifneCsN1a7rP3/mEr/qpf+kCKUAct3KpfMsEvzuKsClZkOXwEcu9eefAr46zOYofBouE8
  1159. cxVD/60CeGuODO3Q23N6XNB/T47PDO38vt6wzNLLRO/pbKl4wj0GFU8727h15bGI5R5X3i9UfKQr
  1160. 78F/oCuv33UE1kTjo/XBYOniPT4/qwn3xUEtI8CYKRAJk+2dt+wYezhyCwHBIU9vQ/uWPNaZzu0C
  1161. YyaQI/sv0CAQP3Dljls15b2vxMw75Gv70kWPv7t4/+r0gmgx/XD6+j9Pv6MjYsxbdWzWg2OdvDhk
  1162. ah96JWlu3KOP9YYmb7EdeGcW11VrCL323pHIAIThGvqhDe0qMrd534BeLXJ/ECB+97I7UPep7EHI
  1163. PedL1726h3md2rFAP+VCH/PLOZcxj0zWlMWhTYma9jaLpWW0F+Tv2zin5KavTrRTql9VtScBMbaF
  1164. X7QDmLxC/rK5K1PFazMk7Kh0311M1Wp4A8Lc8wYpnEvndUP0piEGVfsvSa5A2SWYg2eHcWJfOEj9
  1165. OE+n7Js0MQ8/l7EhiHcFIeyvzxX2hcz2UCEIWOHpl+kwIkb/6cy2PQ16osTlIV12OkRlc2V/4Z5p
  1166. J/fnFM98avtWCmWOSzHfDZ2XTeae49gxvQHk/FFasFg61bWg+Y6Azq14KmBv9JlYIc52IoIoUR9W
  1167. YMEO0VG/UcZBHu2mg72h1TNxuO8qjHsVRIjn+zsuOrdN9IgXPELdM0I15sKBY4GxZmTfHRfxLUHm
  1168. vLKg11B4zgeeZ+iX/MHXm8vnxzYpifyOze5LDpD2oWPYL9uq8jtffOSMJl6pJlQ7gIUq4y74q9Bh
  1169. zaXYH+D0amT3BEHmwIkhhV778Lm6GeG9TDTsImr57hgWJEZP1JgW5VQVa9ztk3Fvsa3K6sPgAun7
  1170. YfS0H4BCKMO+CX74XRugnp/peHDW0NvirMOJ1wodeaBDcp8XeITx+lrsusPpWtODhlO5uC0y5w5d
  1171. 3tP7DWLNXgP38hId+21Bd+UtD+yx/XxBbHj88weM75dT2OEv7nKoba8vBy8lsBOLBTh4PNuhkHkc
  1172. g3UBhTkiNY21m0bC8eJ3S0aHm9qlIVegw0c1PfgmSAosyImdastvjUHwfz3zySQ=
  1173. """.decode("base64").decode("zlib")
  1174. ##file ez_setup.py
  1175. EZ_SETUP_PY = """
  1176. eJzNWmuP28YV/a5fwShYSIJlLt8PGXKRJi5gIEiDPAoU9lY7zxVrilRJyhu1yH/vmeFDJLVU2iIf
  1177. ysDZXXJ45z7PuXekL784nqt9ns3m8/kf87wqq4IcjVJUp2OV52lpJFlZkTQlVYJFs/fSOOcn45lk
  1178. lVHlxqkUw7XqaWEcCftEnsSirB+ax/Pa+PuprLCApScujGqflDOZpEK9Uu0hhByEwZNCsCovzsZz
  1179. Uu2NpFobJOMG4Vy/oDZUa6v8aOSy3qmVv9nMZgYuWeQHQ/xzp+8byeGYF5XScnfRUq8b3lquriwr
  1180. xD9OUMcgRnkULJEJMz6LooQT1N6XV9fqd6zi+XOW5oTPDklR5MXayAvtHZIZJK1EkZFKdIsulq71
  1181. pgyreG6UuUHPRnk6HtNzkj3NlLHkeCzyY5Go1/OjCoL2w+Pj2ILHR3M2+0m5SfuV6Y2VRGEUJ/xe
  1182. KlNYkRy1eU1UtZbHp4LwfhxNlQyzxnnluZx98+5PX/387U+7v7z74cf3f/7O2BpzywyYbc+7Rz//
  1183. 8K3yq3q0r6rj5v7+eD4mZp1cZl483TdJUd7flff4r9vtfm7cqV3Mxr8fNu7DbHbg/o6TikDgv3TE
  1184. Fpc3XmNzar8+nh3TNcXT02JjLKLIcRiRsWU7vsUjL6JxHNBQOj4LRMDIYn1DitdKoWFMIuJZrvB8
  1185. y5GURr4QrrRjzw5dn9EJKc5QFz/ww9CPeUQCHknmeVZokZhboRM6PI5vS+l08WAAibgdxNyhIghs
  1186. SVyHBMJ3hCcjZ8oid6gLpa7NLMlCN45J4PphHIc+IzyWPrECO7oppdPFjUjEcJcHgnHHcbxQ2mEs
  1187. Q06CIJaETUjxhroEjuX5xPEE94QtKAtDKSw3JsQTgQyFf1PKxS+MOsSOfOgRccKkpA63oY/lUpfa
  1188. zHtZChvlC3WlQ33fjXmAuIYy9AgPY9uBIBJb0YRFbJwvsIcLDk8GIXe4I6WwPcuK3cCTDvEmIs1s
  1189. a6gMgzscQn3uEsvxA88PEB9mu5FlkdCKrdtiOm38kONFxCimkRWGDvNj4rsk8lyX+JxPeqYW47di
  1190. uPACwiL4Mg5ZFPt+6AhfRD7SUdCIhbfFBJ02kUAlESGtAA5ymAg824M0B0bC4RPRBqgMfeNQIghq
  1191. 2HY53kcZOZEIKfGpT6ARF7fFXCLFAzeWMbUgzGOe48Wh5XpcMEcwizmTkbKHvgk8FnvSpTIkIbLQ
  1192. FSxyhUUdhDv0YurcFtP5hkoSO7ZlUY4wcdQEJAnOXQQ+8KwomBAzwhlpWYFHZUCIQ0NuQS141kNi
  1193. W5EdMmcqUCOcCezAjh0hmOtLLxSImh0wHhDbgVQnnJIywhlpRwAogC+XSBXi+DGLIUXaPKRhJCfQ
  1194. io1wRliCh14QOSyOIyppCE9HFrLXQsxDeyrY7jBIhAppB5JzGOb7vu1Fns1C4BePozjwp6SM0Ipa
  1195. NLZdmzBCXceCM4BzofQ85gMoQlvelNJZhCSR2DPgnqTSRUVRGXsBs+AqoJ6YShhvaFGk0BrA7zqM
  1196. 05iFDmXSA3w5gXQiIqfQyh9aJEQseWRBHRQkMla6ApjuhwAMHtnBVKT9oUVEAqu4BKvYoWULAeeG
  1197. ICefMhAeCaZQxh/FKOKuDAAIHmOERKHtIXG4G1LGuMt9PiElGFqEgonA8pFtB2CiKPJCByLAmL4X
  1198. o7SngDMYsRvzAyL9kMK/6B5QDYEFQzzPRYH5ZAobgqFF1JERCX0HZA/YpS5I2kKoufAlWgnfnZAS
  1199. juDOQoxkTDhzSWD7wrdtH2WIliICBE7mSzhiAhLJ2PfAAhxYbkkahEza0kEY8MiZqoBwaJEHjiXA
  1200. W4mWAQXouZ5t25KLyLXxL5zSJRp1Q5bqhZwYHok5+EOlIAA8ci3VWFm3pXQWMUrcCNiAnsOLXGap
  1201. nEW2wdkMzDJJA9HQIjt07BAgh0DHnNm+5ccW8SPqCtR57E9FOh5aBN2ZZ6GZsZWHqRcHwmOSCiuC
  1202. rcyainQ8QgYkGRo7cKsbRTwAOhEhrADgxQLXm+rvGimdRVIgtK7wiR1S22EIE/M9m4bgXjC/mGKS
  1203. eMhHjKBsbKlQkziCA5js2AWzhdSPHfQ4kPLrrDcRYLwpZ1Vx3tQD156U+zSh7byF3n0mfmECo8Z7
  1204. feedGomatXjYXzfjQhq7zyRN0O2LHW4todMuwzy4NtQAsNpoAxJptPfVzNiOB/VDdfEEs0WFcUGJ
  1205. 0C+ae/FLfRfzXbsMcpqVX2w7KR9a0Q8XeerC3IVp8O1bNZ2UFRcF5rrlYIW65sqkxoJmPrzDFEYw
  1206. hvEvDGP5fV6WCU174x9GOvx9+MNqfiXsrjNz8Gg1+EvpI35JqqVT3y8Q3CLT7qodOhoO9aJmvNqO
  1207. hrl1p9aOklJsewPdGpPiDqPqNi9NdirwW51M3QtcpOS8tf1ZEySMjV+dqvwAPzBMl2eMohm/78zu
  1208. nRSouf5APiGWGJ4/w1VEOQjOU6YdSbWvx/nHRulHo9znp5SraZbUvu5Layfz7HSgojCqPakMDMKd
  1209. YC1LTcCZ8q4hMfV2Sp0yrl8RxuPAEY+GGmmXz/uE7dvdBbRWRxO1PGNxv1iZULL20qPaUsnpHWPs
  1210. RTE4IHlOMHPTSyYIvkZG1gmuVc5y+CMtBOHni/rY473sqafdrrdrzia0mKrRUkujQqvSOESfWLA8
  1211. 42Xtm1aNI0GiKKfCI6qskipB6LKn3nlGHfHG/jwT+jyhPhvhtV5wap4qH754PqK0bA4bRCNMn+UU
  1212. +Qk7iVqVus6IcRBlSZ5EfcBxKbrHR50vBUlKYfx4LitxePeL8ldWByIzSIV79ckGoQpalPEqBZUx
  1213. 9amH2Wao/vlMyl2NQrB/ayyOn552hSjzU8FEuVAIo7Y/5PyUilKdkvQAdPy4rglUHUceNG5bri5I
  1214. olJueymaXl02HhuVYFt261GhXTCgLRITnhVFtbTWapMeyDVA3e30pn+6Q9tjvl0TmJ0G5q2SUQcI
  1215. wD6WNXCQfvgCwncvtYDUd0jz6HqHgWizSa7l/KLx2+38VeOq1ZtGdl+FoYC/1Cu/zjOZJqyCazZ9
  1216. 9O9H/r9F+/lP+0v2T+T78u32rlx1tdzWsD7K/JgNAX/OSLaoVEl1JQLMUMd3ukaa4zpVLacsQyqb
  1217. xvepQIa0y6/kqRpSpQwAErCl1VAmRQlHnEpVDgtIOLehN17/3FN+YY7kfcw+ZsuvT0UBaYDzWsBd
  1218. MeKtFVjrksvCJMVT+cF6uM1ZOn5pKYYxQKIPw7nuV9qHUZ0+qFe+hLUayfNPA1Ev5eB01nyToCQS
  1219. elIM/l1e/SkHL9zO55ppXyrr35tuVfGjPAc8+80LpKrLmFxIwUhzVrckGj5rG5KqPiHWLcb/KcnW
  1220. EK0+A2hJ9rc4Vt1Tu14TbI37jxfOnODFvGbDlgwVqbDqRNKLEQ3JDImk/YihANdQB9m6RwqldZ61
  1221. /erW6IHZ67sSvfddqVrveb9wRkfgda5Cbp87lM+MV8MWsSSfBbTfoiWvSeHveZItWwppl9biyoIp
  1222. cbpP/g5s3rbWCqra11GkZVUua7GrjSqwrz7niUqgoyCKL1t1yq4+BniuLp2KHIKUN8rWS2n+NFil
  1223. mnEVl+G76sJK85kU2VL5+fXvd9WfkDTA2iB5+VKW3+mUUJ+cLMVnkak/YM4Rys72Ij2qvu99nW29
  1224. 3qNLFTQnKv/VZztL5YoZKGFtAF1m6tYB5ZwJOBKvoA5V5wuEFs8KjwnG2bLUb/c5QCO4OWu2BHQ3
  1225. Pc5lR6jM22w2Z7MlQExslIe1mANhe9Vu8VzUxLRHeKFE9ZwXn5pN18axZpecVqT5XE4hhUaJu3I2
  1226. UygCDzDdtesFkHypxKZyCtGwVd8Ac/V7RhFJsb5KmR7oXjVUOsvWqpquXkNHoZO1StRk2TROqRDH
  1227. N/WP5aj3GmZnC8OaF8u53mLEe7rkGnww8TM/imx5texL4wc0/ffPRVIBfBBj+Fe328DwT2v10eCz
  1228. ip5qF1ihyhDQyPKiOOnkSMVImI57Pz1UF14Jvb7FxPZqPmabGsJhgKkGkuVqqHGNItqaGivW82c6
  1229. hzvxwNR21GN49xKGQTUUbsYQgA02eheW5qVYrq4goqw2Wmj/ecNmLWhBwVT90sLW7D+5FH8fkOlL
  1230. NCyf11OMfeHc97c+NNUc+w6tVbOqJYiXmunRh9G3Oul6eOiw+kriZc3tAUNP6tZ1SzYcIwZThI6Z
  1231. Ko3e7MDywwGGmoMesj3OIc1A1l5NjLSLU3CB9vPqlTpteVjpNH0Wi0KntTAUjf9mqihLlZ9HXKXU
  1232. vuYQLDplmAA/LTuzhg1n0m/czd2u8dZuZ2wxElqmZdqL/3pE+CsAXoOrmotpmacCtToxGrdNP8ik
  1233. buyvGvpCHPLPGm91JOrvPOgJGMxRAXrT38DdUac+2ZI3RfWPYbPSm7z63c71MPgfDHT4eaP/Hk1t
  1234. m+ls/59T8laZdYJ/U8pVNr9Ud225PQxndu1sa4XEh1WK/RE4pjNFPXk5Q9Uuv5MDOvW15jemsDrN
  1235. 5z9etUXzdYsoc4DgkyaiQh3/IgnRJF0Sev6CvMXyB7RT8/bbOebxPJw+5/X3bq6/mmKuFs2x5rHj
  1236. p3aEKS/w/LN+aqgSoackrV7X58QQ+aSGu7NC5H4WF838o3qt9ly5E3txiO65L921+lOtWF66ai2k
  1237. 5UJNmouCLi7PumNm9e5Dc0QtW1J98ZhadmRXj4A1RX+Yqz/uig3+rYEVGB+aTrNuyNqNTJDvoVyu
  1238. HrqXzRIWd9R5VEPFfF5PCjVJ9x2DCGCErNqJQX+faNveNZ9EVRetur/sT+c73THsdk3Wdy5pZKwN
  1239. 7ZY3TUvUOuDN2NgDqTANbqGnWQpSsP1y/jHrfx/oY7b88LdfH16tfp3r9mTVH2P02z0segGxQeT6
  1240. G1mpIRQKfDG/LtIWEWtV8f8PGy3Y1K330l49YAzTjnyln9YPMbri0ebhZfMXz01OyKY96lTvOWAG
  1241. M1o/breL3U4V7G636D4FSZVEqKlr+K2j6bD9+4P9gHdev4az6lLp0VevdrrlzubhJV7UGHGRqRbV
  1242. 178BYnMUkw==
  1243. """.decode("base64").decode("zlib")
  1244. ##file distribute_setup.py
  1245. DISTRIBUTE_SETUP_PY = """
  1246. eJztG2tz2zbyO38FTh4PqYSm7bT3GM+pc2nj9DzNJZnYaT8kGRoiIYk1X+XDsvrrb3cBkCAJyUnb
  1247. u5mbOd3VoYjFYrHvXUBHfyp3zabIndls9m1RNHVT8ZLFCfybLNtGsCSvG56mvEkAyLlasV3Rsi3P
  1248. G9YUrK0Fq0XTlk1RpDXA4mjFSh7d8bVwazkYlDuf/dzWDQBEaRsL1myS2lklKaKHL4CEZwJWrUTU
  1249. FNWObZNmw5LGZzyPGY9jmoALImxTlKxYyZU0/osLx2HwWVVFZlAf0jhLsrKoGqQ27Kkl+OErbz7Z
  1250. YSV+aYEsxlldiihZJRG7F1UNzEAa+qk+PgNUXGzztOCxkyVVVVQ+KyriEs8ZTxtR5Rx4qoH6Hfu0
  1251. aARQccHqgi13rG7LMt0l+drBTfOyrIqySnB6UaIwiB+3t+Md3N4GjnOD7CL+RrQwYhSsauG5xq1E
  1252. VVLS9pR0icpyXfHYlGeASuEo5hW1fqp33WOTZEI/r/KMN9GmGxJZiRR033lFXzsJtU2CKiNH02Lt
  1253. OE21u+ilWCeofXL4/fXlu/D66ubSEQ+RANKv6P0lslhO6SDYgr0ucmFg02S3S2BhJOpaqkosViyU
  1254. yh9GWew94dW6nssp+MGvgMyD7QbiQURtw5ep8OfsKQ11cBXwq8oN9EEEHPUIG1ss2Jmzl+gjUHRg
  1255. PogGpBizFUhBEsSeBV/9oUQesV/aogFlwtdtJvIGWL+C5XPQxR4MXiGmEswdiMmQfBdgvnrm9ktq
  1256. shChwG3Oh2MKjwv/A+OG8emwwTZ3dlzPXHaMgBM4BTMeUpv+0FNArIMHtWL9aSydog7qkoPVefD0
  1257. Nvzp+dWNz0ZMY09Mmb24fPn8/aub8MfLd9dXb17DerOz4C/B+dmsG3r/7hW+3jRNeXF6Wu7KJJCi
  1258. CopqfaqcYH1ag6OKxGl82vul05lzfXnz/u3NmzevrsOXz3+4fDFaKDo/nzkm0Nsfvg+vXr98g+Oz
  1259. 2UfnX6LhMW/4yY/SHV2w8+DMeQ1+9MIwYacbPa6d6zbLOFgFe4CP888iEyclUEjfnectUF6Zzyci
  1260. 40kq37xKIpHXCvSFkA6E8OILIAgkuG9HjuOQGitf44EnWMK/c20D4gFiTkTKSe5dDtNgk5XgImHL
  1261. 2psE2V2Mz+CpcRzcRrDlVe65lz0S0IHj2vXVZAlYpHG4jQERiH8tmmgbKwydlyAosN0NzPHMqQTF
  1262. iQjpwoKiFHm3iw4mVPtQWxxMDqK0qAWGl94g14UiFjfdBYIOAPyJ3DoQVfJmE/wM8IowH1+moE0G
  1263. rR/OPs2nG5FY+oGeYa+LLdsW1Z3JMQ1tUKmEhmFoiuOqG2QvOt1256Y7yYtm4MBcHbFhOVchd0ce
  1264. pF/gGnQUQj/g34LLYtuqgMe4rbSumMlJYCw8wiIEQQv0vCwDFw1az/iyuBd60irJAY9NFaTmzLUS
  1265. L9sEXoj12oP/fK2s8FCEyLr/6/T/gE6TDCkW5gykaEH0bQdhKDbC9oKQ8u45tU/HT37Bv0v0/ag2
  1266. 9OoEv8GfykD0mWoodyCjmtauStRt2gyVB5aSwMoGNcfFAyxd03C/SsUTSFGv3lBq4rnfFW0a0yzi
  1267. lLSd9RptRVlBDESrHNZT6bDfZbXhktdCb8x4HYuU79SqyMqxGih4tw+TJ8f1Sbk7jgP4P/LOmkjA
  1268. 55j1VGBQV18g4qwK0CHLy/NP889njzILILjbi5Fx79n/PlpHnz1c6vXqEYdDgJSzIfngD0XVeGc+
  1269. 6+Wvst9h3WMk+Utd9ekAHVL6vSDTkPIe1Rhqx4tRijTiwMJIk6zckDtYoIq3lYUJi/M/+yCccMXv
  1270. xOKmakXnXTNOJl63UJhtKXkmHeXLukjRUJEXTr+EoWkAgv96Jve2vA4llwR6U7e8W4dgUpS11ZTE
  1271. In+zIm5TUWOl9LHbjdtzZQw49cSDL4ZoBusNAaRybnjNm6byBoBgKGFsBF1rEo6zFQftWTgNDSvg
  1272. MYhyDn3t0kHsK2u6mTL3/j3eYj/zBswIVJnuzXqWfLOYPVWrzS1kjXcxxKfS5u+KfJUmUTNcWoCW
  1273. yNohIm/izcGfjAVnatWU9zgdQh1kJMG2gkLXm0DMbsiz07Zis+dg9Ga8bxbHULBArY+C5veQrlMl
  1274. 8zGfTfFhKyXiudtgvalMHTBvN9gmoP6KagvAU9XmGF0C9jYVIB4rPt064CwrKiQ1whRNE7pKqrrx
  1275. wTQBjXW6C4h32uWwk/fGvtzAAv8x/5h737VVBaukO4mYHVdzQD7w/yLAKg4zh6kqS6EljfdsOCbS
  1276. 2mIfoIFsZHKGfX8Y+YlPOAUjMzV2irt9xeyXWMNnxZB9FmPV6y6bgVVfF83Los3j3220j5JpI3GS
  1277. 6hxyV2FUCd6IsbcKcXNkgV0WheHqQJT+vTGLPpbApeKV8sJQD7/oW3yduVJc7RqJYHtpEVHpQm1O
  1278. xfikkZ27HCp5mRTeKtpvWb2hzGyJ7ch7niYD7Nry8jZbigosmpMpd16BcGH7j5Je6ph0fUjQApoi
  1279. 2O2AH7cMexwe+Ihoo1cXeSzDJvZoOXNP3XnAbiVPbnHFQe4P/kVUQqeQXb9LryLiQO6RONhNV3ug
  1280. DmtU5DH1OkuOgX4pVuhusK0ZNS1P+44r7a/BSqoJtBj+IwnDIBaRUNsKquAlRSGBbW7Vb65SLKsc
  1281. wxqtsdJA8cw2t1n/GqI6YOtnkBwHWIatf0UHqKQvm9rVIFdFQbKnHRaZ//F7ASzdk4JrUJVdVhGi
  1282. g32p1qphraO8WaKdXyDPn98XCWp1iZYbd+T0Gc4kpHfFS2c95OPrmY9bGrpsSZTikjcZPmLvBI9P
  1283. KbYyDDCQnAHpbAkmd+djh32LSojRULoW0OSoqCpwF2R9I2SwW9JqbS8JnnU0guC1CusPNuUwQagi
  1284. 0AcejzIqyUYiWjLLZ7PtcjYBUmkBIuvHJj5TSQLWsqQYQIAu0UfwgN8S7mBRE77vnJKEYS8pWYKS
  1285. sS4FS2z6h8gzD4d9YCNwJm96V/gT2TyP7tqSuLiSCYfIGc0Fj6cNlbQIZB4qHJpTiHhuchP2MIVd
  1286. 6KX7vR2B7HHaTi4lYkut/3wIYbaRFAtecsgPRr2ZtwiNKVKgJ0CURZsJiUlEsYxz5iYgad+6Niei
  1287. xK15Z4+QK5t8sDDSssBTNM0PqzS0TMdMNZinUEEYriEqLYsHb9XmEUYphYOGzXFqm/vsyZO77fxA
  1288. tSMPdfq6U03XDu+FjhjX8v3QIGDN+6SQjb7JIYj+lLwe1k9jnEFYpFjiTd93yB+Z38EBFvscpUYw
  1289. TpLRrx+rlfppUtv281HJUEtlwP5HPYVaZsq7w1u1MtKaMNshTeUzdcdx/mF+I9WamJEkNhdbHQTx
  1290. LQQ0N3jz6kVwXOPpER5EBvhn0kR9h+hkHEGfXcj2nTQOjVP1U7GMxK+ebVRRr186mtisuIe8FDgV
  1291. ms1or0x5JDawd6GbwqOImdTY1puCDal/n99BzBn0uSHHUXsw5u53WStM8Tu1km8qps/ejZ6rnRSg
  1292. Wh3sBupfD+f6ZuvjCTbnTjAPH7ch9OIDU8DPEvzOncmW1bAS6TnQNyMpWzbPp811RwxwJloAckIt
  1293. EKmQp59F22B+iQFpy3e9G9clxTg3MtjjE/u6SDSSqJpvcKK3bRUtgexwACuj36AKnUySIVbN8Jnl
  1294. aFA1kRVHJ6becwNMgY+jns+G1FiV6Qgwb1kqGrdmqPhdPB/zs1M0xW/UNc/slvmjPpvqluOhPz4a
  1295. 3NMYDslDwQxOnsYtXQUyKixNbzPBMu0L2PQSfK3skQNbNbGKE3s61u51f2cmNipyd7QTS4jnK0g7
  1296. u6NUnKx2ZCQ0CNLd7Ojau52C94zDtB4w4OkRpA1ZBm44LJY/e/3BXKB7wiWUTlCfyEznsWp84Jks
  1297. Lv5L5g+cp0k7KJelAnnMoVrEpjmlq/GpMyG27e6JYWA8KuZ4n33UIMuofqPkfRemC1UnHXXv0WCB
  1298. jwPt8fadr/uSti9wXyNSJp5M83Lqyqw+RIIf8CBjb/wdyl/G5MmsPl/uXN3hnNnqCAlgf/4sWdVs
  1299. tCT2s8qQUQAT3HF6MdqKQjneinr92FYGZBjtpbG8Ht+fUZp1wabPpY6UCwfPH92h4BP8ZiuV9qqT
  1300. LGYuv//+BBmOrhuYL5+/QJ2SSdFyML7t88WfG88Mn9rHtD11GxCf3XV8G746yIr5I4b4KOf+KxZg
  1301. sMIML7K71sWXSWz5Vnbf9gYXy3mSwkwtxrCsxCp58LSr7b17F3LIN6ujNKhs7o1TaoNc/K6ugWnA
  1302. D/oBYlYsHowg9vT84lOXkNCgry+LibzNRMXlNTKzpkRQec9Spi4nJxXsVZ7ey02Mc13YBOAIYM2q
  1303. qbE5inq5QD8u8VgK1qYoVbuRZpZp0ngurrNw5x9ORmdKBgs0+8zFFK7xwYakCut7SYX1mDAFZZN3
  1304. 376R/LEfFg7IrT8Q5FMLlb+ZUsVwvHV4ctLWonKpM97f7VQnXdiFnJJ4YMkOw17Fn+jtWPOvI05n
  1305. YsbRmb7hZ7PNvWe7hxoBR2wrXDCvCEiwhFwjawTtNC6mxIWQjKmFyLBVbp7wTRta9HWLtjNMwdXV
  1306. GWTDdENGDMKcESZv6wBzqOGxdPBOHlliEgterwJnM0j77QnxSI4UgRHDgty08qiKcze7Ukz4hn0d
  1307. 4yzk+durP5jweV9cjRGCUg4V0ryQZF6PN1N9WfDaRXPEYtEIdfELgzMeJncRDjU1HmeU3UnSYkxe
  1308. oIfG+mxe2ze6C3Jp0G7dZrCsonhBfXHpGFEhyTEmD0RsWUG5HYtY3uBPVgre/K1AbRT1sbozlvl9
  1309. X143h838fxhFbJTZpaCwAUP9McGASLbzbVcZp9oqLzUDLRuoBvZXDIM0C6xSyrE2b5ypLVk2EYg8
  1310. VhGErj3t2VR+Ii+k9cIb0IH2vb8/ZZWqnqxIAxy21qOlWWHcWdxP0r6MyELK4QRJkejtyy9R54ZV
  1311. /hfkmHuTzAPnBCPeDOdNTwpM3ehOn9Cs6YhUuj86rjT8fS7Goh1m979XniN66cAuF8bZRsrbPNr0
  1312. +Vz/Zhwp36mRwZ4xtLENx5YR/qhGQlD5rX+UgVD6Zv/wZv4n9rTL8qTj0/c4rD+66Eg0Lq/WIl3J
  1313. ru9iFsx8lgk8YK4X6Lj7kyp14ZYODBWEPLagw+IKtiTpx6+RvIqi75tqvvYH3+j48DdBxTbHQjIr
  1314. Yvz1kHSy2KkmgFJUWVLX9HOe/iBBI0lA0tTwAcbGdcBucQNud4EAf8oDSFeCCJlctwVCFQfgESar
  1315. Hbno7mSmxVMiIsOfZtGlAuAnkUzdK40HG8RKVUAtlju2Fo3C5c2HJ+0q64mKcmd+h2oGcmx1c0wy
  1316. VF471gCK8f31MpMDoA+fuuCrxTIJunoAA2C6crp8H1YipwNuW4EMyk81rJq3I+M/0oQN6FEXH2q+
  1317. EihVMTr+7SEDXkIZF3tqjaG/0HQtiFsB/jkIiPeOsFXx9dd/owQhSjIQH5UpQN/ZX8/OjIwnXQVK
  1318. 9BqnVP4ucL8T2KMSrEbumyR3Sc6ojcX+zrxnPvva4BDaGM4XlQcYzn3E82xu8zAsykqCCbDSloBB
  1319. f7QyZhsi9SRmO0AlqfdsffMJojuxW2gFDPAeJagv0uwiAe7cZwqbvGKqGQTpEV0IAFydBXdWi6pL
  1320. 4sB8acy8kdIZ4wMi6RDL2hvQAh8yaHIOSFKONkBcL2OFdz4FbOlw7DMAow3s7ACgysJNi/0NtyOl
  1321. iuLkFLifQt15bino8ObpqEq0XdQjZGG8XHughDPlWvAXT3gxRuhwkPGEqtx7n+25DNYHgqtDP4sk
  1322. Fbjk9U5Baed3+Jq4CqTjH0EBcQmdp2OGElLpG4ZIahiq39wR3V2T4/zi09z5N4dES24=
  1323. """.decode("base64").decode("zlib")
  1324. ##file activate.sh
  1325. ACTIVATE_SH = """
  1326. eJytU11P2zAUffevuKQ8AFqJ+srUh6IhgcTKRFgnjSLXTW4aS6ld2U6zgvbfd50PSD+GNI08JLHv
  1327. 8fW5557bg4dMWkhljrAsrIM5QmExgVK6DAKrCxMjzKUKRezkWjgM4Cw1eglzYbMz1oONLiAWSmkH
  1328. plAgHSTSYOzyDWMJtqfg5BReGNAjU3iEvoLgmN/dfuGTm/uH76Nb/m30cB3AE3wGl6GqkP7x28ND
  1329. 0FcE/lpp4yrg616hLDrYO1TFU8mqb6+u3Ga6yBNI0BHnqigQKoFnm32CMpNxBplYIwj6UCjWy6UP
  1330. u0y4Sq8mFakWizwn3ZyGBd1NMtBfqo1frAQJ2xy15wA/SFtduCbspFo0abaAXgg49rwhzoRaoIWS
  1331. miQS/9qAF5yuNWhXxByTHXEvRxHp2df16md0zSdX99HN3fiAyFVpfbMlz9/aFA0OdSka7DWJgHs9
  1332. igbvtqgJtxRqSBu9Gk/eiB0RLyIyhEBplaB1pvBGwx1uPYgwT6EFHO3c3veh1qHt1b8ZmbqOS2Mw
  1333. p+4rB2thpJjnaLue3r6bsQ7VYcB5Z8l5wBoRuvWwPYuSjLW9m0UHHXJ+eTPm49HXK84vGljX/WxX
  1334. TZ/Mt6GSLJiRuVGJJcJ0K+80mFVKEsdd9by1pMjJ2xa9W2FEO4rst5BxM+baSBKlgSNC5tzqIgzL
  1335. sjx/RkdmXZ+ToUOrU1cKg6HwGUL26prHDq0ZpTxIcDqbPUFdC+YW306fvFPUaX2AWtqxH/ugsf+A
  1336. kf/Pcf/3UW/HnBT5Axjqy2Y=
  1337. """.decode("base64").decode("zlib")
  1338. ##file activate.bat
  1339. ACTIVATE_BAT = """
  1340. eJx9kMsOgjAQRfdN+g+zoAn8goZEDESJPBpEViSzkFbZ0IX8f+RRaVW0u5mee3PanbjeFSgpKXmI
  1341. Hqq4KC9BglFW+YjWhEgJJa2ETvXQCNl2ogFe5CkvwaUEhjPm543vcOdAiacjLxzzJFw6f2bZCsZ0
  1342. 2YitXPtswawi1zwgC9II0QPD/RELyuOb1jB/Sg0rNhM31Ss4n2I+7ibLb8epQGco2Rja1Fs/zeoa
  1343. cR9nWnprJaMspOQJdBR1/g==
  1344. """.decode("base64").decode("zlib")
  1345. ##file deactivate.bat
  1346. DEACTIVATE_BAT = """
  1347. eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
  1348. FlWqXJpcICVYpGzx2OAY4oFsPpCLbjpQCLvZILVcXFaufi5cACHzOrI=
  1349. """.decode("base64").decode("zlib")
  1350. ##file distutils-init.py
  1351. DISTUTILS_INIT = """
  1352. eJytVl2L6zYQffevGBKK7XavKe3bhVBo78uFSyml0IdlEVpbTtR1JCMpm6S/vjOSY0v+uO1DDbs4
  1353. 0tF8nJk5sjz32jjQNpPhzd7H1ys3SqqjhcfCL1q18vgbN1YY2Kc/pQWlHXB4l8ZdeCfUO5x1c+nE
  1354. E1gNVwE1V3CxAqQDp6GVqgF3EmBd08nXLGukUfws4IDBVD13p2pYoS3rLk52ltF6hPhLS1XM4EUc
  1355. VsVYKzvBWPkE+WgmLzPZjkaUNmd6KVI3JRwWoRSLM6P98mMG+Dw4q+il8Ev07P7ATCNmRlfQ8/qN
  1356. HwVwB99Y4H0vMHAi6BWZUoEhoqXTNXdSK+A2LN6tE+fJ0E+7MhOdFSEM5lNgrJIKWXDF908wy87D
  1357. xE3UoHsxkegZTaHIHGNSSYfm+ntelpURvCnK7NEWBI/ap/b8Z1m232N2rj7B60V2DRM3B5NpaLSw
  1358. KnfwpvQVTviHOR+F88lhQyBAGlE7be6DoRNg9ldsG3218IHa6MRNU+tGBEYIggwafRk6yzsXDcVU
  1359. 9Ua08kYxt+F3x12LRaQi52j0xx/ywFxrdMRqVevzmaummlIYEp0WsCAaX8cFb6buuLUTqEgQQ6/Q
  1360. 04iWRoF38m/BdE8VtlBY0bURiB6KG1crpMZwc2fIjqWh+1UrkSLpWUIP8PySwLKv4qPGSVqDuMPy
  1361. dywQ+gS7L1irXVkm5pJsq3l+Ib1lMOvUrxI+/mBBY4KB+WpUtcO06RtzckNvQ6vYj1lGoZM2sdDG
  1362. fryJPYJVn/Cfka8XSqNaoLKhmOlqXMzW9+YBVp1EtIThZtOwzCRvMaARa+0xD0b2kcaJGwJsMbc7
  1363. hLUfY4vKvsCOBdvDnyfuRbzmXRdGTZgPF7oGQkJACWVD22IMQdhx0npt5S2f+pXO+OwH6d+hwiS5
  1364. 7IJOjcK2emj1zBy1aONHByfAMoraw6WlrSIFTbGghqASoRCjVncYROFpXM4uYSqhGnuVeGvks4jz
  1365. cjnCoR5GnPW7KOh4maVbdFeoplgJ3wh3MSrAsv/QuMjOspnTKRl1fTYqqNisv7uTVnhF1GhoBFbp
  1366. lh+OcXN2riA5ZrYXtWxlfcDuC8U5kLoN3CCJYXGpesO6dx6rU0zGMtjU6cNlmW0Fid8Sja4ZG+Z3
  1367. fTPbyj+mZnZ2wSQK8RaT9Km0ySRuLpm0DkUUL0ra3WQ2BgGJ7v9I9SKqNKZ/IR4R28RHm+vEz5ic
  1368. nZ2IH7bfub8pU1PR3gr10W7xLTfHh6Z6bgZ7K14G7Mj/1z5J6MFo6V5e07H0Ou78dTyeI+mxKOpI
  1369. eC2KMSj6HKxd6Uudf/n886fPv+f++x1lbASlmjQuPz8OvGA0j7j2eCu/4bcW6SFeCuNJ0W1GQHI5
  1370. iwC9Ey0bjtHd9P4dPA++XxLnZDVuxvFEtlm3lf5a2c02u2LRYXHH/AOs8pIa
  1371. """.decode("base64").decode("zlib")
  1372. ##file distutils.cfg
  1373. DISTUTILS_CFG = """
  1374. eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  1375. xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
  1376. 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
  1377. """.decode("base64").decode("zlib")
  1378. ##file activate_this.py
  1379. ACTIVATE_THIS = """
  1380. eJx1UsGOnDAMvecrIlYriDRlKvU20h5aaY+teuilGo1QALO4CwlKAjP8fe1QGGalRoLEefbzs+Mk
  1381. Sb7NcvRo3iTcoGqwgyy06As+HWSNVciKaBTFywYoJWc7yit2ndBVwEkHkIzKCV0YdQdmkvShs6YH
  1382. E3IhfjFaaSNLoHxQy2sLJrL0ow98JQmEG/rAYn7OobVGogngBgf0P0hjgwgt7HOUaI5DdBVJkggR
  1383. 3HwSktaqWcCtgiHIH7qHV+esW2CnkRJ+9R5cQGsikkWEV/J7leVGs9TV4TvcO5QOOrTHYI+xeCjY
  1384. JR/m9GPDHv2oSZunUokS2A/WBelnvx6tF6LUJO2FjjlH5zU6Q+Kz/9m69LxvSZVSwiOlGnT1rt/A
  1385. 77j+WDQZ8x9k2mFJetOle88+lc8sJJ/AeerI+fTlQigTfVqJUiXoKaaC3AqmI+KOnivjMLbvBVFU
  1386. 1JDruuadNGcPmkgiBTnQXUGUDd6IK9JEQ9yPdM96xZP8bieeMRqTuqbxIbbey2DjVUNzRs1rosFS
  1387. TsLAdS/0fBGNdTGKhuqD7mUmsFlgGjN2eSj1tM3GnjfXwwCmzjhMbR4rLZXXk+Z/6Hp7Pn2+kJ49
  1388. jfgLHgI4Jg==
  1389. """.decode("base64").decode("zlib")
  1390. if __name__ == '__main__':
  1391. main()
  1392. ## TODO:
  1393. ## Copy python.exe.manifest
  1394. ## Monkeypatch distutils.sysconfig