virtualenv/sync/virtualenv.py
changeset 829 0dccd715b007
parent 659 cbf9bba86065
equal deleted inserted replaced
787:16e420b75336 829:0dccd715b007
     2 """Create a "virtual" Python installation
     2 """Create a "virtual" Python installation
     3 """
     3 """
     4 
     4 
     5 # If you change the version here, change it in setup.py
     5 # If you change the version here, change it in setup.py
     6 # and docs/conf.py as well.
     6 # and docs/conf.py as well.
     7 virtualenv_version = "1.7.1.2"
     7 __version__ = "1.8.2"  # following best practices
       
     8 virtualenv_version = __version__  # legacy, again
     8 
     9 
     9 import base64
    10 import base64
    10 import sys
    11 import sys
    11 import os
    12 import os
       
    13 import codecs
    12 import optparse
    14 import optparse
    13 import re
    15 import re
    14 import shutil
    16 import shutil
    15 import logging
    17 import logging
    16 import tempfile
    18 import tempfile
    17 import zlib
    19 import zlib
    18 import errno
    20 import errno
       
    21 import glob
    19 import distutils.sysconfig
    22 import distutils.sysconfig
    20 from distutils.util import strtobool
    23 from distutils.util import strtobool
    21 
    24 import struct
    22 try:
    25 import subprocess
    23     import subprocess
    26 
    24 except ImportError:
    27 if sys.version_info < (2, 5):
    25     if sys.version_info <= (2, 3):
    28     print('ERROR: %s' % sys.exc_info()[1])
    26         print('ERROR: %s' % sys.exc_info()[1])
    29     print('ERROR: this script requires Python 2.5 or greater.')
    27         print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
    30     sys.exit(101)
    28         print('If you copy subprocess.py from a newer version of Python this script will probably work')
    31 
    29         sys.exit(101)
       
    30     else:
       
    31         raise
       
    32 try:
    32 try:
    33     set
    33     set
    34 except NameError:
    34 except NameError:
    35     from sets import Set as set
    35     from sets import Set as set
    36 try:
    36 try:
    46 join = os.path.join
    46 join = os.path.join
    47 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
    47 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
    48 
    48 
    49 is_jython = sys.platform.startswith('java')
    49 is_jython = sys.platform.startswith('java')
    50 is_pypy = hasattr(sys, 'pypy_version_info')
    50 is_pypy = hasattr(sys, 'pypy_version_info')
    51 is_win  = (sys.platform == 'win32')
    51 is_win = (sys.platform == 'win32')
       
    52 is_cygwin = (sys.platform == 'cygwin')
       
    53 is_darwin = (sys.platform == 'darwin')
    52 abiflags = getattr(sys, 'abiflags', '')
    54 abiflags = getattr(sys, 'abiflags', '')
    53 
    55 
    54 user_dir = os.path.expanduser('~')
    56 user_dir = os.path.expanduser('~')
    55 if sys.platform == 'win32':
    57 if is_win:
    56     user_dir = os.environ.get('APPDATA', user_dir)  # Use %APPDATA% for roaming
       
    57     default_storage_dir = os.path.join(user_dir, 'virtualenv')
    58     default_storage_dir = os.path.join(user_dir, 'virtualenv')
    58 else:
    59 else:
    59     default_storage_dir = os.path.join(user_dir, '.virtualenv')
    60     default_storage_dir = os.path.join(user_dir, '.virtualenv')
    60 default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
    61 default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
    61 
    62 
    87     # Some extra modules are needed for Python 3, but different ones
    88     # Some extra modules are needed for Python 3, but different ones
    88     # for different versions.
    89     # for different versions.
    89     REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
    90     REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
    90                              '_weakrefset', 'copyreg', 'tempfile', 'random',
    91                              '_weakrefset', 'copyreg', 'tempfile', 'random',
    91                              '__future__', 'collections', 'keyword', 'tarfile',
    92                              '__future__', 'collections', 'keyword', 'tarfile',
    92                              'shutil', 'struct', 'copy'])
    93                              'shutil', 'struct', 'copy', 'tokenize', 'token',
       
    94                              'functools', 'heapq', 'bisect', 'weakref',
       
    95                              'reprlib'])
    93     if minver >= 2:
    96     if minver >= 2:
    94         REQUIRED_FILES[-1] = 'config-%s' % majver
    97         REQUIRED_FILES[-1] = 'config-%s' % majver
    95     if minver == 3:
    98     if minver == 3:
    96         # The whole list of 3.3 modules is reproduced below - the current
    99         # The whole list of 3.3 modules is reproduced below - the current
    97         # uncommented ones are required for 3.3 as of now, but more may be
   100         # uncommented ones are required for 3.3 as of now, but more may be
   104             #"asynchat",
   107             #"asynchat",
   105             #"asyncore",
   108             #"asyncore",
   106             "base64",
   109             "base64",
   107             #"bdb",
   110             #"bdb",
   108             #"binhex",
   111             #"binhex",
   109             "bisect",
   112             #"bisect",
   110             #"calendar",
   113             #"calendar",
   111             #"cgi",
   114             #"cgi",
   112             #"cgitb",
   115             #"cgitb",
   113             #"chunk",
   116             #"chunk",
   114             #"cmd",
   117             #"cmd",
   144             #"getpass",
   147             #"getpass",
   145             #"gettext",
   148             #"gettext",
   146             #"glob",
   149             #"glob",
   147             #"gzip",
   150             #"gzip",
   148             "hashlib",
   151             "hashlib",
   149             "heapq",
   152             #"heapq",
   150             "hmac",
   153             "hmac",
   151             #"html",
   154             #"html",
   152             #"http",
   155             #"http",
   153             #"idlelib",
   156             #"idlelib",
   154             #"imaplib",
   157             #"imaplib",
   191             #"pydoc_data",
   194             #"pydoc_data",
   192             #"pydoc",
   195             #"pydoc",
   193             #"_pyio",
   196             #"_pyio",
   194             #"queue",
   197             #"queue",
   195             #"quopri",
   198             #"quopri",
   196             "reprlib",
   199             #"reprlib",
   197             "rlcompleter",
   200             "rlcompleter",
   198             #"runpy",
   201             #"runpy",
   199             #"sched",
   202             #"sched",
   200             #"shelve",
   203             #"shelve",
   201             #"shlex",
   204             #"shlex",
   233             #"unittest",
   236             #"unittest",
   234             #"urllib",
   237             #"urllib",
   235             #"uuid",
   238             #"uuid",
   236             #"uu",
   239             #"uu",
   237             #"wave",
   240             #"wave",
   238             "weakref",
   241             #"weakref",
   239             #"webbrowser",
   242             #"webbrowser",
   240             #"wsgiref",
   243             #"wsgiref",
   241             #"xdrlib",
   244             #"xdrlib",
   242             #"xml",
   245             #"xml",
   243             #"xmlrpc",
   246             #"xmlrpc",
   278     def notify(self, msg, *args, **kw):
   281     def notify(self, msg, *args, **kw):
   279         self.log(self.NOTIFY, msg, *args, **kw)
   282         self.log(self.NOTIFY, msg, *args, **kw)
   280     def warn(self, msg, *args, **kw):
   283     def warn(self, msg, *args, **kw):
   281         self.log(self.WARN, msg, *args, **kw)
   284         self.log(self.WARN, msg, *args, **kw)
   282     def error(self, msg, *args, **kw):
   285     def error(self, msg, *args, **kw):
   283         self.log(self.WARN, msg, *args, **kw)
   286         self.log(self.ERROR, msg, *args, **kw)
   284     def fatal(self, msg, *args, **kw):
   287     def fatal(self, msg, *args, **kw):
   285         self.log(self.FATAL, msg, *args, **kw)
   288         self.log(self.FATAL, msg, *args, **kw)
   286     def log(self, level, msg, *args, **kw):
   289     def log(self, level, msg, *args, **kw):
   287         if args:
   290         if args:
   288             if kw:
   291             if kw:
   441         return
   444         return
   442     else:
   445     else:
   443         f = open(dest, 'rb')
   446         f = open(dest, 'rb')
   444         c = f.read()
   447         c = f.read()
   445         f.close()
   448         f.close()
   446         if c != content:
   449         if c != content.encode("utf-8"):
   447             if not overwrite:
   450             if not overwrite:
   448                 logger.notify('File %s exists with different content; not overwriting', dest)
   451                 logger.notify('File %s exists with different content; not overwriting', dest)
   449                 return
   452                 return
   450             logger.notify('Overwriting %s with new content', dest)
   453             logger.notify('Overwriting %s with new content', dest)
   451             f = open(dest, 'wb')
   454             f = open(dest, 'wb')
   468         os.chmod(fn, newmode)
   471         os.chmod(fn, newmode)
   469         logger.info('Changed mode of %s to %s', fn, oct(newmode))
   472         logger.info('Changed mode of %s to %s', fn, oct(newmode))
   470 
   473 
   471 def _find_file(filename, dirs):
   474 def _find_file(filename, dirs):
   472     for dir in reversed(dirs):
   475     for dir in reversed(dirs):
   473         if os.path.exists(join(dir, filename)):
   476         files = glob.glob(os.path.join(dir, filename))
   474             return join(dir, filename)
   477         if files and os.path.exists(files[0]):
       
   478             return files[0]
   475     return filename
   479     return filename
   476 
   480 
   477 def _install_req(py_executable, unzip=False, distribute=False,
   481 def _install_req(py_executable, unzip=False, distribute=False,
   478                  search_dirs=None, never_download=False):
   482                  search_dirs=None, never_download=False):
   479 
   483 
   480     if search_dirs is None:
   484     if search_dirs is None:
   481         search_dirs = file_search_dirs()
   485         search_dirs = file_search_dirs()
   482 
   486 
   483     if not distribute:
   487     if not distribute:
   484         setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
   488         setup_fn = 'setuptools-*-py%s.egg' % sys.version[:3]
   485         project_name = 'setuptools'
   489         project_name = 'setuptools'
   486         bootstrap_script = EZ_SETUP_PY
   490         bootstrap_script = EZ_SETUP_PY
   487         source = None
   491         source = None
   488     else:
   492     else:
   489         setup_fn = None
   493         setup_fn = None
   490         source = 'distribute-0.6.24.tar.gz'
   494         source = 'distribute-*.tar.gz'
   491         project_name = 'distribute'
   495         project_name = 'distribute'
   492         bootstrap_script = DISTRIBUTE_SETUP_PY
   496         bootstrap_script = DISTRIBUTE_SETUP_PY
   493 
   497 
   494     if setup_fn is not None:
   498     if setup_fn is not None:
   495         setup_fn = _find_file(setup_fn, search_dirs)
   499         setup_fn = _find_file(setup_fn, search_dirs)
   507     else:
   511     else:
   508         cmd = [py_executable, '-c', bootstrap_script]
   512         cmd = [py_executable, '-c', bootstrap_script]
   509     if unzip:
   513     if unzip:
   510         cmd.append('--always-unzip')
   514         cmd.append('--always-unzip')
   511     env = {}
   515     env = {}
   512     remove_from_env = []
   516     remove_from_env = ['__PYVENV_LAUNCHER__']
   513     if logger.stdout_level_matches(logger.DEBUG):
   517     if logger.stdout_level_matches(logger.DEBUG):
   514         cmd.append('-v')
   518         cmd.append('-v')
   515 
   519 
   516     old_chdir = os.getcwd()
   520     old_chdir = os.getcwd()
   517     if setup_fn is not None and os.path.exists(setup_fn):
   521     if setup_fn is not None and os.path.exists(setup_fn):
   566                         remove_from_env=remove_from_env,
   570                         remove_from_env=remove_from_env,
   567                         cwd=cwd)
   571                         cwd=cwd)
   568     finally:
   572     finally:
   569         logger.indent -= 2
   573         logger.indent -= 2
   570         logger.end_progress()
   574         logger.end_progress()
       
   575         if cwd is not None:
       
   576             shutil.rmtree(cwd)
   571         if os.getcwd() != old_chdir:
   577         if os.getcwd() != old_chdir:
   572             os.chdir(old_chdir)
   578             os.chdir(old_chdir)
   573         if is_jython and os._name == 'nt':
   579         if is_jython and os._name == 'nt':
   574             os.remove(ez_setup)
   580             os.remove(ez_setup)
   575 
   581 
   612     if not filenames:
   618     if not filenames:
   613         filename = 'pip'
   619         filename = 'pip'
   614     else:
   620     else:
   615         filename = filenames[-1]
   621         filename = filenames[-1]
   616     easy_install_script = 'easy_install'
   622     easy_install_script = 'easy_install'
   617     if sys.platform == 'win32':
   623     if is_win:
   618         easy_install_script = 'easy_install-script.py'
   624         easy_install_script = 'easy_install-script.py'
   619     cmd = [join(os.path.dirname(py_executable), easy_install_script), filename]
   625     # There's two subtle issues here when invoking easy_install.
   620     if sys.platform == 'win32':
   626     # 1. On unix-like systems the easy_install script can *only* be executed
   621         cmd.insert(0, py_executable)
   627     #    directly if its full filesystem path is no longer than 78 characters.
       
   628     # 2. A work around to [1] is to use the `python path/to/easy_install foo`
       
   629     #    pattern, but that breaks if the path contains non-ASCII characters, as
       
   630     #    you can't put the file encoding declaration before the shebang line.
       
   631     # The solution is to use Python's -x flag to skip the first line of the
       
   632     # script (and any ASCII decoding errors that may have occurred in that line)
       
   633     cmd = [py_executable, '-x', join(os.path.dirname(py_executable), easy_install_script), filename]
       
   634     # jython and pypy don't yet support -x
       
   635     if is_jython or is_pypy:
       
   636         cmd.remove('-x')
   622     if filename == 'pip':
   637     if filename == 'pip':
   623         if never_download:
   638         if never_download:
   624             logger.fatal("Can't find any local distributions of pip to install "
   639             logger.fatal("Can't find any local distributions of pip to install "
   625                          "and --never-download is set.  Either re-run virtualenv "
   640                          "and --never-download is set.  Either re-run virtualenv "
   626                          "without the --never-download option, or place a pip "
   641                          "without the --never-download option, or place a pip "
   716                 # handle multiline configs
   731                 # handle multiline configs
   717                 if option.action == 'append':
   732                 if option.action == 'append':
   718                     val = val.split()
   733                     val = val.split()
   719                 else:
   734                 else:
   720                     option.nargs = 1
   735                     option.nargs = 1
   721                 if option.action in ('store_true', 'store_false', 'count'):
   736                 if option.action == 'store_false':
       
   737                     val = not strtobool(val)
       
   738                 elif option.action in ('store_true', 'count'):
   722                     val = strtobool(val)
   739                     val = strtobool(val)
   723                 try:
   740                 try:
   724                     val = option.convert_value(key, val)
   741                     val = option.convert_value(key, val)
   725                 except optparse.OptionValueError:
   742                 except optparse.OptionValueError:
   726                     e = sys.exc_info()[1]
   743                     e = sys.exc_info()[1]
   752         """
   769         """
   753         if not self.process_default_values:
   770         if not self.process_default_values:
   754             # Old, pre-Optik 1.5 behaviour.
   771             # Old, pre-Optik 1.5 behaviour.
   755             return optparse.Values(self.defaults)
   772             return optparse.Values(self.defaults)
   756 
   773 
   757         defaults = self.update_defaults(self.defaults.copy()) # ours
   774         defaults = self.update_defaults(self.defaults.copy())  # ours
   758         for option in self._get_all_options():
   775         for option in self._get_all_options():
   759             default = defaults.get(option.dest)
   776             default = defaults.get(option.dest)
   760             if isinstance(default, basestring):
   777             if isinstance(default, basestring):
   761                 opt_str = option.get_opt_string()
   778                 opt_str = option.get_opt_string()
   762                 defaults[option.dest] = option.check_value(opt_str, default)
   779                 defaults[option.dest] = option.check_value(opt_str, default)
   795         '--clear',
   812         '--clear',
   796         dest='clear',
   813         dest='clear',
   797         action='store_true',
   814         action='store_true',
   798         help="Clear out the non-root install and start from scratch")
   815         help="Clear out the non-root install and start from scratch")
   799 
   816 
       
   817     parser.set_defaults(system_site_packages=False)
   800     parser.add_option(
   818     parser.add_option(
   801         '--no-site-packages',
   819         '--no-site-packages',
   802         dest='no_site_packages',
   820         dest='system_site_packages',
   803         action='store_true',
   821         action='store_false',
   804         help="Don't give access to the global site-packages dir to the "
   822         help="Don't give access to the global site-packages dir to the "
   805              "virtual environment")
   823              "virtual environment (default)")
   806 
   824 
   807     parser.add_option(
   825     parser.add_option(
   808         '--system-site-packages',
   826         '--system-site-packages',
   809         dest='system_site_packages',
   827         dest='system_site_packages',
   810         action='store_true',
   828         action='store_true',
   823         action='store_true',
   841         action='store_true',
   824         help='Make an EXISTING virtualenv environment relocatable.  '
   842         help='Make an EXISTING virtualenv environment relocatable.  '
   825         'This fixes up scripts and makes all .pth files relative')
   843         'This fixes up scripts and makes all .pth files relative')
   826 
   844 
   827     parser.add_option(
   845     parser.add_option(
   828         '--distribute',
   846         '--distribute', '--use-distribute',  # the second option is for legacy reasons here. Hi Kenneth!
   829         dest='use_distribute',
   847         dest='use_distribute',
   830         action='store_true',
   848         action='store_true',
   831         help='Use Distribute instead of Setuptools. Set environ variable '
   849         help='Use Distribute instead of Setuptools. Set environ variable '
   832         'VIRTUALENV_DISTRIBUTE to make it the default ')
   850         'VIRTUALENV_DISTRIBUTE to make it the default ')
   833 
   851 
   846         action="store_true",
   864         action="store_true",
   847         help="Never download anything from the network.  Instead, virtualenv will fail "
   865         help="Never download anything from the network.  Instead, virtualenv will fail "
   848         "if local distributions of setuptools/distribute/pip are not present.")
   866         "if local distributions of setuptools/distribute/pip are not present.")
   849 
   867 
   850     parser.add_option(
   868     parser.add_option(
   851         '--prompt=',
   869         '--prompt',
   852         dest='prompt',
   870         dest='prompt',
   853         help='Provides an alternative prompt prefix for this environment')
   871         help='Provides an alternative prompt prefix for this environment')
   854 
   872 
   855     if 'extend_parser' in globals():
   873     if 'extend_parser' in globals():
   856         extend_parser(parser)
   874         extend_parser(parser)
   861 
   879 
   862     if 'adjust_options' in globals():
   880     if 'adjust_options' in globals():
   863         adjust_options(options, args)
   881         adjust_options(options, args)
   864 
   882 
   865     verbosity = options.verbose - options.quiet
   883     verbosity = options.verbose - options.quiet
   866     logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
   884     logger = Logger([(Logger.level_for_integer(2 - verbosity), sys.stdout)])
   867 
   885 
   868     if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
   886     if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
   869         env = os.environ.copy()
   887         env = os.environ.copy()
   870         interpreter = resolve_interpreter(options.python)
   888         interpreter = resolve_interpreter(options.python)
   871         if interpreter == sys.executable:
   889         if interpreter == sys.executable:
   911         del os.environ['PYTHONHOME']
   929         del os.environ['PYTHONHOME']
   912 
   930 
   913     if options.relocatable:
   931     if options.relocatable:
   914         make_environment_relocatable(home_dir)
   932         make_environment_relocatable(home_dir)
   915         return
   933         return
   916 
       
   917     if options.no_site_packages:
       
   918         logger.warn('The --no-site-packages flag is deprecated; it is now '
       
   919                     'the default behavior.')
       
   920 
   934 
   921     create_environment(home_dir,
   935     create_environment(home_dir,
   922                        site_packages=options.system_site_packages,
   936                        site_packages=options.system_site_packages,
   923                        clear=options.clear,
   937                        clear=options.clear,
   924                        unzip_setuptools=options.unzip_setuptools,
   938                        unzip_setuptools=options.unzip_setuptools,
  1028         home_dir, lib_dir, inc_dir, bin_dir,
  1042         home_dir, lib_dir, inc_dir, bin_dir,
  1029         site_packages=site_packages, clear=clear))
  1043         site_packages=site_packages, clear=clear))
  1030 
  1044 
  1031     install_distutils(home_dir)
  1045     install_distutils(home_dir)
  1032 
  1046 
  1033     # use_distribute also is True if VIRTUALENV_DISTRIBUTE env var is set
  1047     if use_distribute:
  1034     # we also check VIRTUALENV_USE_DISTRIBUTE for backwards compatibility
       
  1035     if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
       
  1036         install_distribute(py_executable, unzip=unzip_setuptools,
  1048         install_distribute(py_executable, unzip=unzip_setuptools,
  1037                            search_dirs=search_dirs, never_download=never_download)
  1049                            search_dirs=search_dirs, never_download=never_download)
  1038     else:
  1050     else:
  1039         install_setuptools(py_executable, unzip=unzip_setuptools,
  1051         install_setuptools(py_executable, unzip=unzip_setuptools,
  1040                            search_dirs=search_dirs, never_download=never_download)
  1052                            search_dirs=search_dirs, never_download=never_download)
  1041 
  1053 
  1042     install_pip(py_executable, search_dirs=search_dirs, never_download=never_download)
  1054     install_pip(py_executable, search_dirs=search_dirs, never_download=never_download)
  1043 
  1055 
  1044     install_activate(home_dir, bin_dir, prompt)
  1056     install_activate(home_dir, bin_dir, prompt)
  1045 
  1057 
       
  1058 def is_executable_file(fpath):
       
  1059     return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
       
  1060 
  1046 def path_locations(home_dir):
  1061 def path_locations(home_dir):
  1047     """Return the path locations for the environment (where libraries are,
  1062     """Return the path locations for the environment (where libraries are,
  1048     where scripts go, etc)"""
  1063     where scripts go, etc)"""
  1049     # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  1064     # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  1050     # prefix arg is broken: http://bugs.python.org/issue3386
  1065     # prefix arg is broken: http://bugs.python.org/issue3386
  1051     if sys.platform == 'win32':
  1066     if is_win:
  1052         # Windows has lots of problems with executables with spaces in
  1067         # Windows has lots of problems with executables with spaces in
  1053         # the name; this function will remove them (using the ~1
  1068         # the name; this function will remove them (using the ~1
  1054         # format):
  1069         # format):
  1055         mkdir(home_dir)
  1070         mkdir(home_dir)
  1056         if ' ' in home_dir:
  1071         if ' ' in home_dir:
  1063                 sys.exit(3)
  1078                 sys.exit(3)
  1064             home_dir = win32api.GetShortPathName(home_dir)
  1079             home_dir = win32api.GetShortPathName(home_dir)
  1065         lib_dir = join(home_dir, 'Lib')
  1080         lib_dir = join(home_dir, 'Lib')
  1066         inc_dir = join(home_dir, 'Include')
  1081         inc_dir = join(home_dir, 'Include')
  1067         bin_dir = join(home_dir, 'Scripts')
  1082         bin_dir = join(home_dir, 'Scripts')
  1068     elif is_jython:
  1083     if is_jython:
  1069         lib_dir = join(home_dir, 'Lib')
  1084         lib_dir = join(home_dir, 'Lib')
  1070         inc_dir = join(home_dir, 'Include')
  1085         inc_dir = join(home_dir, 'Include')
  1071         bin_dir = join(home_dir, 'bin')
  1086         bin_dir = join(home_dir, 'bin')
  1072     elif is_pypy:
  1087     elif is_pypy:
  1073         lib_dir = home_dir
  1088         lib_dir = home_dir
  1074         inc_dir = join(home_dir, 'include')
  1089         inc_dir = join(home_dir, 'include')
  1075         bin_dir = join(home_dir, 'bin')
  1090         bin_dir = join(home_dir, 'bin')
  1076     else:
  1091     elif not is_win:
  1077         lib_dir = join(home_dir, 'lib', py_version)
  1092         lib_dir = join(home_dir, 'lib', py_version)
  1078         inc_dir = join(home_dir, 'include', py_version + abiflags)
  1093         multiarch_exec = '/usr/bin/multiarch-platform'
       
  1094         if is_executable_file(multiarch_exec):
       
  1095             # In Mageia (2) and Mandriva distros the include dir must be like:
       
  1096             # virtualenv/include/multiarch-x86_64-linux/python2.7
       
  1097             # instead of being virtualenv/include/python2.7
       
  1098             p = subprocess.Popen(multiarch_exec, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       
  1099             stdout, stderr = p.communicate()
       
  1100             # stdout.strip is needed to remove newline character
       
  1101             inc_dir = join(home_dir, 'include', stdout.strip(), py_version + abiflags)
       
  1102         else:
       
  1103             inc_dir = join(home_dir, 'include', py_version + abiflags)
  1079         bin_dir = join(home_dir, 'bin')
  1104         bin_dir = join(home_dir, 'bin')
  1080     return home_dir, lib_dir, inc_dir, bin_dir
  1105     return home_dir, lib_dir, inc_dir, bin_dir
  1081 
  1106 
  1082 
  1107 
  1083 def change_prefix(filename, dst_prefix):
  1108 def change_prefix(filename, dst_prefix):
  1084     prefixes = [sys.prefix]
  1109     prefixes = [sys.prefix]
  1085 
  1110 
  1086     if sys.platform == "darwin":
  1111     if is_darwin:
  1087         prefixes.extend((
  1112         prefixes.extend((
  1088             os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  1113             os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  1089             os.path.join(sys.prefix, "Extras", "lib", "python"),
  1114             os.path.join(sys.prefix, "Extras", "lib", "python"),
  1090             os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
  1115             os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"),
       
  1116             # Python 2.6 no-frameworks
       
  1117             os.path.join("~", ".local", "lib","python", sys.version[:3], "site-packages"),
       
  1118             # System Python 2.7 on OSX Mountain Lion
       
  1119             os.path.join("~", "Library", "Python", sys.version[:3], "lib", "python", "site-packages")))
  1091 
  1120 
  1092     if hasattr(sys, 'real_prefix'):
  1121     if hasattr(sys, 'real_prefix'):
  1093         prefixes.append(sys.real_prefix)
  1122         prefixes.append(sys.real_prefix)
       
  1123     prefixes = list(map(os.path.expanduser, prefixes))
  1094     prefixes = list(map(os.path.abspath, prefixes))
  1124     prefixes = list(map(os.path.abspath, prefixes))
  1095     filename = os.path.abspath(filename)
  1125     filename = os.path.abspath(filename)
  1096     for src_prefix in prefixes:
  1126     for src_prefix in prefixes:
  1097         if filename.startswith(src_prefix):
  1127         if filename.startswith(src_prefix):
  1098             _, relpath = filename.split(src_prefix, 1)
  1128             _, relpath = filename.split(src_prefix, 1)
  1099             assert relpath[0] == os.sep
  1129             if src_prefix != os.sep: # sys.prefix == "/"
  1100             relpath = relpath[1:]
  1130                 assert relpath[0] == os.sep
       
  1131                 relpath = relpath[1:]
  1101             return join(dst_prefix, relpath)
  1132             return join(dst_prefix, relpath)
  1102     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1133     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1103         (filename, prefixes)
  1134         (filename, prefixes)
  1104 
  1135 
  1105 def copy_required_modules(dst_prefix):
  1136 def copy_required_modules(dst_prefix):
  1152     else:
  1183     else:
  1153         prefix = sys.prefix
  1184         prefix = sys.prefix
  1154     mkdir(lib_dir)
  1185     mkdir(lib_dir)
  1155     fix_lib64(lib_dir)
  1186     fix_lib64(lib_dir)
  1156     stdlib_dirs = [os.path.dirname(os.__file__)]
  1187     stdlib_dirs = [os.path.dirname(os.__file__)]
  1157     if sys.platform == 'win32':
  1188     if is_win:
  1158         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1189         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1159     elif sys.platform == 'darwin':
  1190     elif is_darwin:
  1160         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1191         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1161     if hasattr(os, 'symlink'):
  1192     if hasattr(os, 'symlink'):
  1162         logger.info('Symlinking Python bootstrap modules')
  1193         logger.info('Symlinking Python bootstrap modules')
  1163     else:
  1194     else:
  1164         logger.info('Copying Python bootstrap modules')
  1195         logger.info('Copying Python bootstrap modules')
  1188     writefile(site_filename_dst, SITE_PY)
  1219     writefile(site_filename_dst, SITE_PY)
  1189     writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1220     writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1190     site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1221     site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1191     if not site_packages:
  1222     if not site_packages:
  1192         writefile(site_packages_filename, '')
  1223         writefile(site_packages_filename, '')
  1193     else:
       
  1194         if os.path.exists(site_packages_filename):
       
  1195             logger.info('Deleting %s' % site_packages_filename)
       
  1196             os.unlink(site_packages_filename)
       
  1197 
  1224 
  1198     if is_pypy or is_win:
  1225     if is_pypy or is_win:
  1199         stdinc_dir = join(prefix, 'include')
  1226         stdinc_dir = join(prefix, 'include')
  1200     else:
  1227     else:
  1201         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1228         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1204     else:
  1231     else:
  1205         logger.debug('No include dir %s' % stdinc_dir)
  1232         logger.debug('No include dir %s' % stdinc_dir)
  1206 
  1233 
  1207     # pypy never uses exec_prefix, just ignore it
  1234     # pypy never uses exec_prefix, just ignore it
  1208     if sys.exec_prefix != prefix and not is_pypy:
  1235     if sys.exec_prefix != prefix and not is_pypy:
  1209         if sys.platform == 'win32':
  1236         if is_win:
  1210             exec_dir = join(sys.exec_prefix, 'lib')
  1237             exec_dir = join(sys.exec_prefix, 'lib')
  1211         elif is_jython:
  1238         elif is_jython:
  1212             exec_dir = join(sys.exec_prefix, 'Lib')
  1239             exec_dir = join(sys.exec_prefix, 'Lib')
  1213         else:
  1240         else:
  1214             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1241             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1230                  symlink=False)
  1257                  symlink=False)
  1231 
  1258 
  1232     mkdir(bin_dir)
  1259     mkdir(bin_dir)
  1233     py_executable = join(bin_dir, os.path.basename(sys.executable))
  1260     py_executable = join(bin_dir, os.path.basename(sys.executable))
  1234     if 'Python.framework' in prefix:
  1261     if 'Python.framework' in prefix:
       
  1262         # OS X framework builds cause validation to break
       
  1263         # https://github.com/pypa/virtualenv/issues/322
       
  1264         if os.environ.get('__PYVENV_LAUNCHER__'):
       
  1265           os.unsetenv('__PYVENV_LAUNCHER__')
  1235         if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1266         if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1236             # The name of the python executable is not quite what
  1267             # The name of the python executable is not quite what
  1237             # we want, rename it.
  1268             # we want, rename it.
  1238             py_executable = os.path.join(
  1269             py_executable = os.path.join(
  1239                     os.path.dirname(py_executable), 'python')
  1270                     os.path.dirname(py_executable), 'python')
  1248     else:
  1279     else:
  1249         pcbuild_dir = None
  1280         pcbuild_dir = None
  1250         if os.path.exists(pyd_pth):
  1281         if os.path.exists(pyd_pth):
  1251             logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1282             logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1252             os.unlink(pyd_pth)
  1283             os.unlink(pyd_pth)
  1253         
  1284 
  1254     if sys.executable != py_executable:
  1285     if sys.executable != py_executable:
  1255         ## FIXME: could I just hard link?
  1286         ## FIXME: could I just hard link?
  1256         executable = sys.executable
  1287         executable = sys.executable
  1257         if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
  1288         if is_cygwin and os.path.exists(executable + '.exe'):
  1258             # Cygwin misreports sys.executable sometimes
  1289             # Cygwin misreports sys.executable sometimes
  1259             executable += '.exe'
  1290             executable += '.exe'
  1260             py_executable += '.exe'
  1291             py_executable += '.exe'
  1261             logger.info('Executable actually exists in %s' % executable)
  1292             logger.info('Executable actually exists in %s' % executable)
  1262         shutil.copyfile(executable, py_executable)
  1293         shutil.copyfile(executable, py_executable)
  1263         make_exe(py_executable)
  1294         make_exe(py_executable)
  1264         if sys.platform == 'win32' or sys.platform == 'cygwin':
  1295         if is_win or is_cygwin:
  1265             pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1296             pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1266             if os.path.exists(pythonw):
  1297             if os.path.exists(pythonw):
  1267                 logger.info('Also created pythonw.exe')
  1298                 logger.info('Also created pythonw.exe')
  1268                 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  1299                 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  1269             python_d = os.path.join(os.path.dirname(sys.executable), 'python_d.exe')
  1300             python_d = os.path.join(os.path.dirname(sys.executable), 'python_d.exe')
  1293                 logger.info('Removed %s as the source does not exist' % pythondll_d_dest)
  1324                 logger.info('Removed %s as the source does not exist' % pythondll_d_dest)
  1294                 os.unlink(pythondll_d_dest)
  1325                 os.unlink(pythondll_d_dest)
  1295         if is_pypy:
  1326         if is_pypy:
  1296             # make a symlink python --> pypy-c
  1327             # make a symlink python --> pypy-c
  1297             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1328             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
       
  1329             if sys.platform in ('win32', 'cygwin'):
       
  1330                 python_executable += '.exe'
  1298             logger.info('Also created executable %s' % python_executable)
  1331             logger.info('Also created executable %s' % python_executable)
  1299             copyfile(py_executable, python_executable)
  1332             copyfile(py_executable, python_executable)
       
  1333 
       
  1334             if is_win:
       
  1335                 for name in 'libexpat.dll', 'libpypy.dll', 'libpypy-c.dll', 'libeay32.dll', 'ssleay32.dll', 'sqlite.dll':
       
  1336                     src = join(prefix, name)
       
  1337                     if os.path.exists(src):
       
  1338                         copyfile(src, join(bin_dir, name))
  1300 
  1339 
  1301     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1340     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1302         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1341         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1303                                      expected_exe)
  1342                                      expected_exe)
  1304         py_executable_ext = os.path.splitext(py_executable)[1]
  1343         py_executable_ext = os.path.splitext(py_executable)[1]
  1338             os.path.join(prefix, 'Python'),
  1377             os.path.join(prefix, 'Python'),
  1339             virtual_lib)
  1378             virtual_lib)
  1340 
  1379 
  1341         # And then change the install_name of the copied python executable
  1380         # And then change the install_name of the copied python executable
  1342         try:
  1381         try:
  1343             call_subprocess(
  1382             mach_o_change(py_executable,
  1344                 ["install_name_tool", "-change",
  1383                           os.path.join(prefix, 'Python'),
  1345                  os.path.join(prefix, 'Python'),
  1384                           '@executable_path/../.Python')
  1346                  '@executable_path/../.Python',
       
  1347                  py_executable])
       
  1348         except:
  1385         except:
  1349             logger.fatal(
  1386             e = sys.exc_info()[1]
  1350                 "Could not call install_name_tool -- you must have Apple's development tools installed")
  1387             logger.warn("Could not call mach_o_change: %s. "
  1351             raise
  1388                         "Trying to call install_name_tool instead." % e)
       
  1389             try:
       
  1390                 call_subprocess(
       
  1391                     ["install_name_tool", "-change",
       
  1392                      os.path.join(prefix, 'Python'),
       
  1393                      '@executable_path/../.Python',
       
  1394                      py_executable])
       
  1395             except:
       
  1396                 logger.fatal("Could not call install_name_tool -- you must "
       
  1397                              "have Apple's development tools installed")
       
  1398                 raise
  1352 
  1399 
  1353         # Some tools depend on pythonX.Y being present
  1400         # Some tools depend on pythonX.Y being present
  1354         py_executable_version = '%s.%s' % (
  1401         py_executable_version = '%s.%s' % (
  1355             sys.version_info[0], sys.version_info[1])
  1402             sys.version_info[0], sys.version_info[1])
  1356         if not py_executable.endswith(py_executable_version):
  1403         if not py_executable.endswith(py_executable_version):
  1365             pth = join(bin_dir, 'python')
  1412             pth = join(bin_dir, 'python')
  1366             if os.path.exists(pth):
  1413             if os.path.exists(pth):
  1367                 os.unlink(pth)
  1414                 os.unlink(pth)
  1368             os.symlink(os.path.basename(py_executable), pth)
  1415             os.symlink(os.path.basename(py_executable), pth)
  1369 
  1416 
  1370     if sys.platform == 'win32' and ' ' in py_executable:
  1417     if is_win and ' ' in py_executable:
  1371         # There's a bug with subprocess on Windows when using a first
  1418         # There's a bug with subprocess on Windows when using a first
  1372         # argument that has a space in it.  Instead we have to quote
  1419         # argument that has a space in it.  Instead we have to quote
  1373         # the value:
  1420         # the value:
  1374         py_executable = '"%s"' % py_executable
  1421         py_executable = '"%s"' % py_executable
  1375     cmd = [py_executable, '-c', """
  1422     # NOTE: keep this check as one line, cmd.exe doesn't cope with line breaks
  1376 import sys
  1423     cmd = [py_executable, '-c', 'import sys;out=sys.stdout;'
  1377 prefix = sys.prefix
  1424         'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))']
  1378 if sys.version_info[0] == 3:
       
  1379     prefix = prefix.encode('utf8')
       
  1380 if hasattr(sys.stdout, 'detach'):
       
  1381     sys.stdout = sys.stdout.detach()
       
  1382 elif hasattr(sys.stdout, 'buffer'):
       
  1383     sys.stdout = sys.stdout.buffer
       
  1384 sys.stdout.write(prefix)
       
  1385 """]
       
  1386     logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  1425     logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  1387     try:
  1426     try:
  1388         proc = subprocess.Popen(cmd,
  1427         proc = subprocess.Popen(cmd,
  1389                             stdout=subprocess.PIPE)
  1428                             stdout=subprocess.PIPE)
  1390         proc_stdout, proc_stderr = proc.communicate()
  1429         proc_stdout, proc_stderr = proc.communicate()
  1392         e = sys.exc_info()[1]
  1431         e = sys.exc_info()[1]
  1393         if e.errno == errno.EACCES:
  1432         if e.errno == errno.EACCES:
  1394             logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1433             logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1395             sys.exit(100)
  1434             sys.exit(100)
  1396         else:
  1435         else:
  1397           raise e
  1436             raise e
  1398 
  1437 
  1399     proc_stdout = proc_stdout.strip().decode("utf-8")
  1438     proc_stdout = proc_stdout.strip().decode("utf-8")
  1400     proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1439     proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1401     norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1440     norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1402     if hasattr(norm_home_dir, 'decode'):
  1441     if hasattr(norm_home_dir, 'decode'):
  1407         logger.fatal(
  1446         logger.fatal(
  1408             'ERROR: It thinks sys.prefix is %r (should be %r)'
  1447             'ERROR: It thinks sys.prefix is %r (should be %r)'
  1409             % (proc_stdout, norm_home_dir))
  1448             % (proc_stdout, norm_home_dir))
  1410         logger.fatal(
  1449         logger.fatal(
  1411             'ERROR: virtualenv is not compatible with this system or executable')
  1450             'ERROR: virtualenv is not compatible with this system or executable')
  1412         if sys.platform == 'win32':
  1451         if is_win:
  1413             logger.fatal(
  1452             logger.fatal(
  1414                 'Note: some Windows users have reported this error when they '
  1453                 'Note: some Windows users have reported this error when they '
  1415                 'installed Python for "Only this user" or have multiple '
  1454                 'installed Python for "Only this user" or have multiple '
  1416                 'versions of Python installed. Copying the appropriate '
  1455                 'versions of Python installed. Copying the appropriate '
  1417                 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1456                 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1426                       'your %s file.' % pydistutils)
  1465                       'your %s file.' % pydistutils)
  1427     ## FIXME: really this should be calculated earlier
  1466     ## FIXME: really this should be calculated earlier
  1428 
  1467 
  1429     fix_local_scheme(home_dir)
  1468     fix_local_scheme(home_dir)
  1430 
  1469 
       
  1470     if site_packages:
       
  1471         if os.path.exists(site_packages_filename):
       
  1472             logger.info('Deleting %s' % site_packages_filename)
       
  1473             os.unlink(site_packages_filename)
       
  1474 
  1431     return py_executable
  1475     return py_executable
       
  1476 
  1432 
  1477 
  1433 def install_activate(home_dir, bin_dir, prompt=None):
  1478 def install_activate(home_dir, bin_dir, prompt=None):
  1434     home_dir = os.path.abspath(home_dir)
  1479     home_dir = os.path.abspath(home_dir)
  1435     if sys.platform == 'win32' or is_jython and os._name == 'nt':
  1480     if is_win or is_jython and os._name == 'nt':
  1436         files = {
  1481         files = {
  1437             'activate.bat': ACTIVATE_BAT,
  1482             'activate.bat': ACTIVATE_BAT,
  1438             'deactivate.bat': DEACTIVATE_BAT,
  1483             'deactivate.bat': DEACTIVATE_BAT,
  1439             'activate.ps1': ACTIVATE_PS,
  1484             'activate.ps1': ACTIVATE_PS,
  1440         }
  1485         }
  1442         # MSYS needs paths of the form /c/path/to/file
  1487         # MSYS needs paths of the form /c/path/to/file
  1443         drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1488         drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1444         home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1489         home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1445 
  1490 
  1446         # Run-time conditional enables (basic) Cygwin compatibility
  1491         # Run-time conditional enables (basic) Cygwin compatibility
  1447         home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" % 
  1492         home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" %
  1448                        (home_dir, home_dir_msys))
  1493                        (home_dir, home_dir_msys))
  1449         files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1494         files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1450 
  1495 
  1451     else:
  1496     else:
  1452         files = {'activate': ACTIVATE_SH}
  1497         files = {'activate': ACTIVATE_SH}
  1513         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1558         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1514             "Unexpected python lib dir: %r" % lib_dir)
  1559             "Unexpected python lib dir: %r" % lib_dir)
  1515         lib_parent = os.path.dirname(lib_dir)
  1560         lib_parent = os.path.dirname(lib_dir)
  1516         assert os.path.basename(lib_parent) == 'lib', (
  1561         assert os.path.basename(lib_parent) == 'lib', (
  1517             "Unexpected parent dir: %r" % lib_parent)
  1562             "Unexpected parent dir: %r" % lib_parent)
  1518         copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
  1563         os.symlink(os.path.join('.', os.path.basename(lib_parent)),
       
  1564                    os.path.join(os.path.dirname(lib_parent), 'lib64'))
  1519 
  1565 
  1520 def resolve_interpreter(exe):
  1566 def resolve_interpreter(exe):
  1521     """
  1567     """
  1522     If the executable given isn't an absolute path, search $PATH for the interpreter
  1568     If the executable given isn't an absolute path, search $PATH for the interpreter
  1523     """
  1569     """
  1563 def fixup_scripts(home_dir):
  1609 def fixup_scripts(home_dir):
  1564     # This is what we expect at the top of scripts:
  1610     # This is what we expect at the top of scripts:
  1565     shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  1611     shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  1566     # This is what we'll put:
  1612     # This is what we'll put:
  1567     new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  1613     new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  1568     activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
  1614     if is_win:
  1569     if sys.platform == 'win32':
       
  1570         bin_suffix = 'Scripts'
  1615         bin_suffix = 'Scripts'
  1571     else:
  1616     else:
  1572         bin_suffix = 'bin'
  1617         bin_suffix = 'bin'
  1573     bin_dir = os.path.join(home_dir, bin_suffix)
  1618     bin_dir = os.path.join(home_dir, bin_suffix)
  1574     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1619     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1598             else:
  1643             else:
  1599                 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1644                 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1600                             % (filename, shebang))
  1645                             % (filename, shebang))
  1601             continue
  1646             continue
  1602         logger.notify('Making script %s relative' % filename)
  1647         logger.notify('Making script %s relative' % filename)
  1603         lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
  1648         script = relative_script([new_shebang] + lines[1:])
  1604         f = open(filename, 'wb')
  1649         f = open(filename, 'wb')
  1605         f.write('\n'.join(lines).encode('utf-8'))
  1650         f.write('\n'.join(script).encode('utf-8'))
  1606         f.close()
  1651         f.close()
       
  1652 
       
  1653 def relative_script(lines):
       
  1654     "Return a script that'll work in a relocatable environment."
       
  1655     activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
       
  1656     # Find the last future statement in the script. If we insert the activation
       
  1657     # line before a future statement, Python will raise a SyntaxError.
       
  1658     activate_at = None
       
  1659     for idx, line in reversed(list(enumerate(lines))):
       
  1660         if line.split()[:3] == ['from', '__future__', 'import']:
       
  1661             activate_at = idx + 1
       
  1662             break
       
  1663     if activate_at is None:
       
  1664         # Activate after the shebang.
       
  1665         activate_at = 1
       
  1666     return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]
  1607 
  1667 
  1608 def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1668 def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1609     """Makes .pth and .egg-link files use relative paths"""
  1669     """Makes .pth and .egg-link files use relative paths"""
  1610     home_dir = os.path.normcase(os.path.abspath(home_dir))
  1670     home_dir = os.path.normcase(os.path.abspath(home_dir))
  1611     if sys_path is None:
  1671     if sys_path is None:
  1656     f.write('\n'.join(lines) + '\n')
  1716     f.write('\n'.join(lines) + '\n')
  1657     f.close()
  1717     f.close()
  1658 
  1718 
  1659 def fixup_egg_link(filename):
  1719 def fixup_egg_link(filename):
  1660     f = open(filename)
  1720     f = open(filename)
  1661     link = f.read().strip()
  1721     link = f.readline().strip()
  1662     f.close()
  1722     f.close()
  1663     if os.path.abspath(link) != link:
  1723     if os.path.abspath(link) != link:
  1664         logger.debug('Link in %s already relative' % filename)
  1724         logger.debug('Link in %s already relative' % filename)
  1665         return
  1725         return
  1666     new_link = make_relative_path(filename, link)
  1726     new_link = make_relative_path(filename, link)
  1748     be run with a particular Python version.
  1808     be run with a particular Python version.
  1749     """
  1809     """
  1750     filename = __file__
  1810     filename = __file__
  1751     if filename.endswith('.pyc'):
  1811     if filename.endswith('.pyc'):
  1752         filename = filename[:-1]
  1812         filename = filename[:-1]
  1753     f = open(filename, 'rb')
  1813     f = codecs.open(filename, 'r', encoding='utf-8')
  1754     content = f.read()
  1814     content = f.read()
  1755     f.close()
  1815     f.close()
  1756     py_exe = 'python%s' % python_version
  1816     py_exe = 'python%s' % python_version
  1757     content = (('#!/usr/bin/env %s\n' % py_exe)
  1817     content = (('#!/usr/bin/env %s\n' % py_exe)
  1758                + '## WARNING: This file is generated\n'
  1818                + '## WARNING: This file is generated\n'
  1850 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
  1905 Q7wQmAIMcman2gOwRiH4P2ts6wE=
  1965 YAowyJmdag/AGoXg/wBaZusT
  1906 """)
  1966 """)
  1907 
  1967 
  1908 ##file ez_setup.py
  1968 ##file ez_setup.py
  1909 EZ_SETUP_PY = convert("""
  1969 EZ_SETUP_PY = convert("""
  1910 eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt
  1970 eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt
  1976 BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
  2036 BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
  1977 """)
  2037 """)
  1978 
  2038 
  1979 ##file distribute_setup.py
  2039 ##file distribute_setup.py
  1980 DISTRIBUTE_SETUP_PY = convert("""
  2040 DISTRIBUTE_SETUP_PY = convert("""
  1981 eJztG2tz2zbyu34FTh4PqYSi7TT3GM+pM2nj9DzNJZnYaT8kHhoiIYk1X+XDsvrrb3cBkCAJyc61
  2041 eJztO21z27jR3/Ur8MjjIZVKtJ27XjueRzeTuzhXz6VJJnZ6HxIPDZGQxDPfDiQtq7++uwuAAF9k
  1982 dzM3c7qrIxGLxWLfuwCP/lTs6k2eTabT6Xd5Xld1yQsWxfBvvGxqweKsqnmS8DoGoMnliu3yhm15
  2042 O722M52p2nMkYrFY7PsuwKP/K/f1tsgn0+n0h6Koq1ryksUJ/JusmlqwJK9qnqa8TgBocrlm+6Jh
  1983 VrM6Z00lWCXqpqjzPKkAFkdLVvDwjq+FU8lBv9h57JemqgEgTJpIsHoTV5NVnCB6+AFIeCpg1VKE
  2043 O57XrC5YUwlWibop66JIK4DFUclKHt3xjfAqNRiU+zn7talqAIjSJhas3ibVZJ2kiB5+ABKeCVhV
  1984 dV7u2DauNyyuPcaziPEoogm4IMLWecHylVxJ4z8/n0wYfFZlnhrUBzTO4rTIyxqpDTpqCb7/yJ2N
  2044 iqgu5J7tknrLknrOeB4zHsc0ARdE2LooWbFWKxn85+eTCYPPWhaZQ31I4yzJykLWSG1oqSX47iN/
  1985 dliKXxsgi3FWFSKMV3HI7kVZATOQhm6qh98BKsq3WZLzaJLGZZmXHstL4hLPGE9qUWYceKqBuh17
  2045 NtihFL81QBbjrCpFlKyTiN0LWQEzkAY7dY7fASoudnla8HiSJVIWcs4KSVziOeNpLWTOgacGyO54
  1986 tGgIUFHOqpwtd6xqiiLZxdl6gpvmRVHmRRnj9LxAYRA/bm+HO7i99SeTa2QX8TekhRGjYGUD3yvc
  2046 TotGABUXrCrYas+qpizTfZJvJrhpXpayKGWC04sShUH8uL3t7+D2NphMrpFdxN+IFkaMgskGvle4
  1987 SljGBW1PSZeoLNYlj0x5+qgUE8W8vNLfql37tY5Tob+vspTX4aYdEmmBFLS/eUk/Wwk1dYwqI0eT
  2047 lUgmJW1PS5eoLDeSx648A1SKiWZeUZlv1bapk7T9tW8H6iQT5vs6z3gdbdshkZVIT/ubS/rZygtR
  1988 fD2Z1OXuvJNiFaP2yeFPVxcfg6vL64uJeAgFkH5Jzy+QxXJKC8EW7F2eCQObJrtZAgtDUVVSVSKx
  2048 VkZQabGZTGq5P7cyrRLURTX86eriY3h1eX0xEQ+RgI1c0vMLZLia0kKwJXtX5MLBZshuVsDQSFSV
  1989 YoFU/iBMI/cZL9fVTE7BD/4EZC5s1xcPImxqvkyEN2PPaaiFK4FfZWag90PgqEvY2GLBTid7iT4C
  2049 UpxYrFmoTCGMsth/weWmmqkp+MGfgMyH7QbiQURNzVepmM/YH2iohZPAPZk76IMI+OsTNrZcstPJ
  1990 RQfmg2hAihFbgRQkQeyF/80fSuQR+7XJa1AmfNykIquB9StYPgNd7MDgEWIqwNyBmBTJdwDmmxdO
  2050 QaKPQO1BFCAokGnM1iATRRB7GXzzLyXyiP3WFDWoFj5uMpHXwPo1LJ+DZloweISYSjB+ICZD8j2A
  1991 t6QmCxEK3OasP6bwOPA/MG4YHw8bbHOmx9XUYccIOIJTMMMhtenPHQXEOviiVqxuhtLJK78qOFid
  2051 +ealZ5c0ZCFCgducdcc0Hg/+B6YO48Nhh23e9LiaeuwYAQdwGqY/pDf92VJArIMvesXqpi+dogqq
  1992 C98+BD+/urz22IBp7Jkps9cXb159ensd/HTx8ery/TtYb3rq/8V/8XLaDn36+BYfb+q6OD85KXZF
  2052 koMN+vDtQ/jLq8vrOesxjb1wZfb64s2rT2+vw79dfLy6fP8O1pueBt8FL/88bYc+fXyLj7d1XZ6f
  1993 7EtR+Xm5PlFOsDqpwFGF4iQ66fzSyXRydXH96cP1+/dvr4I3r368eD1YKDw7m05MoA8//hBcvnvz
  2053 nJT7MgmUqIJCbk60S6xOKnBbkTiJT6yXOplOri6uP324fv/+7VX45tXPF697C0VnZ9OJC/Th55/C
  1994 Hsen0y+Tf4qaR7zm85+kOzpnZ/7p5B340XPDhCft6HE1uWrSlINVsAf4TP6Rp2JeAIX0e/KqAcpL
  2054 y3dv3uP4dPpl8ldR85jXfPE35ZzO2VlwOnkHXvXcMehJO3pcTa6aLONgFewBPpO/FJlYlEAh/Z68
  1995 8/tcpDxO5JO3cSiySoG+FtKBEF58AASBBPftaDKZkBorX+OCJ1jCvzNtA+IBYk5IyknuXQ7TYJ0W
  2055 aoBy6X5fiIwnqXryNolEXmnQ10K5E8KLD4AgkOChHU0mE1Jj7Xl88AQr+HduXFGIbF/6s5kxCvEA
  1996 4CJhy9qb+OldhN/BU+M4uA1/y8vMdS46JKADx5XjqckSME+iYBsBIhD/WtThNlIYWi9BUGC7G5jj
  2056 ISkibSXvr+BpsM5K8KDAA+Neguwuxu/gyHEc/Eiw4zL3vQuLBJTiuPLmerICLNI43MWACPRhI+po
  1997 mlMJihMR0oX5eSGydhctTKD2obbYm+yHSV4JDC+dQa5zRSxuug0ELQD4E7l1IKrg9cb/BeAVYR4+
  2057 F2sMrdsgKDDmLczx3akExYkI5dOCohS52ZaFCfU+9J47k4MoLSqB0cda6KbQxOKm2zjRAoCDUVsH
  1998 TECbDFo/n97MxhuRWLqBjmHv8i3b5uWdyTENbVCphIZhaIzjsh1kr1vddmamO8nyuufAHB2xYTlH
  2058 okpeb4NfAV4TNseHKaiXQ+vn05vZcCMKix2wDHtX7NiukHcuxwy0Q6UWGkapIY7LdpC9bpXdm7n+
  1999 IXcGHqRb4Ap0FEI/4N+Cy2LbMoevUVNqXTGTE99YeIBFCIIW6HlZCi4atJ7xZX4v9KRVnAEemypI
  2059 JS/qjkfzTECH5TyNHL6+cJWj52Hselegw5AowHI7cGlsJwv4GjfSqI6bygQOHT0sQhC0QM/MMnDh
  2000 zZlpJV42MTwQ67UL/3laWeFLHiDr/q/T/wM6TTKkWJgxkKIF0XcthKHYCNsJQsq749Q+HZ//in+X
  2060 YBWMr4p7YSatkxzwjGmGUiSLWsXKQGa1FKLVG20CqyYBcLHZ+PDfnLWWUBchgv3PAP4LDIBkSJE0
  2001 6PtRbejRHH/Bn9JA9EQ1lDuQUU1rVymqJqn7ygNLSWBlg5rj4gGWrmi4W6XkMaSol+8pNXGd7/Mm
  2061 ZyDFEUQ/tBCOFSCsFYSSt+XUIYNY/IZ/Vxg5UG3o0QJ/wR/pIPqXKKnan4qYRvekqJq07qoWEKKA
  2002 iWgWcUraznqNtqKsIAKiVQ7rqnTYa7PaYMkroTdmPI5EwndqVWTlUA0UvNOFyflxNS92x5EP/0fe
  2062 tTkbeYgHIKyiYUuD5Akkw5fvKe3xvR+LJo1pFvFR2d1mg3ambSSGLels2deJ97zNn8MVr4TZtvM4
  2003 WRMJ+ByzjgoM6uoHRJxVDjpkeXh2M3s6e5RZAMHtXoyMe8/+99E6+OzhUqdXjzgcAqScDckHfyjK
  2063 Finf61WR0X0l0fCeDcGL42pR7o/jAP6PnB1NUuBzzCwVmDDoHxDN1gVo2MjDs5vZ89mjjQYIbvfi
  2004 2j31WCd/lf326x4jyV/qqk8H6IDS7wWZhpT3oMZQO14MUqQBBxZGmmTlhtzBAlW8KS1MWJz92QPh
  2064 5PYH9n+I1t7nAJes1j3hjgiQ8kEkH3ypkLV/OmdW/jqz7lZYTjmxMvWlCf4hpfZLMhwl7141o3e8
  2005 BCt+JxbXZSNa75pyMvGqgcJsS8kz6ShfVnmChoq8mHRLGJoGIPiva3Jvy6tAckmgN3WKu3UAJkVZ
  2065 7KVfPQ4snRRslBtqB0s0gEaOMGF59sc5CCdc8zuxvJaNaH1vxskBVA2UgDtKzElH+aoqUjRj5MXE
  2006 W0VJLPI3zaMmERVWSl/a3TgdV4aAY0/c+2GIprdeH0Aq54ZXvK5LtwcIhhJERtC1JuE4W3HQnoXT
  2066 LuFoGoDgv77LvR2vQsUlgb7WK+82IZgUZYQVJcjI36yIm1RUWJN9aXfjWa70AYd+uvPDEU1nvS6A
  2007 UL8CHoIo59DVLi3EvrKmnSlz79/jLfYzr8cMX5Xp7rRjybeL6XO12sxC1nAXfXwqbf4+z1ZJHNb9
  2067 Us4tr3hdS78DCIYSxk78Hk3wcbbm4HiGT0PdWrsPop2DrYtaiEMlUztT5fW/x1scZl6HGYFuCPhT
  2008 pQVoiawdQvIm7gz8yVBwplaNeY/TIdRBRuJvSyh03RHE9Jo8O20rMnsORm/G/XZxDAUL1PooaH4P
  2068 y5Lvl1OosPR6sxHC+vvoYtRJ+Y9Fvk6TqO4uLkBPVGUSkT/xZ+BR+qJz9WrIfZwOoRDymWAnoYz2
  2009 6TpVMl+y6RgftlJCnjk11pvK1AHzdoNtAuqvqLYAfCubDKOLzz4kAsRjxadbB5yleYmkhpiiaUJX
  2069 BxDTa/LttLHY7W84fSD/++UxlENJRaLm91AMUJ30JZ8O8WHbJuK5V2M1q40dMO+22JKgXo5uQcA3
  2010 cVnVHpgmoLFOdwDxTrscNv9k7MvxLfBfsi+Z+31TlrBKspOI2XE5A+Q9/y98rOIwcxirshRaXLsv
  2070 2eQYXwL2IRUgoFF8pk3BWVZIJDXCBM8Quk5kVc/BOAHN6HQPEO+N02GLT86+vGAE/kv+Jfd/bKSE
  2011 +mMiqSz2ARrIBiZn2PfngZ+4wSkYmamxk9/tK2a/xhqeFEP2WYxVr9tsBlZ9l9dv8iaLfrfRPkqm
  2071 VdK9QsyO5QyQdyKACDAfxcxiqMxKaEntv+yOibQasRDQQdYzOsfCP/c8xQ1OwdhMTaTi7lCp/DX2
  2012 jcRRqnPIXQVhKXgtht4qwM2RBbZZFIarA1H698Ys+lgCl4pXygtDPfy6a/G15kpxtW0kgu0leUil
  2072 8KwocshmRvW6zXZg1XdF/aZo8vh3m+2TZI6ROEiFHnNYYSQFr0XfX4W4ObLANsuiiPVIoP69YYs+
  2013 C7U5FePjWnbuMqjkZVJ4q2i/ZdWGMrMltiPveRL3sGvLy5p0KUqwaE6m3HoFwoXtP0p6qWPS9iFB
  2073 I7FLhyztiKHcfm37ia29Umhtu5ZgfGkRUeVDPVXN+aRWbcKcZ0Jljbea9lvICik5W2Hv856nSQe7
  2014 C2iKYLc9ftwy7HG44CPCjV5dZJEMm9ij5cw5cWY+u5U8ucUVe7k/+BdRCp1Ctv0uvYqIfLlH4mA7
  2074 Mb28yVZCgklzsuXWLRAu7DVSVkwNmbbpCWpAUwS77fDjlmELxQcnEW3N6iKPVeTEhjBn3ok3C9it
  2015 Xe2BOqxhnkXU6yw4BvqlWKG7wbZmWDc86TqutL8aK6na12L4jyQMvVhEQm1KqIKXFIUEtrlVv7lM
  2075 4sktrtgpDsDBCClMFtm208wqIg7UHomD7XS9B2rnRkUeU2O15BjrV2KN/gZ7qFHd8NS2d2l/NZZa
  2016 sKyaGNZojZUGihe2ufX6twDVAVs/veTYxzJs/Rs6QCV92dQue7kqCpI9b7HI/I/fC2DpnhRcg6rs
  2076 dWDE8G/JGTrhiITaSKipVxSIBPbUdXNbplh3TRxzHA2XDoqXY3Przd9DVAfsLHXy4wDrtM3f0QNq
  2017 sgwRHexLtVYNax3kzRLt7Bx5/uo+j1GrC7TcqCWny3BGIb0tXlrrIR9fTT3cUt9lS6IUl9zR8BH7
  2077 6asOuuykqyhICIYGi0oB+b0Alh7Iwg2oTjBlhOhgX7pz65hrL3VWaGfnyPNX90WCWl2i6cYtOTbJ
  2018 KHh0QrGVYYCB5AxIZ0swuTsPO+xbVEKMhtK1gCaHeVmCuyDrGyCD3ZJWa3uJ8ayjFgSvVVh/sCmH
  2078 GUT1tn5prYecfDWd45a6PlsRpbnkD4aP2EfB4xMKrgwjDORnQDpbgcndzbGdv0MlxHCofAtoclRI
  2019 CUIZgj7waJBRSTYS0ZJZHptul9MRkEoLEFk3NvKZShKwliXFAAJ0iT6AB/yWcAeLmvBd55QkDHtJ
  2079 Ce6CrK+HDHZLWm3sJcGDlVoQvFFh88GeH2YIMgJ94HEvqVJsJKIVs+ZsultNB0A6L0BkdmzgNLUk
  2020 yBKUjFUlCO66Au+1zB/cVZOF6M2UE6Rhc5zaqx579uxuOzuQFcvmf1efqOnaMF5rz3Ilnx9KmIew
  2080 YK2RHAMIMDV8Dx7wj8Q7WNSFt41ZkjDsJSVL0DI21SA47Arc16p48NdNHqE7016Qht1xat/O2YsX
  2021 mDNDIW1LlpHa+ziXraRRm938FLyqRgPDlXxcBwQ9ft4u8gQcLSxg2j+vwGMXKl2wSHpCYtNNeMMB
  2081 d7vZI5mxOlywNYqebizjtXEtV+r5Y0lzHxbzZii1xxJmpPY+KVQratDGdz8lr6rBQH+lANcBSQ+f
  2022 4Mn5/HDefhkq3dEa0RP9o9qslhnTfZhBVhFYkzo7pKn0pt4qRSeqAvQNLpqBB+4CPEBWdyH/Z4pt
  2082 t4s8A0cLC5gOzyvxWIfKFyyUnpHa2AlvOAA8O6fvzzssQ608RiM6on9SnfUyQ7ofZ9CoCEbTunFI
  2023 PLxrCvIWK5lYi0zuCCK7DkjkLcG3BQqH9giIeGZ6DeDGGHahl+44dAQ+DqftNPMsPa1XfQizXap2
  2083 V+tdvTWaTmSF6B18NIQ5OAzwAXltg/4vFN14dNeU5C/WKrcWudoSxHYTkshfgncLNQ7jExDxzPUb
  2024 3WlDN+sDQmMp4OsJkE1ibAjIGRDFMp8zNwGGtnVswVK5Nc07eya4svkh0u2JIQZYz/Quxoj2TXio
  2084 wI4h7NIsbVl0BF4Op+0N90baXq+6EG6/VW/bqoOd9QGhsRoIzARIKDE6hOQOiGKV0rmbAEvbeWPh
  2025 rNlmFZp2cUPeGzxWqEZ7lggysdWRGZ9ClHX8929f+8cVHmnh6aiPf0ad3Y+ITgY3DCS57ClKEjVO
  2085 Ujs2w7vxZHA95olIuSeOGGA91704I613wkNsw7dRqRkv12e+w2SDa7BrhSEXOxOd8SlEWi94//Z1
  2026 1eTF2hZ/urZRtQH9sCU2ze8hWQbTCMwOuVskPBQbUHahO9WDMB5X2Gscg/Wp/5TdQSDsNd8h8VJ7
  2086 cFzhqRkewAb4Z9D+/YjoVIDDYFKoxqOi0eDUnWAscfGnPzaqd2AeWmqz4h5SZjCP0O2y+2XKI7EF
  2027 MObu168V1h09/4PpqL4QYDSC7aQA1eq02Vf/ujjXM/sxz7BjOMfiYOju9eIjb7kE6d+ZbFn1y6OO
  2087 hRemn92L5UmFHckhWJf8T/kdRMNOAx+yL70JZ+5hFVtj9dHxQZiTmisITrt4nBSgWp9oB/pfH+fO
  2028 A12HlFJ489DcXHfAgMlIC0BOqAUiEfJINm9qTHrRe2z5rrM5XecMEzaDPR6Tqq/IH0hUzTc40Tlz
  2088 3b7MC+wcLrBE6Lt8s/jAY65A/ncuW9bdIslywHZKKY93j+nddXsMmAzUAOSEaiBSoY59i6bGzBcd
  2029 ZTlAdtCDla6qF0FGk6Q/VDM8ZjmvVJ1txdGRb++4AabAhy7KY31qrMp0BJi3LBG1UzFU/Nb5DvnZ
  2089 yI7vrdmZaqeftTnsmTOl/Zr8nkT1fIcT1qFr4wGyww6s8ladKDKYpFyinjFnI2eiuv+tOTrw75Yb
  2030 KpriN+qaa7bwvEHzT7Xw8SYCfjW4pzEckoeC6R2HDfvMCmRQ7ZreZoRlHNNteglOVTbuga2aWMWJ
  2090 YAu876XmrEvNqDIdAeYdS0XtVQwVv/W/fX62iqb5jbrmu628ea8JqBv9eNsBvzrcMxgek4eG6Zyw
  2031 PW1056q7yBMZbQJnsJO+P97na4beeR+c9tV8Bel0e0SM6yumGAEMQdobK23burWRjvdYrgAGPBUD
  2091 9fvNGqRX87ruZoBlGNfH9BL8qmrgA1sNsZoTB9rp3pW9OhQ7zQKvt5OuSz7ka/oO+hBc6675GpLq
  2032 /5+mQESQL39xuwNHX/e6CygJoe6Ske2xLkPPuUm6v2ZKz+Wa5IJKWoqpx9ywRdiaObqxMHZBxKnd
  2092 9hwaCdBccYIYgrSXZNr+dWsklvlYtAAGPDyDEJBlQEVYrH7120PMWWCa3iUUhlB9qej2VLOh4900
  2033 PfEITE5FKvfJpyayIuw2qiKxYUXq0Kbq/CAs8KWnc+6+qwKepO0rnN6AlJH/07wcO0Cr55HgB/zO
  2093 4V8zp+N0XXpBKUdqqqcc8Yi4DXdMf2HohIhV+3tiEhidDlb+s89PVGFoN6rDsWNH+vimsp4QFvjS
  2034 0Id/j/KXkXw0q0uJWgd5OC2yuk8C2J8iSVbVbU60n1WGjHyY4AyTksFW6o3B0W4r6vFjW+mRYXTK
  2094 0Tr/0IWEuaLtK9xej5SBBzS8HLrAUd+jwB/xPB1/BovwCC8WOU4Qnv0Svv95bCGobrHu3EIdxUoh
  2035 hvJ6fH+PmdjQ0zwCPuvl823Q63K6IxVKIAKFd6hKMf6y5dd7FVRmwBc//DBHEWIIAXHK71+hoPEo
  2095 s6SqzN0xVa8eY6vxLilLCAtTl4aeKfyISqcyiAGpNhlrSXo8IRv12gRwODlT8qnbbOywfBzFCGCC
  2036 hT0YZ/fFhKfGVcO3d7F1T7IPxKd3Ld/6jw6yYvaIaT/Kuf+KTRms6JUdSlvslYca1Pol+5RtRBtF
  2096 10+Gelupt44Y7Vb046e20iHD6dL1leTp/T1l1z0H9yz/MZl1C4o25NqU8kgHMoh/0R1qWYK/xhL8
  2037 s+9kH3NvOLOczCnM1KwNilKs4gdXe/ouuLRBjkKDOpSE+vveOO839oa/1YU6DfhZf4EoGYkHI2w+
  2097 g8ahUvCLn35aoCQxgIFU1fevMI5kkEI/GuUPRaTnRnVrX05kP1BtAPHZXcu37qNHWTF7wq08ybn/
  2038 Pzu/abMoGvT0tTuRNakoubyQZ/ZOEFTeWJX51nxewl7lPQi5iWGCDpsAHD6sWdYVtplRiRcYRiQe
  2098 iGk5rOjUPVpbxksfPWhvs1CvtI2ng1j6g+qlHgymIweEGjM1jMNSinXy4JswYyNbG2LJP+qzUS43
  2039 S2OmzgslGZpZJHHtOrjOwpl9ng9O5wwWaPaZiylcwyMiSRWWhpIK64FrApopbxF+K/lj7yH1yK0+
  2099 9861A2dz+FvfGTSAn80XiNGxeHCCNhRYZ+c3bRpHw3Nzt1DkTSYkV7cO3QYOgqpLuirhWywk7FZd
  2040 E+RzC5VfS2lHIzC3qUTp0NFCdzlWHRViG9fasbGt0s62GIbUyJGqDpX9KuR0oGicO+rrkTbb3Xsw
  2100 11Db6FcIsA3AEcCqsq6w2Y16vMQopvCMdIfqotTCoZllmtS+h+ssvdnnRe+Q0GGCYaC7mMbVP6lS
  2041 fqhDdcS2wgGLCoEES5A3sltQSONWT5QLyZRKiBTPGczj0XGXhH5u0Vz6pYK6d4RsGG/IiEOYmMLk
  2101 VGF1qqgYPflNQTnVVcnvFX/GG1kdcqvPBIncHdL5tbRaKoG9TSWkR0cc9g6wPrPEdvJo42hslXb2
  2042 beVj1tY/0/c/yvNeTLbBK5bgjHrliT1xH2gLxXzEsCA3rjyu4tz1rhAjvmGr0jhIevXh8g8mfNYV
  2102 iHUorRyoa1/hryJOJ5vOAai5BTpmwAfP6B9rlB2xnfDAqiIgYSTLcBJsUEnn+lFcCMWUSogMkwH3
  2043 gUOEoJB9ZTRvc5nvFpgliSzM7aI5YpGohbo1h8EbT+LbCIiaGg1z2PYYbjEkz9dDQ30233kwih65
  2103 nHbYq6GfOzSZbrWiL0ghG4YbcsIRpsYweVcFmDZ2D6C7GD+qU2hM/sFPSnBP3XJJCgr1OL4kt93V
  2044 NGi3bodYVlG8oEMF6QtRIckXxg9EbFHm93EkIvn6Q7xS8OaLFpXRfIjUhbvU6w41dMfRrDj6gcNG
  2104 2ZnLset9KQb8wk6pc5D16sPlv5NgS52tSvvLgHp2VdO9hOa+XuHWSKpTMC6oIxaLWujLfhjP8YJA
  2045 mV0KChsw1BsSDIjkWYjtHuhYW+WNcKBlA/XH/hqll4aBVUo5VuZ1PbUlyyZ8kUUqaNCdsT2byuby
  2105 GxRRb+N+St0eDi775AVmqK/d7msfThWmlgZdN/2ZkVU0L+ioQ/lGVE/yjckDEVvK4j6JRazeAEnW
  2046 Nl8nvB4daN/7+2hWqerJijTAYfOwlqaKceFzP0n7MiYLKYcTKEWiuy//RJ3rdyO+Igfdm4QeaD4P
  2106 Gt5916RyuiGxvieYze1Ri+mCuslzN5SMUTYuBY0NGDrvEwyI1AnN2F3XoW9T1+CBli2UQ4dLpk5m
  2047 eNOfN24/m7rRHt2hWdP5snR/dNZr+PtMDEXbz/5/rzwH9NJpZyaMhnnCmyzcdClc92QYKT+qkd6e
  2107 Bjaq5Fi5twz1lkY2EYg81kGELrMd2FS+UJcQrfA6dKC1H27sjUrVTNakAY4xfzvS5XHuqR4m6VAS
  2048 MbSxDcfWFr6RJCGo4NdvtEioIi5Yyss7PMvPGacDWN5NWDat8bSp3vk3N5gufHbmoXkjm7IzvGKT
  2108 NULK4zmVJtE/lJKiznXbI1+Rlh7MSx9piPd40503bIm7utEeKKJZ06m38pB0Au14/1z0RdstCH6v
  2049 iLlqAczFA72/BDnzPOUZxO7IuTFCnMZ4etP2A7BpZiaYn/tvXNyw5+20icZB93OsL9O03DMuJVci
  2109 PHv00hlsLpwmfsqbPNrapM4+6cfNj3qks2cMdKqKpZeyFAT1H8xrPAqqTEqWcXmHNwwKxulYmNsJ
  2050 WcnG+WLqTz2WCrw4UC0wpnQnM+oiNR0EKwh5zEiXAErgtmQt/gzlFSN9j1jvr7vQgD4Z3/XKtxlW
  2110 q2aj66YMe4qfvUXUvWkOKQTe9knFQnchFuKBXtuC1HmR8Ryid+zdtK7cJJDn39xgAoJonQBoRk9v
  2051 1Wke4Vth0v9js58AClGmcVXRa1rdkZ1GEoMSUsMLZB5VPrvFDTjtxRB8RQuQrgQRMrpGDYQqDsBX
  2111 2nYFdvXcFPRz97WTG0iJzLSJwUHXiEbfKGq56dytrkS6Vq395TSAij4TeL2hWmKMsadH+j44HVdr
  2052 mKx25KAnlqkpT4iIFF+5o8siwE8imRqAGg/22JUWg8Yud2wtaoXLnfVvUKiELMyLnfkbCjHI+NWN
  2112 CHUWSlcVJHBfsRp/RuomlLkObfZnr12gj8bX34pdjvV3VsT4opyKB3gcQQBu98GeKxokCSglNeRA
  2053 QMlQeZ1cAyjGd9cGTQ6APty0eYEWyygf0AMYm5PVpK0+YCXyhxBRFEivclbDqv898EtHmrAePepC
  2113 B+IqYLe4Aa+9voJvrQHStSBCBrfBgVDNAfgKk/WOPPTMKnXlKRGR4VuIdKUF+EkkU4fS4MFDAK3V
  2054 S8VXAqUqBsf6HaTPC6hAI1et0Xdlmq4FccvHPwcB8T4Z9m1evvwb5S5hnIL4qGgC+k7/enpqJGPJ
  2114 oMGrPduIWuPyZ917Hjpdi4py7/6GWg0qAn11UTFU3Yo3AJrx9n6jywHQh5s2TzBiGeQHZgBjdbqe
  2055 ylei1zil8rc5xUeB1ipYhdw3STYN3+zpsb8z94XHXhocQhvD+aJ0AcOZh3hezKzlQpgWBONjk0AC
  2115 tNUJrET+ESKMBukU13pYN+h7furIENahR1+7qfhaoFRF7/KBhQx4CUVq7Os1uq7N0LUkbgX451FA
  2056 +t3p1JBtiNSVmO0ApaTetR09jBDdid1CK6CPx/2gvkizgwQ4M48pbPLqsGYQZG500QNwtRbcWi2q
  2116 vPaGHZ5vv/2zSmaiJAP5UVUFBJ7+6fTUydnSdaBlb5Aq7W+TjI8CTVmwCtnv0uxasdtzZP/P/Jdz
  2057 LokDU7kh8wZKZ4z3iKRzQGtbQwu8z6DR2TlJOdwAcZ2MFd7ZGLCh88UnAIYb2NkBQFUgmBb7b9x6
  2117 9q3DIjQynC+kDxjO5ojn5Wy0moiykmACbCQowMAeoPX5hkh9hXkcQCrq/bHDkQGiO7FfGg0M8FIC
  2058 lSqKkxPgfgJV8Nm4AqYbxYPq2nZPgZAF0XLtghJOlWvBN9nwwpPQ4SDlMdXc9x7bc8mvCwSXh153
  2118 6C/S7CEB3gzTZ8KmLjkbBkEqR/dRAFdrwq3Zou6SPDC36zOvp3XOeIdIOqocbX0YiXcZNDjhJylH
  2059 JRW44NVOQWnnd/j6v4rxw5fbgLiY7r9g8hRQRR4ESGoQqHcpie42ap6d38wm/wIwBuVg
  2119 WyDOyljjnQ0BGzoCfQZgtIWdPQKo6wjXZP+J27lKRXFyCtxPoUw+G5bIdPe5V36P3aYgZGG82vig
       
  2120 hFPtW/B9PryXJXqvFrlvTWHAuDdNE+e58jn4FEvn9pKsU0yrtyjvjbV0wMjzj5vPd6PtaIXUXDau
       
  2121 2Afzhut3mFFDziekcz9J3Qi/2le1yC4wCp7Nxshw3JyzM+OTzEY6lbwLqJmW8YQ6GfdzduACpw2f
       
  2122 l4+9N01cueDVXkOZkPH42x06Uxq8F3lQlijshG49YXYaUgMkDHEXYajf0KUttWnI2fnNbPIPtwCg
       
  2123 9g==
  2060 """)
  2124 """)
  2061 
  2125 
  2062 ##file activate.sh
  2126 ##file activate.sh
  2063 ACTIVATE_SH = convert("""
  2127 ACTIVATE_SH = convert("""
  2064 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
       
  2142 +n8O9H8f5vsGOWXsL1+1k3g=
  2078 """)
  2143 """)
  2079 
  2144 
  2080 ##file activate.fish
  2145 ##file activate.fish
  2081 ACTIVATE_FISH = convert("""
  2146 ACTIVATE_FISH = convert("""
  2082 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
       
  2101 """)
  2162 """)
  2102 
  2163 
  2103 ##file activate.csh
  2164 ##file activate.csh
  2104 ACTIVATE_CSH = convert("""
  2165 ACTIVATE_CSH = convert("""
  2105 eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
  2166 eJx9U11v2jAUffevOA2o3ZBG9gxjGx2VVqmlVUUrTWMyTnLTWEocZDsg+uvnOEDDx5aHKLn3fFyf
  2106 XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
  2167 3HQwy6RBKnNCURmLiFAZSrCWNkNgykrHhEiqUMRWroSlfmyyAL1UlwXcY6/POvhVVoiFUqWFrhSk
  2107 kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
  2168 RSI1xTbf1N0fmhwvQbTBRKxkQphIXOfCSHxJfCGJvr8WQub9uCy+9hkTuRQGCe08cWXJzdb9xh/u
  2108 pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
  2169 Jvzl9mn2PL7jj+PZT1yM8BmXlzBkSa3ga0H3BBfUmEo5FE56Q2jKhMmGOOvy9HD/OGv7YOnOvrSj
  2109 sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
  2170 YxsP/KeR7w6bVj3prnEzfdkaB/OLQS+onQJVqsSVdFUHQFvNk1Ra1eUmKeMr5tJ+9t5Sa8ppJZTF
  2110 yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
  2171 SmgpopxMn7W4hw6MnU6FgPPWK+eBR53m54LwEbPDb9Dihpxf3075dHx/w/lgiz4j5jNyck3ADiJT
  2111 E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
  2172 fGiN0QDcJD6k4CNsRorBXbWW8+ZKFIQRznEY5YY8uFZdRMKQRx9MGiww8vS2eH11YJYUS5G7RTeE
  2112 lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
  2173 tNQYu4pCIV5lvN33UksybQoRMmuXgzBcr9f9N7IioVW95aEpU7sWmkJRq4R70tFB3secL5zHmYHn
  2113 r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
  2174 i4Un70/3X5WjwzZMlciUNff39a5T/N3difzB/qM0y71r7H5Wv4DubrNS4VPRvDPW/FmM/QUd8WEa
  2114 """)
  2175 """)
  2115 
  2176 
  2116 ##file activate.bat
  2177 ##file activate.bat
  2117 ACTIVATE_BAT = convert("""
  2178 ACTIVATE_BAT = convert("""
  2118 eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
  2179 eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
  2219 QastYw==
  2280 QastYw==
  2220 """)
  2281 """)
  2221 
  2282 
  2222 ##file distutils-init.py
  2283 ##file distutils-init.py
  2223 DISTUTILS_INIT = convert("""
  2284 DISTUTILS_INIT = convert("""
  2224 eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
  2285 eJytV1uL4zYUfvevOE0ottuMW9q3gVDa3aUMXXbLMlDKMBiNrSTqOJKRlMxkf33PkXyRbGe7Dw2E
  2225 luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
  2286 UXTu37lpxLFV2oIyifAncxmOL0xLIfcG+gv80x9VW6maw7o/CANSWWBwFtqeWMPlGY6qPjV8A0bB
  2226 KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
  2287 C4eKSTgZ5LRgFeyErMEeOBhbN+Ipgeizhjtnhkn7DdyjuNLPoCS0l/ayQTG0djwZC08cLXozeMss
  2227 ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
  2288 aG5EzQ0IScpnWtHSTXuxByV/QCmxE7y+eS0uxWeoheaVVfqSJHiU7Mhhi6gULbOHorshkrEnKxpT
  2228 QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
  2289 0n3A8Y8SMpuwZx6aoix3ouFlmW8gHRSkeSJ2g7hU+kiHLDaQw3bmRDaTGfTnty7gPm0FHbIBg9U9
  2229 yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
  2290 oh1kZzAFLaue2R6htPCtAda2nGlDSUJ4PZBgCJBGVcwKTAMz/vJiLD+Oin5Z5QlvDPdulC6EsiyE
  2230 bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
  2291 NFzb7McNTKJzbJqzphx92VKRFY1idenzmq3K0emRcbWBD0ryqc4NZGmKOOOX9Pz5x+/l27tP797c
  2231 bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
  2292 f/z0d+4NruGNai8uAM0bfsYaw8itFk8ny41jsfpyO+BWlpqfhcG4yxLdi/0tQqoT4a8Vby382mt8
  2232 yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
  2293 p7XSo7aWGdPBc+b6utaBmCQ7rQKQoWtAuthQCiold2KfJIPTT8xwg9blPumc+YDZC/wYGdAyHpJk
  2233 Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
  2294 vUbHbHWAp5No6pK/WhhLEWrFjUwtPEv1Agf8YmnsuXUQYkeZoHm8ogP16gt2uHoxcEMdf2C6pmbw
  2234 Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
  2295 hUMsWGhanboh4IzzmsIpWs134jVPqD/c74bZHdY69UKKSn/+KfVhxLgUlToemayLMYQOqfEC61bh
  2235 /n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
  2296 cbhwaqoGUzIyZRFHPmau5juaWqwRn3mpWmoEA5nhzS5gog/5jbcFQqOZvmBasZtwYlG93k5GEiyw
  2236 FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
  2297 buHhMWLjDarEGpMGB2LFs5nIJkhp/nUmZneFaRth++lieJtHepIvKgx6PJqIlD9X2j6pG1i9x3pZ
  2237 AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
  2298 5bHuCPFiirGHeO7McvoXkz786GaKVzC9DSpnOxJdc4xm6NSVq7lNEnKdVlnpu9BNYoKX2Iq3wvgh
  2238 hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
  2299 gGEUM66kK6j4NiyoneuPLSwaCWDxczgaolEWpiMyDVDb7dNuLAbriL8ig8mmeju31oNvQdpnvEPC
  2239 UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
  2300 1vAXbWacGRVrGt/uXN/gU0CDDwgooKRrHfTBb1/s9lYZ8ZqOBU0yLvpuP6+K9hLFsvIjeNhBi0KL
  2240 8h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
  2301 MlOuWRn3FRwx5oHXjl0YImUx0+gLzjGchrgzca026ETmYJzPD+IpuKzNi8AFn048Thd63OdD86M6
  2241 XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
  2302 84zE8yQm0VqXdbbgvub2pKVnS76icBGdeTHHXTKspUmr4NYo/furFLKiMdQzFjHJNcdAnMhltBJK
  2242 azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
  2303 0/IKX3DVFqvPJ2dLE7bDBkH0l/PJ29074+F0CsGYOxsb7U3myTUncYfXqnLLfa6sJybX4g+hmcjO
  2243 8dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
  2304 kMRBfA1JellfRRKJcyRpxdS4rIl6FdmQCWjo/o9Qz7yKffoP4JHjOvABcRn4CZIT2RH4jnxmfpVG
  2244 gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
  2305 qgLaAvQBNfuO6X0/Ux02nb4FKx3vgP+XnkX0QW9pLy/NsXgdN24dD3LxO2Nwil7Zlc1dqtP3d7/h
  2245 5C4rFgwLGfMvJuAMew==
  2306 kzp1/+7hGBuY4pk0XD/0Ao/oTe/XGrfyM773aB7iUhgkpy+dwAMalxMP0DrBcsVw/6p25+/hobP9
       
  2307 GBknrWExDhLJ1bwt1NcCNblaFbMKCyvmX0PeRaQ=
  2246 """)
  2308 """)
  2247 
  2309 
  2248 ##file distutils.cfg
  2310 ##file distutils.cfg
  2249 DISTUTILS_CFG = convert("""
  2311 DISTUTILS_CFG = convert("""
  2250 eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  2312 eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  2264 PyRfJkZRgj+VbFv+EzHFi5pKwUEepa4JslMnwkowSRCXI+m5XvEOvtuBrxHdhLalG0JofYBok6qj
  2326 PyRfJkZRgj+VbFv+EzHFi5pKwUEepa4JslMnwkowSRCXI+m5XvEOvtuBrxHdhLalG0JofYBok6qj
  2265 YdN2dEngUlbC4PG60M1WEN0piu7Nq7on0mgyyUw3iV1etLo6r/81biWdQ9MWHFaePWZYaq+nmp+t
  2327 YdN2dEngUlbC4PG60M1WEN0piu7Nq7on0mgyyUw3iV1etLo6r/81biWdQ9MWHFaePWZYaq+nmp+t
  2266 s3az+sj7eA0jfgPfeoN1
  2328 s3az+sj7eA0jfgPfeoN1
  2267 """)
  2329 """)
  2268 
  2330 
       
  2331 MH_MAGIC = 0xfeedface
       
  2332 MH_CIGAM = 0xcefaedfe
       
  2333 MH_MAGIC_64 = 0xfeedfacf
       
  2334 MH_CIGAM_64 = 0xcffaedfe
       
  2335 FAT_MAGIC = 0xcafebabe
       
  2336 BIG_ENDIAN = '>'
       
  2337 LITTLE_ENDIAN = '<'
       
  2338 LC_LOAD_DYLIB = 0xc
       
  2339 maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint')
       
  2340 
       
  2341 
       
  2342 class fileview(object):
       
  2343     """
       
  2344     A proxy for file-like objects that exposes a given view of a file.
       
  2345     Modified from macholib.
       
  2346     """
       
  2347 
       
  2348     def __init__(self, fileobj, start=0, size=maxint):
       
  2349         if isinstance(fileobj, fileview):
       
  2350             self._fileobj = fileobj._fileobj
       
  2351         else:
       
  2352             self._fileobj = fileobj
       
  2353         self._start = start
       
  2354         self._end = start + size
       
  2355         self._pos = 0
       
  2356 
       
  2357     def __repr__(self):
       
  2358         return '<fileview [%d, %d] %r>' % (
       
  2359             self._start, self._end, self._fileobj)
       
  2360 
       
  2361     def tell(self):
       
  2362         return self._pos
       
  2363 
       
  2364     def _checkwindow(self, seekto, op):
       
  2365         if not (self._start <= seekto <= self._end):
       
  2366             raise IOError("%s to offset %d is outside window [%d, %d]" % (
       
  2367                 op, seekto, self._start, self._end))
       
  2368 
       
  2369     def seek(self, offset, whence=0):
       
  2370         seekto = offset
       
  2371         if whence == os.SEEK_SET:
       
  2372             seekto += self._start
       
  2373         elif whence == os.SEEK_CUR:
       
  2374             seekto += self._start + self._pos
       
  2375         elif whence == os.SEEK_END:
       
  2376             seekto += self._end
       
  2377         else:
       
  2378             raise IOError("Invalid whence argument to seek: %r" % (whence,))
       
  2379         self._checkwindow(seekto, 'seek')
       
  2380         self._fileobj.seek(seekto)
       
  2381         self._pos = seekto - self._start
       
  2382 
       
  2383     def write(self, bytes):
       
  2384         here = self._start + self._pos
       
  2385         self._checkwindow(here, 'write')
       
  2386         self._checkwindow(here + len(bytes), 'write')
       
  2387         self._fileobj.seek(here, os.SEEK_SET)
       
  2388         self._fileobj.write(bytes)
       
  2389         self._pos += len(bytes)
       
  2390 
       
  2391     def read(self, size=maxint):
       
  2392         assert size >= 0
       
  2393         here = self._start + self._pos
       
  2394         self._checkwindow(here, 'read')
       
  2395         size = min(size, self._end - here)
       
  2396         self._fileobj.seek(here, os.SEEK_SET)
       
  2397         bytes = self._fileobj.read(size)
       
  2398         self._pos += len(bytes)
       
  2399         return bytes
       
  2400 
       
  2401 
       
  2402 def read_data(file, endian, num=1):
       
  2403     """
       
  2404     Read a given number of 32-bits unsigned integers from the given file
       
  2405     with the given endianness.
       
  2406     """
       
  2407     res = struct.unpack(endian + 'L' * num, file.read(num * 4))
       
  2408     if len(res) == 1:
       
  2409         return res[0]
       
  2410     return res
       
  2411 
       
  2412 
       
  2413 def mach_o_change(path, what, value):
       
  2414     """
       
  2415     Replace a given name (what) in any LC_LOAD_DYLIB command found in
       
  2416     the given binary with a new name (value), provided it's shorter.
       
  2417     """
       
  2418 
       
  2419     def do_macho(file, bits, endian):
       
  2420         # Read Mach-O header (the magic number is assumed read by the caller)
       
  2421         cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = read_data(file, endian, 6)
       
  2422         # 64-bits header has one more field.
       
  2423         if bits == 64:
       
  2424             read_data(file, endian)
       
  2425         # The header is followed by ncmds commands
       
  2426         for n in range(ncmds):
       
  2427             where = file.tell()
       
  2428             # Read command header
       
  2429             cmd, cmdsize = read_data(file, endian, 2)
       
  2430             if cmd == LC_LOAD_DYLIB:
       
  2431                 # The first data field in LC_LOAD_DYLIB commands is the
       
  2432                 # offset of the name, starting from the beginning of the
       
  2433                 # command.
       
  2434                 name_offset = read_data(file, endian)
       
  2435                 file.seek(where + name_offset, os.SEEK_SET)
       
  2436                 # Read the NUL terminated string
       
  2437                 load = file.read(cmdsize - name_offset).decode()
       
  2438                 load = load[:load.index('\0')]
       
  2439                 # If the string is what is being replaced, overwrite it.
       
  2440                 if load == what:
       
  2441                     file.seek(where + name_offset, os.SEEK_SET)
       
  2442                     file.write(value.encode() + '\0'.encode())
       
  2443             # Seek to the next command
       
  2444             file.seek(where + cmdsize, os.SEEK_SET)
       
  2445 
       
  2446     def do_file(file, offset=0, size=maxint):
       
  2447         file = fileview(file, offset, size)
       
  2448         # Read magic number
       
  2449         magic = read_data(file, BIG_ENDIAN)
       
  2450         if magic == FAT_MAGIC:
       
  2451             # Fat binaries contain nfat_arch Mach-O binaries
       
  2452             nfat_arch = read_data(file, BIG_ENDIAN)
       
  2453             for n in range(nfat_arch):
       
  2454                 # Read arch header
       
  2455                 cputype, cpusubtype, offset, size, align = read_data(file, BIG_ENDIAN, 5)
       
  2456                 do_file(file, offset, size)
       
  2457         elif magic == MH_MAGIC:
       
  2458             do_macho(file, 32, BIG_ENDIAN)
       
  2459         elif magic == MH_CIGAM:
       
  2460             do_macho(file, 32, LITTLE_ENDIAN)
       
  2461         elif magic == MH_MAGIC_64:
       
  2462             do_macho(file, 64, BIG_ENDIAN)
       
  2463         elif magic == MH_CIGAM_64:
       
  2464             do_macho(file, 64, LITTLE_ENDIAN)
       
  2465 
       
  2466     assert(len(what) >= len(value))
       
  2467     do_file(open(path, 'r+b'))
       
  2468 
       
  2469 
  2269 if __name__ == '__main__':
  2470 if __name__ == '__main__':
  2270     main()
  2471     main()
  2271 
  2472 
  2272 ## TODO:
  2473 ## TODO:
  2273 ## Copy python.exe.manifest
  2474 ## Copy python.exe.manifest