| 1 | #!/usr/bin/env python |
|---|
| 2 | ## WARNING: This file is generated |
|---|
| 3 | #!/usr/bin/env python |
|---|
| 4 | """Create a "virtual" Python installation |
|---|
| 5 | """ |
|---|
| 6 | |
|---|
| 7 | # If you change the version here, change it in setup.py |
|---|
| 8 | # and docs/conf.py as well. |
|---|
| 9 | virtualenv_version = "1.6.4" |
|---|
| 10 | |
|---|
| 11 | import base64 |
|---|
| 12 | import sys |
|---|
| 13 | import os |
|---|
| 14 | import optparse |
|---|
| 15 | import re |
|---|
| 16 | import shutil |
|---|
| 17 | import logging |
|---|
| 18 | import tempfile |
|---|
| 19 | import zlib |
|---|
| 20 | import errno |
|---|
| 21 | import distutils.sysconfig |
|---|
| 22 | try: |
|---|
| 23 | import subprocess |
|---|
| 24 | except ImportError: |
|---|
| 25 | if sys.version_info <= (2, 3): |
|---|
| 26 | print('ERROR: %s' % sys.exc_info()[1]) |
|---|
| 27 | print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.') |
|---|
| 28 | print('If you copy subprocess.py from a newer version of Python this script will probably work') |
|---|
| 29 | sys.exit(101) |
|---|
| 30 | else: |
|---|
| 31 | raise |
|---|
| 32 | try: |
|---|
| 33 | set |
|---|
| 34 | except NameError: |
|---|
| 35 | from sets import Set as set |
|---|
| 36 | try: |
|---|
| 37 | basestring |
|---|
| 38 | except NameError: |
|---|
| 39 | basestring = str |
|---|
| 40 | |
|---|
| 41 | join = os.path.join |
|---|
| 42 | py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) |
|---|
| 43 | |
|---|
| 44 | is_jython = sys.platform.startswith('java') |
|---|
| 45 | is_pypy = hasattr(sys, 'pypy_version_info') |
|---|
| 46 | is_win = (sys.platform == 'win32') |
|---|
| 47 | abiflags = getattr(sys, 'abiflags', '') |
|---|
| 48 | |
|---|
| 49 | if is_pypy: |
|---|
| 50 | expected_exe = 'pypy' |
|---|
| 51 | elif is_jython: |
|---|
| 52 | expected_exe = 'jython' |
|---|
| 53 | else: |
|---|
| 54 | expected_exe = 'python' |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath', |
|---|
| 58 | 'fnmatch', 'locale', 'encodings', 'codecs', |
|---|
| 59 | 'stat', 'UserDict', 'readline', 'copy_reg', 'types', |
|---|
| 60 | 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile', |
|---|
| 61 | 'zlib'] |
|---|
| 62 | |
|---|
| 63 | REQUIRED_FILES = ['lib-dynload', 'config'] |
|---|
| 64 | |
|---|
| 65 | majver, minver = sys.version_info[:2] |
|---|
| 66 | if majver == 2: |
|---|
| 67 | if minver >= 6: |
|---|
| 68 | REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) |
|---|
| 69 | if minver >= 7: |
|---|
| 70 | REQUIRED_MODULES.extend(['_weakrefset']) |
|---|
| 71 | if minver <= 3: |
|---|
| 72 | REQUIRED_MODULES.extend(['sets', '__future__']) |
|---|
| 73 | elif majver == 3: |
|---|
| 74 | # Some extra modules are needed for Python 3, but different ones |
|---|
| 75 | # for different versions. |
|---|
| 76 | REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io', |
|---|
| 77 | '_weakrefset', 'copyreg', 'tempfile', 'random', |
|---|
| 78 | '__future__', 'collections', 'keyword', 'tarfile', |
|---|
| 79 | 'shutil', 'struct', 'copy']) |
|---|
| 80 | if minver >= 2: |
|---|
| 81 | REQUIRED_FILES[-1] = 'config-%s' % majver |
|---|
| 82 | if minver == 3: |
|---|
| 83 | # The whole list of 3.3 modules is reproduced below - the current |
|---|
| 84 | # uncommented ones are required for 3.3 as of now, but more may be |
|---|
| 85 | # added as 3.3 development continues. |
|---|
| 86 | REQUIRED_MODULES.extend([ |
|---|
| 87 | #"aifc", |
|---|
| 88 | #"antigravity", |
|---|
| 89 | #"argparse", |
|---|
| 90 | #"ast", |
|---|
| 91 | #"asynchat", |
|---|
| 92 | #"asyncore", |
|---|
| 93 | "base64", |
|---|
| 94 | #"bdb", |
|---|
| 95 | #"binhex", |
|---|
| 96 | "bisect", |
|---|
| 97 | #"calendar", |
|---|
| 98 | #"cgi", |
|---|
| 99 | #"cgitb", |
|---|
| 100 | #"chunk", |
|---|
| 101 | #"cmd", |
|---|
| 102 | #"codeop", |
|---|
| 103 | #"code", |
|---|
| 104 | #"colorsys", |
|---|
| 105 | #"_compat_pickle", |
|---|
| 106 | #"compileall", |
|---|
| 107 | #"concurrent", |
|---|
| 108 | #"configparser", |
|---|
| 109 | #"contextlib", |
|---|
| 110 | #"cProfile", |
|---|
| 111 | #"crypt", |
|---|
| 112 | #"csv", |
|---|
| 113 | #"ctypes", |
|---|
| 114 | #"curses", |
|---|
| 115 | #"datetime", |
|---|
| 116 | #"dbm", |
|---|
| 117 | #"decimal", |
|---|
| 118 | #"difflib", |
|---|
| 119 | #"dis", |
|---|
| 120 | #"doctest", |
|---|
| 121 | #"dummy_threading", |
|---|
| 122 | "_dummy_thread", |
|---|
| 123 | #"email", |
|---|
| 124 | #"filecmp", |
|---|
| 125 | #"fileinput", |
|---|
| 126 | #"formatter", |
|---|
| 127 | #"fractions", |
|---|
| 128 | #"ftplib", |
|---|
| 129 | #"functools", |
|---|
| 130 | #"getopt", |
|---|
| 131 | #"getpass", |
|---|
| 132 | #"gettext", |
|---|
| 133 | #"glob", |
|---|
| 134 | #"gzip", |
|---|
| 135 | "hashlib", |
|---|
| 136 | "heapq", |
|---|
| 137 | "hmac", |
|---|
| 138 | #"html", |
|---|
| 139 | #"http", |
|---|
| 140 | #"idlelib", |
|---|
| 141 | #"imaplib", |
|---|
| 142 | #"imghdr", |
|---|
| 143 | #"importlib", |
|---|
| 144 | #"inspect", |
|---|
| 145 | #"json", |
|---|
| 146 | #"lib2to3", |
|---|
| 147 | #"logging", |
|---|
| 148 | #"macpath", |
|---|
| 149 | #"macurl2path", |
|---|
| 150 | #"mailbox", |
|---|
| 151 | #"mailcap", |
|---|
| 152 | #"_markupbase", |
|---|
| 153 | #"mimetypes", |
|---|
| 154 | #"modulefinder", |
|---|
| 155 | #"multiprocessing", |
|---|
| 156 | #"netrc", |
|---|
| 157 | #"nntplib", |
|---|
| 158 | #"nturl2path", |
|---|
| 159 | #"numbers", |
|---|
| 160 | #"opcode", |
|---|
| 161 | #"optparse", |
|---|
| 162 | #"os2emxpath", |
|---|
| 163 | #"pdb", |
|---|
| 164 | #"pickle", |
|---|
| 165 | #"pickletools", |
|---|
| 166 | #"pipes", |
|---|
| 167 | #"pkgutil", |
|---|
| 168 | #"platform", |
|---|
| 169 | #"plat-linux2", |
|---|
| 170 | #"plistlib", |
|---|
| 171 | #"poplib", |
|---|
| 172 | #"pprint", |
|---|
| 173 | #"profile", |
|---|
| 174 | #"pstats", |
|---|
| 175 | #"pty", |
|---|
| 176 | #"pyclbr", |
|---|
| 177 | #"py_compile", |
|---|
| 178 | #"pydoc_data", |
|---|
| 179 | #"pydoc", |
|---|
| 180 | #"_pyio", |
|---|
| 181 | #"queue", |
|---|
| 182 | #"quopri", |
|---|
| 183 | "reprlib", |
|---|
| 184 | "rlcompleter", |
|---|
| 185 | #"runpy", |
|---|
| 186 | #"sched", |
|---|
| 187 | #"shelve", |
|---|
| 188 | #"shlex", |
|---|
| 189 | #"smtpd", |
|---|
| 190 | #"smtplib", |
|---|
| 191 | #"sndhdr", |
|---|
| 192 | #"socket", |
|---|
| 193 | #"socketserver", |
|---|
| 194 | #"sqlite3", |
|---|
| 195 | #"ssl", |
|---|
| 196 | #"stringprep", |
|---|
| 197 | #"string", |
|---|
| 198 | #"_strptime", |
|---|
| 199 | #"subprocess", |
|---|
| 200 | #"sunau", |
|---|
| 201 | #"symbol", |
|---|
| 202 | #"symtable", |
|---|
| 203 | #"sysconfig", |
|---|
| 204 | #"tabnanny", |
|---|
| 205 | #"telnetlib", |
|---|
| 206 | #"test", |
|---|
| 207 | #"textwrap", |
|---|
| 208 | #"this", |
|---|
| 209 | #"_threading_local", |
|---|
| 210 | #"threading", |
|---|
| 211 | #"timeit", |
|---|
| 212 | #"tkinter", |
|---|
| 213 | #"tokenize", |
|---|
| 214 | #"token", |
|---|
| 215 | #"traceback", |
|---|
| 216 | #"trace", |
|---|
| 217 | #"tty", |
|---|
| 218 | #"turtledemo", |
|---|
| 219 | #"turtle", |
|---|
| 220 | #"unittest", |
|---|
| 221 | #"urllib", |
|---|
| 222 | #"uuid", |
|---|
| 223 | #"uu", |
|---|
| 224 | #"wave", |
|---|
| 225 | "weakref", |
|---|
| 226 | #"webbrowser", |
|---|
| 227 | #"wsgiref", |
|---|
| 228 | #"xdrlib", |
|---|
| 229 | #"xml", |
|---|
| 230 | #"xmlrpc", |
|---|
| 231 | #"zipfile", |
|---|
| 232 | ]) |
|---|
| 233 | |
|---|
| 234 | if is_pypy: |
|---|
| 235 | # these are needed to correctly display the exceptions that may happen |
|---|
| 236 | # during the bootstrap |
|---|
| 237 | REQUIRED_MODULES.extend(['traceback', 'linecache']) |
|---|
| 238 | |
|---|
| 239 | class Logger(object): |
|---|
| 240 | |
|---|
| 241 | """ |
|---|
| 242 | Logging object for use in command-line script. Allows ranges of |
|---|
| 243 | levels, to avoid some redundancy of displayed information. |
|---|
| 244 | """ |
|---|
| 245 | |
|---|
| 246 | DEBUG = logging.DEBUG |
|---|
| 247 | INFO = logging.INFO |
|---|
| 248 | NOTIFY = (logging.INFO+logging.WARN)/2 |
|---|
| 249 | WARN = WARNING = logging.WARN |
|---|
| 250 | ERROR = logging.ERROR |
|---|
| 251 | FATAL = logging.FATAL |
|---|
| 252 | |
|---|
| 253 | LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] |
|---|
| 254 | |
|---|
| 255 | def __init__(self, consumers): |
|---|
| 256 | self.consumers = consumers |
|---|
| 257 | self.indent = 0 |
|---|
| 258 | self.in_progress = None |
|---|
| 259 | self.in_progress_hanging = False |
|---|
| 260 | |
|---|
| 261 | def debug(self, msg, *args, **kw): |
|---|
| 262 | self.log(self.DEBUG, msg, *args, **kw) |
|---|
| 263 | def info(self, msg, *args, **kw): |
|---|
| 264 | self.log(self.INFO, msg, *args, **kw) |
|---|
| 265 | def notify(self, msg, *args, **kw): |
|---|
| 266 | self.log(self.NOTIFY, msg, *args, **kw) |
|---|
| 267 | def warn(self, msg, *args, **kw): |
|---|
| 268 | self.log(self.WARN, msg, *args, **kw) |
|---|
| 269 | def error(self, msg, *args, **kw): |
|---|
| 270 | self.log(self.WARN, msg, *args, **kw) |
|---|
| 271 | def fatal(self, msg, *args, **kw): |
|---|
| 272 | self.log(self.FATAL, msg, *args, **kw) |
|---|
| 273 | def log(self, level, msg, *args, **kw): |
|---|
| 274 | if args: |
|---|
| 275 | if kw: |
|---|
| 276 | raise TypeError( |
|---|
| 277 | "You may give positional or keyword arguments, not both") |
|---|
| 278 | args = args or kw |
|---|
| 279 | rendered = None |
|---|
| 280 | for consumer_level, consumer in self.consumers: |
|---|
| 281 | if self.level_matches(level, consumer_level): |
|---|
| 282 | if (self.in_progress_hanging |
|---|
| 283 | and consumer in (sys.stdout, sys.stderr)): |
|---|
| 284 | self.in_progress_hanging = False |
|---|
| 285 | sys.stdout.write('\n') |
|---|
| 286 | sys.stdout.flush() |
|---|
| 287 | if rendered is None: |
|---|
| 288 | if args: |
|---|
| 289 | rendered = msg % args |
|---|
| 290 | else: |
|---|
| 291 | rendered = msg |
|---|
| 292 | rendered = ' '*self.indent + rendered |
|---|
| 293 | if hasattr(consumer, 'write'): |
|---|
| 294 | consumer.write(rendered+'\n') |
|---|
| 295 | else: |
|---|
| 296 | consumer(rendered) |
|---|
| 297 | |
|---|
| 298 | def start_progress(self, msg): |
|---|
| 299 | assert not self.in_progress, ( |
|---|
| 300 | "Tried to start_progress(%r) while in_progress %r" |
|---|
| 301 | % (msg, self.in_progress)) |
|---|
| 302 | if self.level_matches(self.NOTIFY, self._stdout_level()): |
|---|
| 303 | sys.stdout.write(msg) |
|---|
| 304 | sys.stdout.flush() |
|---|
| 305 | self.in_progress_hanging = True |
|---|
| 306 | else: |
|---|
| 307 | self.in_progress_hanging = False |
|---|
| 308 | self.in_progress = msg |
|---|
| 309 | |
|---|
| 310 | def end_progress(self, msg='done.'): |
|---|
| 311 | assert self.in_progress, ( |
|---|
| 312 | "Tried to end_progress without start_progress") |
|---|
| 313 | if self.stdout_level_matches(self.NOTIFY): |
|---|
| 314 | if not self.in_progress_hanging: |
|---|
| 315 | # Some message has been printed out since start_progress |
|---|
| 316 | sys.stdout.write('...' + self.in_progress + msg + '\n') |
|---|
| 317 | sys.stdout.flush() |
|---|
| 318 | else: |
|---|
| 319 | sys.stdout.write(msg + '\n') |
|---|
| 320 | sys.stdout.flush() |
|---|
| 321 | self.in_progress = None |
|---|
| 322 | self.in_progress_hanging = False |
|---|
| 323 | |
|---|
| 324 | def show_progress(self): |
|---|
| 325 | """If we are in a progress scope, and no log messages have been |
|---|
| 326 | shown, write out another '.'""" |
|---|
| 327 | if self.in_progress_hanging: |
|---|
| 328 | sys.stdout.write('.') |
|---|
| 329 | sys.stdout.flush() |
|---|
| 330 | |
|---|
| 331 | def stdout_level_matches(self, level): |
|---|
| 332 | """Returns true if a message at this level will go to stdout""" |
|---|
| 333 | return self.level_matches(level, self._stdout_level()) |
|---|
| 334 | |
|---|
| 335 | def _stdout_level(self): |
|---|
| 336 | """Returns the level that stdout runs at""" |
|---|
| 337 | for level, consumer in self.consumers: |
|---|
| 338 | if consumer is sys.stdout: |
|---|
| 339 | return level |
|---|
| 340 | return self.FATAL |
|---|
| 341 | |
|---|
| 342 | def level_matches(self, level, consumer_level): |
|---|
| 343 | """ |
|---|
| 344 | >>> l = Logger([]) |
|---|
| 345 | >>> l.level_matches(3, 4) |
|---|
| 346 | False |
|---|
| 347 | >>> l.level_matches(3, 2) |
|---|
| 348 | True |
|---|
| 349 | >>> l.level_matches(slice(None, 3), 3) |
|---|
| 350 | False |
|---|
| 351 | >>> l.level_matches(slice(None, 3), 2) |
|---|
| 352 | True |
|---|
| 353 | >>> l.level_matches(slice(1, 3), 1) |
|---|
| 354 | True |
|---|
| 355 | >>> l.level_matches(slice(2, 3), 1) |
|---|
| 356 | False |
|---|
| 357 | """ |
|---|
| 358 | if isinstance(level, slice): |
|---|
| 359 | start, stop = level.start, level.stop |
|---|
| 360 | if start is not None and start > consumer_level: |
|---|
| 361 | return False |
|---|
| 362 | if stop is not None and stop <= consumer_level: |
|---|
| 363 | return False |
|---|
| 364 | return True |
|---|
| 365 | else: |
|---|
| 366 | return level >= consumer_level |
|---|
| 367 | |
|---|
| 368 | #@classmethod |
|---|
| 369 | def level_for_integer(cls, level): |
|---|
| 370 | levels = cls.LEVELS |
|---|
| 371 | if level < 0: |
|---|
| 372 | return levels[0] |
|---|
| 373 | if level >= len(levels): |
|---|
| 374 | return levels[-1] |
|---|
| 375 | return levels[level] |
|---|
| 376 | |
|---|
| 377 | level_for_integer = classmethod(level_for_integer) |
|---|
| 378 | |
|---|
| 379 | # create a silent logger just to prevent this from being undefined |
|---|
| 380 | # will be overridden with requested verbosity main() is called. |
|---|
| 381 | logger = Logger([(Logger.LEVELS[-1], sys.stdout)]) |
|---|
| 382 | |
|---|
| 383 | def mkdir(path): |
|---|
| 384 | if not os.path.exists(path): |
|---|
| 385 | logger.info('Creating %s', path) |
|---|
| 386 | os.makedirs(path) |
|---|
| 387 | else: |
|---|
| 388 | logger.info('Directory %s already exists', path) |
|---|
| 389 | |
|---|
| 390 | def copyfileordir(src, dest): |
|---|
| 391 | if os.path.isdir(src): |
|---|
| 392 | shutil.copytree(src, dest, True) |
|---|
| 393 | else: |
|---|
| 394 | shutil.copy2(src, dest) |
|---|
| 395 | |
|---|
| 396 | def copyfile(src, dest, symlink=True): |
|---|
| 397 | if not os.path.exists(src): |
|---|
| 398 | # Some bad symlink in the src |
|---|
| 399 | logger.warn('Cannot find file %s (bad symlink)', src) |
|---|
| 400 | return |
|---|
| 401 | if os.path.exists(dest): |
|---|
| 402 | logger.debug('File %s already exists', dest) |
|---|
| 403 | return |
|---|
| 404 | if not os.path.exists(os.path.dirname(dest)): |
|---|
| 405 | logger.info('Creating parent directories for %s' % os.path.dirname(dest)) |
|---|
| 406 | os.makedirs(os.path.dirname(dest)) |
|---|
| 407 | if not os.path.islink(src): |
|---|
| 408 | srcpath = os.path.abspath(src) |
|---|
| 409 | else: |
|---|
| 410 | srcpath = os.readlink(src) |
|---|
| 411 | if symlink and hasattr(os, 'symlink'): |
|---|
| 412 | logger.info('Symlinking %s', dest) |
|---|
| 413 | try: |
|---|
| 414 | os.symlink(srcpath, dest) |
|---|
| 415 | except (OSError, NotImplementedError): |
|---|
| 416 | logger.info('Symlinking failed, copying to %s', dest) |
|---|
| 417 | copyfileordir(src, dest) |
|---|
| 418 | else: |
|---|
| 419 | logger.info('Copying to %s', dest) |
|---|
| 420 | copyfileordir(src, dest) |
|---|
| 421 | |
|---|
| 422 | def writefile(dest, content, overwrite=True): |
|---|
| 423 | if not os.path.exists(dest): |
|---|
| 424 | logger.info('Writing %s', dest) |
|---|
| 425 | f = open(dest, 'wb') |
|---|
| 426 | f.write(content.encode('utf-8')) |
|---|
| 427 | f.close() |
|---|
| 428 | return |
|---|
| 429 | else: |
|---|
| 430 | f = open(dest, 'rb') |
|---|
| 431 | c = f.read() |
|---|
| 432 | f.close() |
|---|
| 433 | if c != content: |
|---|
| 434 | if not overwrite: |
|---|
| 435 | logger.notify('File %s exists with different content; not overwriting', dest) |
|---|
| 436 | return |
|---|
| 437 | logger.notify('Overwriting %s with new content', dest) |
|---|
| 438 | f = open(dest, 'wb') |
|---|
| 439 | f.write(content.encode('utf-8')) |
|---|
| 440 | f.close() |
|---|
| 441 | else: |
|---|
| 442 | logger.info('Content %s already in place', dest) |
|---|
| 443 | |
|---|
| 444 | def rmtree(dir): |
|---|
| 445 | if os.path.exists(dir): |
|---|
| 446 | logger.notify('Deleting tree %s', dir) |
|---|
| 447 | shutil.rmtree(dir) |
|---|
| 448 | else: |
|---|
| 449 | logger.info('Do not need to delete %s; already gone', dir) |
|---|
| 450 | |
|---|
| 451 | def make_exe(fn): |
|---|
| 452 | if hasattr(os, 'chmod'): |
|---|
| 453 | oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777 |
|---|
| 454 | newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777 |
|---|
| 455 | os.chmod(fn, newmode) |
|---|
| 456 | logger.info('Changed mode of %s to %s', fn, oct(newmode)) |
|---|
| 457 | |
|---|
| 458 | def _find_file(filename, dirs): |
|---|
| 459 | for dir in dirs: |
|---|
| 460 | if os.path.exists(join(dir, filename)): |
|---|
| 461 | return join(dir, filename) |
|---|
| 462 | return filename |
|---|
| 463 | |
|---|
| 464 | def _install_req(py_executable, unzip=False, distribute=False, |
|---|
| 465 | search_dirs=None, never_download=False): |
|---|
| 466 | |
|---|
| 467 | if search_dirs is None: |
|---|
| 468 | search_dirs = file_search_dirs() |
|---|
| 469 | |
|---|
| 470 | if not distribute: |
|---|
| 471 | setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3] |
|---|
| 472 | project_name = 'setuptools' |
|---|
| 473 | bootstrap_script = EZ_SETUP_PY |
|---|
| 474 | source = None |
|---|
| 475 | else: |
|---|
| 476 | setup_fn = None |
|---|
| 477 | source = 'distribute-0.6.19.tar.gz' |
|---|
| 478 | project_name = 'distribute' |
|---|
| 479 | bootstrap_script = DISTRIBUTE_SETUP_PY |
|---|
| 480 | |
|---|
| 481 | # If we are running under -p, we need to remove the current |
|---|
| 482 | # directory from sys.path temporarily here, so that we |
|---|
| 483 | # definitely get the pkg_resources from the site directory of |
|---|
| 484 | # the interpreter we are running under, not the one |
|---|
| 485 | # virtualenv.py is installed under (which might lead to py2/py3 |
|---|
| 486 | # incompatibility issues) |
|---|
| 487 | _prev_sys_path = sys.path |
|---|
| 488 | if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): |
|---|
| 489 | sys.path = sys.path[1:] |
|---|
| 490 | |
|---|
| 491 | try: |
|---|
| 492 | try: |
|---|
| 493 | # check if the global Python has distribute installed or plain |
|---|
| 494 | # setuptools |
|---|
| 495 | import pkg_resources |
|---|
| 496 | if not hasattr(pkg_resources, '_distribute'): |
|---|
| 497 | location = os.path.dirname(pkg_resources.__file__) |
|---|
| 498 | logger.notify("A globally installed setuptools was found (in %s)" % location) |
|---|
| 499 | logger.notify("Use the --no-site-packages option to use distribute in " |
|---|
| 500 | "the virtualenv.") |
|---|
| 501 | except ImportError: |
|---|
| 502 | pass |
|---|
| 503 | finally: |
|---|
| 504 | sys.path = _prev_sys_path |
|---|
| 505 | |
|---|
| 506 | if setup_fn is not None: |
|---|
| 507 | setup_fn = _find_file(setup_fn, search_dirs) |
|---|
| 508 | |
|---|
| 509 | if source is not None: |
|---|
| 510 | source = _find_file(source, search_dirs) |
|---|
| 511 | |
|---|
| 512 | if is_jython and os._name == 'nt': |
|---|
| 513 | # Jython's .bat sys.executable can't handle a command line |
|---|
| 514 | # argument with newlines |
|---|
| 515 | fd, ez_setup = tempfile.mkstemp('.py') |
|---|
| 516 | os.write(fd, bootstrap_script) |
|---|
| 517 | os.close(fd) |
|---|
| 518 | cmd = [py_executable, ez_setup] |
|---|
| 519 | else: |
|---|
| 520 | cmd = [py_executable, '-c', bootstrap_script] |
|---|
| 521 | if unzip: |
|---|
| 522 | cmd.append('--always-unzip') |
|---|
| 523 | env = {} |
|---|
| 524 | remove_from_env = [] |
|---|
| 525 | if logger.stdout_level_matches(logger.DEBUG): |
|---|
| 526 | cmd.append('-v') |
|---|
| 527 | |
|---|
| 528 | old_chdir = os.getcwd() |
|---|
| 529 | if setup_fn is not None and os.path.exists(setup_fn): |
|---|
| 530 | logger.info('Using existing %s egg: %s' % (project_name, setup_fn)) |
|---|
| 531 | cmd.append(setup_fn) |
|---|
| 532 | if os.environ.get('PYTHONPATH'): |
|---|
| 533 | env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH'] |
|---|
| 534 | else: |
|---|
| 535 | env['PYTHONPATH'] = setup_fn |
|---|
| 536 | else: |
|---|
| 537 | # the source is found, let's chdir |
|---|
| 538 | if source is not None and os.path.exists(source): |
|---|
| 539 | logger.info('Using existing %s egg: %s' % (project_name, source)) |
|---|
| 540 | os.chdir(os.path.dirname(source)) |
|---|
| 541 | # in this case, we want to be sure that PYTHONPATH is unset (not |
|---|
| 542 | # just empty, really unset), else CPython tries to import the |
|---|
| 543 | # site.py that it's in virtualenv_support |
|---|
| 544 | remove_from_env.append('PYTHONPATH') |
|---|
| 545 | else: |
|---|
| 546 | if never_download: |
|---|
| 547 | logger.fatal("Can't find any local distributions of %s to install " |
|---|
| 548 | "and --never-download is set. Either re-run virtualenv " |
|---|
| 549 | "without the --never-download option, or place a %s " |
|---|
| 550 | "distribution (%s) in one of these " |
|---|
| 551 | "locations: %r" % (project_name, project_name, |
|---|
| 552 | setup_fn or source, |
|---|
| 553 | search_dirs)) |
|---|
| 554 | sys.exit(1) |
|---|
| 555 | |
|---|
| 556 | logger.info('No %s egg found; downloading' % project_name) |
|---|
| 557 | cmd.extend(['--always-copy', '-U', project_name]) |
|---|
| 558 | logger.start_progress('Installing %s...' % project_name) |
|---|
| 559 | logger.indent += 2 |
|---|
| 560 | cwd = None |
|---|
| 561 | if project_name == 'distribute': |
|---|
| 562 | env['DONT_PATCH_SETUPTOOLS'] = 'true' |
|---|
| 563 | |
|---|
| 564 | def _filter_ez_setup(line): |
|---|
| 565 | return filter_ez_setup(line, project_name) |
|---|
| 566 | |
|---|
| 567 | if not os.access(os.getcwd(), os.W_OK): |
|---|
| 568 | cwd = tempfile.mkdtemp() |
|---|
| 569 | if source is not None and os.path.exists(source): |
|---|
| 570 | # the current working dir is hostile, let's copy the |
|---|
| 571 | # tarball to a temp dir |
|---|
| 572 | target = os.path.join(cwd, os.path.split(source)[-1]) |
|---|
| 573 | shutil.copy(source, target) |
|---|
| 574 | try: |
|---|
| 575 | call_subprocess(cmd, show_stdout=False, |
|---|
| 576 | filter_stdout=_filter_ez_setup, |
|---|
| 577 | extra_env=env, |
|---|
| 578 | remove_from_env=remove_from_env, |
|---|
| 579 | cwd=cwd) |
|---|
| 580 | finally: |
|---|
| 581 | logger.indent -= 2 |
|---|
| 582 | logger.end_progress() |
|---|
| 583 | if os.getcwd() != old_chdir: |
|---|
| 584 | os.chdir(old_chdir) |
|---|
| 585 | if is_jython and os._name == 'nt': |
|---|
| 586 | os.remove(ez_setup) |
|---|
| 587 | |
|---|
| 588 | def file_search_dirs(): |
|---|
| 589 | here = os.path.dirname(os.path.abspath(__file__)) |
|---|
| 590 | dirs = ['.', here, |
|---|
| 591 | join(here, 'virtualenv_support')] |
|---|
| 592 | if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': |
|---|
| 593 | # Probably some boot script; just in case virtualenv is installed... |
|---|
| 594 | try: |
|---|
| 595 | import virtualenv |
|---|
| 596 | except ImportError: |
|---|
| 597 | pass |
|---|
| 598 | else: |
|---|
| 599 | dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support')) |
|---|
| 600 | return [d for d in dirs if os.path.isdir(d)] |
|---|
| 601 | |
|---|
| 602 | def install_setuptools(py_executable, unzip=False, |
|---|
| 603 | search_dirs=None, never_download=False): |
|---|
| 604 | _install_req(py_executable, unzip, |
|---|
| 605 | search_dirs=search_dirs, never_download=never_download) |
|---|
| 606 | |
|---|
| 607 | def install_distribute(py_executable, unzip=False, |
|---|
| 608 | search_dirs=None, never_download=False): |
|---|
| 609 | _install_req(py_executable, unzip, distribute=True, |
|---|
| 610 | search_dirs=search_dirs, never_download=never_download) |
|---|
| 611 | |
|---|
| 612 | _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I) |
|---|
| 613 | def install_pip(py_executable, search_dirs=None, never_download=False): |
|---|
| 614 | if search_dirs is None: |
|---|
| 615 | search_dirs = file_search_dirs() |
|---|
| 616 | |
|---|
| 617 | filenames = [] |
|---|
| 618 | for dir in search_dirs: |
|---|
| 619 | filenames.extend([join(dir, fn) for fn in os.listdir(dir) |
|---|
| 620 | if _pip_re.search(fn)]) |
|---|
| 621 | filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)] |
|---|
| 622 | filenames.sort() |
|---|
| 623 | filenames = [filename for basename, i, filename in filenames] |
|---|
| 624 | if not filenames: |
|---|
| 625 | filename = 'pip' |
|---|
| 626 | else: |
|---|
| 627 | filename = filenames[-1] |
|---|
| 628 | easy_install_script = 'easy_install' |
|---|
| 629 | if sys.platform == 'win32': |
|---|
| 630 | easy_install_script = 'easy_install-script.py' |
|---|
| 631 | cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename] |
|---|
| 632 | if filename == 'pip': |
|---|
| 633 | if never_download: |
|---|
| 634 | logger.fatal("Can't find any local distributions of pip to install " |
|---|
| 635 | "and --never-download is set. Either re-run virtualenv " |
|---|
| 636 | "without the --never-download option, or place a pip " |
|---|
| 637 | "source distribution (zip/tar.gz/tar.bz2) in one of these " |
|---|
| 638 | "locations: %r" % search_dirs) |
|---|
| 639 | sys.exit(1) |
|---|
| 640 | logger.info('Installing pip from network...') |
|---|
| 641 | else: |
|---|
| 642 | logger.info('Installing existing %s distribution: %s' % ( |
|---|
| 643 | os.path.basename(filename), filename)) |
|---|
| 644 | logger.start_progress('Installing pip...') |
|---|
| 645 | logger.indent += 2 |
|---|
| 646 | def _filter_setup(line): |
|---|
| 647 | return filter_ez_setup(line, 'pip') |
|---|
| 648 | try: |
|---|
| 649 | call_subprocess(cmd, show_stdout=False, |
|---|
| 650 | filter_stdout=_filter_setup) |
|---|
| 651 | finally: |
|---|
| 652 | logger.indent -= 2 |
|---|
| 653 | logger.end_progress() |
|---|
| 654 | |
|---|
| 655 | def filter_ez_setup(line, project_name='setuptools'): |
|---|
| 656 | if not line.strip(): |
|---|
| 657 | return Logger.DEBUG |
|---|
| 658 | if project_name == 'distribute': |
|---|
| 659 | for prefix in ('Extracting', 'Now working', 'Installing', 'Before', |
|---|
| 660 | 'Scanning', 'Setuptools', 'Egg', 'Already', |
|---|
| 661 | 'running', 'writing', 'reading', 'installing', |
|---|
| 662 | 'creating', 'copying', 'byte-compiling', 'removing', |
|---|
| 663 | 'Processing'): |
|---|
| 664 | if line.startswith(prefix): |
|---|
| 665 | return Logger.DEBUG |
|---|
| 666 | return Logger.DEBUG |
|---|
| 667 | for prefix in ['Reading ', 'Best match', 'Processing setuptools', |
|---|
| 668 | 'Copying setuptools', 'Adding setuptools', |
|---|
| 669 | 'Installing ', 'Installed ']: |
|---|
| 670 | if line.startswith(prefix): |
|---|
| 671 | return Logger.DEBUG |
|---|
| 672 | return Logger.INFO |
|---|
| 673 | |
|---|
| 674 | def main(): |
|---|
| 675 | parser = optparse.OptionParser( |
|---|
| 676 | version=virtualenv_version, |
|---|
| 677 | usage="%prog [OPTIONS] DEST_DIR") |
|---|
| 678 | |
|---|
| 679 | parser.add_option( |
|---|
| 680 | '-v', '--verbose', |
|---|
| 681 | action='count', |
|---|
| 682 | dest='verbose', |
|---|
| 683 | default=0, |
|---|
| 684 | help="Increase verbosity") |
|---|
| 685 | |
|---|
| 686 | parser.add_option( |
|---|
| 687 | '-q', '--quiet', |
|---|
| 688 | action='count', |
|---|
| 689 | dest='quiet', |
|---|
| 690 | default=0, |
|---|
| 691 | help='Decrease verbosity') |
|---|
| 692 | |
|---|
| 693 | parser.add_option( |
|---|
| 694 | '-p', '--python', |
|---|
| 695 | dest='python', |
|---|
| 696 | metavar='PYTHON_EXE', |
|---|
| 697 | help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 ' |
|---|
| 698 | 'interpreter to create the new environment. The default is the interpreter that ' |
|---|
| 699 | 'virtualenv was installed with (%s)' % sys.executable) |
|---|
| 700 | |
|---|
| 701 | parser.add_option( |
|---|
| 702 | '--clear', |
|---|
| 703 | dest='clear', |
|---|
| 704 | action='store_true', |
|---|
| 705 | help="Clear out the non-root install and start from scratch") |
|---|
| 706 | |
|---|
| 707 | parser.add_option( |
|---|
| 708 | '--no-site-packages', |
|---|
| 709 | dest='no_site_packages', |
|---|
| 710 | action='store_true', |
|---|
| 711 | help="Don't give access to the global site-packages dir to the " |
|---|
| 712 | "virtual environment") |
|---|
| 713 | |
|---|
| 714 | parser.add_option( |
|---|
| 715 | '--unzip-setuptools', |
|---|
| 716 | dest='unzip_setuptools', |
|---|
| 717 | action='store_true', |
|---|
| 718 | help="Unzip Setuptools or Distribute when installing it") |
|---|
| 719 | |
|---|
| 720 | parser.add_option( |
|---|
| 721 | '--relocatable', |
|---|
| 722 | dest='relocatable', |
|---|
| 723 | action='store_true', |
|---|
| 724 | help='Make an EXISTING virtualenv environment relocatable. ' |
|---|
| 725 | 'This fixes up scripts and makes all .pth files relative') |
|---|
| 726 | |
|---|
| 727 | parser.add_option( |
|---|
| 728 | '--distribute', |
|---|
| 729 | dest='use_distribute', |
|---|
| 730 | action='store_true', |
|---|
| 731 | help='Use Distribute instead of Setuptools. Set environ variable ' |
|---|
| 732 | 'VIRTUALENV_USE_DISTRIBUTE to make it the default ') |
|---|
| 733 | |
|---|
| 734 | default_search_dirs = file_search_dirs() |
|---|
| 735 | parser.add_option( |
|---|
| 736 | '--extra-search-dir', |
|---|
| 737 | dest="search_dirs", |
|---|
| 738 | action="append", |
|---|
| 739 | default=default_search_dirs, |
|---|
| 740 | help="Directory to look for setuptools/distribute/pip distributions in. " |
|---|
| 741 | "You can add any number of additional --extra-search-dir paths.") |
|---|
| 742 | |
|---|
| 743 | parser.add_option( |
|---|
| 744 | '--never-download', |
|---|
| 745 | dest="never_download", |
|---|
| 746 | action="store_true", |
|---|
| 747 | help="Never download anything from the network. Instead, virtualenv will fail " |
|---|
| 748 | "if local distributions of setuptools/distribute/pip are not present.") |
|---|
| 749 | |
|---|
| 750 | parser.add_option( |
|---|
| 751 | '--prompt=', |
|---|
| 752 | dest='prompt', |
|---|
| 753 | help='Provides an alternative prompt prefix for this environment') |
|---|
| 754 | |
|---|
| 755 | if 'extend_parser' in globals(): |
|---|
| 756 | extend_parser(parser) |
|---|
| 757 | |
|---|
| 758 | options, args = parser.parse_args() |
|---|
| 759 | |
|---|
| 760 | global logger |
|---|
| 761 | |
|---|
| 762 | if 'adjust_options' in globals(): |
|---|
| 763 | adjust_options(options, args) |
|---|
| 764 | |
|---|
| 765 | verbosity = options.verbose - options.quiet |
|---|
| 766 | logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)]) |
|---|
| 767 | |
|---|
| 768 | if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): |
|---|
| 769 | env = os.environ.copy() |
|---|
| 770 | interpreter = resolve_interpreter(options.python) |
|---|
| 771 | if interpreter == sys.executable: |
|---|
| 772 | logger.warn('Already using interpreter %s' % interpreter) |
|---|
| 773 | else: |
|---|
| 774 | logger.notify('Running virtualenv with interpreter %s' % interpreter) |
|---|
| 775 | env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true' |
|---|
| 776 | file = __file__ |
|---|
| 777 | if file.endswith('.pyc'): |
|---|
| 778 | file = file[:-1] |
|---|
| 779 | popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env) |
|---|
| 780 | raise SystemExit(popen.wait()) |
|---|
| 781 | |
|---|
| 782 | if not args: |
|---|
| 783 | print('You must provide a DEST_DIR') |
|---|
| 784 | parser.print_help() |
|---|
| 785 | sys.exit(2) |
|---|
| 786 | if len(args) > 1: |
|---|
| 787 | print('There must be only one argument: DEST_DIR (you gave %s)' % ( |
|---|
| 788 | ' '.join(args))) |
|---|
| 789 | parser.print_help() |
|---|
| 790 | sys.exit(2) |
|---|
| 791 | |
|---|
| 792 | home_dir = args[0] |
|---|
| 793 | |
|---|
| 794 | if os.environ.get('WORKING_ENV'): |
|---|
| 795 | logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') |
|---|
| 796 | logger.fatal('Please deactivate your workingenv, then re-run this script') |
|---|
| 797 | sys.exit(3) |
|---|
| 798 | |
|---|
| 799 | if 'PYTHONHOME' in os.environ: |
|---|
| 800 | logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it') |
|---|
| 801 | del os.environ['PYTHONHOME'] |
|---|
| 802 | |
|---|
| 803 | if options.relocatable: |
|---|
| 804 | make_environment_relocatable(home_dir) |
|---|
| 805 | return |
|---|
| 806 | |
|---|
| 807 | create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear, |
|---|
| 808 | unzip_setuptools=options.unzip_setuptools, |
|---|
| 809 | use_distribute=options.use_distribute or majver > 2, |
|---|
| 810 | prompt=options.prompt, |
|---|
| 811 | search_dirs=options.search_dirs, |
|---|
| 812 | never_download=options.never_download) |
|---|
| 813 | if 'after_install' in globals(): |
|---|
| 814 | after_install(options, home_dir) |
|---|
| 815 | |
|---|
| 816 | def call_subprocess(cmd, show_stdout=True, |
|---|
| 817 | filter_stdout=None, cwd=None, |
|---|
| 818 | raise_on_returncode=True, extra_env=None, |
|---|
| 819 | remove_from_env=None): |
|---|
| 820 | cmd_parts = [] |
|---|
| 821 | for part in cmd: |
|---|
| 822 | if len(part) > 45: |
|---|
| 823 | part = part[:20]+"..."+part[-20:] |
|---|
| 824 | if ' ' in part or '\n' in part or '"' in part or "'" in part: |
|---|
| 825 | part = '"%s"' % part.replace('"', '\\"') |
|---|
| 826 | cmd_parts.append(part) |
|---|
| 827 | cmd_desc = ' '.join(cmd_parts) |
|---|
| 828 | if show_stdout: |
|---|
| 829 | stdout = None |
|---|
| 830 | else: |
|---|
| 831 | stdout = subprocess.PIPE |
|---|
| 832 | logger.debug("Running command %s" % cmd_desc) |
|---|
| 833 | if extra_env or remove_from_env: |
|---|
| 834 | env = os.environ.copy() |
|---|
| 835 | if extra_env: |
|---|
| 836 | env.update(extra_env) |
|---|
| 837 | if remove_from_env: |
|---|
| 838 | for varname in remove_from_env: |
|---|
| 839 | env.pop(varname, None) |
|---|
| 840 | else: |
|---|
| 841 | env = None |
|---|
| 842 | try: |
|---|
| 843 | proc = subprocess.Popen( |
|---|
| 844 | cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, |
|---|
| 845 | cwd=cwd, env=env) |
|---|
| 846 | except Exception: |
|---|
| 847 | e = sys.exc_info()[1] |
|---|
| 848 | logger.fatal( |
|---|
| 849 | "Error %s while executing command %s" % (e, cmd_desc)) |
|---|
| 850 | raise |
|---|
| 851 | all_output = [] |
|---|
| 852 | if stdout is not None: |
|---|
| 853 | stdout = proc.stdout |
|---|
| 854 | encoding = sys.getdefaultencoding() |
|---|
| 855 | while 1: |
|---|
| 856 | line = stdout.readline().decode(encoding) |
|---|
| 857 | if not line: |
|---|
| 858 | break |
|---|
| 859 | line = line.rstrip() |
|---|
| 860 | all_output.append(line) |
|---|
| 861 | if filter_stdout: |
|---|
| 862 | level = filter_stdout(line) |
|---|
| 863 | if isinstance(level, tuple): |
|---|
| 864 | level, line = level |
|---|
| 865 | logger.log(level, line) |
|---|
| 866 | if not logger.stdout_level_matches(level): |
|---|
| 867 | logger.show_progress() |
|---|
| 868 | else: |
|---|
| 869 | logger.info(line) |
|---|
| 870 | else: |
|---|
| 871 | proc.communicate() |
|---|
| 872 | proc.wait() |
|---|
| 873 | if proc.returncode: |
|---|
| 874 | if raise_on_returncode: |
|---|
| 875 | if all_output: |
|---|
| 876 | logger.notify('Complete output from command %s:' % cmd_desc) |
|---|
| 877 | logger.notify('\n'.join(all_output) + '\n----------------------------------------') |
|---|
| 878 | raise OSError( |
|---|
| 879 | "Command %s failed with error code %s" |
|---|
| 880 | % (cmd_desc, proc.returncode)) |
|---|
| 881 | else: |
|---|
| 882 | logger.warn( |
|---|
| 883 | "Command %s had error code %s" |
|---|
| 884 | % (cmd_desc, proc.returncode)) |
|---|
| 885 | |
|---|
| 886 | |
|---|
| 887 | def create_environment(home_dir, site_packages=True, clear=False, |
|---|
| 888 | unzip_setuptools=False, use_distribute=False, |
|---|
| 889 | prompt=None, search_dirs=None, never_download=False): |
|---|
| 890 | """ |
|---|
| 891 | Creates a new environment in ``home_dir``. |
|---|
| 892 | |
|---|
| 893 | If ``site_packages`` is true (the default) then the global |
|---|
| 894 | ``site-packages/`` directory will be on the path. |
|---|
| 895 | |
|---|
| 896 | If ``clear`` is true (default False) then the environment will |
|---|
| 897 | first be cleared. |
|---|
| 898 | """ |
|---|
| 899 | home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|---|
| 900 | |
|---|
| 901 | py_executable = os.path.abspath(install_python( |
|---|
| 902 | home_dir, lib_dir, inc_dir, bin_dir, |
|---|
| 903 | site_packages=site_packages, clear=clear)) |
|---|
| 904 | |
|---|
| 905 | install_distutils(home_dir) |
|---|
| 906 | |
|---|
| 907 | if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'): |
|---|
| 908 | install_distribute(py_executable, unzip=unzip_setuptools, |
|---|
| 909 | search_dirs=search_dirs, never_download=never_download) |
|---|
| 910 | else: |
|---|
| 911 | install_setuptools(py_executable, unzip=unzip_setuptools, |
|---|
| 912 | search_dirs=search_dirs, never_download=never_download) |
|---|
| 913 | |
|---|
| 914 | install_pip(py_executable, search_dirs=search_dirs, never_download=never_download) |
|---|
| 915 | |
|---|
| 916 | install_activate(home_dir, bin_dir, prompt) |
|---|
| 917 | |
|---|
| 918 | def path_locations(home_dir): |
|---|
| 919 | """Return the path locations for the environment (where libraries are, |
|---|
| 920 | where scripts go, etc)""" |
|---|
| 921 | # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its |
|---|
| 922 | # prefix arg is broken: http://bugs.python.org/issue3386 |
|---|
| 923 | if sys.platform == 'win32': |
|---|
| 924 | # Windows has lots of problems with executables with spaces in |
|---|
| 925 | # the name; this function will remove them (using the ~1 |
|---|
| 926 | # format): |
|---|
| 927 | mkdir(home_dir) |
|---|
| 928 | if ' ' in home_dir: |
|---|
| 929 | try: |
|---|
| 930 | import win32api |
|---|
| 931 | except ImportError: |
|---|
| 932 | print('Error: the path "%s" has a space in it' % home_dir) |
|---|
| 933 | print('To handle these kinds of paths, the win32api module must be installed:') |
|---|
| 934 | print(' http://sourceforge.net/projects/pywin32/') |
|---|
| 935 | sys.exit(3) |
|---|
| 936 | home_dir = win32api.GetShortPathName(home_dir) |
|---|
| 937 | lib_dir = join(home_dir, 'Lib') |
|---|
| 938 | inc_dir = join(home_dir, 'Include') |
|---|
| 939 | bin_dir = join(home_dir, 'Scripts') |
|---|
| 940 | elif is_jython: |
|---|
| 941 | lib_dir = join(home_dir, 'Lib') |
|---|
| 942 | inc_dir = join(home_dir, 'Include') |
|---|
| 943 | bin_dir = join(home_dir, 'bin') |
|---|
| 944 | elif is_pypy: |
|---|
| 945 | lib_dir = home_dir |
|---|
| 946 | inc_dir = join(home_dir, 'include') |
|---|
| 947 | bin_dir = join(home_dir, 'bin') |
|---|
| 948 | else: |
|---|
| 949 | lib_dir = join(home_dir, 'lib', py_version) |
|---|
| 950 | inc_dir = join(home_dir, 'include', py_version + abiflags) |
|---|
| 951 | bin_dir = join(home_dir, 'bin') |
|---|
| 952 | return home_dir, lib_dir, inc_dir, bin_dir |
|---|
| 953 | |
|---|
| 954 | |
|---|
| 955 | def change_prefix(filename, dst_prefix): |
|---|
| 956 | prefixes = [sys.prefix] |
|---|
| 957 | |
|---|
| 958 | if sys.platform == "darwin": |
|---|
| 959 | prefixes.extend(( |
|---|
| 960 | os.path.join("/Library/Python", sys.version[:3], "site-packages"), |
|---|
| 961 | os.path.join(sys.prefix, "Extras", "lib", "python"), |
|---|
| 962 | os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"))) |
|---|
| 963 | |
|---|
| 964 | if hasattr(sys, 'real_prefix'): |
|---|
| 965 | prefixes.append(sys.real_prefix) |
|---|
| 966 | prefixes = list(map(os.path.abspath, prefixes)) |
|---|
| 967 | filename = os.path.abspath(filename) |
|---|
| 968 | for src_prefix in prefixes: |
|---|
| 969 | if filename.startswith(src_prefix): |
|---|
| 970 | _, relpath = filename.split(src_prefix, 1) |
|---|
| 971 | assert relpath[0] == os.sep |
|---|
| 972 | relpath = relpath[1:] |
|---|
| 973 | return join(dst_prefix, relpath) |
|---|
| 974 | assert False, "Filename %s does not start with any of these prefixes: %s" % \ |
|---|
| 975 | (filename, prefixes) |
|---|
| 976 | |
|---|
| 977 | def copy_required_modules(dst_prefix): |
|---|
| 978 | import imp |
|---|
| 979 | for modname in REQUIRED_MODULES: |
|---|
| 980 | if modname in sys.builtin_module_names: |
|---|
| 981 | logger.info("Ignoring built-in bootstrap module: %s" % modname) |
|---|
| 982 | continue |
|---|
| 983 | try: |
|---|
| 984 | f, filename, _ = imp.find_module(modname) |
|---|
| 985 | except ImportError: |
|---|
| 986 | logger.info("Cannot import bootstrap module: %s" % modname) |
|---|
| 987 | else: |
|---|
| 988 | if f is not None: |
|---|
| 989 | f.close() |
|---|
| 990 | dst_filename = change_prefix(filename, dst_prefix) |
|---|
| 991 | copyfile(filename, dst_filename) |
|---|
| 992 | if filename.endswith('.pyc'): |
|---|
| 993 | pyfile = filename[:-1] |
|---|
| 994 | if os.path.exists(pyfile): |
|---|
| 995 | copyfile(pyfile, dst_filename[:-1]) |
|---|
| 996 | |
|---|
| 997 | |
|---|
| 998 | def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear): |
|---|
| 999 | """Install just the base environment, no distutils patches etc""" |
|---|
| 1000 | if sys.executable.startswith(bin_dir): |
|---|
| 1001 | print('Please use the *system* python to run this script') |
|---|
| 1002 | return |
|---|
| 1003 | |
|---|
| 1004 | if clear: |
|---|
| 1005 | rmtree(lib_dir) |
|---|
| 1006 | ## FIXME: why not delete it? |
|---|
| 1007 | ## Maybe it should delete everything with #!/path/to/venv/python in it |
|---|
| 1008 | logger.notify('Not deleting %s', bin_dir) |
|---|
| 1009 | |
|---|
| 1010 | if hasattr(sys, 'real_prefix'): |
|---|
| 1011 | logger.notify('Using real prefix %r' % sys.real_prefix) |
|---|
| 1012 | prefix = sys.real_prefix |
|---|
| 1013 | else: |
|---|
| 1014 | prefix = sys.prefix |
|---|
| 1015 | mkdir(lib_dir) |
|---|
| 1016 | fix_lib64(lib_dir) |
|---|
| 1017 | fix_local_scheme(home_dir) |
|---|
| 1018 | stdlib_dirs = [os.path.dirname(os.__file__)] |
|---|
| 1019 | if sys.platform == 'win32': |
|---|
| 1020 | stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs')) |
|---|
| 1021 | elif sys.platform == 'darwin': |
|---|
| 1022 | stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages')) |
|---|
| 1023 | if hasattr(os, 'symlink'): |
|---|
| 1024 | logger.info('Symlinking Python bootstrap modules') |
|---|
| 1025 | else: |
|---|
| 1026 | logger.info('Copying Python bootstrap modules') |
|---|
| 1027 | logger.indent += 2 |
|---|
| 1028 | try: |
|---|
| 1029 | # copy required files... |
|---|
| 1030 | for stdlib_dir in stdlib_dirs: |
|---|
| 1031 | if not os.path.isdir(stdlib_dir): |
|---|
| 1032 | continue |
|---|
| 1033 | for fn in os.listdir(stdlib_dir): |
|---|
| 1034 | bn = os.path.splitext(fn)[0] |
|---|
| 1035 | if fn != 'site-packages' and bn in REQUIRED_FILES: |
|---|
| 1036 | copyfile(join(stdlib_dir, fn), join(lib_dir, fn)) |
|---|
| 1037 | # ...and modules |
|---|
| 1038 | copy_required_modules(home_dir) |
|---|
| 1039 | finally: |
|---|
| 1040 | logger.indent -= 2 |
|---|
| 1041 | mkdir(join(lib_dir, 'site-packages')) |
|---|
| 1042 | import site |
|---|
| 1043 | site_filename = site.__file__ |
|---|
| 1044 | if site_filename.endswith('.pyc'): |
|---|
| 1045 | site_filename = site_filename[:-1] |
|---|
| 1046 | elif site_filename.endswith('$py.class'): |
|---|
| 1047 | site_filename = site_filename.replace('$py.class', '.py') |
|---|
| 1048 | site_filename_dst = change_prefix(site_filename, home_dir) |
|---|
| 1049 | site_dir = os.path.dirname(site_filename_dst) |
|---|
| 1050 | writefile(site_filename_dst, SITE_PY) |
|---|
| 1051 | writefile(join(site_dir, 'orig-prefix.txt'), prefix) |
|---|
| 1052 | site_packages_filename = join(site_dir, 'no-global-site-packages.txt') |
|---|
| 1053 | if not site_packages: |
|---|
| 1054 | writefile(site_packages_filename, '') |
|---|
| 1055 | else: |
|---|
| 1056 | if os.path.exists(site_packages_filename): |
|---|
| 1057 | logger.info('Deleting %s' % site_packages_filename) |
|---|
| 1058 | os.unlink(site_packages_filename) |
|---|
| 1059 | |
|---|
| 1060 | if is_pypy or is_win: |
|---|
| 1061 | stdinc_dir = join(prefix, 'include') |
|---|
| 1062 | else: |
|---|
| 1063 | stdinc_dir = join(prefix, 'include', py_version + abiflags) |
|---|
| 1064 | if os.path.exists(stdinc_dir): |
|---|
| 1065 | copyfile(stdinc_dir, inc_dir) |
|---|
| 1066 | else: |
|---|
| 1067 | logger.debug('No include dir %s' % stdinc_dir) |
|---|
| 1068 | |
|---|
| 1069 | # pypy never uses exec_prefix, just ignore it |
|---|
| 1070 | if sys.exec_prefix != prefix and not is_pypy: |
|---|
| 1071 | if sys.platform == 'win32': |
|---|
| 1072 | exec_dir = join(sys.exec_prefix, 'lib') |
|---|
| 1073 | elif is_jython: |
|---|
| 1074 | exec_dir = join(sys.exec_prefix, 'Lib') |
|---|
| 1075 | else: |
|---|
| 1076 | exec_dir = join(sys.exec_prefix, 'lib', py_version) |
|---|
| 1077 | for fn in os.listdir(exec_dir): |
|---|
| 1078 | copyfile(join(exec_dir, fn), join(lib_dir, fn)) |
|---|
| 1079 | |
|---|
| 1080 | if is_jython: |
|---|
| 1081 | # Jython has either jython-dev.jar and javalib/ dir, or just |
|---|
| 1082 | # jython.jar |
|---|
| 1083 | for name in 'jython-dev.jar', 'javalib', 'jython.jar': |
|---|
| 1084 | src = join(prefix, name) |
|---|
| 1085 | if os.path.exists(src): |
|---|
| 1086 | copyfile(src, join(home_dir, name)) |
|---|
| 1087 | # XXX: registry should always exist after Jython 2.5rc1 |
|---|
| 1088 | src = join(prefix, 'registry') |
|---|
| 1089 | if os.path.exists(src): |
|---|
| 1090 | copyfile(src, join(home_dir, 'registry'), symlink=False) |
|---|
| 1091 | copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'), |
|---|
| 1092 | symlink=False) |
|---|
| 1093 | |
|---|
| 1094 | mkdir(bin_dir) |
|---|
| 1095 | py_executable = join(bin_dir, os.path.basename(sys.executable)) |
|---|
| 1096 | if 'Python.framework' in prefix: |
|---|
| 1097 | if re.search(r'/Python(?:-32|-64)*$', py_executable): |
|---|
| 1098 | # The name of the python executable is not quite what |
|---|
| 1099 | # we want, rename it. |
|---|
| 1100 | py_executable = os.path.join( |
|---|
| 1101 | os.path.dirname(py_executable), 'python') |
|---|
| 1102 | |
|---|
| 1103 | logger.notify('New %s executable in %s', expected_exe, py_executable) |
|---|
| 1104 | if sys.executable != py_executable: |
|---|
| 1105 | ## FIXME: could I just hard link? |
|---|
| 1106 | executable = sys.executable |
|---|
| 1107 | if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'): |
|---|
| 1108 | # Cygwin misreports sys.executable sometimes |
|---|
| 1109 | executable += '.exe' |
|---|
| 1110 | py_executable += '.exe' |
|---|
| 1111 | logger.info('Executable actually exists in %s' % executable) |
|---|
| 1112 | shutil.copyfile(executable, py_executable) |
|---|
| 1113 | make_exe(py_executable) |
|---|
| 1114 | if sys.platform == 'win32' or sys.platform == 'cygwin': |
|---|
| 1115 | pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe') |
|---|
| 1116 | if os.path.exists(pythonw): |
|---|
| 1117 | logger.info('Also created pythonw.exe') |
|---|
| 1118 | shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe')) |
|---|
| 1119 | if is_pypy: |
|---|
| 1120 | # make a symlink python --> pypy-c |
|---|
| 1121 | python_executable = os.path.join(os.path.dirname(py_executable), 'python') |
|---|
| 1122 | logger.info('Also created executable %s' % python_executable) |
|---|
| 1123 | copyfile(py_executable, python_executable) |
|---|
| 1124 | |
|---|
| 1125 | if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe: |
|---|
| 1126 | secondary_exe = os.path.join(os.path.dirname(py_executable), |
|---|
| 1127 | expected_exe) |
|---|
| 1128 | py_executable_ext = os.path.splitext(py_executable)[1] |
|---|
| 1129 | if py_executable_ext == '.exe': |
|---|
| 1130 | # python2.4 gives an extension of '.4' :P |
|---|
| 1131 | secondary_exe += py_executable_ext |
|---|
| 1132 | if os.path.exists(secondary_exe): |
|---|
| 1133 | logger.warn('Not overwriting existing %s script %s (you must use %s)' |
|---|
| 1134 | % (expected_exe, secondary_exe, py_executable)) |
|---|
| 1135 | else: |
|---|
| 1136 | logger.notify('Also creating executable in %s' % secondary_exe) |
|---|
| 1137 | shutil.copyfile(sys.executable, secondary_exe) |
|---|
| 1138 | make_exe(secondary_exe) |
|---|
| 1139 | |
|---|
| 1140 | if 'Python.framework' in prefix: |
|---|
| 1141 | logger.debug('MacOSX Python framework detected') |
|---|
| 1142 | |
|---|
| 1143 | # Make sure we use the the embedded interpreter inside |
|---|
| 1144 | # the framework, even if sys.executable points to |
|---|
| 1145 | # the stub executable in ${sys.prefix}/bin |
|---|
| 1146 | # See http://groups.google.com/group/python-virtualenv/ |
|---|
| 1147 | # browse_thread/thread/17cab2f85da75951 |
|---|
| 1148 | original_python = os.path.join( |
|---|
| 1149 | prefix, 'Resources/Python.app/Contents/MacOS/Python') |
|---|
| 1150 | shutil.copy(original_python, py_executable) |
|---|
| 1151 | |
|---|
| 1152 | # Copy the framework's dylib into the virtual |
|---|
| 1153 | # environment |
|---|
| 1154 | virtual_lib = os.path.join(home_dir, '.Python') |
|---|
| 1155 | |
|---|
| 1156 | if os.path.exists(virtual_lib): |
|---|
| 1157 | os.unlink(virtual_lib) |
|---|
| 1158 | copyfile( |
|---|
| 1159 | os.path.join(prefix, 'Python'), |
|---|
| 1160 | virtual_lib) |
|---|
| 1161 | |
|---|
| 1162 | # And then change the install_name of the copied python executable |
|---|
| 1163 | try: |
|---|
| 1164 | call_subprocess( |
|---|
| 1165 | ["install_name_tool", "-change", |
|---|
| 1166 | os.path.join(prefix, 'Python'), |
|---|
| 1167 | '@executable_path/../.Python', |
|---|
| 1168 | py_executable]) |
|---|
| 1169 | except: |
|---|
| 1170 | logger.fatal( |
|---|
| 1171 | "Could not call install_name_tool -- you must have Apple's development tools installed") |
|---|
| 1172 | raise |
|---|
| 1173 | |
|---|
| 1174 | # Some tools depend on pythonX.Y being present |
|---|
| 1175 | py_executable_version = '%s.%s' % ( |
|---|
| 1176 | sys.version_info[0], sys.version_info[1]) |
|---|
| 1177 | if not py_executable.endswith(py_executable_version): |
|---|
| 1178 | # symlinking pythonX.Y > python |
|---|
| 1179 | pth = py_executable + '%s.%s' % ( |
|---|
| 1180 | sys.version_info[0], sys.version_info[1]) |
|---|
| 1181 | if os.path.exists(pth): |
|---|
| 1182 | os.unlink(pth) |
|---|
| 1183 | os.symlink('python', pth) |
|---|
| 1184 | else: |
|---|
| 1185 | # reverse symlinking python -> pythonX.Y (with --python) |
|---|
| 1186 | pth = join(bin_dir, 'python') |
|---|
| 1187 | if os.path.exists(pth): |
|---|
| 1188 | os.unlink(pth) |
|---|
| 1189 | os.symlink(os.path.basename(py_executable), pth) |
|---|
| 1190 | |
|---|
| 1191 | if sys.platform == 'win32' and ' ' in py_executable: |
|---|
| 1192 | # There's a bug with subprocess on Windows when using a first |
|---|
| 1193 | # argument that has a space in it. Instead we have to quote |
|---|
| 1194 | # the value: |
|---|
| 1195 | py_executable = '"%s"' % py_executable |
|---|
| 1196 | cmd = [py_executable, '-c', 'import sys; print(sys.prefix)'] |
|---|
| 1197 | logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) |
|---|
| 1198 | try: |
|---|
| 1199 | proc = subprocess.Popen(cmd, |
|---|
| 1200 | stdout=subprocess.PIPE) |
|---|
| 1201 | proc_stdout, proc_stderr = proc.communicate() |
|---|
| 1202 | except OSError: |
|---|
| 1203 | e = sys.exc_info()[1] |
|---|
| 1204 | if e.errno == errno.EACCES: |
|---|
| 1205 | logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e)) |
|---|
| 1206 | sys.exit(100) |
|---|
| 1207 | else: |
|---|
| 1208 | raise e |
|---|
| 1209 | |
|---|
| 1210 | proc_stdout = proc_stdout.strip().decode(sys.getdefaultencoding()) |
|---|
| 1211 | proc_stdout = os.path.normcase(os.path.abspath(proc_stdout)) |
|---|
| 1212 | if proc_stdout != os.path.normcase(os.path.abspath(home_dir)): |
|---|
| 1213 | logger.fatal( |
|---|
| 1214 | 'ERROR: The executable %s is not functioning' % py_executable) |
|---|
| 1215 | logger.fatal( |
|---|
| 1216 | 'ERROR: It thinks sys.prefix is %r (should be %r)' |
|---|
| 1217 | % (proc_stdout, os.path.normcase(os.path.abspath(home_dir)))) |
|---|
| 1218 | logger.fatal( |
|---|
| 1219 | 'ERROR: virtualenv is not compatible with this system or executable') |
|---|
| 1220 | if sys.platform == 'win32': |
|---|
| 1221 | logger.fatal( |
|---|
| 1222 | '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)') |
|---|
| 1223 | sys.exit(100) |
|---|
| 1224 | else: |
|---|
| 1225 | logger.info('Got sys.prefix result: %r' % proc_stdout) |
|---|
| 1226 | |
|---|
| 1227 | pydistutils = os.path.expanduser('~/.pydistutils.cfg') |
|---|
| 1228 | if os.path.exists(pydistutils): |
|---|
| 1229 | logger.notify('Please make sure you remove any previous custom paths from ' |
|---|
| 1230 | 'your %s file.' % pydistutils) |
|---|
| 1231 | ## FIXME: really this should be calculated earlier |
|---|
| 1232 | return py_executable |
|---|
| 1233 | |
|---|
| 1234 | def install_activate(home_dir, bin_dir, prompt=None): |
|---|
| 1235 | if sys.platform == 'win32' or is_jython and os._name == 'nt': |
|---|
| 1236 | files = {'activate.bat': ACTIVATE_BAT, |
|---|
| 1237 | 'deactivate.bat': DEACTIVATE_BAT} |
|---|
| 1238 | if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin': |
|---|
| 1239 | files['activate'] = ACTIVATE_SH |
|---|
| 1240 | else: |
|---|
| 1241 | files = {'activate': ACTIVATE_SH} |
|---|
| 1242 | |
|---|
| 1243 | # suppling activate.fish in addition to, not instead of, the |
|---|
| 1244 | # bash script support. |
|---|
| 1245 | files['activate.fish'] = ACTIVATE_FISH |
|---|
| 1246 | |
|---|
| 1247 | # same for csh/tcsh support... |
|---|
| 1248 | files['activate.csh'] = ACTIVATE_CSH |
|---|
| 1249 | |
|---|
| 1250 | |
|---|
| 1251 | |
|---|
| 1252 | files['activate_this.py'] = ACTIVATE_THIS |
|---|
| 1253 | vname = os.path.basename(os.path.abspath(home_dir)) |
|---|
| 1254 | for name, content in files.items(): |
|---|
| 1255 | content = content.replace('__VIRTUAL_PROMPT__', prompt or '') |
|---|
| 1256 | content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname) |
|---|
| 1257 | content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir)) |
|---|
| 1258 | content = content.replace('__VIRTUAL_NAME__', vname) |
|---|
| 1259 | content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) |
|---|
| 1260 | writefile(os.path.join(bin_dir, name), content) |
|---|
| 1261 | |
|---|
| 1262 | def install_distutils(home_dir): |
|---|
| 1263 | distutils_path = change_prefix(distutils.__path__[0], home_dir) |
|---|
| 1264 | mkdir(distutils_path) |
|---|
| 1265 | ## FIXME: maybe this prefix setting should only be put in place if |
|---|
| 1266 | ## there's a local distutils.cfg with a prefix setting? |
|---|
| 1267 | home_dir = os.path.abspath(home_dir) |
|---|
| 1268 | ## FIXME: this is breaking things, removing for now: |
|---|
| 1269 | #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir |
|---|
| 1270 | writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) |
|---|
| 1271 | writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False) |
|---|
| 1272 | |
|---|
| 1273 | def fix_local_scheme(home_dir): |
|---|
| 1274 | """ |
|---|
| 1275 | Platforms that use the "posix_local" install scheme (like Ubuntu with |
|---|
| 1276 | Python 2.7) need to be given an additional "local" location, sigh. |
|---|
| 1277 | """ |
|---|
| 1278 | try: |
|---|
| 1279 | import sysconfig |
|---|
| 1280 | except ImportError: |
|---|
| 1281 | pass |
|---|
| 1282 | else: |
|---|
| 1283 | if sysconfig._get_default_scheme() == 'posix_local': |
|---|
| 1284 | local_path = os.path.join(home_dir, 'local') |
|---|
| 1285 | if not os.path.exists(local_path): |
|---|
| 1286 | os.symlink(os.path.abspath(home_dir), local_path) |
|---|
| 1287 | |
|---|
| 1288 | def fix_lib64(lib_dir): |
|---|
| 1289 | """ |
|---|
| 1290 | Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y |
|---|
| 1291 | instead of lib/pythonX.Y. If this is such a platform we'll just create a |
|---|
| 1292 | symlink so lib64 points to lib |
|---|
| 1293 | """ |
|---|
| 1294 | if [p for p in distutils.sysconfig.get_config_vars().values() |
|---|
| 1295 | if isinstance(p, basestring) and 'lib64' in p]: |
|---|
| 1296 | logger.debug('This system uses lib64; symlinking lib64 to lib') |
|---|
| 1297 | assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( |
|---|
| 1298 | "Unexpected python lib dir: %r" % lib_dir) |
|---|
| 1299 | lib_parent = os.path.dirname(lib_dir) |
|---|
| 1300 | assert os.path.basename(lib_parent) == 'lib', ( |
|---|
| 1301 | "Unexpected parent dir: %r" % lib_parent) |
|---|
| 1302 | copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64')) |
|---|
| 1303 | |
|---|
| 1304 | def resolve_interpreter(exe): |
|---|
| 1305 | """ |
|---|
| 1306 | If the executable given isn't an absolute path, search $PATH for the interpreter |
|---|
| 1307 | """ |
|---|
| 1308 | if os.path.abspath(exe) != exe: |
|---|
| 1309 | paths = os.environ.get('PATH', '').split(os.pathsep) |
|---|
| 1310 | for path in paths: |
|---|
| 1311 | if os.path.exists(os.path.join(path, exe)): |
|---|
| 1312 | exe = os.path.join(path, exe) |
|---|
| 1313 | break |
|---|
| 1314 | if not os.path.exists(exe): |
|---|
| 1315 | logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe)) |
|---|
| 1316 | raise SystemExit(3) |
|---|
| 1317 | if not is_executable(exe): |
|---|
| 1318 | logger.fatal('The executable %s (from --python=%s) is not executable' % (exe, exe)) |
|---|
| 1319 | raise SystemExit(3) |
|---|
| 1320 | return exe |
|---|
| 1321 | |
|---|
| 1322 | def is_executable(exe): |
|---|
| 1323 | """Checks a file is executable""" |
|---|
| 1324 | return os.access(exe, os.X_OK) |
|---|
| 1325 | |
|---|
| 1326 | ############################################################ |
|---|
| 1327 | ## Relocating the environment: |
|---|
| 1328 | |
|---|
| 1329 | def make_environment_relocatable(home_dir): |
|---|
| 1330 | """ |
|---|
| 1331 | Makes the already-existing environment use relative paths, and takes out |
|---|
| 1332 | the #!-based environment selection in scripts. |
|---|
| 1333 | """ |
|---|
| 1334 | home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|---|
| 1335 | activate_this = os.path.join(bin_dir, 'activate_this.py') |
|---|
| 1336 | if not os.path.exists(activate_this): |
|---|
| 1337 | logger.fatal( |
|---|
| 1338 | 'The environment doesn\'t have a file %s -- please re-run virtualenv ' |
|---|
| 1339 | 'on this environment to update it' % activate_this) |
|---|
| 1340 | fixup_scripts(home_dir) |
|---|
| 1341 | fixup_pth_and_egg_link(home_dir) |
|---|
| 1342 | ## FIXME: need to fix up distutils.cfg |
|---|
| 1343 | |
|---|
| 1344 | OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3], |
|---|
| 1345 | 'activate', 'activate.bat', 'activate_this.py'] |
|---|
| 1346 | |
|---|
| 1347 | def fixup_scripts(home_dir): |
|---|
| 1348 | # This is what we expect at the top of scripts: |
|---|
| 1349 | shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir)) |
|---|
| 1350 | # This is what we'll put: |
|---|
| 1351 | new_shebang = '#!/usr/bin/env python%s' % sys.version[:3] |
|---|
| 1352 | 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" |
|---|
| 1353 | if sys.platform == 'win32': |
|---|
| 1354 | bin_suffix = 'Scripts' |
|---|
| 1355 | else: |
|---|
| 1356 | bin_suffix = 'bin' |
|---|
| 1357 | bin_dir = os.path.join(home_dir, bin_suffix) |
|---|
| 1358 | home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|---|
| 1359 | for filename in os.listdir(bin_dir): |
|---|
| 1360 | filename = os.path.join(bin_dir, filename) |
|---|
| 1361 | if not os.path.isfile(filename): |
|---|
| 1362 | # ignore subdirs, e.g. .svn ones. |
|---|
| 1363 | continue |
|---|
| 1364 | f = open(filename, 'rb') |
|---|
| 1365 | lines = f.readlines() |
|---|
| 1366 | f.close() |
|---|
| 1367 | if not lines: |
|---|
| 1368 | logger.warn('Script %s is an empty file' % filename) |
|---|
| 1369 | continue |
|---|
| 1370 | if not lines[0].strip().startswith(shebang): |
|---|
| 1371 | if os.path.basename(filename) in OK_ABS_SCRIPTS: |
|---|
| 1372 | logger.debug('Cannot make script %s relative' % filename) |
|---|
| 1373 | elif lines[0].strip() == new_shebang: |
|---|
| 1374 | logger.info('Script %s has already been made relative' % filename) |
|---|
| 1375 | else: |
|---|
| 1376 | logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)' |
|---|
| 1377 | % (filename, shebang)) |
|---|
| 1378 | continue |
|---|
| 1379 | logger.notify('Making script %s relative' % filename) |
|---|
| 1380 | lines = [new_shebang+'\n', activate+'\n'] + lines[1:] |
|---|
| 1381 | f = open(filename, 'wb') |
|---|
| 1382 | f.writelines(lines) |
|---|
| 1383 | f.close() |
|---|
| 1384 | |
|---|
| 1385 | def fixup_pth_and_egg_link(home_dir, sys_path=None): |
|---|
| 1386 | """Makes .pth and .egg-link files use relative paths""" |
|---|
| 1387 | home_dir = os.path.normcase(os.path.abspath(home_dir)) |
|---|
| 1388 | if sys_path is None: |
|---|
| 1389 | sys_path = sys.path |
|---|
| 1390 | for path in sys_path: |
|---|
| 1391 | if not path: |
|---|
| 1392 | path = '.' |
|---|
| 1393 | if not os.path.isdir(path): |
|---|
| 1394 | continue |
|---|
| 1395 | path = os.path.normcase(os.path.abspath(path)) |
|---|
| 1396 | if not path.startswith(home_dir): |
|---|
| 1397 | logger.debug('Skipping system (non-environment) directory %s' % path) |
|---|
| 1398 | continue |
|---|
| 1399 | for filename in os.listdir(path): |
|---|
| 1400 | filename = os.path.join(path, filename) |
|---|
| 1401 | if filename.endswith('.pth'): |
|---|
| 1402 | if not os.access(filename, os.W_OK): |
|---|
| 1403 | logger.warn('Cannot write .pth file %s, skipping' % filename) |
|---|
| 1404 | else: |
|---|
| 1405 | fixup_pth_file(filename) |
|---|
| 1406 | if filename.endswith('.egg-link'): |
|---|
| 1407 | if not os.access(filename, os.W_OK): |
|---|
| 1408 | logger.warn('Cannot write .egg-link file %s, skipping' % filename) |
|---|
| 1409 | else: |
|---|
| 1410 | fixup_egg_link(filename) |
|---|
| 1411 | |
|---|
| 1412 | def fixup_pth_file(filename): |
|---|
| 1413 | lines = [] |
|---|
| 1414 | prev_lines = [] |
|---|
| 1415 | f = open(filename) |
|---|
| 1416 | prev_lines = f.readlines() |
|---|
| 1417 | f.close() |
|---|
| 1418 | for line in prev_lines: |
|---|
| 1419 | line = line.strip() |
|---|
| 1420 | if (not line or line.startswith('#') or line.startswith('import ') |
|---|
| 1421 | or os.path.abspath(line) != line): |
|---|
| 1422 | lines.append(line) |
|---|
| 1423 | else: |
|---|
| 1424 | new_value = make_relative_path(filename, line) |
|---|
| 1425 | if line != new_value: |
|---|
| 1426 | logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename)) |
|---|
| 1427 | lines.append(new_value) |
|---|
| 1428 | if lines == prev_lines: |
|---|
| 1429 | logger.info('No changes to .pth file %s' % filename) |
|---|
| 1430 | return |
|---|
| 1431 | logger.notify('Making paths in .pth file %s relative' % filename) |
|---|
| 1432 | f = open(filename, 'w') |
|---|
| 1433 | f.write('\n'.join(lines) + '\n') |
|---|
| 1434 | f.close() |
|---|
| 1435 | |
|---|
| 1436 | def fixup_egg_link(filename): |
|---|
| 1437 | f = open(filename) |
|---|
| 1438 | link = f.read().strip() |
|---|
| 1439 | f.close() |
|---|
| 1440 | if os.path.abspath(link) != link: |
|---|
| 1441 | logger.debug('Link in %s already relative' % filename) |
|---|
| 1442 | return |
|---|
| 1443 | new_link = make_relative_path(filename, link) |
|---|
| 1444 | logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) |
|---|
| 1445 | f = open(filename, 'w') |
|---|
| 1446 | f.write(new_link) |
|---|
| 1447 | f.close() |
|---|
| 1448 | |
|---|
| 1449 | def make_relative_path(source, dest, dest_is_directory=True): |
|---|
| 1450 | """ |
|---|
| 1451 | Make a filename relative, where the filename is dest, and it is |
|---|
| 1452 | being referred to from the filename source. |
|---|
| 1453 | |
|---|
| 1454 | >>> make_relative_path('/usr/share/something/a-file.pth', |
|---|
| 1455 | ... '/usr/share/another-place/src/Directory') |
|---|
| 1456 | '../another-place/src/Directory' |
|---|
| 1457 | >>> make_relative_path('/usr/share/something/a-file.pth', |
|---|
| 1458 | ... '/home/user/src/Directory') |
|---|
| 1459 | '../../../home/user/src/Directory' |
|---|
| 1460 | >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') |
|---|
| 1461 | './' |
|---|
| 1462 | """ |
|---|
| 1463 | source = os.path.dirname(source) |
|---|
| 1464 | if not dest_is_directory: |
|---|
| 1465 | dest_filename = os.path.basename(dest) |
|---|
| 1466 | dest = os.path.dirname(dest) |
|---|
| 1467 | dest = os.path.normpath(os.path.abspath(dest)) |
|---|
| 1468 | source = os.path.normpath(os.path.abspath(source)) |
|---|
| 1469 | dest_parts = dest.strip(os.path.sep).split(os.path.sep) |
|---|
| 1470 | source_parts = source.strip(os.path.sep).split(os.path.sep) |
|---|
| 1471 | while dest_parts and source_parts and dest_parts[0] == source_parts[0]: |
|---|
| 1472 | dest_parts.pop(0) |
|---|
| 1473 | source_parts.pop(0) |
|---|
| 1474 | full_parts = ['..']*len(source_parts) + dest_parts |
|---|
| 1475 | if not dest_is_directory: |
|---|
| 1476 | full_parts.append(dest_filename) |
|---|
| 1477 | if not full_parts: |
|---|
| 1478 | # Special case for the current directory (otherwise it'd be '') |
|---|
| 1479 | return './' |
|---|
| 1480 | return os.path.sep.join(full_parts) |
|---|
| 1481 | |
|---|
| 1482 | |
|---|
| 1483 | |
|---|
| 1484 | ############################################################ |
|---|
| 1485 | ## Bootstrap script creation: |
|---|
| 1486 | |
|---|
| 1487 | def create_bootstrap_script(extra_text, python_version=''): |
|---|
| 1488 | """ |
|---|
| 1489 | Creates a bootstrap script, which is like this script but with |
|---|
| 1490 | extend_parser, adjust_options, and after_install hooks. |
|---|
| 1491 | |
|---|
| 1492 | This returns a string that (written to disk of course) can be used |
|---|
| 1493 | as a bootstrap script with your own customizations. The script |
|---|
| 1494 | will be the standard virtualenv.py script, with your extra text |
|---|
| 1495 | added (your extra text should be Python code). |
|---|
| 1496 | |
|---|
| 1497 | If you include these functions, they will be called: |
|---|
| 1498 | |
|---|
| 1499 | ``extend_parser(optparse_parser)``: |
|---|
| 1500 | You can add or remove options from the parser here. |
|---|
| 1501 | |
|---|
| 1502 | ``adjust_options(options, args)``: |
|---|
| 1503 | You can change options here, or change the args (if you accept |
|---|
| 1504 | different kinds of arguments, be sure you modify ``args`` so it is |
|---|
| 1505 | only ``[DEST_DIR]``). |
|---|
| 1506 | |
|---|
| 1507 | ``after_install(options, home_dir)``: |
|---|
| 1508 | |
|---|
| 1509 | After everything is installed, this function is called. This |
|---|
| 1510 | is probably the function you are most likely to use. An |
|---|
| 1511 | example would be:: |
|---|
| 1512 | |
|---|
| 1513 | def after_install(options, home_dir): |
|---|
| 1514 | subprocess.call([join(home_dir, 'bin', 'easy_install'), |
|---|
| 1515 | 'MyPackage']) |
|---|
| 1516 | subprocess.call([join(home_dir, 'bin', 'my-package-script'), |
|---|
| 1517 | 'setup', home_dir]) |
|---|
| 1518 | |
|---|
| 1519 | This example immediately installs a package, and runs a setup |
|---|
| 1520 | script from that package. |
|---|
| 1521 | |
|---|
| 1522 | If you provide something like ``python_version='2.4'`` then the |
|---|
| 1523 | script will start with ``#!/usr/bin/env python2.4`` instead of |
|---|
| 1524 | ``#!/usr/bin/env python``. You can use this when the script must |
|---|
| 1525 | be run with a particular Python version. |
|---|
| 1526 | """ |
|---|
| 1527 | filename = __file__ |
|---|
| 1528 | if filename.endswith('.pyc'): |
|---|
| 1529 | filename = filename[:-1] |
|---|
| 1530 | f = open(filename, 'rb') |
|---|
| 1531 | content = f.read() |
|---|
| 1532 | f.close() |
|---|
| 1533 | py_exe = 'python%s' % python_version |
|---|
| 1534 | content = (('#!/usr/bin/env %s\n' % py_exe) |
|---|
| 1535 | + '## WARNING: This file is generated\n' |
|---|
| 1536 | + content) |
|---|
| 1537 | return content.replace('##EXT' 'END##', extra_text) |
|---|
| 1538 | |
|---|
| 1539 | import os, subprocess |
|---|
| 1540 | |
|---|
| 1541 | def after_install(options, home_dir): |
|---|
| 1542 | def call(*args): |
|---|
| 1543 | retcode = subprocess.call(*args) |
|---|
| 1544 | if retcode: |
|---|
| 1545 | sys.stderr.write("Exit status %d from command args %s\n" % (retcode, args)) |
|---|
| 1546 | sys.exit(retcode) |
|---|
| 1547 | |
|---|
| 1548 | call([join(home_dir, 'bin', 'easy_install'), 'virtualenv>=1.6.1']) |
|---|
| 1549 | call([join(home_dir, 'bin', 'easy_install'), '--upgrade', 'pip']) |
|---|
| 1550 | call([join(home_dir, 'bin', 'easy_install'), 'paver']) |
|---|
| 1551 | |
|---|
| 1552 | source_root = os.path.dirname(__file__) |
|---|
| 1553 | pavement_file = join(source_root, 'obadmin', 'obadmin', 'pavement.py') |
|---|
| 1554 | call([join(home_dir, 'bin', 'paver'), '-f', pavement_file, 'post_bootstrap']) |
|---|
| 1555 | |
|---|
| 1556 | # link source code |
|---|
| 1557 | if not os.path.abspath(source_root).startswith(os.path.abspath(home_dir)): |
|---|
| 1558 | source_link = join(home_dir, 'src', 'openblock') |
|---|
| 1559 | print "symlinking openblock source in %s to %s" % (source_root, source_link) |
|---|
| 1560 | copyfile(source_root, source_link, symlink=True) |
|---|
| 1561 | |
|---|
| 1562 | |
|---|
| 1563 | def adjust_options(options, args): |
|---|
| 1564 | # Sanity-checking Python version here b/c we want to do this early and |
|---|
| 1565 | # there's no more appropriate hook in a virtualenv bootstrap |
|---|
| 1566 | # script. |
|---|
| 1567 | import sys |
|---|
| 1568 | if not ((2, 6) <= sys.version_info[:2] < (3, 0)): |
|---|
| 1569 | raise EnvironmentError( |
|---|
| 1570 | "Incompatible Python version, we need Python >= 2.6" |
|---|
| 1571 | " and less than 3.0.") |
|---|
| 1572 | # assume build in place unless otherwise specified |
|---|
| 1573 | if len(args) == 0: |
|---|
| 1574 | args[:] = ['./'] |
|---|
| 1575 | |
|---|
| 1576 | |
|---|
| 1577 | def convert(s): |
|---|
| 1578 | b = base64.b64decode(s.encode('ascii')) |
|---|
| 1579 | return zlib.decompress(b).decode('utf-8') |
|---|
| 1580 | |
|---|
| 1581 | ##file site.py |
|---|
| 1582 | SITE_PY = convert(""" |
|---|
| 1583 | eJzVPP1z2zaWv/OvwMqTIZXKdD66nR2n7o2TOK3v3MTbpLO5dT06SoIk1hTJEqQV7c3d337vAwAB |
|---|
| 1584 | kvLHdvvDaTKxRAIPDw/vGw8YjUanZSnzhdgUiyaTQsmkmq9FmdRrJZZFJep1Wi0Oy6Sqd/B0fpOs |
|---|
| 1585 | pBJ1IdROxdgqDoKnv/MTPBWf1qkyKMC3pKmLTVKn8yTLdiLdlEVVy4VYNFWar0Sap3WaZOk/oEWR |
|---|
| 1586 | x+Lp78cgOM8FzDxLZSVuZaUArhLFUlzu6nWRi6gpcc7P4z8nL8cToeZVWtbQoNI4A0XWSR3kUi4A |
|---|
| 1587 | TWjZKCBlWstDVcp5ukzntuG2aLKFKLNkLsV//RdPjZqGYaCKjdyuZSVFDsgATAmwSsQDvqaVmBcL |
|---|
| 1588 | GQvxWs4THICft8QKGNoE10whGfNCZEW+gjnlci6VSqqdiGZNTYAIZbEoAKcUMKjTLAu2RXWjxrCk |
|---|
| 1589 | tB5beCQSZg9/MsweME8cv885gOOHPPg5T79MGDZwD4Kr18w2lVymX0SCYOGn/CLnU/0sSpdikS6X |
|---|
| 1590 | QIO8HmOTgBFQIktnRyUtx7d6hb47IqwsVyYwhkSUuTG/pB5xcF6LJFPAtk2JNFKE+Vs5S5McqJHf |
|---|
| 1591 | wnAAEUgaDI2zSFVtx6HZiQIAVLiONUjJRolok6Q5MOuPyZzQ/luaL4qtGhMFYLWU+LVRtTv/aIAA |
|---|
| 1592 | 0NohwCTAxTKr2eRZeiOz3RgQ+ATYV1I1WY0CsUgrOa+LKpWKAABqOyG/ANITkVRSk5A508jthOhP |
|---|
| 1593 | NElzXFgUMBR4fIkkWaarpiIJE8sUOBe44t2Hn8Tbs9fnp+81jxlgLLOrDeAMUGihHZxgAHHUqOoo |
|---|
| 1594 | K0Cg4+AC/4hksUAhW+H4gFfb4OjelQ4imHsZd/s4Cw5k14urh4E51qBMaKyA+v03dJmoNdDnf+5Z |
|---|
| 1595 | 7yA43UcVmjh/264LkMk82UixTpi/kDOCbzWc7+KyXr8CblAIpwZSKVwcRDBFeEASl2ZRkUtRAotl |
|---|
| 1596 | aS7HAVBoRm39VQRWeF/kh7TWHU4ACFWQw0vn2ZhGzCVMtA/rFeoL03hHM9NNArvOm6IixQH8n89J |
|---|
| 1597 | F2VJfkM4KmIo/jaTqzTPESHkhSA8CGlgdZMCJy5icUGtSC+YRiJk7cUtUSQa4CVkOuBJ+SXZlJmc |
|---|
| 1598 | sPiibr1bjdBgshZmrTPmOGhZk3qlVWunOsh7L+LPHa4jNOt1JQF4M/OEblkUEzEDnU3YlMmGxave |
|---|
| 1599 | FsQ5wYA8USfkCWoJffE7UPRUqWYj7UvkFdAsxFDBssiyYgskOw4CIQ6wkTHKPnPCW3gH/wNc/D+T |
|---|
| 1600 | 9XwdBM5IFrAGhcjvA4VAwCTIXHO1RsLjNs3KXSWT5qwpimohKxrqYcQ+YsQf2BjnGrwvam3UeLq4 |
|---|
| 1601 | ysUmrVElzbTJTNni5WHN+vEVzxumAZZbEc1M05ZOG5xeVq6TmTQuyUwuURL0Ir2yyw5jBgNjki2u |
|---|
| 1602 | xYatDLwDssiULciwYkGls6wlOQEAg4UvydOyyaiRQgYTCQy0KQn+JkGTXmhnCdibzXKAConN9xzs |
|---|
| 1603 | D+D2DxCj7ToF+swBAmgY1FKwfLO0rtBBaPVR4Bt905/HB049X2rbxEMukzTTVj7Jg3N6eFZVJL5z |
|---|
| 1604 | WWKviSaGghnmNbp2qxzoiGI+Go2CwLhDO2W+Fiqoq90xsIIw40ynsyZFwzedoqnXP1TAowhnYK+b |
|---|
| 1605 | bWfhgYYwnd4DlZwuy6rY4Gs7t4+gTGAs7BEciEvSMpIdZI8TXyH5XJVemqZoux12FqiHgsufzt6d |
|---|
| 1606 | fz77KE7EVavSJl19dg1jnuUJsDVZBGCqzrCtLoOWqPhS1H3iHZh3YgqwZ9SbxFcmdQO8C6h/qhp6 |
|---|
| 1607 | DdOYey+Ds/enry/Opj9/PPtp+vH80xkgCHZGBgc0ZTSPDTiMKgbhAK5cqFjb16DXgx68Pv1oHwTT |
|---|
| 1608 | VE3LXbmDB2AogYWrCOY7ESE+nGobPE3zZRGOqfGv7ISfsFrRHtfV8dfX4uREhL8mt0kYgNfTNuVF |
|---|
| 1609 | /JEE4NOulNC1hj9RocZBsJBLEJYbiSIVPSVPdswdgIjQstCW9dcizc175iN3CJL4iHoADtPpPEuU |
|---|
| 1610 | wsbTaQikpQ4DH+gQszuMchJBx3Lndh1rVPBTSViKHLtM8L8BFJMZ9UM0GEW3i2kEAraZJ0pyK5o+ |
|---|
| 1611 | 9JtOUctMp5EeEMSPeBxcJFYcoTBNUMtUKXiixCuodWaqyPAnwke5JZHBYAj1Gi6SDnbi2yRrpIqc |
|---|
| 1612 | SQERo6hDRlSNqSIOAqciAtvZLt143KWm4RloBuTLCtB7VYdy+DkADwUUjAm7MDTjaIlphpj+O8cG |
|---|
| 1613 | hAM4iSEqaKU6UFificuzS/Hy2YtDdEAgSlxY6njN0aameSPtwyWs1krWDsLcK5yQMIxduixRM+LT |
|---|
| 1614 | 47thbmK7Mn1WWOolruSmuJULwBYZ2Fll8RO9gVga5jFPYBVBE5MFZ6VnPL0EI0eePUgLWnug3oag |
|---|
| 1615 | mPU3S3/A4bvMFagODoWJ1DpOZ+NVVsVtiu7BbKdfgnUD9YY2zrgigbNwHpOhEQMNAX5rjpTayhAU |
|---|
| 1616 | WNWwi0l4I0jU8ItWFcYE7gJ16zV9vcmLbT7l2PUE1WQ0tqyLgqWZFxu0S3Ag3oHdACQLCMVaojEU |
|---|
| 1617 | cNIFytYhIA/Th+kCZSkaAEBgmhUFWA4sE5zRFDnOw2ERxviVIOGtJFr4WzMEBUeGGA4kehvbB0ZL |
|---|
| 1618 | ICSYnFVwVjVoJkNZM81gYIckPtddxBw0+gA6VIzB0EUaGjcy9Ls6BuUsLlyl5PRDG/r582dmG7Wm |
|---|
| 1619 | jAgiNsNJo9FfknmLyx2YwhR0gvGhOL9CbLAFdxTANEqzpjj8KIqS/SdYz0st22C5IR6r6/L46Gi7 |
|---|
| 1620 | 3cY6H1BUqyO1PPrzX7755i/PWCcuFsQ/MB1HWnRyLD6id+iDxt8aC/SdWbkOP6a5z40EK5LkR5Hz |
|---|
| 1621 | iPh936SLQhwfjq3+RC5uDSv+b5wPUCBTMyhTGWg7ajF6og6fxC/VSDwRkds2GrMnoU2qtWK+1YUe |
|---|
| 1622 | dQG2GzyNedHkdegoUiW+AusGMfVCzppVaAf3bKT5AVNFOY0sDxw+v0YMfM4wfGVM8RS1BLEFWnyH |
|---|
| 1623 | 9D8x2yTkz2gNgeRFE9WLd3fDWswQd/FwebfeoSM0ZoapQu5AifCbPFgAbeO+5OBHO6No9xxn1Hw8 |
|---|
| 1624 | Q2AsfWCYV7uCEQoO4YJrMXGlzuFq9FFBmrasmkHBuKoRFDS4dTOmtgZHNjJEkOjdmPCcF1a3ADp1 |
|---|
| 1625 | cn0mojerAC3ccXrWrssKjieEPHAintMTCU7tce/dM17aJssoBdPhUY8qDNhbaLTTBfBlZABMxKj6 |
|---|
| 1626 | ecQtTWDxobMovAYDwArO2iCDLXvMhG9cH3B0MBpgp57V39ebaTwEAhcp4uzRg6ATyic8QqVAmsrI |
|---|
| 1627 | 77mPxS1x+4PdaXGIqcwykUirPcLVVR6DQnWnYVqmOepeZ5HieVaAV2y1IjFS+953FihywcdDxkxL |
|---|
| 1628 | oCZDSw6n0Ql5e54AhrodJrxWDaYG3MwJYrRJFVk3JNMa/gO3gjISlD4CWhI0C+ahUuZP7F8gc3a+ |
|---|
| 1629 | +sse9rCERoZwm+5zQ3oWQ8Mx7w8EklHnT0AKciBhXxjJdWR1kAGHOQvkCTe8lnulm2DECuTMsSCk |
|---|
| 1630 | ZgB3eukFOPgkxj0LklCE/KVWshRfiREsX1dUH6a7/6VcatIGkdOAXAWdbzhxcxFOHuKkk5fwGdrP |
|---|
| 1631 | SNDuRlkAB8/A5XFT8y6bG6a1aRJw1n3FbZECjUyZk9HYRfXaEMZN//7pxGnREssMYhjKG8jbhDEj |
|---|
| 1632 | jQO73Bo0LLgB4615dyz92M1YYN8oLNQLufkC8V9YpWpeqBAD3F7uwv1orujTxmJ7kc5G8MdbgNH4 |
|---|
| 1633 | 2oMkM52/wCzLPzFI6EEPh6B7k8W0yCKptmkekgLT9Dvxl6aHhyWlZ+SOPlI4dQQTxRzl0bsKBIQ2 |
|---|
| 1634 | K49AnFATQFQuQ6Xd/j7YO6c4snC5+8hzm6+OX173iTvZl+Gxn+GlOvtSV4nC1cp40VgocLX6BhyV |
|---|
| 1635 | LkwuyXd6u1FvR2OYUBUKokjx4eNngYTgTOw22T1u6i3DIzb3zsn7GNRBr91Lrs7siF0AEdSKyChH |
|---|
| 1636 | 4eM58uHIPnZyd0zsEUAexTB3LIqBpPnkn4Fz10LBGIeLXY55tK7KwA+8/ubr6UBm1EXym69H94zS |
|---|
| 1637 | IcaQ2EcdT9COTGUAYnDapkslk4x8DacTZRXzlndsm3LMCp3iP81k1wNOJ37Me2MyWvi95r3A0XwO |
|---|
| 1638 | iB4QZhezXyFYVTq/dZukGSXlAY3DQ9RzJs7m1MEwPh6ku1HGnBR4LM8mg6GQunoGCxNyYD/uT0f7 |
|---|
| 1639 | Racm9zsQkJpPmag+Kgd6A77dP/I21d29w/2yP2ip/yCd9UhA3mxGAwR84BzM3ub//5mwsmJoWlmN |
|---|
| 1640 | O1pfybv1vAH2AHW4x825ww3pD827WUvjTLDcKfEUBfSp2NKGNuXycGcCoCzYzxiAg8uot0XfNFXF |
|---|
| 1641 | m5sk56WsDnHDbiKwlsd4GlQi1Adz9F7WiIltNqfcqFP5UQypzlBnO+1MwtZPHRbZdWFyJDK/TSvo |
|---|
| 1642 | C1olCn/48ONZ2GcAPQx2GgbnrqPhkofbKYT7CKYNNXHCx/RhCj2myz8vVV1X2Seo2TM2GUhNtj5h |
|---|
| 1643 | e4lHE7cOr8E9GQhvg5A3YjEinK/l/GYqaXMZ2RS7OknYN/gaMbF7zn6FkEqWVOYEM5lnDdKKHT2s |
|---|
| 1644 | T1s2+Zzy8bUEe66LSbG4hLaMOd20zJKViKjzAlMdmhspG3KbVNrbKasCyxdFky6OVulCyN+aJMMw |
|---|
| 1645 | Ui6XgAtuluhXMQ9PGQ/xlne9uaxNyXlTpfUOSJCoQu810Qa503C244lGHpK8rcAExC3zY/ERp43v |
|---|
| 1646 | mXALQy4TjPoZdpwkxnnYwWwGInfRc3ifF1McdUpVoBNGqr8PTI+D7ggFABgBUJj/aKwzRf4bSa/c |
|---|
| 1647 | DS1ac5eoqCU9UrqRbUEeB0KJxhhZ82/66TOiy1t7sFztx3J1N5arLparQSxXPparu7F0RQIX1iZJ |
|---|
| 1648 | jCQMJUq6afTBigw3x8HDnCXzNbfD6kCsAgSIojQBnZEpLpL1Mim8n0RASG07G5z0sK2wSLnssCo4 |
|---|
| 1649 | 5apBIvfjpokOHk15s9OZ6jV0Z56K8dn2VZn4fY/imIqJZtSd5W2R1EnsycUqK2YgthbdSQtgIroF |
|---|
| 1650 | J5yby2+nM84mdizV6PI/P/3w4T02R1Ajs51O3XAR0bDgVKKnSbVSfWlqg40S2JFa+oUf1E0DPHhg |
|---|
| 1651 | JodHOeD/3lJFATKO2NKOeCFK8ACo7sc2c6tjwrDzXJfR6OfM5Ly5cSJGeT1qJ7WHSKeXl29PP52O |
|---|
| 1652 | KMU0+t+RKzCGtr50uPiYFrZB339zm1uKYx8Qap1LaY2fOyeP1i1H3G9jDdiO2/vsuvPgxUMM9mBY |
|---|
| 1653 | 6s/yD6UULAkQKtbJxscQ6sHBz+8KE3r0MYzYKw9zd3LYWbHvHNlzXBRH9IfS3N0B/M01jDGmQADt |
|---|
| 1654 | QkUmMmiDqY7St+b1Doo6QB/o6/3uEKwbenUjGZ+idhIDDqBDWdtsv/vn7Quw0VOyfn32/fn7i/PX |
|---|
| 1655 | l6effnBcQHTlPnw8eiHOfvwsqB4BDRj7RAluxddY+QKGxT0KIxYF/GswvbFoak5KQq+3Fxd6Z2CD |
|---|
| 1656 | hyGwOhZtTgzPuWzGQuMcDWc97UNd74IYZTpAck6dUHkInUrBeGnDJx5UoSto6TDLDJ3VRode+jSR |
|---|
| 1657 | OXVE+6gxSB80dknBILikCV5RnXNtosKKd5z0SZwBpLSNtoUIGeWgetvTzn6LyeZ7iTnqDE/azlrR |
|---|
| 1658 | X4UuruF1rMoshUjuVWhlSXfDcoyWcfRDu6HKeA1pQKc7jKwb8qz3YoFW61XIc9P9xy2j/dYAhi2D |
|---|
| 1659 | vYV555LKEahGF4upRIiNeOcglF/gq116vQYKFgw3lmpcRMN0Kcw+geBarFMIIIAn12B9MU4ACJ2V |
|---|
| 1660 | 8BPQx052QBZYDRC+2SwO/xpqgvitf/lloHldZYd/FyVEQYJLV8IBYrqN30LgE8tYnH14Nw4ZOSoF |
|---|
| 1661 | FX9tsIAcHBLK8jnSTvUyvGM7jZTMlrqewdcH+EL7CfS6072SZaW7D7vGIUrAExWR1/BEGfqFWF5k |
|---|
| 1662 | YU9wKuMOaKyNt5jhGTN329t8DsTHtcwyXRF9/vbiDHxHLNdHCeJ9njMYjvMluGWri734DFwHFG7o |
|---|
| 1663 | wusK2bhCF5Y29Rex12wwM4siR729OgC7TpT97PfqpTqrJFUu2hFOm2GZgvMYWRnWwiwrs3anDVLY |
|---|
| 1664 | bUMUR5lhlpheVlQw6fME8DI9TTgkglgJDwOYNDPvWqZ5bSrksnQOehRULijUCQgJEhdPvBHnFTkn |
|---|
| 1665 | eotKmYMy8LDcVelqXWMyHTrHVKSPzX88/Xxx/p4K11+8bL3uAeacUCQw4aKFEyxJw2wHfHHLzJCr |
|---|
| 1666 | ptMhntWvEAZqH/jTfcXVECc8QK8fJxbxT/cVn1Q6cSJBngEoqKbsigcGAE63IblpZYFxtXEwftyS |
|---|
| 1667 | sxYzHwzlIvFghC4scOfX50TbsmNKKO9jXj5il2JZahpGprNbAtX96DkuS9xWWUTDjeDtkGyZzwy6 |
|---|
| 1668 | 3vTe7Cu2cj89KcRDk4BRv7U/hqlG6jXV03GYbR+3UFirbewvuZMrddrNcxRlIGLkdh67TDashHVz |
|---|
| 1669 | 5kCvbLcHTHyr0TWSOKjKR7/kI+1heJhYYvfiFNORjk2QEcBMhtSnQxrwodAigAKhatPIkdzJ+OkL |
|---|
| 1670 | b46ONbh/jlp3gW38ARShrv2kMwVFBZwIX35jx5FfEVqoR49F6HgqucwLW5eEn+0avcrn/hwHZYCS |
|---|
| 1671 | mCh2VZKvZMSwJgbmVz6x96RgSdt6pL5Kr4cMizgH5/TLHg7vy8XwxolBrcMIvXY3ctdVRz55sMHg |
|---|
| 1672 | 0YM7CeaDr5It6P6yqSNeyWGRHz5ttR/q/RCx2g2a6s3eKMR0zG/hnvVpAQ9SQ8NCD++3gd0i/PDa |
|---|
| 1673 | GEfW2sfOKZrQvtAe7LyC0KxWtC3jHF8zvqj1AlqDe9Ka/JF9qgtT7O+Bc0lOTsgC5cFdkN7cRrpB |
|---|
| 1674 | J50w4uMxfLYwpfLr9vSGfreQtzIrwPWCqA6r63+11fXj2KZTBuuOfjd2l7vL3TBu9KbF7NiU/6Nn |
|---|
| 1675 | pkpYvziX9RGiM5jxuQuzFhlc6l90SJLkN+Qlv/nb+US8ef8T/P9afoC4Co/HTcTfAQ3xpqggvuTz |
|---|
| 1676 | nXTwHk8O1Bw4Fo3CM3QEjbYq+I4CdNsuPTrjtog+0uCfZbCaUmAVZ7XhizEARZ4gnXlu/QRTqA+/ |
|---|
| 1677 | zUmijjdqPMWhRRnpl0iD/Ycr8EDCkW4Zr+tNhvbCyZK0q3k1ujh/c/b+41lcf0EONz9HThbFLwDC |
|---|
| 1678 | 6eg94gr3wybCPpk3+OTacZx/kFk54DfroNMc1MCgU4QQl5Q20ORLFxIbXCQVZg5EuVsU8xhbAsvz |
|---|
| 1679 | 2bB6C4702Ikv7zX0npVFWNFY76K13jw+BmqIX7qKaAQNqY+eE/UkhJIZHlLix/Fo2BRPBKW24c/T |
|---|
| 1680 | m+3CzYzr0yY0wS6m7awjv7vVhWums4ZnOYnwOrHLYA4gZmmiNrO5ezDtQy70nRmg5WifQy6TJquF |
|---|
| 1681 | zEFyKcinywtA07tnyVhCmFXYnNEBK0rTZNtkp5xKm0SJEY46ovPXuCFDGUOIwX9Mbtge4CE30fBp |
|---|
| 1682 | WYBOiFL8VDhdVTNfswRzSETUGyg82Kb5yxdhj8I8KEfI89aRhXmi28gYrWSt588PovHV87bSgbLS |
|---|
| 1683 | c+8k6bwEq+eyyQGozvLp06cj8W/3ez+MSpwVxQ24ZQB70Gu5oNd7LLeenF2tvmdv3sTAj/O1vIIH |
|---|
| 1684 | 15Q9t8+bnFKTd3SlBZH2r4ER4tqElhlN+45d5qRdxRvN3II3rLTl+DlP6WYcTC1JVLb6giFMOxlp |
|---|
| 1685 | IpYExRAmap6mIacpYD12RYOHwDDNqPlFfgGOTxHMBN/iDhmH2mv0MKlg03KPRedEjAjwiAqoeDQ6 |
|---|
| 1686 | RUvHoADP6eVOozk9z9O6Pb/wzN081afFa3vhjeYrkWxRMsw8OsRwzhN6rNp62MWdLOpFLMX8yk04 |
|---|
| 1687 | dmbJr+/DHVgbJK1YLg2m8NAs0ryQ1dyYU1yxdJ7WDhjTDuFwZ7rnh6xPHAygNAL1TlZhYSXavv2T |
|---|
| 1688 | XRcX0w+0j3xoRtLlQ7W9O4mTQ0neqaKL43Z8SkNZQlq+NV/GMMp7SmtrT8AbS/xJJ1WxeN274sE9 |
|---|
| 1689 | R9fk+uoGrt9o73MAOHRdkFWQlh09HeHcUWXhM9PuuXABPxSiE263aVU3STbVNwRM0WGb2o11jac9 |
|---|
| 1690 | f3XnyULrrYCTX4AHfKhLxcFxMFU2SE+s9DRHAU7EUqcoYvdIk3/6pyzQy3vBvhL4FEiZxdQcxDVJ |
|---|
| 1691 | pCvLrvaE4zO+gsBR8QjqK3Nq5iE2wZzd6B17cKcxoaKncNwt5ey1wg0WU5tvPe9uZPCoITuwfC/e |
|---|
| 1692 | TLB7cYP47kREzyfiz51AbF7u8OohIMOTRfxkEfo+IXW9On7R2rl+4NuBsBfIy+tHTzdLZzS9cKjG |
|---|
| 1693 | +v6+uugRA9ANyO4ylYvDJwqxY5x/L1QNpZ3Xfk6lGeMR7ANbdaVPH7dnMujo1Qyiim2r0BzVZvxf |
|---|
| 1694 | O4g51qz1EJ8ARaXBFtCeWjeFL53iQ3uzGBYmavT8lUUpmQ5tjuE3vB0E3muCukK1d9NUl5FbsAM5 |
|---|
| 1695 | AX1WkLfA2oYDQeEjeCikm0xo0b7qbAv/kYvHlen7Nhd7WH7z9V14ugI+WJY/QFCPmE6rP5Cp9rLM |
|---|
| 1696 | YxfmAfv19/Pfw3nvLr57NJV0r2FaYSiFhczrhN+gSWzKY5tqMCKJW0GRW96Gn/pm8OAHiyPqpvom |
|---|
| 1697 | vGv63P+uuesWgZ252d3tzd0/4OXSQPfdzy9DNOAwTxPiQTXjrcAO6wJXjCe6qGA4Zak/SH63E850 |
|---|
| 1698 | j1a4D4wpYcAEKLGpxt5ozU0yd79jhcwh32Hqnucb1NWdafcOOHY5/iGKlqsB8Lk94kslHgvNgew3 |
|---|
| 1699 | 0qVUUy4anMrVSk0TvBBtSsEGFbj0vEjjvr6j+6xkonbG68RbQwCE4SZdiuhWGwNjQEDDF7NyfYhz |
|---|
| 1700 | PYSgoamK0inLVOmCM0jaxQVwMWeOqL/JTHJd5SiTmPBTTVVWEBWM9PWdXLgwVOvZAjWJjE2ibgzq |
|---|
| 1701 | psdE3+aIQ3C1jDkDyPkqjjQ86gAh+GiQczcRFypPp/Yd8Muz9qxzOrEMIfNmI6ukbu/58LdJU/Gd |
|---|
| 1702 | MwKd/MQFdlIVrWR2OMVFLLX84SCFyQL7/SvtZHtBxh0HnMdW6z2craiHToE95uy0Y3sMN6df7D1f |
|---|
| 1703 | 7v0yC7oV1jXytlnLffZuE1gKc2kV6UqdO+C3+iIdvp6RM5voJjh8BHLvnrvyy3OtWmMnxaLhPHMV |
|---|
| 1704 | Q//mFDy6S7Z46EK0Hhf0rz7rOPp2fF9vWGbphQZ7GlsqatdqUPG0o43biBor6e6JqP1q6UdG1B78 |
|---|
| 1705 | B0bU+vo6MDgaH60PBuun7wm9WU24d8G1jAB9pkAk3Nnr3CRmTGbkViND2Jt+Gdm7WFlnOkecjJlA |
|---|
| 1706 | juxfEkQg+M435ZZuencymXGHIlpfuujx9xcfXp9eEC2ml6dv/uP0e6pWwfRxx2Y9OOWQF4dM7UOv |
|---|
| 1707 | LtZNP+gKg6HBW2wHLlfkwx0aQu99b3N2AMLwQZ6hBe0qMvf1vg69AxH9ToD43dPuQN2nsgch9/wz |
|---|
| 1708 | XXzv1hV0ClgD/ZSrDc0vZ8vWPDI7FywO7c6Eed8mk7WM9nJt+xbOqfvrqxPtt+rr+PbkAce2+pRW |
|---|
| 1709 | AHPIyF82hWyOEthEJTsq3RvyqWQWj2GZqyxACufSuVKNblNjULV/FX8Fyi7BfTB2GCf2Wltqx+ly |
|---|
| 1710 | Ze9rxr2wuYwNQbxzUKP+/FxhX8hsDxWCgBWevjCMETH6T28w2e3YJ0pcHdKJy0NUNtf2F66ZdnL/ |
|---|
| 1711 | luKma20v3lFcucHbTtB42WTuRqrt0+tAzh9l54ulU+IPmu8I6NyKpwL2Rp+JFeJsJ0IIJPWGIVYN |
|---|
| 1712 | Eh31rVkO8mg3HewNrZ6Jw33n8dzzaEI8399w0Tnypnu84B7qnh6qMaeeHAuM5Wv7DtqJ7wgyb+8I |
|---|
| 1713 | umnHcz5wT1Ff8Apfb6+eH9tkK/I7vnYUCZXZjBzDfuWUqd15u5vTnZilmlAdE8ZszjFN3eLagco+ |
|---|
| 1714 | wb4Yp1ervycOMvu+DGnkvR8u8jE9vFurR11MLesdw5RE9ESNaVrO6QaNu30y7k+3VVt9IHxS4wFA |
|---|
| 1715 | eioQYCGYnm50Kud2XP4aPdNR4ayhezHdjHvoSAVV0fgcwT2M79fi1+1OJywf1J1RNP25QZcD9ZKD |
|---|
| 1716 | cLPvwK3GXkpkv0noTr3lgz0uAB9WHe7//AH9+/VdtvuLu/xq2+rl4AEp9mWxJBArJTokMo9jMDKg |
|---|
| 1717 | NyPS1lhHbgQdL6Fo6egyVDs35At0/KjMEG+9pQCDnNmp9gCsUQj+D1/Qrqc= |
|---|
| 1718 | """) |
|---|
| 1719 | |
|---|
| 1720 | ##file ez_setup.py |
|---|
| 1721 | EZ_SETUP_PY = convert(""" |
|---|
| 1722 | eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt |
|---|
| 1723 | RT6UwcQ2ebjPfq6195G+/upwanZlMZvP538sy6ZuKnKwatEcD01Z5rWVFXVD8pw0GRbNPkrrVB6t |
|---|
| 1724 | Z1I0VlNax1qM16qnlXUg7DN5EovaPLQPp7X192PdYAHLj1xYzS6rZzLLhXql2UEI2QuLZ5VgTVmd |
|---|
| 1725 | rOes2VlZs7ZIwS3CuX5BbajWNuXBKqXZqZN/dzebWbhkVe4t8c+tvm9l+0NZNUrL7VlLvW58a7m6 |
|---|
| 1726 | sqwS/zhCHYtY9UGwTGbM+iKqGk5Qe59fXavfsYqXz0VeEj7bZ1VVVmurrLR3SGGRvBFVQRrRLzpb |
|---|
| 1727 | utabMqzipVWXFj1Z9fFwyE9Z8TRTxpLDoSoPVaZeLw8qCNoPj4+XFjw+2rPZT8pN2q9Mb6wkCqs6 |
|---|
| 1728 | 4vdamcKq7KDNa6OqtTw8VYQP42irZJi1zqtP9ey7D3/65uc//7T964cffvz4P99bG2vu2BFz3Xn/ |
|---|
| 1729 | 6Ocf/qz8qh7tmuZwd3t7OB0y2ySXXVZPt21S1Lc39S3+63e7nVs3ahe79e/9nf8wm+15uOWkIRD4 |
|---|
| 1730 | Lx2xxfmNt9icum8PJ8/2bfH0tLizFknieYzI1HG90OFJkNA0jWgsvZBFImJksX5FStBJoXFKEhI4 |
|---|
| 1731 | vghCx5OUJqEQvnTTwI39kNEJKd5YlzAK4zhMeUIinkgWBE7skJQ7sRd7PE1fl9LrEsAAknA3SrlH |
|---|
| 1732 | RRS5kvgeiUToiUAm3pRF/lgXSn2XOZLFfpqSyA/jNI1DRngqQ+JEbvKqlF4XPyEJw10eCcY9zwti |
|---|
| 1733 | 6capjDmJolQSNiElGOsSeU4QEi8QPBCuoCyOpXD8lJBARDIW4atSzn5h1CNuEkKPhBMmJfW4C30c |
|---|
| 1734 | n/rUZcHLUthFvlBfejQM/ZRHiGss44DwOHU9CCKpk0xYxC7zBfZwweHJKOYe96QUbuA4qR8F0iPB |
|---|
| 1735 | RKSZ64yVYXCHR2jIfeJ4YRSEEeLDXD9xHBI7qfO6mF6bMOZ4ETFKaeLEscfClIQ+SQLfJyHnk54x |
|---|
| 1736 | YsJODBdBRFgCX6YxS9IwjD0RiiREOgqasPh1MVGvTSJQSURIJ4KDPCaiwA0gzYORcPhEtAEqY994 |
|---|
| 1737 | lAiCGnZ9jvdRRl4iYkpCGhJoxMXrYs6R4pGfypQ6EBawwAvS2PEDLpgnmMO8yUi5Y99EAUsD6VMZ |
|---|
| 1738 | kxhZ6AuW+MKhHsIdByn1XhfT+4ZKknqu41COMHHUBCQJzn0EPgqcJJoQc4Ez0nGigMqIEI/G3IFa |
|---|
| 1739 | 8GyAxHYSN2beVKAucCZyIzf1hGB+KINYIGpuxHhEXA9SvXhKygXOSDcBQAF8uUSqEC9MWQop0uUx |
|---|
| 1740 | jRM5gVbsAmeEI3gcRInH0jShksbwdOIgex3EPHangu2Pg0SokG4kOYdhYRi6QRK4LAZ+8TRJo3BK |
|---|
| 1741 | ygVaUYemru8SRqjvOXAGcC6WQcBCAEXsylel9BYhSST2jHggqfRRUVSmQcQcuAqoJ6YSJhhblCi0 |
|---|
| 1742 | BvD7HuM0ZbFHmQwAX14kvYTIKbQKxxYJkUqeOFAHBYmMlb4ApocxAIMnbjQV6XBsEZHAKi7BKm7s |
|---|
| 1743 | uELAuTHIKaQMhEeiKZQJL2KUcF9GAISAMUKS2A2QONyPKWPc5yGfkBKNLULBJGD5xHUjMFGSBLEH |
|---|
| 1744 | EWDMMEhR2lPAGV2wGwsjIsOYwr/oHlANkQNDgsBHgYVkChuisUXUkwmJQw9kD9ilPkjaQai5CCVa |
|---|
| 1745 | idCfkBJfwJ2DGMmUcOaTyA1F6LohyhAtRQIInMyX+IIJSCLTMAALcGC5I2kUM+lKD2HAI2+qAuKx |
|---|
| 1746 | RQE4lgBvJVoGFGDgB67rSi4S38W/eEqX5KIbclQv5KXwSMrBHyoFAeCJ76jGynldSm8Ro8RPgA3o |
|---|
| 1747 | OYLEZ47KWWQbnM3ALJM0kIwtcmPPjQFyCHTKmRs6YeqQMKG+QJ2n4VSk07FF0J0FDpoZV3mYBmkk |
|---|
| 1748 | AiapcBLYypypSKcXyIAkQ2MHbvWThEdAJyKEEwG8WOQHU/1dK6W3SAqE1hchcWPqegxhYmHg0hjc |
|---|
| 1749 | C+YXU0ySjvmIEZSNKxVqEk9wAJOb+mC2mIaphx4HUn6dDSYCjDf1rKlOd2bg2pF6l2e0m7fQu8/E |
|---|
| 1750 | L0xg1Pio73xQI1G7Fg+H62ZcSGv7heQZun2xxa0ldNoWmAfXlhoAVnfagExa3X01M3bjgXmoLp5h |
|---|
| 1751 | tmgwLigR+kV7J34xdzHfdcsgp1351aaXct+JfjjLUxfmLkyD79+r6aRuuKgw1y1HK9Q1Vya1FrTz |
|---|
| 1752 | 4Q2mMIIxjH9lWcu/lHWd0Xww/mGkw9/7P6zmV8JuejNHj1ajv5Q+4pesWXrmfoXgVoV2l3HoxXCo |
|---|
| 1753 | F7Xj1eZimFv3am0pqcVmMNCtMSluMapuytpmxwq/mWTqX+AiJ6eNG87aIGFs/ObYlHv4gWG6PGEU |
|---|
| 1754 | Lfhtb/bgpEDN9XvyGbHE8PwFriLKQXCeMu1Amp0Z5x9bpR+telcec66mWWJ8PZTWTebFcU9FZTU7 |
|---|
| 1755 | 0lgYhHvBWpaagAvlXUti6u2VOhZcvyKsx5EjHi010i6fdxnbdbsLaK2OJow8a3G7WNlQ0njpUW2p |
|---|
| 1756 | 5AyOMXaiGh2QPGeYuek5EwRfIyNNgmuVixL+yCtB+OmsPvb4KAfqabfr7dqzCS2mabXU0qjQqrQO |
|---|
| 1757 | 0ScWrCx4bXzTqXEgSBTlVHhElVXWZAhd8TQ4zzARb+0vC6HPE8zZCDd6wallrnz44vmI0rI9bBCt |
|---|
| 1758 | MH2WU5VH7CSMKqbOiLUXdU2ehDngOBfd46POl4pktbB+PNWN2H/4RfmrMIEoLNLgnjnZIFRBizJe |
|---|
| 1759 | paAyxpx62F2G6p/PpN4aFIL9G2tx+Py0rURdHism6oVCGLX9vuTHXNTqlGQAoJePTU2g6jjyoHXb |
|---|
| 1760 | cnVGEpVym3PRDOqy9dhFCXZlt74otDMGdEViw7OiapbOWm0yALkWqPud3g1Pd2h3zLdtA7PVwLxR |
|---|
| 1761 | MkyAAOyXskYO0g9fQPj+pQ6Qhg5pH13vMBJtt8m1nJ81fr+Zv2ldtXrXyh6qMBbwV7Py27KQecaa |
|---|
| 1762 | QRxgokFOBstluVzduw9DYhgmxX9KBPOfdufCmCiF5fvNTb3qy7wrb33K+akYc8GckWLRqGrrqwdw |
|---|
| 1763 | ok72dPm0J3mqkI5FgSy3rb/kAsnTLb+Sp8pLVTmwScCWTkOZVXWzBmGoSllAwqnLCuvtzwPlF/aF |
|---|
| 1764 | vE/Fp2L57bGqIA1IbwTcVBeUtgKhndNc2KR6qu+dh9fp7MWwfpchZzN6VBT7fdn8qQRwD3KI1PWs |
|---|
| 1765 | LcR8/OZ6WKv3F5X+oF75Gk7RXFB+HtHpMHsNr75UxL83uapSR6aOWPW7FyhUFy05U4CVl8w0IBos |
|---|
| 1766 | jQ1ZY86DdUPxX0qpBpDViX9Hqb/FqOqe2vWaTg3KP54ZcoIFS8N9HfUpCmHNkeRnI1pKGdNG94FC |
|---|
| 1767 | BWahHjJrh3zMTdJ23enGGkDX25sanfZNrRrt+bAWLg68TeJD7pAplM+sN+OGsCZfBLTfoAE3FPD3 |
|---|
| 1768 | MiuWHWF0S424umJKnO6Kvwd3d420Qp/uddRd3dRLI3Z1p4rhmy9lphLoIIhix06dui+2EXqrS6ci |
|---|
| 1769 | hyDljbrzUl4+jVap1lvFZfyuurDSfiZVsVR+fvv7XebzkBYrW3CuX8ryG50S6nOSpfgiCvUHzDlA |
|---|
| 1770 | 2dlO5AfV5X002TboNPpUQSui8l99krNUrpgB5dcWoGqmbu1RzoWAI/EK6lD1uQBd8awglmB4rWv9 |
|---|
| 1771 | 9hDWNSjbs3ZLoHHb0Zx3hMq8y2Z7NlsCEcWd8rAWsydsp5orXgrDNTuEF0o0z2X1ud10bR0MYZS0 |
|---|
| 1772 | Ie2ncAopNErcAEwVisADTPfoegEknyuxrZxKtAQ0NMBe/Z5RRFKsr1JmALpX7ZPOsrWqpqvX0D/o |
|---|
| 1773 | ZG0yNUe2bVIuxOGd+bG86LTG2dnBsKa6eq63uKAyXXItPtj4WR5Esbxa9rX1A1r82+cqawA+iDH8 |
|---|
| 1774 | q5trYPjntfog8FlFT3UArFJlCGhkZVUddXLk4kKYjvswPVTP3Qi9vsPE7mo/VJsauWGArcaP5Wqs |
|---|
| 1775 | sUERbY3BivX8mc7hTjywtR1m6O5fwuinRsC7SwjABnd6F5aXtViuriCibu600OHzls060IKCufql |
|---|
| 1776 | g63Zv3Mp/t4j05foQb6spxj7zLkfX/uIVHPsB3RL7aqOIF5qnS8+en6tbzajQo/VVxLPa14fJ/Rc |
|---|
| 1777 | 7lx3WeOhYTQz6Jip0hhMCqzc72GoPWoLu8Mb0o5f3dXGSLs4BxdoP6/eqLOVh5VO02exqHRaC0vR |
|---|
| 1778 | +G+mirJU+fmCq5Ta1xyCRccC897nZW+WyGsxiMawF7e329Zb2621wQDo2I7tLv7jrv9/AfAaXNUU |
|---|
| 1779 | TOsyF6jViUG46+NBJqZXv+rRK7Evv2i81ZEw33DQ8y6YowH05r+BuxfN92SX3RbVP8bNymDOGnY7 |
|---|
| 1780 | 16PfvzG+4ecrzfzkjPZya/H/ScnXyqwX/JtSrrL5pbrryu1hPKFrZzsrJD6sUuyPwDGdKerJyxmq |
|---|
| 1781 | dvmdHNCrrzU/+2W0pQ6gSvPl/Mertmi+7hBlDhB80kRUqcNeJCGapHNCz1cvCFwsf0A/Ne++jGMf |
|---|
| 1782 | TuOJcm6+ZnP9TRR7tWjHreOhZ6huiKnPAP2zfmqpIqHHLG/emnNhyHxSs+JJYfIwj6t2AlLdVneO |
|---|
| 1783 | 3Is9u0R33ef+Wv2pVizPfbUW0rGhps1FRRfnZ/2xsnr3oT2Slh2tvngsLXu6M0OgIen7ufrjprrD |
|---|
| 1784 | vzXQAgNE22ualqzbyAb97uvl6qF/2a5hcU+eBzVWzOdmVjA0PXQMQoAhsulmBv39oU13134SjSlb |
|---|
| 1785 | dX85nKW3umfYbtu8713Sylhb2i3v2qaoc8C7S2P3pME8uIGedi1IxXbL+adi+P2fT8Xy/m+/PrxZ |
|---|
| 1786 | /TrXDcpqOMjotwdo9AJmg8r1N7BySygc+Gp+XaYdJhpV8f/7Oy3Y1s330l09YBDTjnyjn5qHGF7x |
|---|
| 1787 | 6O7hZfMXz21OyLZB6lUfOGAGMzo/bjaL7VaV7Ha76D/1yJVEqKmr+L2nCbH7+959wDtv38JZplQG |
|---|
| 1788 | BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7 |
|---|
| 1789 | """) |
|---|
| 1790 | |
|---|
| 1791 | ##file distribute_setup.py |
|---|
| 1792 | DISTRIBUTE_SETUP_PY = convert(""" |
|---|
| 1793 | eJztG2tz27jxu34FKo+HVELRdu768lQ3k0ucq+fSJBM7dx8SDw2RkMQzX8eHZd2v7+4CIEESkp1e |
|---|
| 1794 | 25nOVO05ErFYLPa9C/DoD8Wu3uTZZDqdfp/ndVWXvGBRDP/Gy6YWLM6qmicJr2MAmlyu2C5v2JZn |
|---|
| 1795 | Natz1lSCVaJuijrPkwpgcbRkBQ/v+Fo4lRz0i53HfmmqGgDCpIkEqzdxNVnFCaKHH4CEpwJWLUVY |
|---|
| 1796 | 5+WObeN6w+LaYzyLGI8imoALImydFyxfyZU0/vPzyYTBZ1XmqUF9QOMsTou8rJHaoKOW4PuP3Nlo |
|---|
| 1797 | h6X4tQGyGGdVIcJ4FYfsXpQVMANp6KZ6+B2gonybJTmPJmlclnnpsbwkLvGM8aQWZcaBpxqo27FH |
|---|
| 1798 | i4YAFeWsytlyx6qmKJJdnK0nuGleFGVelDFOzwsUBvHj9na4g9tbfzK5RnYRf0NaGDEKVjbwvcKt |
|---|
| 1799 | hGVc0PaUdInKYl3yyJSnj0oxUczLK/2t2rVf6zgV+vsqS3kdbtohkRZIQfubl/SzlVBTx6gycjTJ |
|---|
| 1800 | 15NJXe7OOylWMWqfHP50dfExuLq8vpiIh1AA6Zf0/AJZLKe0EGzB3uWZMLBpspslsDAUVSVVJRIr |
|---|
| 1801 | FkjlD8I0cp/xcl3N5BT84E9A5sJ2ffEgwqbmy0R4M/achlq4EvhVZgZ6PwSOuoSNLRbsdLKX6CNQ |
|---|
| 1802 | dGA+iAakGLEVSEESxF743/xbiTxivzZ5DcqEj5tUZDWwfgXLZ6CLHRg8QkwFmDsQkyL5DsB888Lp |
|---|
| 1803 | ltRkIUKB25z1xxQeB/4Hxg3j42GDbc70uJo67BgBR3AKZjikNv25o4BYB1/UitXNUDp55VcFB6tz |
|---|
| 1804 | 4duH4OeXl9ceGzCNPTNl9vrizctPb6+Dny4+Xl2+fwfrTU/9P/lnf522Q58+vsXHm7ouzk9Oil0R |
|---|
| 1805 | +1JUfl6uT5QTrE4qcFShOIlOOr90Mp1cXVx/+nD9/v3bq+DNyx8vXg8WCs/OphMT6MOPPwSX7968 |
|---|
| 1806 | x/Hp9MvkH6LmEa/5/Cfpjs7ZmX86eQd+9Nww4Uk7elxNrpo05WAV7AE+k7/nqZgXQCH9nrxsgPLS |
|---|
| 1807 | /D4XKY8T+eRtHIqsUqCvhXQghBcfAEEgwX07mkwmpMbK17jgCZbw70zbgHiAmBOScpJ7l8M0WKcF |
|---|
| 1808 | uEjYsvYmfnoX4Xfw1DgObsPf8jJznYsOCejAceV4arIEzJMo2EaACMS/FnW4jRSG1ksQFNjuBua4 |
|---|
| 1809 | 5lSC4kSEdGF+Xois3UULE6h9qC32JvthklcCw0tnkOtcEYubbgNBCwD+RG4diCp4vfF/AXhFmIcP |
|---|
| 1810 | E9Amg9bPpzez8UYklm6gY9i7fMu2eXlnckxDG1QqoWEYGuO4bAfZ61a3nZnpTrK87jkwR0dsWM5R |
|---|
| 1811 | yJ2BB+kWuAIdhdAP+Lfgsti2zOFr1JRaV8zkxDcWHmARgqAFel6WgosGrWd8md8LPWkVZ4DHpgpS |
|---|
| 1812 | c2ZaiZdNDA/Eeu3Cf55WVviSB8i6/+v0/4BOkwwpFmYMpGhB9H0LYSg2wnaCkPLuOLVPx+e/4t8l |
|---|
| 1813 | +n5UG3o0x1/wpzQQPVEN5Q5kVNPaVYqqSeq+8sBSEljZoOa4eIClKxruVil5DCnq5XtKTVznVd4k |
|---|
| 1814 | Ec0iTknbWa/RVpQVREC0ymFdlQ57bVYbLHkl9MaMx5FI+E6tiqwcqoGCd7owOT+u5sXuOPLh/8g7 |
|---|
| 1815 | ayIBn2PWUYFBXf2AiLPKQYcsD89uZk9njzILILjdi5Fx79n/PloHnz1c6vTqEYdDgJSzIfngD0VZ |
|---|
| 1816 | u6ce6+Svst9+3WMk+Utd9ekAHVD6vSDTkPIe1Bhqx4tBijTgwMJIk6zckDtYoIo3pYUJi7M/eiCc |
|---|
| 1817 | YMXvxOK6bETrXVNOJl41UJhtKXkmHeXLKk/QUJEXk24JQ9MABP91Te5teRVILgn0pk5xtw7ApChr |
|---|
| 1818 | qyiJRf6medQkosJK6Uu7G6fjyhBw7Il7PwzR9NbrA0jl3PCK13Xp9gDBUILICLrWJBxnKw7as3Aa |
|---|
| 1819 | 6lfAQxDlHLrapYXYV9a0M2Xu/Xu8xX7m9ZjhqzLdnXYs+W4xfa5Wm1nIGu6ij0+lza/ybJXEYd1f |
|---|
| 1820 | WoCWyNohJG/izsCfDAVnatWY9zgdQh1kJP62hELXHUFMr8mz07Yis+dg9Gbc7xbHULBArY+C5veQ |
|---|
| 1821 | rlMl8yWbjvFhKyXkmVNjvalMHTBvN9gmoP6KagvAt7LJMLr47EMiQDxWfLp1wFmal0hqiCmaJnQV |
|---|
| 1822 | l1XtgWkCGut0BxDvtMth80/GvhzfAv8l+5K5r5qyhFWSnUTMjssZIO/5f+FjFYeZw1iVpdDi2n3R |
|---|
| 1823 | HxNJZbEP0EA2MDnDvj8P/MQNTsHITI2d/G5fMfs11vCkGLLPYqx63WYzsOq7vH6TN1n0u432UTJt |
|---|
| 1824 | JI5SnUPuKghLwWsx9FYBbo4ssM2iMFwdiNK/N2bRxxK4VLxSXhjq4dddi681V4qrbSMRbC/JQypd |
|---|
| 1825 | qM2pGB/XsnOXQSUvk8JbRfstqzaUmS2xHXnPk7iHXVte1qRLUYJFczLl1isQLmz/UdJLHZO2Dwla |
|---|
| 1826 | QFMEu+3x45Zhj8MFHxFu9Ooii2TYxB4tZ86JM/PZreTJLa7Yy/3Bv4hS6BSy7XfpVUTkyz0SB9vp |
|---|
| 1827 | ag/UYQ3zLKJeZ8Ex0C/FCt0NtjXDuuFJ13Gl/dVYSdW+FsN/JGHoxSISalNCFbykKCSwza36zWWC |
|---|
| 1828 | ZdXEsEZrrDRQvLDNrde/BagO2PrpJcc+lmHr39ABKunLpnbZy1VRkOx5i0Xmf/xeAEv3pOAaVGWX |
|---|
| 1829 | ZYjoYF+qtWpY6yBvlmhn58jzl/d5jFpdoOVGLTldhjMK6W3x0loP+fhq6uGW+i5bEqW45I6Gj9hH |
|---|
| 1830 | waMTiq0MAwwkZ0A6W4LJ3XnYYd+iEmI0lK4FNDnMyxLcBVnfABnslrRa20uMZx21IHitwvqDTTlM |
|---|
| 1831 | EMoQ9IFHg4xKspGIlszy2HS7nI6AVFqAyLqxkc9UkoC1LCkGEKBL9AE84LeEO1jUhO86pyRh2EtC |
|---|
| 1832 | lqBkrCpBcNcVeK9l/uCumixEb6acIA2b49Re9dizZ3fb2YGsWDb/u/pETdeG8Vp7liv5/FDCPITF |
|---|
| 1833 | nBkKaVuyjNTex7lsJY3a7Oan4FU1Ghiu5OM6IOjx83aRJ+BoYQHT/nkFHrtQ6YJF0hMSm27CGw4A |
|---|
| 1834 | T87nh/P2y1DpjtaInugf1Wa1zJjuwwyyisCa1NkhTaU39VYpOlEVoG9w0Qw8cBfgAbK6C/k/U2zj |
|---|
| 1835 | 4V1TkLdYycRaZHJHENl1QCJvCb4tUDi0R0DEM9NrADfGsAu9dMehI/BxOG2nmWfpab3sQ5jtUrXr |
|---|
| 1836 | Thu6WR8QGksBX0+AbBJjQ0DOgCiW+Zy5CTC0rWMLlsqtad7ZM8GVzQ+Rbk8MMcB6pncxRrRvwkNl |
|---|
| 1837 | zTar0LSLG/Le4LFCNdqzRJCJrY7M+BSirOO/f/vaP67wSAtPR338M+rsfkR0MrhhIMllT1GSqHGq |
|---|
| 1838 | Ji/WtvjTtY2qDeiHLbFpfg/JMphGYHbI3SLhodiAsgvdqR6E8bjCXuMYrE/9p+wOAmGv+Q6Jl9qD |
|---|
| 1839 | MXe/fq2w7uj5H0xH9YUAoxFsJwWoVqfNvvrXxbme2Y95hh3DORYHQ3evFx95yyVI/85ky6pfHnUc |
|---|
| 1840 | 6DqklMKbh+bmugMGTEZaAHJCLRCJkEeyeVNj0oveY8t3nc3pOmeYsBns8ZhUfUX+QKJqvsGJzpkr |
|---|
| 1841 | ywGygx6sdFW9CDKaJP2hmuExy3ml6mwrjo58e8cNMAU+dFEe61NjVaYjwLxliaidiqHit853yM9W |
|---|
| 1842 | 0RS/Uddcs4XnDZp/qoWPNxHwq8E9jeGQPBRM7zhs2GdWIINq1/Q2IyzjmG7TS3CqsnEPbNXEKk7s |
|---|
| 1843 | aaM7V91FnshoEziDnfT98T5fM/TO++C0r+YrSKfbI2JcXzHFCGAI0t5YadvWrY10vMdyBTDgqRj4 |
|---|
| 1844 | /zQFIoJ8+YvbHTj6utddQEkIdZeMbI91GXrOTdL9NVN6LtckF1TSUkw95oYtwtbM0Y2FsQsiTu3u |
|---|
| 1845 | iUdgcipSuU8+NZEVYbdRFYkNK1KHNlXnB2GBLz2dc/ddFfAkbV/h9AakjPyf5uXYAVo9jwQ/4HeG |
|---|
| 1846 | PvwVyl9G8tGsLiVqHeThtMjqPglgf4okWVW3OdF+Vhky8mGCM0xKBlupNwZHu62ox49tpUeG0Skb |
|---|
| 1847 | yuvx/T1mYkNP8wj4rJfPt0Gvy+mOVCiBCBTeoSrF+MuWX+9VUJkBX/zwwxxFiCEExCm/f4WCxqMU |
|---|
| 1848 | 9mCc3RcTnhpXDd/exdY9yT4Qn961fOs/OsiK2SOm/Sjn/is2ZbCiV3YobbFXHmpQ65fsU7YRbRTN |
|---|
| 1849 | vpd9zL3hzHIypzBTszYoSrGKH1zt6bvg0gY5Cg3qUBLq73vjvN/YG/5WF+o04Gf9BaJkJB6MsPn8 |
|---|
| 1850 | 7PymzaJo0NPX7kTWpKLk8kKe2TtBUHljVeZb83kJe5X3IOQmhgk6bAJw+LBmWVfYZkYlXmAYkXgs |
|---|
| 1851 | jZk6L5RkaGaRxLXr4DoLZ/Z5PjidM1ig2WcupnANj4gkVVgaSiqsB64JaKa8Rfid5I+9h9Qjt/pM |
|---|
| 1852 | kM8tVH4tpR2NwNymEqVDRwvd5Vh1VIhtXGvHxrZKO9tiGFIjR6o6VParkNOBonHuqK9H2mx378H4 |
|---|
| 1853 | oQ7VEdsKBywqBBIsQd7IbkEhjVs9US4kUyohUjxnMI9Hx10S+rlFc+mXCureEbJhvCEjDmFiCpO3 |
|---|
| 1854 | lY9ZW/9M3/8oz3sx2QavWIIz6pUn9sR9oC0U8xHDgty48riKc9e7Qoz4hq1K4yDp5YfLfzPhs64I |
|---|
| 1855 | HCIEhewro3mby3y3wCxJZGFuF80Ri0Qt1K05DN54Et9GQNTUaJjDtsdwiyF5vh4a6rP5zoNR9Mil |
|---|
| 1856 | Qbt1O8SyiuIFHSpIX4gKSb4wfiBiizK/jyMRydcf4pWCN1+0qIzmQ6Qu3KVed6ihO45mxdEPHDbK |
|---|
| 1857 | 7FJQ2ICh3pBgQCTPQmz3QMfaKm+EAy0bqD/21yi9NAysUsqxMq/rqS1ZNuGLLFJBg+6M7dlUNpe3 |
|---|
| 1858 | +Trh9ehA+97fR7NKVU9WpAEOm4e1NFWMC5/7SdqXMVlIOZxAKRLdffkn6ly/G/EVOejeJPRA83nA |
|---|
| 1859 | m/68cfvZ1I326A7Nms6Xpfujs17D32diKNp+9v975Tmgl047M2E0zBPeZOGmS+G6J8NI+VGN9PaM |
|---|
| 1860 | oY1tOLa28I0kCUEFv36jRUIVccFSXt7hWX7OOB3A8m7CsmmNp031zr+5wXThszMPzRvZlJ3hFZtE |
|---|
| 1861 | zFULYC4e6P0lyJnnKc8gdkfOjRHiNMbTm7YfgE0zM8H83H/j4oY9b6dNNA66n2N9mablnnEpuRLJ |
|---|
| 1862 | SjbOF1N/6rFU4MWBaoExpTuZURep6SBYQchjRroEUAK3JWvxZyivGOl7xHp/3YUG9Mn4rle+zbCq |
|---|
| 1863 | TvMI3wqT/h+b/QRQiDKNq4pe0+qO7DSSGJSQGl4g86jy2S1uwGkvhuArWoB0JYiQ0TVqIFRxAL7C |
|---|
| 1864 | ZLUjBz2xTE15QkSk+ModXRYBfhLJ1ADUeLDHrrQYNHa5Y2tRK1zurH+DQiVkYV7szN9QiEHGr24E |
|---|
| 1865 | SobK6+QaQDG+uzZocgD04abNC7RYRvmAHsDYnKwmbfUBK5E/hIiiQHqVsxpW/e+BXzrShPXoURda |
|---|
| 1866 | Kr4SKFUxONbvIH1eQAUauWqNvivTdC2IWz7+OQiI98mwb/Ptt3+h3CWMUxAfFU1A3+mfT0+NZCxZ |
|---|
| 1867 | +Ur0GqdU/jan+CjQWgWrkPsmyabhmz099jfmvvDYtwaH0MZwvihdwHDmIZ4XM2u5EKYFwfjYJJCA |
|---|
| 1868 | fnc6NWQbInUlZjtAKal3bUcPI0R3YrfQCujjcT+oL9LsIAHOzGMKm7w6rBkEmRtd9ABcrQW3Vouq |
|---|
| 1869 | S+LAVG7IvIHSGeM9Iukc0NrW0ALvM2h0dk5SDjdAXCdjhXc2BmzofPEJgOEGdnYAUBUIpsX+C7de |
|---|
| 1870 | pYri5AS4n0AVfDaugOlG8aC6tt1TIGRBtFy7oIRT5VrwTTa88CR0OEh5TDX3vcf2XPLrAsHloddd |
|---|
| 1871 | SQUueLVTUNr5Hb7+r2L88OU2IC6m+y+YPAVUkQcBkhoE6l1KoruNmmfnN7PJPwERhOVk |
|---|
| 1872 | """) |
|---|
| 1873 | |
|---|
| 1874 | ##file activate.sh |
|---|
| 1875 | ACTIVATE_SH = convert(""" |
|---|
| 1876 | eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9 |
|---|
| 1877 | H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq |
|---|
| 1878 | DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs |
|---|
| 1879 | cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY |
|---|
| 1880 | G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T |
|---|
| 1881 | EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs |
|---|
| 1882 | wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG |
|---|
| 1883 | 5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/ |
|---|
| 1884 | JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR |
|---|
| 1885 | huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx |
|---|
| 1886 | Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L |
|---|
| 1887 | Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw |
|---|
| 1888 | WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX |
|---|
| 1889 | LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2 |
|---|
| 1890 | """) |
|---|
| 1891 | |
|---|
| 1892 | ##file activate.fish |
|---|
| 1893 | ACTIVATE_FISH = convert(""" |
|---|
| 1894 | eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A |
|---|
| 1895 | Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7 |
|---|
| 1896 | pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ |
|---|
| 1897 | lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v |
|---|
| 1898 | g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u |
|---|
| 1899 | grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS |
|---|
| 1900 | xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV |
|---|
| 1901 | MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu |
|---|
| 1902 | H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM |
|---|
| 1903 | L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz |
|---|
| 1904 | fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV |
|---|
| 1905 | pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh |
|---|
| 1906 | MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT |
|---|
| 1907 | O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz |
|---|
| 1908 | 7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi |
|---|
| 1909 | m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq |
|---|
| 1910 | djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5 |
|---|
| 1911 | mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN |
|---|
| 1912 | jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk= |
|---|
| 1913 | """) |
|---|
| 1914 | |
|---|
| 1915 | ##file activate.csh |
|---|
| 1916 | ACTIVATE_CSH = convert(""" |
|---|
| 1917 | eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49 |
|---|
| 1918 | XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp |
|---|
| 1919 | kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u |
|---|
| 1920 | pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx |
|---|
| 1921 | sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM |
|---|
| 1922 | yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu |
|---|
| 1923 | E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF |
|---|
| 1924 | lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7 |
|---|
| 1925 | r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo= |
|---|
| 1926 | """) |
|---|
| 1927 | |
|---|
| 1928 | ##file activate.bat |
|---|
| 1929 | ACTIVATE_BAT = convert(""" |
|---|
| 1930 | eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8 |
|---|
| 1931 | qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug |
|---|
| 1932 | sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU |
|---|
| 1933 | ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu |
|---|
| 1934 | """) |
|---|
| 1935 | |
|---|
| 1936 | ##file deactivate.bat |
|---|
| 1937 | DEACTIVATE_BAT = convert(""" |
|---|
| 1938 | eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q |
|---|
| 1939 | FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL |
|---|
| 1940 | i2dASrm4rFz9XLgAwJNbyQ== |
|---|
| 1941 | """) |
|---|
| 1942 | |
|---|
| 1943 | ##file distutils-init.py |
|---|
| 1944 | DISTUTILS_INIT = convert(""" |
|---|
| 1945 | eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB |
|---|
| 1946 | luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c |
|---|
| 1947 | KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5 |
|---|
| 1948 | ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9 |
|---|
| 1949 | QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7 |
|---|
| 1950 | yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw |
|---|
| 1951 | bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv |
|---|
| 1952 | bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc |
|---|
| 1953 | yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr |
|---|
| 1954 | Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi |
|---|
| 1955 | Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp |
|---|
| 1956 | /n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+ |
|---|
| 1957 | FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ |
|---|
| 1958 | AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8 |
|---|
| 1959 | hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC |
|---|
| 1960 | UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y |
|---|
| 1961 | 8h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf |
|---|
| 1962 | XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO |
|---|
| 1963 | azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb |
|---|
| 1964 | 8dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw |
|---|
| 1965 | gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT |
|---|
| 1966 | 5C4rFgwLGfMvJuAMew== |
|---|
| 1967 | """) |
|---|
| 1968 | |
|---|
| 1969 | ##file distutils.cfg |
|---|
| 1970 | DISTUTILS_CFG = convert(""" |
|---|
| 1971 | eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH |
|---|
| 1972 | xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg |
|---|
| 1973 | 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q= |
|---|
| 1974 | """) |
|---|
| 1975 | |
|---|
| 1976 | ##file activate_this.py |
|---|
| 1977 | ACTIVATE_THIS = convert(""" |
|---|
| 1978 | eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ |
|---|
| 1979 | VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a |
|---|
| 1980 | Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE |
|---|
| 1981 | qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX |
|---|
| 1982 | 4lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7 |
|---|
| 1983 | HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n |
|---|
| 1984 | xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96 |
|---|
| 1985 | 1Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI |
|---|
| 1986 | 3vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU= |
|---|
| 1987 | """) |
|---|
| 1988 | |
|---|
| 1989 | if __name__ == '__main__': |
|---|
| 1990 | main() |
|---|
| 1991 | |
|---|
| 1992 | ## TODO: |
|---|
| 1993 | ## Copy python.exe.manifest |
|---|
| 1994 | ## Monkeypatch distutils.sysconfig |
|---|