virtualenv/web/virtualenv.py
changeset 345 7bc38c7d6cf9
parent 272 1c774f7a0341
child 653 f90aa05732cc
equal deleted inserted replaced
344:1473ba25af1f 345:7bc38c7d6cf9
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     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 __version__ = "1.11.6"
     6 # and docs/conf.py as well.
     6 virtualenv_version = __version__  # legacy
     7 virtualenv_version = "1.7.1.2"
       
     8 
     7 
     9 import base64
     8 import base64
    10 import sys
     9 import sys
    11 import os
    10 import os
       
    11 import codecs
    12 import optparse
    12 import optparse
    13 import re
    13 import re
    14 import shutil
    14 import shutil
    15 import logging
    15 import logging
    16 import tempfile
    16 import tempfile
    17 import zlib
    17 import zlib
    18 import errno
    18 import errno
       
    19 import glob
    19 import distutils.sysconfig
    20 import distutils.sysconfig
    20 from distutils.util import strtobool
    21 from distutils.util import strtobool
    21 
    22 import struct
    22 try:
    23 import subprocess
    23     import subprocess
    24 import tarfile
    24 except ImportError:
    25 
    25     if sys.version_info <= (2, 3):
    26 if sys.version_info < (2, 6):
    26         print('ERROR: %s' % sys.exc_info()[1])
    27     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('ERROR: this script requires Python 2.6 or greater.')
    28         print('If you copy subprocess.py from a newer version of Python this script will probably work')
    29     sys.exit(101)
    29         sys.exit(101)
    30 
    30     else:
       
    31         raise
       
    32 try:
    31 try:
    33     set
    32     set
    34 except NameError:
    33 except NameError:
    35     from sets import Set as set
    34     from sets import Set as set
    36 try:
    35 try:
    46 join = os.path.join
    45 join = os.path.join
    47 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
    46 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
    48 
    47 
    49 is_jython = sys.platform.startswith('java')
    48 is_jython = sys.platform.startswith('java')
    50 is_pypy = hasattr(sys, 'pypy_version_info')
    49 is_pypy = hasattr(sys, 'pypy_version_info')
    51 is_win  = (sys.platform == 'win32')
    50 is_win = (sys.platform == 'win32')
       
    51 is_cygwin = (sys.platform == 'cygwin')
       
    52 is_darwin = (sys.platform == 'darwin')
    52 abiflags = getattr(sys, 'abiflags', '')
    53 abiflags = getattr(sys, 'abiflags', '')
    53 
    54 
    54 user_dir = os.path.expanduser('~')
    55 user_dir = os.path.expanduser('~')
    55 if sys.platform == 'win32':
    56 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')
    57     default_storage_dir = os.path.join(user_dir, 'virtualenv')
    58 else:
    58 else:
    59     default_storage_dir = os.path.join(user_dir, '.virtualenv')
    59     default_storage_dir = os.path.join(user_dir, '.virtualenv')
    60 default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
    60 default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
    61 
    61 
    64 elif is_jython:
    64 elif is_jython:
    65     expected_exe = 'jython'
    65     expected_exe = 'jython'
    66 else:
    66 else:
    67     expected_exe = 'python'
    67     expected_exe = 'python'
    68 
    68 
       
    69 # Return a mapping of version -> Python executable
       
    70 # Only provided for Windows, where the information in the registry is used
       
    71 if not is_win:
       
    72     def get_installed_pythons():
       
    73         return {}
       
    74 else:
       
    75     try:
       
    76         import winreg
       
    77     except ImportError:
       
    78         import _winreg as winreg
       
    79 
       
    80     def get_installed_pythons():
       
    81         python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE,
       
    82                 "Software\\Python\\PythonCore")
       
    83         i = 0
       
    84         versions = []
       
    85         while True:
       
    86             try:
       
    87                 versions.append(winreg.EnumKey(python_core, i))
       
    88                 i = i + 1
       
    89             except WindowsError:
       
    90                 break
       
    91         exes = dict()
       
    92         for ver in versions:
       
    93             path = winreg.QueryValue(python_core, "%s\\InstallPath" % ver)
       
    94             exes[ver] = join(path, "python.exe")
       
    95 
       
    96         winreg.CloseKey(python_core)
       
    97 
       
    98         # Add the major versions
       
    99         # Sort the keys, then repeatedly update the major version entry
       
   100         # Last executable (i.e., highest version) wins with this approach
       
   101         for ver in sorted(exes):
       
   102             exes[ver[0]] = exes[ver]
       
   103 
       
   104         return exes
    69 
   105 
    70 REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
   106 REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
    71                     'fnmatch', 'locale', 'encodings', 'codecs',
   107                     'fnmatch', 'locale', 'encodings', 'codecs',
    72                     'stat', 'UserDict', 'readline', 'copy_reg', 'types',
   108                     'stat', 'UserDict', 'readline', 'copy_reg', 'types',
    73                     're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
   109                     're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
    87     # Some extra modules are needed for Python 3, but different ones
   123     # Some extra modules are needed for Python 3, but different ones
    88     # for different versions.
   124     # for different versions.
    89     REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
   125     REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
    90                              '_weakrefset', 'copyreg', 'tempfile', 'random',
   126                              '_weakrefset', 'copyreg', 'tempfile', 'random',
    91                              '__future__', 'collections', 'keyword', 'tarfile',
   127                              '__future__', 'collections', 'keyword', 'tarfile',
    92                              'shutil', 'struct', 'copy'])
   128                              'shutil', 'struct', 'copy', 'tokenize', 'token',
       
   129                              'functools', 'heapq', 'bisect', 'weakref',
       
   130                              'reprlib'])
    93     if minver >= 2:
   131     if minver >= 2:
    94         REQUIRED_FILES[-1] = 'config-%s' % majver
   132         REQUIRED_FILES[-1] = 'config-%s' % majver
    95     if minver == 3:
   133     if minver >= 3:
       
   134         import sysconfig
       
   135         platdir = sysconfig.get_config_var('PLATDIR')
       
   136         REQUIRED_FILES.append(platdir)
    96         # The whole list of 3.3 modules is reproduced below - the current
   137         # 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
   138         # uncommented ones are required for 3.3 as of now, but more may be
    98         # added as 3.3 development continues.
   139         # added as 3.3 development continues.
    99         REQUIRED_MODULES.extend([
   140         REQUIRED_MODULES.extend([
   100             #"aifc",
   141             #"aifc",
   104             #"asynchat",
   145             #"asynchat",
   105             #"asyncore",
   146             #"asyncore",
   106             "base64",
   147             "base64",
   107             #"bdb",
   148             #"bdb",
   108             #"binhex",
   149             #"binhex",
   109             "bisect",
   150             #"bisect",
   110             #"calendar",
   151             #"calendar",
   111             #"cgi",
   152             #"cgi",
   112             #"cgitb",
   153             #"cgitb",
   113             #"chunk",
   154             #"chunk",
   114             #"cmd",
   155             #"cmd",
   144             #"getpass",
   185             #"getpass",
   145             #"gettext",
   186             #"gettext",
   146             #"glob",
   187             #"glob",
   147             #"gzip",
   188             #"gzip",
   148             "hashlib",
   189             "hashlib",
   149             "heapq",
   190             #"heapq",
   150             "hmac",
   191             "hmac",
   151             #"html",
   192             #"html",
   152             #"http",
   193             #"http",
   153             #"idlelib",
   194             #"idlelib",
   154             #"imaplib",
   195             #"imaplib",
   155             #"imghdr",
   196             #"imghdr",
   156             #"importlib",
   197             "imp",
       
   198             "importlib",
   157             #"inspect",
   199             #"inspect",
   158             #"json",
   200             #"json",
   159             #"lib2to3",
   201             #"lib2to3",
   160             #"logging",
   202             #"logging",
   161             #"macpath",
   203             #"macpath",
   191             #"pydoc_data",
   233             #"pydoc_data",
   192             #"pydoc",
   234             #"pydoc",
   193             #"_pyio",
   235             #"_pyio",
   194             #"queue",
   236             #"queue",
   195             #"quopri",
   237             #"quopri",
   196             "reprlib",
   238             #"reprlib",
   197             "rlcompleter",
   239             "rlcompleter",
   198             #"runpy",
   240             #"runpy",
   199             #"sched",
   241             #"sched",
   200             #"shelve",
   242             #"shelve",
   201             #"shlex",
   243             #"shlex",
   233             #"unittest",
   275             #"unittest",
   234             #"urllib",
   276             #"urllib",
   235             #"uuid",
   277             #"uuid",
   236             #"uu",
   278             #"uu",
   237             #"wave",
   279             #"wave",
   238             "weakref",
   280             #"weakref",
   239             #"webbrowser",
   281             #"webbrowser",
   240             #"wsgiref",
   282             #"wsgiref",
   241             #"xdrlib",
   283             #"xdrlib",
   242             #"xml",
   284             #"xml",
   243             #"xmlrpc",
   285             #"xmlrpc",
   244             #"zipfile",
   286             #"zipfile",
       
   287         ])
       
   288     if minver >= 4:
       
   289         REQUIRED_MODULES.extend([
       
   290             'operator',
       
   291             '_collections_abc',
       
   292             '_bootlocale',
   245         ])
   293         ])
   246 
   294 
   247 if is_pypy:
   295 if is_pypy:
   248     # these are needed to correctly display the exceptions that may happen
   296     # these are needed to correctly display the exceptions that may happen
   249     # during the bootstrap
   297     # during the bootstrap
   278     def notify(self, msg, *args, **kw):
   326     def notify(self, msg, *args, **kw):
   279         self.log(self.NOTIFY, msg, *args, **kw)
   327         self.log(self.NOTIFY, msg, *args, **kw)
   280     def warn(self, msg, *args, **kw):
   328     def warn(self, msg, *args, **kw):
   281         self.log(self.WARN, msg, *args, **kw)
   329         self.log(self.WARN, msg, *args, **kw)
   282     def error(self, msg, *args, **kw):
   330     def error(self, msg, *args, **kw):
   283         self.log(self.WARN, msg, *args, **kw)
   331         self.log(self.ERROR, msg, *args, **kw)
   284     def fatal(self, msg, *args, **kw):
   332     def fatal(self, msg, *args, **kw):
   285         self.log(self.FATAL, msg, *args, **kw)
   333         self.log(self.FATAL, msg, *args, **kw)
   286     def log(self, level, msg, *args, **kw):
   334     def log(self, level, msg, *args, **kw):
   287         if args:
   335         if args:
   288             if kw:
   336             if kw:
   398         logger.info('Creating %s', path)
   446         logger.info('Creating %s', path)
   399         os.makedirs(path)
   447         os.makedirs(path)
   400     else:
   448     else:
   401         logger.info('Directory %s already exists', path)
   449         logger.info('Directory %s already exists', path)
   402 
   450 
   403 def copyfileordir(src, dest):
   451 def copyfileordir(src, dest, symlink=True):
   404     if os.path.isdir(src):
   452     if os.path.isdir(src):
   405         shutil.copytree(src, dest, True)
   453         shutil.copytree(src, dest, symlink)
   406     else:
   454     else:
   407         shutil.copy2(src, dest)
   455         shutil.copy2(src, dest)
   408 
   456 
   409 def copyfile(src, dest, symlink=True):
   457 def copyfile(src, dest, symlink=True):
   410     if not os.path.exists(src):
   458     if not os.path.exists(src):
   413         return
   461         return
   414     if os.path.exists(dest):
   462     if os.path.exists(dest):
   415         logger.debug('File %s already exists', dest)
   463         logger.debug('File %s already exists', dest)
   416         return
   464         return
   417     if not os.path.exists(os.path.dirname(dest)):
   465     if not os.path.exists(os.path.dirname(dest)):
   418         logger.info('Creating parent directories for %s' % os.path.dirname(dest))
   466         logger.info('Creating parent directories for %s', os.path.dirname(dest))
   419         os.makedirs(os.path.dirname(dest))
   467         os.makedirs(os.path.dirname(dest))
   420     if not os.path.islink(src):
   468     if not os.path.islink(src):
   421         srcpath = os.path.abspath(src)
   469         srcpath = os.path.abspath(src)
   422     else:
   470     else:
   423         srcpath = os.readlink(src)
   471         srcpath = os.readlink(src)
   425         logger.info('Symlinking %s', dest)
   473         logger.info('Symlinking %s', dest)
   426         try:
   474         try:
   427             os.symlink(srcpath, dest)
   475             os.symlink(srcpath, dest)
   428         except (OSError, NotImplementedError):
   476         except (OSError, NotImplementedError):
   429             logger.info('Symlinking failed, copying to %s', dest)
   477             logger.info('Symlinking failed, copying to %s', dest)
   430             copyfileordir(src, dest)
   478             copyfileordir(src, dest, symlink)
   431     else:
   479     else:
   432         logger.info('Copying to %s', dest)
   480         logger.info('Copying to %s', dest)
   433         copyfileordir(src, dest)
   481         copyfileordir(src, dest, symlink)
   434 
   482 
   435 def writefile(dest, content, overwrite=True):
   483 def writefile(dest, content, overwrite=True):
   436     if not os.path.exists(dest):
   484     if not os.path.exists(dest):
   437         logger.info('Writing %s', dest)
   485         logger.info('Writing %s', dest)
   438         f = open(dest, 'wb')
   486         f = open(dest, 'wb')
   441         return
   489         return
   442     else:
   490     else:
   443         f = open(dest, 'rb')
   491         f = open(dest, 'rb')
   444         c = f.read()
   492         c = f.read()
   445         f.close()
   493         f.close()
   446         if c != content:
   494         if c != content.encode("utf-8"):
   447             if not overwrite:
   495             if not overwrite:
   448                 logger.notify('File %s exists with different content; not overwriting', dest)
   496                 logger.notify('File %s exists with different content; not overwriting', dest)
   449                 return
   497                 return
   450             logger.notify('Overwriting %s with new content', dest)
   498             logger.notify('Overwriting %s with new content', dest)
   451             f = open(dest, 'wb')
   499             f = open(dest, 'wb')
   468         os.chmod(fn, newmode)
   516         os.chmod(fn, newmode)
   469         logger.info('Changed mode of %s to %s', fn, oct(newmode))
   517         logger.info('Changed mode of %s to %s', fn, oct(newmode))
   470 
   518 
   471 def _find_file(filename, dirs):
   519 def _find_file(filename, dirs):
   472     for dir in reversed(dirs):
   520     for dir in reversed(dirs):
   473         if os.path.exists(join(dir, filename)):
   521         files = glob.glob(os.path.join(dir, filename))
   474             return join(dir, filename)
   522         if files and os.path.isfile(files[0]):
   475     return filename
   523             return True, files[0]
   476 
   524     return False, filename
   477 def _install_req(py_executable, unzip=False, distribute=False,
       
   478                  search_dirs=None, never_download=False):
       
   479 
       
   480     if search_dirs is None:
       
   481         search_dirs = file_search_dirs()
       
   482 
       
   483     if not distribute:
       
   484         setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
       
   485         project_name = 'setuptools'
       
   486         bootstrap_script = EZ_SETUP_PY
       
   487         source = None
       
   488     else:
       
   489         setup_fn = None
       
   490         source = 'distribute-0.6.24.tar.gz'
       
   491         project_name = 'distribute'
       
   492         bootstrap_script = DISTRIBUTE_SETUP_PY
       
   493 
       
   494     if setup_fn is not None:
       
   495         setup_fn = _find_file(setup_fn, search_dirs)
       
   496 
       
   497     if source is not None:
       
   498         source = _find_file(source, search_dirs)
       
   499 
       
   500     if is_jython and os._name == 'nt':
       
   501         # Jython's .bat sys.executable can't handle a command line
       
   502         # argument with newlines
       
   503         fd, ez_setup = tempfile.mkstemp('.py')
       
   504         os.write(fd, bootstrap_script)
       
   505         os.close(fd)
       
   506         cmd = [py_executable, ez_setup]
       
   507     else:
       
   508         cmd = [py_executable, '-c', bootstrap_script]
       
   509     if unzip:
       
   510         cmd.append('--always-unzip')
       
   511     env = {}
       
   512     remove_from_env = []
       
   513     if logger.stdout_level_matches(logger.DEBUG):
       
   514         cmd.append('-v')
       
   515 
       
   516     old_chdir = os.getcwd()
       
   517     if setup_fn is not None and os.path.exists(setup_fn):
       
   518         logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
       
   519         cmd.append(setup_fn)
       
   520         if os.environ.get('PYTHONPATH'):
       
   521             env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
       
   522         else:
       
   523             env['PYTHONPATH'] = setup_fn
       
   524     else:
       
   525         # the source is found, let's chdir
       
   526         if source is not None and os.path.exists(source):
       
   527             logger.info('Using existing %s egg: %s' % (project_name, source))
       
   528             os.chdir(os.path.dirname(source))
       
   529             # in this case, we want to be sure that PYTHONPATH is unset (not
       
   530             # just empty, really unset), else CPython tries to import the
       
   531             # site.py that it's in virtualenv_support
       
   532             remove_from_env.append('PYTHONPATH')
       
   533         else:
       
   534             if never_download:
       
   535                 logger.fatal("Can't find any local distributions of %s to install "
       
   536                              "and --never-download is set.  Either re-run virtualenv "
       
   537                              "without the --never-download option, or place a %s "
       
   538                              "distribution (%s) in one of these "
       
   539                              "locations: %r" % (project_name, project_name,
       
   540                                                 setup_fn or source,
       
   541                                                 search_dirs))
       
   542                 sys.exit(1)
       
   543 
       
   544             logger.info('No %s egg found; downloading' % project_name)
       
   545         cmd.extend(['--always-copy', '-U', project_name])
       
   546     logger.start_progress('Installing %s...' % project_name)
       
   547     logger.indent += 2
       
   548     cwd = None
       
   549     if project_name == 'distribute':
       
   550         env['DONT_PATCH_SETUPTOOLS'] = 'true'
       
   551 
       
   552     def _filter_ez_setup(line):
       
   553         return filter_ez_setup(line, project_name)
       
   554 
       
   555     if not os.access(os.getcwd(), os.W_OK):
       
   556         cwd = tempfile.mkdtemp()
       
   557         if source is not None and os.path.exists(source):
       
   558             # the current working dir is hostile, let's copy the
       
   559             # tarball to a temp dir
       
   560             target = os.path.join(cwd, os.path.split(source)[-1])
       
   561             shutil.copy(source, target)
       
   562     try:
       
   563         call_subprocess(cmd, show_stdout=False,
       
   564                         filter_stdout=_filter_ez_setup,
       
   565                         extra_env=env,
       
   566                         remove_from_env=remove_from_env,
       
   567                         cwd=cwd)
       
   568     finally:
       
   569         logger.indent -= 2
       
   570         logger.end_progress()
       
   571         if os.getcwd() != old_chdir:
       
   572             os.chdir(old_chdir)
       
   573         if is_jython and os._name == 'nt':
       
   574             os.remove(ez_setup)
       
   575 
   525 
   576 def file_search_dirs():
   526 def file_search_dirs():
   577     here = os.path.dirname(os.path.abspath(__file__))
   527     here = os.path.dirname(os.path.abspath(__file__))
   578     dirs = ['.', here,
   528     dirs = ['.', here,
   579             join(here, 'virtualenv_support')]
   529             join(here, 'virtualenv_support')]
   585             pass
   535             pass
   586         else:
   536         else:
   587             dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
   537             dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
   588     return [d for d in dirs if os.path.isdir(d)]
   538     return [d for d in dirs if os.path.isdir(d)]
   589 
   539 
   590 def install_setuptools(py_executable, unzip=False,
       
   591                        search_dirs=None, never_download=False):
       
   592     _install_req(py_executable, unzip,
       
   593                  search_dirs=search_dirs, never_download=never_download)
       
   594 
       
   595 def install_distribute(py_executable, unzip=False,
       
   596                        search_dirs=None, never_download=False):
       
   597     _install_req(py_executable, unzip, distribute=True,
       
   598                  search_dirs=search_dirs, never_download=never_download)
       
   599 
       
   600 _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
       
   601 def install_pip(py_executable, search_dirs=None, never_download=False):
       
   602     if search_dirs is None:
       
   603         search_dirs = file_search_dirs()
       
   604 
       
   605     filenames = []
       
   606     for dir in search_dirs:
       
   607         filenames.extend([join(dir, fn) for fn in os.listdir(dir)
       
   608                           if _pip_re.search(fn)])
       
   609     filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
       
   610     filenames.sort()
       
   611     filenames = [filename for basename, i, filename in filenames]
       
   612     if not filenames:
       
   613         filename = 'pip'
       
   614     else:
       
   615         filename = filenames[-1]
       
   616     easy_install_script = 'easy_install'
       
   617     if sys.platform == 'win32':
       
   618         easy_install_script = 'easy_install-script.py'
       
   619     cmd = [join(os.path.dirname(py_executable), easy_install_script), filename]
       
   620     if sys.platform == 'win32':
       
   621         cmd.insert(0, py_executable)
       
   622     if filename == 'pip':
       
   623         if never_download:
       
   624             logger.fatal("Can't find any local distributions of pip to install "
       
   625                          "and --never-download is set.  Either re-run virtualenv "
       
   626                          "without the --never-download option, or place a pip "
       
   627                          "source distribution (zip/tar.gz/tar.bz2) in one of these "
       
   628                          "locations: %r" % search_dirs)
       
   629             sys.exit(1)
       
   630         logger.info('Installing pip from network...')
       
   631     else:
       
   632         logger.info('Installing existing %s distribution: %s' % (
       
   633                 os.path.basename(filename), filename))
       
   634     logger.start_progress('Installing pip...')
       
   635     logger.indent += 2
       
   636     def _filter_setup(line):
       
   637         return filter_ez_setup(line, 'pip')
       
   638     try:
       
   639         call_subprocess(cmd, show_stdout=False,
       
   640                         filter_stdout=_filter_setup)
       
   641     finally:
       
   642         logger.indent -= 2
       
   643         logger.end_progress()
       
   644 
       
   645 def filter_ez_setup(line, project_name='setuptools'):
       
   646     if not line.strip():
       
   647         return Logger.DEBUG
       
   648     if project_name == 'distribute':
       
   649         for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
       
   650                        'Scanning', 'Setuptools', 'Egg', 'Already',
       
   651                        'running', 'writing', 'reading', 'installing',
       
   652                        'creating', 'copying', 'byte-compiling', 'removing',
       
   653                        'Processing'):
       
   654             if line.startswith(prefix):
       
   655                 return Logger.DEBUG
       
   656         return Logger.DEBUG
       
   657     for prefix in ['Reading ', 'Best match', 'Processing setuptools',
       
   658                    'Copying setuptools', 'Adding setuptools',
       
   659                    'Installing ', 'Installed ']:
       
   660         if line.startswith(prefix):
       
   661             return Logger.DEBUG
       
   662     return Logger.INFO
       
   663 
       
   664 
   540 
   665 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
   541 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
   666     """
   542     """
   667     Custom help formatter for use in ConfigOptionParser that updates
   543     Custom help formatter for use in ConfigOptionParser that updates
   668     the defaults before expanding them, allowing them to show up correctly
   544     the defaults before expanding them, allowing them to show up correctly
   674         return optparse.IndentedHelpFormatter.expand_default(self, option)
   550         return optparse.IndentedHelpFormatter.expand_default(self, option)
   675 
   551 
   676 
   552 
   677 class ConfigOptionParser(optparse.OptionParser):
   553 class ConfigOptionParser(optparse.OptionParser):
   678     """
   554     """
   679     Custom option parser which updates its defaults by by checking the
   555     Custom option parser which updates its defaults by checking the
   680     configuration files and environmental variables
   556     configuration files and environmental variables
   681     """
   557     """
   682     def __init__(self, *args, **kwargs):
   558     def __init__(self, *args, **kwargs):
   683         self.config = ConfigParser.RawConfigParser()
   559         self.config = ConfigParser.RawConfigParser()
   684         self.files = self.get_config_files()
   560         self.files = self.get_config_files()
   716                 # handle multiline configs
   592                 # handle multiline configs
   717                 if option.action == 'append':
   593                 if option.action == 'append':
   718                     val = val.split()
   594                     val = val.split()
   719                 else:
   595                 else:
   720                     option.nargs = 1
   596                     option.nargs = 1
   721                 if option.action in ('store_true', 'store_false', 'count'):
   597                 if option.action == 'store_false':
       
   598                     val = not strtobool(val)
       
   599                 elif option.action in ('store_true', 'count'):
   722                     val = strtobool(val)
   600                     val = strtobool(val)
   723                 try:
   601                 try:
   724                     val = option.convert_value(key, val)
   602                     val = option.convert_value(key, val)
   725                 except optparse.OptionValueError:
   603                 except optparse.OptionValueError:
   726                     e = sys.exc_info()[1]
   604                     e = sys.exc_info()[1]
   752         """
   630         """
   753         if not self.process_default_values:
   631         if not self.process_default_values:
   754             # Old, pre-Optik 1.5 behaviour.
   632             # Old, pre-Optik 1.5 behaviour.
   755             return optparse.Values(self.defaults)
   633             return optparse.Values(self.defaults)
   756 
   634 
   757         defaults = self.update_defaults(self.defaults.copy()) # ours
   635         defaults = self.update_defaults(self.defaults.copy())  # ours
   758         for option in self._get_all_options():
   636         for option in self._get_all_options():
   759             default = defaults.get(option.dest)
   637             default = defaults.get(option.dest)
   760             if isinstance(default, basestring):
   638             if isinstance(default, basestring):
   761                 opt_str = option.get_opt_string()
   639                 opt_str = option.get_opt_string()
   762                 defaults[option.dest] = option.check_value(opt_str, default)
   640                 defaults[option.dest] = option.check_value(opt_str, default)
   772     parser.add_option(
   650     parser.add_option(
   773         '-v', '--verbose',
   651         '-v', '--verbose',
   774         action='count',
   652         action='count',
   775         dest='verbose',
   653         dest='verbose',
   776         default=0,
   654         default=0,
   777         help="Increase verbosity")
   655         help="Increase verbosity.")
   778 
   656 
   779     parser.add_option(
   657     parser.add_option(
   780         '-q', '--quiet',
   658         '-q', '--quiet',
   781         action='count',
   659         action='count',
   782         dest='quiet',
   660         dest='quiet',
   783         default=0,
   661         default=0,
   784         help='Decrease verbosity')
   662         help='Decrease verbosity.')
   785 
   663 
   786     parser.add_option(
   664     parser.add_option(
   787         '-p', '--python',
   665         '-p', '--python',
   788         dest='python',
   666         dest='python',
   789         metavar='PYTHON_EXE',
   667         metavar='PYTHON_EXE',
   793 
   671 
   794     parser.add_option(
   672     parser.add_option(
   795         '--clear',
   673         '--clear',
   796         dest='clear',
   674         dest='clear',
   797         action='store_true',
   675         action='store_true',
   798         help="Clear out the non-root install and start from scratch")
   676         help="Clear out the non-root install and start from scratch.")
   799 
   677 
       
   678     parser.set_defaults(system_site_packages=False)
   800     parser.add_option(
   679     parser.add_option(
   801         '--no-site-packages',
   680         '--no-site-packages',
   802         dest='no_site_packages',
   681         dest='system_site_packages',
   803         action='store_true',
   682         action='store_false',
   804         help="Don't give access to the global site-packages dir to the "
   683         help="DEPRECATED. Retained only for backward compatibility. "
   805              "virtual environment")
   684              "Not having access to global site-packages is now the default behavior.")
   806 
   685 
   807     parser.add_option(
   686     parser.add_option(
   808         '--system-site-packages',
   687         '--system-site-packages',
   809         dest='system_site_packages',
   688         dest='system_site_packages',
   810         action='store_true',
   689         action='store_true',
   811         help="Give access to the global site-packages dir to the "
   690         help="Give the virtual environment access to the global site-packages.")
   812              "virtual environment")
   691 
       
   692     parser.add_option(
       
   693         '--always-copy',
       
   694         dest='symlink',
       
   695         action='store_false',
       
   696         default=True,
       
   697         help="Always copy files rather than symlinking.")
   813 
   698 
   814     parser.add_option(
   699     parser.add_option(
   815         '--unzip-setuptools',
   700         '--unzip-setuptools',
   816         dest='unzip_setuptools',
   701         dest='unzip_setuptools',
   817         action='store_true',
   702         action='store_true',
   818         help="Unzip Setuptools or Distribute when installing it")
   703         help="Unzip Setuptools when installing it.")
   819 
   704 
   820     parser.add_option(
   705     parser.add_option(
   821         '--relocatable',
   706         '--relocatable',
   822         dest='relocatable',
   707         dest='relocatable',
   823         action='store_true',
   708         action='store_true',
   824         help='Make an EXISTING virtualenv environment relocatable.  '
   709         help='Make an EXISTING virtualenv environment relocatable. '
   825         'This fixes up scripts and makes all .pth files relative')
   710              'This fixes up scripts and makes all .pth files relative.')
   826 
   711 
   827     parser.add_option(
   712     parser.add_option(
   828         '--distribute',
   713         '--no-setuptools',
   829         dest='use_distribute',
   714         dest='no_setuptools',
   830         action='store_true',
   715         action='store_true',
   831         help='Use Distribute instead of Setuptools. Set environ variable '
   716         help='Do not install setuptools (or pip) in the new virtualenv.')
   832         'VIRTUALENV_DISTRIBUTE to make it the default ')
   717 
       
   718     parser.add_option(
       
   719         '--no-pip',
       
   720         dest='no_pip',
       
   721         action='store_true',
       
   722         help='Do not install pip in the new virtualenv.')
   833 
   723 
   834     default_search_dirs = file_search_dirs()
   724     default_search_dirs = file_search_dirs()
   835     parser.add_option(
   725     parser.add_option(
   836         '--extra-search-dir',
   726         '--extra-search-dir',
   837         dest="search_dirs",
   727         dest="search_dirs",
   838         action="append",
   728         action="append",
       
   729         metavar='DIR',
   839         default=default_search_dirs,
   730         default=default_search_dirs,
   840         help="Directory to look for setuptools/distribute/pip distributions in. "
   731         help="Directory to look for setuptools/pip distributions in. "
   841         "You can add any number of additional --extra-search-dir paths.")
   732               "This option can be used multiple times.")
   842 
   733 
   843     parser.add_option(
   734     parser.add_option(
   844         '--never-download',
   735         '--never-download',
   845         dest="never_download",
   736         dest="never_download",
   846         action="store_true",
   737         action="store_true",
   847         help="Never download anything from the network.  Instead, virtualenv will fail "
   738         default=True,
   848         "if local distributions of setuptools/distribute/pip are not present.")
   739         help="DEPRECATED. Retained only for backward compatibility. This option has no effect. "
       
   740               "Virtualenv never downloads pip or setuptools.")
   849 
   741 
   850     parser.add_option(
   742     parser.add_option(
   851         '--prompt=',
   743         '--prompt',
   852         dest='prompt',
   744         dest='prompt',
   853         help='Provides an alternative prompt prefix for this environment')
   745         help='Provides an alternative prompt prefix for this environment.')
       
   746 
       
   747     parser.add_option(
       
   748         '--setuptools',
       
   749         dest='setuptools',
       
   750         action='store_true',
       
   751         help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
       
   752 
       
   753     parser.add_option(
       
   754         '--distribute',
       
   755         dest='distribute',
       
   756         action='store_true',
       
   757         help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
   854 
   758 
   855     if 'extend_parser' in globals():
   759     if 'extend_parser' in globals():
   856         extend_parser(parser)
   760         extend_parser(parser)
   857 
   761 
   858     options, args = parser.parse_args()
   762     options, args = parser.parse_args()
   861 
   765 
   862     if 'adjust_options' in globals():
   766     if 'adjust_options' in globals():
   863         adjust_options(options, args)
   767         adjust_options(options, args)
   864 
   768 
   865     verbosity = options.verbose - options.quiet
   769     verbosity = options.verbose - options.quiet
   866     logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
   770     logger = Logger([(Logger.level_for_integer(2 - verbosity), sys.stdout)])
   867 
   771 
   868     if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
   772     if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
   869         env = os.environ.copy()
   773         env = os.environ.copy()
   870         interpreter = resolve_interpreter(options.python)
   774         interpreter = resolve_interpreter(options.python)
   871         if interpreter == sys.executable:
   775         if interpreter == sys.executable:
   877             if file.endswith('.pyc'):
   781             if file.endswith('.pyc'):
   878                 file = file[:-1]
   782                 file = file[:-1]
   879             popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
   783             popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
   880             raise SystemExit(popen.wait())
   784             raise SystemExit(popen.wait())
   881 
   785 
   882     # Force --distribute on Python 3, since setuptools is not available.
       
   883     if majver > 2:
       
   884         options.use_distribute = True
       
   885 
       
   886     if os.environ.get('PYTHONDONTWRITEBYTECODE') and not options.use_distribute:
       
   887         print(
       
   888             "The PYTHONDONTWRITEBYTECODE environment variable is "
       
   889             "not compatible with setuptools. Either use --distribute "
       
   890             "or unset PYTHONDONTWRITEBYTECODE.")
       
   891         sys.exit(2)
       
   892     if not args:
   786     if not args:
   893         print('You must provide a DEST_DIR')
   787         print('You must provide a DEST_DIR')
   894         parser.print_help()
   788         parser.print_help()
   895         sys.exit(2)
   789         sys.exit(2)
   896     if len(args) > 1:
   790     if len(args) > 1:
   912 
   806 
   913     if options.relocatable:
   807     if options.relocatable:
   914         make_environment_relocatable(home_dir)
   808         make_environment_relocatable(home_dir)
   915         return
   809         return
   916 
   810 
   917     if options.no_site_packages:
   811     if not options.never_download:
   918         logger.warn('The --no-site-packages flag is deprecated; it is now '
   812         logger.warn('The --never-download option is for backward compatibility only.')
   919                     'the default behavior.')
   813         logger.warn('Setting it to false is no longer supported, and will be ignored.')
   920 
   814 
   921     create_environment(home_dir,
   815     create_environment(home_dir,
   922                        site_packages=options.system_site_packages,
   816                        site_packages=options.system_site_packages,
   923                        clear=options.clear,
   817                        clear=options.clear,
   924                        unzip_setuptools=options.unzip_setuptools,
   818                        unzip_setuptools=options.unzip_setuptools,
   925                        use_distribute=options.use_distribute,
       
   926                        prompt=options.prompt,
   819                        prompt=options.prompt,
   927                        search_dirs=options.search_dirs,
   820                        search_dirs=options.search_dirs,
   928                        never_download=options.never_download)
   821                        never_download=True,
       
   822                        no_setuptools=options.no_setuptools,
       
   823                        no_pip=options.no_pip,
       
   824                        symlink=options.symlink)
   929     if 'after_install' in globals():
   825     if 'after_install' in globals():
   930         after_install(options, home_dir)
   826         after_install(options, home_dir)
   931 
   827 
   932 def call_subprocess(cmd, show_stdout=True,
   828 def call_subprocess(cmd, show_stdout=True,
   933                     filter_stdout=None, cwd=None,
   829                     filter_stdout=None, cwd=None,
  1007         else:
   903         else:
  1008             logger.warn(
   904             logger.warn(
  1009                 "Command %s had error code %s"
   905                 "Command %s had error code %s"
  1010                 % (cmd_desc, proc.returncode))
   906                 % (cmd_desc, proc.returncode))
  1011 
   907 
       
   908 def filter_install_output(line):
       
   909     if line.strip().startswith('running'):
       
   910         return Logger.INFO
       
   911     return Logger.DEBUG
       
   912 
       
   913 def find_wheels(projects, search_dirs):
       
   914     """Find wheels from which we can import PROJECTS.
       
   915 
       
   916     Scan through SEARCH_DIRS for a wheel for each PROJECT in turn. Return
       
   917     a list of the first wheel found for each PROJECT
       
   918     """
       
   919 
       
   920     wheels = []
       
   921 
       
   922     # Look through SEARCH_DIRS for the first suitable wheel. Don't bother
       
   923     # about version checking here, as this is simply to get something we can
       
   924     # then use to install the correct version.
       
   925     for project in projects:
       
   926         for dirname in search_dirs:
       
   927             # This relies on only having "universal" wheels available.
       
   928             # The pattern could be tightened to require -py2.py3-none-any.whl.
       
   929             files = glob.glob(os.path.join(dirname, project + '-*.whl'))
       
   930             if files:
       
   931                 wheels.append(os.path.abspath(files[0]))
       
   932                 break
       
   933         else:
       
   934             # We're out of luck, so quit with a suitable error
       
   935             logger.fatal('Cannot find a wheel for %s' % (project,))
       
   936 
       
   937     return wheels
       
   938 
       
   939 def install_wheel(project_names, py_executable, search_dirs=None):
       
   940     if search_dirs is None:
       
   941         search_dirs = file_search_dirs()
       
   942 
       
   943     wheels = find_wheels(['setuptools', 'pip'], search_dirs)
       
   944     pythonpath = os.pathsep.join(wheels)
       
   945     findlinks = ' '.join(search_dirs)
       
   946 
       
   947     cmd = [
       
   948         py_executable, '-c',
       
   949         'import sys, pip; sys.exit(pip.main(["install", "--ignore-installed"] + sys.argv[1:]))',
       
   950     ] + project_names
       
   951     logger.start_progress('Installing %s...' % (', '.join(project_names)))
       
   952     logger.indent += 2
       
   953     try:
       
   954         call_subprocess(cmd, show_stdout=False,
       
   955             extra_env = {
       
   956                 'PYTHONPATH': pythonpath,
       
   957                 'PIP_FIND_LINKS': findlinks,
       
   958                 'PIP_USE_WHEEL': '1',
       
   959                 'PIP_PRE': '1',
       
   960                 'PIP_NO_INDEX': '1'
       
   961             }
       
   962         )
       
   963     finally:
       
   964         logger.indent -= 2
       
   965         logger.end_progress()
  1012 
   966 
  1013 def create_environment(home_dir, site_packages=False, clear=False,
   967 def create_environment(home_dir, site_packages=False, clear=False,
  1014                        unzip_setuptools=False, use_distribute=False,
   968                        unzip_setuptools=False,
  1015                        prompt=None, search_dirs=None, never_download=False):
   969                        prompt=None, search_dirs=None, never_download=False,
       
   970                        no_setuptools=False, no_pip=False, symlink=True):
  1016     """
   971     """
  1017     Creates a new environment in ``home_dir``.
   972     Creates a new environment in ``home_dir``.
  1018 
   973 
  1019     If ``site_packages`` is true, then the global ``site-packages/``
   974     If ``site_packages`` is true, then the global ``site-packages/``
  1020     directory will be on the path.
   975     directory will be on the path.
  1024     """
   979     """
  1025     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
   980     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1026 
   981 
  1027     py_executable = os.path.abspath(install_python(
   982     py_executable = os.path.abspath(install_python(
  1028         home_dir, lib_dir, inc_dir, bin_dir,
   983         home_dir, lib_dir, inc_dir, bin_dir,
  1029         site_packages=site_packages, clear=clear))
   984         site_packages=site_packages, clear=clear, symlink=symlink))
  1030 
   985 
  1031     install_distutils(home_dir)
   986     install_distutils(home_dir)
  1032 
   987 
  1033     # use_distribute also is True if VIRTUALENV_DISTRIBUTE env var is set
   988     if not no_setuptools:
  1034     # we also check VIRTUALENV_USE_DISTRIBUTE for backwards compatibility
   989         to_install = ['setuptools']
  1035     if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
   990         if not no_pip:
  1036         install_distribute(py_executable, unzip=unzip_setuptools,
   991             to_install.append('pip')
  1037                            search_dirs=search_dirs, never_download=never_download)
   992         install_wheel(to_install, py_executable, search_dirs)
  1038     else:
       
  1039         install_setuptools(py_executable, unzip=unzip_setuptools,
       
  1040                            search_dirs=search_dirs, never_download=never_download)
       
  1041 
       
  1042     install_pip(py_executable, search_dirs=search_dirs, never_download=never_download)
       
  1043 
   993 
  1044     install_activate(home_dir, bin_dir, prompt)
   994     install_activate(home_dir, bin_dir, prompt)
       
   995 
       
   996 def is_executable_file(fpath):
       
   997     return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
  1045 
   998 
  1046 def path_locations(home_dir):
   999 def path_locations(home_dir):
  1047     """Return the path locations for the environment (where libraries are,
  1000     """Return the path locations for the environment (where libraries are,
  1048     where scripts go, etc)"""
  1001     where scripts go, etc)"""
  1049     # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  1002     # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  1050     # prefix arg is broken: http://bugs.python.org/issue3386
  1003     # prefix arg is broken: http://bugs.python.org/issue3386
  1051     if sys.platform == 'win32':
  1004     if is_win:
  1052         # Windows has lots of problems with executables with spaces in
  1005         # Windows has lots of problems with executables with spaces in
  1053         # the name; this function will remove them (using the ~1
  1006         # the name; this function will remove them (using the ~1
  1054         # format):
  1007         # format):
  1055         mkdir(home_dir)
  1008         mkdir(home_dir)
  1056         if ' ' in home_dir:
  1009         if ' ' in home_dir:
       
  1010             import ctypes
       
  1011             GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW
       
  1012             size = max(len(home_dir)+1, 256)
       
  1013             buf = ctypes.create_unicode_buffer(size)
  1057             try:
  1014             try:
  1058                 import win32api
  1015                 u = unicode
  1059             except ImportError:
  1016             except NameError:
       
  1017                 u = str
       
  1018             ret = GetShortPathName(u(home_dir), buf, size)
       
  1019             if not ret:
  1060                 print('Error: the path "%s" has a space in it' % home_dir)
  1020                 print('Error: the path "%s" has a space in it' % home_dir)
  1061                 print('To handle these kinds of paths, the win32api module must be installed:')
  1021                 print('We could not determine the short pathname for it.')
  1062                 print('  http://sourceforge.net/projects/pywin32/')
  1022                 print('Exiting.')
  1063                 sys.exit(3)
  1023                 sys.exit(3)
  1064             home_dir = win32api.GetShortPathName(home_dir)
  1024             home_dir = str(buf.value)
  1065         lib_dir = join(home_dir, 'Lib')
  1025         lib_dir = join(home_dir, 'Lib')
  1066         inc_dir = join(home_dir, 'Include')
  1026         inc_dir = join(home_dir, 'Include')
  1067         bin_dir = join(home_dir, 'Scripts')
  1027         bin_dir = join(home_dir, 'Scripts')
  1068     elif is_jython:
  1028     if is_jython:
  1069         lib_dir = join(home_dir, 'Lib')
  1029         lib_dir = join(home_dir, 'Lib')
  1070         inc_dir = join(home_dir, 'Include')
  1030         inc_dir = join(home_dir, 'Include')
  1071         bin_dir = join(home_dir, 'bin')
  1031         bin_dir = join(home_dir, 'bin')
  1072     elif is_pypy:
  1032     elif is_pypy:
  1073         lib_dir = home_dir
  1033         lib_dir = home_dir
  1074         inc_dir = join(home_dir, 'include')
  1034         inc_dir = join(home_dir, 'include')
  1075         bin_dir = join(home_dir, 'bin')
  1035         bin_dir = join(home_dir, 'bin')
  1076     else:
  1036     elif not is_win:
  1077         lib_dir = join(home_dir, 'lib', py_version)
  1037         lib_dir = join(home_dir, 'lib', py_version)
  1078         inc_dir = join(home_dir, 'include', py_version + abiflags)
  1038         multiarch_exec = '/usr/bin/multiarch-platform'
       
  1039         if is_executable_file(multiarch_exec):
       
  1040             # In Mageia (2) and Mandriva distros the include dir must be like:
       
  1041             # virtualenv/include/multiarch-x86_64-linux/python2.7
       
  1042             # instead of being virtualenv/include/python2.7
       
  1043             p = subprocess.Popen(multiarch_exec, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       
  1044             stdout, stderr = p.communicate()
       
  1045             # stdout.strip is needed to remove newline character
       
  1046             inc_dir = join(home_dir, 'include', stdout.strip(), py_version + abiflags)
       
  1047         else:
       
  1048             inc_dir = join(home_dir, 'include', py_version + abiflags)
  1079         bin_dir = join(home_dir, 'bin')
  1049         bin_dir = join(home_dir, 'bin')
  1080     return home_dir, lib_dir, inc_dir, bin_dir
  1050     return home_dir, lib_dir, inc_dir, bin_dir
  1081 
  1051 
  1082 
  1052 
  1083 def change_prefix(filename, dst_prefix):
  1053 def change_prefix(filename, dst_prefix):
  1084     prefixes = [sys.prefix]
  1054     prefixes = [sys.prefix]
  1085 
  1055 
  1086     if sys.platform == "darwin":
  1056     if is_darwin:
  1087         prefixes.extend((
  1057         prefixes.extend((
  1088             os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  1058             os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  1089             os.path.join(sys.prefix, "Extras", "lib", "python"),
  1059             os.path.join(sys.prefix, "Extras", "lib", "python"),
  1090             os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
  1060             os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"),
       
  1061             # Python 2.6 no-frameworks
       
  1062             os.path.join("~", ".local", "lib","python", sys.version[:3], "site-packages"),
       
  1063             # System Python 2.7 on OSX Mountain Lion
       
  1064             os.path.join("~", "Library", "Python", sys.version[:3], "lib", "python", "site-packages")))
  1091 
  1065 
  1092     if hasattr(sys, 'real_prefix'):
  1066     if hasattr(sys, 'real_prefix'):
  1093         prefixes.append(sys.real_prefix)
  1067         prefixes.append(sys.real_prefix)
       
  1068     if hasattr(sys, 'base_prefix'):
       
  1069         prefixes.append(sys.base_prefix)
       
  1070     prefixes = list(map(os.path.expanduser, prefixes))
  1094     prefixes = list(map(os.path.abspath, prefixes))
  1071     prefixes = list(map(os.path.abspath, prefixes))
       
  1072     # Check longer prefixes first so we don't split in the middle of a filename
       
  1073     prefixes = sorted(prefixes, key=len, reverse=True)
  1095     filename = os.path.abspath(filename)
  1074     filename = os.path.abspath(filename)
  1096     for src_prefix in prefixes:
  1075     for src_prefix in prefixes:
  1097         if filename.startswith(src_prefix):
  1076         if filename.startswith(src_prefix):
  1098             _, relpath = filename.split(src_prefix, 1)
  1077             _, relpath = filename.split(src_prefix, 1)
  1099             assert relpath[0] == os.sep
  1078             if src_prefix != os.sep: # sys.prefix == "/"
  1100             relpath = relpath[1:]
  1079                 assert relpath[0] == os.sep
       
  1080                 relpath = relpath[1:]
  1101             return join(dst_prefix, relpath)
  1081             return join(dst_prefix, relpath)
  1102     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1082     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1103         (filename, prefixes)
  1083         (filename, prefixes)
  1104 
  1084 
  1105 def copy_required_modules(dst_prefix):
  1085 def copy_required_modules(dst_prefix, symlink):
  1106     import imp
  1086     import imp
  1107     # If we are running under -p, we need to remove the current
  1087     # If we are running under -p, we need to remove the current
  1108     # directory from sys.path temporarily here, so that we
  1088     # directory from sys.path temporarily here, so that we
  1109     # definitely get the modules from the site directory of
  1089     # definitely get the modules from the site directory of
  1110     # the interpreter we are running under, not the one
  1090     # the interpreter we are running under, not the one
  1123             except ImportError:
  1103             except ImportError:
  1124                 logger.info("Cannot import bootstrap module: %s" % modname)
  1104                 logger.info("Cannot import bootstrap module: %s" % modname)
  1125             else:
  1105             else:
  1126                 if f is not None:
  1106                 if f is not None:
  1127                     f.close()
  1107                     f.close()
  1128                 dst_filename = change_prefix(filename, dst_prefix)
  1108                 # special-case custom readline.so on OS X, but not for pypy:
  1129                 copyfile(filename, dst_filename)
  1109                 if modname == 'readline' and sys.platform == 'darwin' and not (
       
  1110                         is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))):
       
  1111                     dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so')
       
  1112                 elif modname == 'readline' and sys.platform == 'win32':
       
  1113                     # special-case for Windows, where readline is not a
       
  1114                     # standard module, though it may have been installed in
       
  1115                     # site-packages by a third-party package
       
  1116                     pass
       
  1117                 else:
       
  1118                     dst_filename = change_prefix(filename, dst_prefix)
       
  1119                 copyfile(filename, dst_filename, symlink)
  1130                 if filename.endswith('.pyc'):
  1120                 if filename.endswith('.pyc'):
  1131                     pyfile = filename[:-1]
  1121                     pyfile = filename[:-1]
  1132                     if os.path.exists(pyfile):
  1122                     if os.path.exists(pyfile):
  1133                         copyfile(pyfile, dst_filename[:-1])
  1123                         copyfile(pyfile, dst_filename[:-1], symlink)
  1134     finally:
  1124     finally:
  1135         sys.path = _prev_sys_path
  1125         sys.path = _prev_sys_path
  1136 
  1126 
  1137 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
  1127 
       
  1128 def subst_path(prefix_path, prefix, home_dir):
       
  1129     prefix_path = os.path.normpath(prefix_path)
       
  1130     prefix = os.path.normpath(prefix)
       
  1131     home_dir = os.path.normpath(home_dir)
       
  1132     if not prefix_path.startswith(prefix):
       
  1133         logger.warn('Path not in prefix %r %r', prefix_path, prefix)
       
  1134         return
       
  1135     return prefix_path.replace(prefix, home_dir, 1)
       
  1136 
       
  1137 
       
  1138 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, symlink=True):
  1138     """Install just the base environment, no distutils patches etc"""
  1139     """Install just the base environment, no distutils patches etc"""
  1139     if sys.executable.startswith(bin_dir):
  1140     if sys.executable.startswith(bin_dir):
  1140         print('Please use the *system* python to run this script')
  1141         print('Please use the *system* python to run this script')
  1141         return
  1142         return
  1142 
  1143 
  1147         logger.notify('Not deleting %s', bin_dir)
  1148         logger.notify('Not deleting %s', bin_dir)
  1148 
  1149 
  1149     if hasattr(sys, 'real_prefix'):
  1150     if hasattr(sys, 'real_prefix'):
  1150         logger.notify('Using real prefix %r' % sys.real_prefix)
  1151         logger.notify('Using real prefix %r' % sys.real_prefix)
  1151         prefix = sys.real_prefix
  1152         prefix = sys.real_prefix
       
  1153     elif hasattr(sys, 'base_prefix'):
       
  1154         logger.notify('Using base prefix %r' % sys.base_prefix)
       
  1155         prefix = sys.base_prefix
  1152     else:
  1156     else:
  1153         prefix = sys.prefix
  1157         prefix = sys.prefix
  1154     mkdir(lib_dir)
  1158     mkdir(lib_dir)
  1155     fix_lib64(lib_dir)
  1159     fix_lib64(lib_dir, symlink)
  1156     stdlib_dirs = [os.path.dirname(os.__file__)]
  1160     stdlib_dirs = [os.path.dirname(os.__file__)]
  1157     if sys.platform == 'win32':
  1161     if is_win:
  1158         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1162         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1159     elif sys.platform == 'darwin':
  1163     elif is_darwin:
  1160         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1164         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1161     if hasattr(os, 'symlink'):
  1165     if hasattr(os, 'symlink'):
  1162         logger.info('Symlinking Python bootstrap modules')
  1166         logger.info('Symlinking Python bootstrap modules')
  1163     else:
  1167     else:
  1164         logger.info('Copying Python bootstrap modules')
  1168         logger.info('Copying Python bootstrap modules')
  1169             if not os.path.isdir(stdlib_dir):
  1173             if not os.path.isdir(stdlib_dir):
  1170                 continue
  1174                 continue
  1171             for fn in os.listdir(stdlib_dir):
  1175             for fn in os.listdir(stdlib_dir):
  1172                 bn = os.path.splitext(fn)[0]
  1176                 bn = os.path.splitext(fn)[0]
  1173                 if fn != 'site-packages' and bn in REQUIRED_FILES:
  1177                 if fn != 'site-packages' and bn in REQUIRED_FILES:
  1174                     copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
  1178                     copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink)
  1175         # ...and modules
  1179         # ...and modules
  1176         copy_required_modules(home_dir)
  1180         copy_required_modules(home_dir, symlink)
  1177     finally:
  1181     finally:
  1178         logger.indent -= 2
  1182         logger.indent -= 2
  1179     mkdir(join(lib_dir, 'site-packages'))
  1183     mkdir(join(lib_dir, 'site-packages'))
  1180     import site
  1184     import site
  1181     site_filename = site.__file__
  1185     site_filename = site.__file__
  1188     writefile(site_filename_dst, SITE_PY)
  1192     writefile(site_filename_dst, SITE_PY)
  1189     writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1193     writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1190     site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1194     site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1191     if not site_packages:
  1195     if not site_packages:
  1192         writefile(site_packages_filename, '')
  1196         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 
  1197 
  1198     if is_pypy or is_win:
  1198     if is_pypy or is_win:
  1199         stdinc_dir = join(prefix, 'include')
  1199         stdinc_dir = join(prefix, 'include')
  1200     else:
  1200     else:
  1201         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1201         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1202     if os.path.exists(stdinc_dir):
  1202     if os.path.exists(stdinc_dir):
  1203         copyfile(stdinc_dir, inc_dir)
  1203         copyfile(stdinc_dir, inc_dir, symlink)
  1204     else:
  1204     else:
  1205         logger.debug('No include dir %s' % stdinc_dir)
  1205         logger.debug('No include dir %s' % stdinc_dir)
  1206 
  1206 
       
  1207     platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
       
  1208     if platinc_dir != stdinc_dir:
       
  1209         platinc_dest = distutils.sysconfig.get_python_inc(
       
  1210             plat_specific=1, prefix=home_dir)
       
  1211         if platinc_dir == platinc_dest:
       
  1212             # Do platinc_dest manually due to a CPython bug;
       
  1213             # not http://bugs.python.org/issue3386 but a close cousin
       
  1214             platinc_dest = subst_path(platinc_dir, prefix, home_dir)
       
  1215         if platinc_dest:
       
  1216             # PyPy's stdinc_dir and prefix are relative to the original binary
       
  1217             # (traversing virtualenvs), whereas the platinc_dir is relative to
       
  1218             # the inner virtualenv and ignores the prefix argument.
       
  1219             # This seems more evolved than designed.
       
  1220             copyfile(platinc_dir, platinc_dest, symlink)
       
  1221 
  1207     # pypy never uses exec_prefix, just ignore it
  1222     # pypy never uses exec_prefix, just ignore it
  1208     if sys.exec_prefix != prefix and not is_pypy:
  1223     if sys.exec_prefix != prefix and not is_pypy:
  1209         if sys.platform == 'win32':
  1224         if is_win:
  1210             exec_dir = join(sys.exec_prefix, 'lib')
  1225             exec_dir = join(sys.exec_prefix, 'lib')
  1211         elif is_jython:
  1226         elif is_jython:
  1212             exec_dir = join(sys.exec_prefix, 'Lib')
  1227             exec_dir = join(sys.exec_prefix, 'Lib')
  1213         else:
  1228         else:
  1214             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1229             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1215         for fn in os.listdir(exec_dir):
  1230         for fn in os.listdir(exec_dir):
  1216             copyfile(join(exec_dir, fn), join(lib_dir, fn))
  1231             copyfile(join(exec_dir, fn), join(lib_dir, fn), symlink)
  1217 
  1232 
  1218     if is_jython:
  1233     if is_jython:
  1219         # Jython has either jython-dev.jar and javalib/ dir, or just
  1234         # Jython has either jython-dev.jar and javalib/ dir, or just
  1220         # jython.jar
  1235         # jython.jar
  1221         for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1236         for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1222             src = join(prefix, name)
  1237             src = join(prefix, name)
  1223             if os.path.exists(src):
  1238             if os.path.exists(src):
  1224                 copyfile(src, join(home_dir, name))
  1239                 copyfile(src, join(home_dir, name), symlink)
  1225         # XXX: registry should always exist after Jython 2.5rc1
  1240         # XXX: registry should always exist after Jython 2.5rc1
  1226         src = join(prefix, 'registry')
  1241         src = join(prefix, 'registry')
  1227         if os.path.exists(src):
  1242         if os.path.exists(src):
  1228             copyfile(src, join(home_dir, 'registry'), symlink=False)
  1243             copyfile(src, join(home_dir, 'registry'), symlink=False)
  1229         copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1244         copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1230                  symlink=False)
  1245                  symlink=False)
  1231 
  1246 
  1232     mkdir(bin_dir)
  1247     mkdir(bin_dir)
  1233     py_executable = join(bin_dir, os.path.basename(sys.executable))
  1248     py_executable = join(bin_dir, os.path.basename(sys.executable))
  1234     if 'Python.framework' in prefix:
  1249     if 'Python.framework' in prefix:
       
  1250         # OS X framework builds cause validation to break
       
  1251         # https://github.com/pypa/virtualenv/issues/322
       
  1252         if os.environ.get('__PYVENV_LAUNCHER__'):
       
  1253             del os.environ["__PYVENV_LAUNCHER__"]
  1235         if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1254         if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1236             # The name of the python executable is not quite what
  1255             # The name of the python executable is not quite what
  1237             # we want, rename it.
  1256             # we want, rename it.
  1238             py_executable = os.path.join(
  1257             py_executable = os.path.join(
  1239                     os.path.dirname(py_executable), 'python')
  1258                     os.path.dirname(py_executable), 'python')
  1248     else:
  1267     else:
  1249         pcbuild_dir = None
  1268         pcbuild_dir = None
  1250         if os.path.exists(pyd_pth):
  1269         if os.path.exists(pyd_pth):
  1251             logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1270             logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1252             os.unlink(pyd_pth)
  1271             os.unlink(pyd_pth)
  1253         
  1272 
  1254     if sys.executable != py_executable:
  1273     if sys.executable != py_executable:
  1255         ## FIXME: could I just hard link?
  1274         ## FIXME: could I just hard link?
  1256         executable = sys.executable
  1275         executable = sys.executable
  1257         if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
       
  1258             # Cygwin misreports sys.executable sometimes
       
  1259             executable += '.exe'
       
  1260             py_executable += '.exe'
       
  1261             logger.info('Executable actually exists in %s' % executable)
       
  1262         shutil.copyfile(executable, py_executable)
  1276         shutil.copyfile(executable, py_executable)
  1263         make_exe(py_executable)
  1277         make_exe(py_executable)
  1264         if sys.platform == 'win32' or sys.platform == 'cygwin':
  1278         if is_win or is_cygwin:
  1265             pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1279             pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1266             if os.path.exists(pythonw):
  1280             if os.path.exists(pythonw):
  1267                 logger.info('Also created pythonw.exe')
  1281                 logger.info('Also created pythonw.exe')
  1268                 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  1282                 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')
  1283             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)
  1307                 logger.info('Removed %s as the source does not exist' % pythondll_d_dest)
  1294                 os.unlink(pythondll_d_dest)
  1308                 os.unlink(pythondll_d_dest)
  1295         if is_pypy:
  1309         if is_pypy:
  1296             # make a symlink python --> pypy-c
  1310             # make a symlink python --> pypy-c
  1297             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1311             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
       
  1312             if sys.platform in ('win32', 'cygwin'):
       
  1313                 python_executable += '.exe'
  1298             logger.info('Also created executable %s' % python_executable)
  1314             logger.info('Also created executable %s' % python_executable)
  1299             copyfile(py_executable, python_executable)
  1315             copyfile(py_executable, python_executable, symlink)
       
  1316 
       
  1317             if is_win:
       
  1318                 for name in 'libexpat.dll', 'libpypy.dll', 'libpypy-c.dll', 'libeay32.dll', 'ssleay32.dll', 'sqlite.dll':
       
  1319                     src = join(prefix, name)
       
  1320                     if os.path.exists(src):
       
  1321                         copyfile(src, join(bin_dir, name), symlink)
  1300 
  1322 
  1301     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1323     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1302         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1324         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1303                                      expected_exe)
  1325                                      expected_exe)
  1304         py_executable_ext = os.path.splitext(py_executable)[1]
  1326         py_executable_ext = os.path.splitext(py_executable)[1]
  1305         if py_executable_ext == '.exe':
  1327         if py_executable_ext.lower() == '.exe':
  1306             # python2.4 gives an extension of '.4' :P
  1328             # python2.4 gives an extension of '.4' :P
  1307             secondary_exe += py_executable_ext
  1329             secondary_exe += py_executable_ext
  1308         if os.path.exists(secondary_exe):
  1330         if os.path.exists(secondary_exe):
  1309             logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1331             logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1310                         % (expected_exe, secondary_exe, py_executable))
  1332                         % (expected_exe, secondary_exe, py_executable))
  1334 
  1356 
  1335         if os.path.exists(virtual_lib):
  1357         if os.path.exists(virtual_lib):
  1336             os.unlink(virtual_lib)
  1358             os.unlink(virtual_lib)
  1337         copyfile(
  1359         copyfile(
  1338             os.path.join(prefix, 'Python'),
  1360             os.path.join(prefix, 'Python'),
  1339             virtual_lib)
  1361             virtual_lib,
       
  1362             symlink)
  1340 
  1363 
  1341         # And then change the install_name of the copied python executable
  1364         # And then change the install_name of the copied python executable
  1342         try:
  1365         try:
  1343             call_subprocess(
  1366             mach_o_change(py_executable,
  1344                 ["install_name_tool", "-change",
  1367                           os.path.join(prefix, 'Python'),
  1345                  os.path.join(prefix, 'Python'),
  1368                           '@executable_path/../.Python')
  1346                  '@executable_path/../.Python',
       
  1347                  py_executable])
       
  1348         except:
  1369         except:
  1349             logger.fatal(
  1370             e = sys.exc_info()[1]
  1350                 "Could not call install_name_tool -- you must have Apple's development tools installed")
  1371             logger.warn("Could not call mach_o_change: %s. "
  1351             raise
  1372                         "Trying to call install_name_tool instead." % e)
  1352 
  1373             try:
  1353         # Some tools depend on pythonX.Y being present
  1374                 call_subprocess(
  1354         py_executable_version = '%s.%s' % (
  1375                     ["install_name_tool", "-change",
       
  1376                      os.path.join(prefix, 'Python'),
       
  1377                      '@executable_path/../.Python',
       
  1378                      py_executable])
       
  1379             except:
       
  1380                 logger.fatal("Could not call install_name_tool -- you must "
       
  1381                              "have Apple's development tools installed")
       
  1382                 raise
       
  1383 
       
  1384     if not is_win:
       
  1385         # Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
       
  1386         py_exe_version_major = 'python%s' % sys.version_info[0]
       
  1387         py_exe_version_major_minor = 'python%s.%s' % (
  1355             sys.version_info[0], sys.version_info[1])
  1388             sys.version_info[0], sys.version_info[1])
  1356         if not py_executable.endswith(py_executable_version):
  1389         py_exe_no_version = 'python'
  1357             # symlinking pythonX.Y > python
  1390         required_symlinks = [ py_exe_no_version, py_exe_version_major,
  1358             pth = py_executable + '%s.%s' % (
  1391                          py_exe_version_major_minor ]
  1359                     sys.version_info[0], sys.version_info[1])
  1392 
  1360             if os.path.exists(pth):
  1393         py_executable_base = os.path.basename(py_executable)
  1361                 os.unlink(pth)
  1394 
  1362             os.symlink('python', pth)
  1395         if py_executable_base in required_symlinks:
  1363         else:
  1396             # Don't try to symlink to yourself.
  1364             # reverse symlinking python -> pythonX.Y (with --python)
  1397             required_symlinks.remove(py_executable_base)
  1365             pth = join(bin_dir, 'python')
  1398 
  1366             if os.path.exists(pth):
  1399         for pth in required_symlinks:
  1367                 os.unlink(pth)
  1400             full_pth = join(bin_dir, pth)
  1368             os.symlink(os.path.basename(py_executable), pth)
  1401             if os.path.exists(full_pth):
  1369 
  1402                 os.unlink(full_pth)
  1370     if sys.platform == 'win32' and ' ' in py_executable:
  1403             if symlink:
       
  1404                 os.symlink(py_executable_base, full_pth)
       
  1405             else:
       
  1406                 copyfile(py_executable, full_pth, symlink)
       
  1407 
       
  1408     if is_win and ' ' in py_executable:
  1371         # There's a bug with subprocess on Windows when using a first
  1409         # 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
  1410         # argument that has a space in it.  Instead we have to quote
  1373         # the value:
  1411         # the value:
  1374         py_executable = '"%s"' % py_executable
  1412         py_executable = '"%s"' % py_executable
  1375     cmd = [py_executable, '-c', """
  1413     # NOTE: keep this check as one line, cmd.exe doesn't cope with line breaks
  1376 import sys
  1414     cmd = [py_executable, '-c', 'import sys;out=sys.stdout;'
  1377 prefix = sys.prefix
  1415         '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))
  1416     logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  1387     try:
  1417     try:
  1388         proc = subprocess.Popen(cmd,
  1418         proc = subprocess.Popen(cmd,
  1389                             stdout=subprocess.PIPE)
  1419                             stdout=subprocess.PIPE)
  1390         proc_stdout, proc_stderr = proc.communicate()
  1420         proc_stdout, proc_stderr = proc.communicate()
  1392         e = sys.exc_info()[1]
  1422         e = sys.exc_info()[1]
  1393         if e.errno == errno.EACCES:
  1423         if e.errno == errno.EACCES:
  1394             logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1424             logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1395             sys.exit(100)
  1425             sys.exit(100)
  1396         else:
  1426         else:
  1397           raise e
  1427             raise e
  1398 
  1428 
  1399     proc_stdout = proc_stdout.strip().decode("utf-8")
  1429     proc_stdout = proc_stdout.strip().decode("utf-8")
  1400     proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1430     proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1401     norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1431     norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1402     if hasattr(norm_home_dir, 'decode'):
  1432     if hasattr(norm_home_dir, 'decode'):
  1407         logger.fatal(
  1437         logger.fatal(
  1408             'ERROR: It thinks sys.prefix is %r (should be %r)'
  1438             'ERROR: It thinks sys.prefix is %r (should be %r)'
  1409             % (proc_stdout, norm_home_dir))
  1439             % (proc_stdout, norm_home_dir))
  1410         logger.fatal(
  1440         logger.fatal(
  1411             'ERROR: virtualenv is not compatible with this system or executable')
  1441             'ERROR: virtualenv is not compatible with this system or executable')
  1412         if sys.platform == 'win32':
  1442         if is_win:
  1413             logger.fatal(
  1443             logger.fatal(
  1414                 'Note: some Windows users have reported this error when they '
  1444                 'Note: some Windows users have reported this error when they '
  1415                 'installed Python for "Only this user" or have multiple '
  1445                 'installed Python for "Only this user" or have multiple '
  1416                 'versions of Python installed. Copying the appropriate '
  1446                 'versions of Python installed. Copying the appropriate '
  1417                 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1447                 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1424     if os.path.exists(pydistutils):
  1454     if os.path.exists(pydistutils):
  1425         logger.notify('Please make sure you remove any previous custom paths from '
  1455         logger.notify('Please make sure you remove any previous custom paths from '
  1426                       'your %s file.' % pydistutils)
  1456                       'your %s file.' % pydistutils)
  1427     ## FIXME: really this should be calculated earlier
  1457     ## FIXME: really this should be calculated earlier
  1428 
  1458 
  1429     fix_local_scheme(home_dir)
  1459     fix_local_scheme(home_dir, symlink)
       
  1460 
       
  1461     if site_packages:
       
  1462         if os.path.exists(site_packages_filename):
       
  1463             logger.info('Deleting %s' % site_packages_filename)
       
  1464             os.unlink(site_packages_filename)
  1430 
  1465 
  1431     return py_executable
  1466     return py_executable
       
  1467 
  1432 
  1468 
  1433 def install_activate(home_dir, bin_dir, prompt=None):
  1469 def install_activate(home_dir, bin_dir, prompt=None):
  1434     home_dir = os.path.abspath(home_dir)
  1470     home_dir = os.path.abspath(home_dir)
  1435     if sys.platform == 'win32' or is_jython and os._name == 'nt':
  1471     if is_win or is_jython and os._name == 'nt':
  1436         files = {
  1472         files = {
  1437             'activate.bat': ACTIVATE_BAT,
  1473             'activate.bat': ACTIVATE_BAT,
  1438             'deactivate.bat': DEACTIVATE_BAT,
  1474             'deactivate.bat': DEACTIVATE_BAT,
  1439             'activate.ps1': ACTIVATE_PS,
  1475             'activate.ps1': ACTIVATE_PS,
  1440         }
  1476         }
  1442         # MSYS needs paths of the form /c/path/to/file
  1478         # MSYS needs paths of the form /c/path/to/file
  1443         drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1479         drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1444         home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1480         home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1445 
  1481 
  1446         # Run-time conditional enables (basic) Cygwin compatibility
  1482         # Run-time conditional enables (basic) Cygwin compatibility
  1447         home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" % 
  1483         home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" %
  1448                        (home_dir, home_dir_msys))
  1484                        (home_dir, home_dir_msys))
  1449         files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1485         files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1450 
  1486 
  1451     else:
  1487     else:
  1452         files = {'activate': ACTIVATE_SH}
  1488         files = {'activate': ACTIVATE_SH}
  1479     ## FIXME: this is breaking things, removing for now:
  1515     ## FIXME: this is breaking things, removing for now:
  1480     #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1516     #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1481     writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1517     writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1482     writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1518     writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1483 
  1519 
  1484 def fix_local_scheme(home_dir):
  1520 def fix_local_scheme(home_dir, symlink=True):
  1485     """
  1521     """
  1486     Platforms that use the "posix_local" install scheme (like Ubuntu with
  1522     Platforms that use the "posix_local" install scheme (like Ubuntu with
  1487     Python 2.7) need to be given an additional "local" location, sigh.
  1523     Python 2.7) need to be given an additional "local" location, sigh.
  1488     """
  1524     """
  1489     try:
  1525     try:
  1496             if not os.path.exists(local_path):
  1532             if not os.path.exists(local_path):
  1497                 os.mkdir(local_path)
  1533                 os.mkdir(local_path)
  1498                 for subdir_name in os.listdir(home_dir):
  1534                 for subdir_name in os.listdir(home_dir):
  1499                     if subdir_name == 'local':
  1535                     if subdir_name == 'local':
  1500                         continue
  1536                         continue
  1501                     os.symlink(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1537                     copyfile(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1502                                                             os.path.join(local_path, subdir_name))
  1538                                                             os.path.join(local_path, subdir_name), symlink)
  1503 
  1539 
  1504 def fix_lib64(lib_dir):
  1540 def fix_lib64(lib_dir, symlink=True):
  1505     """
  1541     """
  1506     Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1542     Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1507     instead of lib/pythonX.Y.  If this is such a platform we'll just create a
  1543     instead of lib/pythonX.Y.  If this is such a platform we'll just create a
  1508     symlink so lib64 points to lib
  1544     symlink so lib64 points to lib
  1509     """
  1545     """
  1510     if [p for p in distutils.sysconfig.get_config_vars().values()
  1546     if [p for p in distutils.sysconfig.get_config_vars().values()
  1511         if isinstance(p, basestring) and 'lib64' in p]:
  1547         if isinstance(p, basestring) and 'lib64' in p]:
       
  1548         # PyPy's library path scheme is not affected by this.
       
  1549         # Return early or we will die on the following assert.
       
  1550         if is_pypy:
       
  1551             logger.debug('PyPy detected, skipping lib64 symlinking')
       
  1552             return
       
  1553 
  1512         logger.debug('This system uses lib64; symlinking lib64 to lib')
  1554         logger.debug('This system uses lib64; symlinking lib64 to lib')
       
  1555 
  1513         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1556         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1514             "Unexpected python lib dir: %r" % lib_dir)
  1557             "Unexpected python lib dir: %r" % lib_dir)
  1515         lib_parent = os.path.dirname(lib_dir)
  1558         lib_parent = os.path.dirname(lib_dir)
       
  1559         top_level = os.path.dirname(lib_parent)
       
  1560         lib_dir = os.path.join(top_level, 'lib')
       
  1561         lib64_link = os.path.join(top_level, 'lib64')
  1516         assert os.path.basename(lib_parent) == 'lib', (
  1562         assert os.path.basename(lib_parent) == 'lib', (
  1517             "Unexpected parent dir: %r" % lib_parent)
  1563             "Unexpected parent dir: %r" % lib_parent)
  1518         copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
  1564         if os.path.lexists(lib64_link):
       
  1565             return
       
  1566         cp_or_ln = (os.symlink if symlink else copyfile)
       
  1567         cp_or_ln('lib', lib64_link)
  1519 
  1568 
  1520 def resolve_interpreter(exe):
  1569 def resolve_interpreter(exe):
  1521     """
  1570     """
  1522     If the executable given isn't an absolute path, search $PATH for the interpreter
  1571     If the executable given isn't an absolute path, search $PATH for the interpreter
  1523     """
  1572     """
       
  1573     # If the "executable" is a version number, get the installed executable for
       
  1574     # that version
       
  1575     python_versions = get_installed_pythons()
       
  1576     if exe in python_versions:
       
  1577         exe = python_versions[exe]
       
  1578 
  1524     if os.path.abspath(exe) != exe:
  1579     if os.path.abspath(exe) != exe:
  1525         paths = os.environ.get('PATH', '').split(os.pathsep)
  1580         paths = os.environ.get('PATH', '').split(os.pathsep)
  1526         for path in paths:
  1581         for path in paths:
  1527             if os.path.exists(os.path.join(path, exe)):
  1582             if os.path.exists(os.path.join(path, exe)):
  1528                 exe = os.path.join(path, exe)
  1583                 exe = os.path.join(path, exe)
  1551     activate_this = os.path.join(bin_dir, 'activate_this.py')
  1606     activate_this = os.path.join(bin_dir, 'activate_this.py')
  1552     if not os.path.exists(activate_this):
  1607     if not os.path.exists(activate_this):
  1553         logger.fatal(
  1608         logger.fatal(
  1554             'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1609             'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1555             'on this environment to update it' % activate_this)
  1610             'on this environment to update it' % activate_this)
  1556     fixup_scripts(home_dir)
  1611     fixup_scripts(home_dir, bin_dir)
  1557     fixup_pth_and_egg_link(home_dir)
  1612     fixup_pth_and_egg_link(home_dir)
  1558     ## FIXME: need to fix up distutils.cfg
  1613     ## FIXME: need to fix up distutils.cfg
  1559 
  1614 
  1560 OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1615 OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1561                   'activate', 'activate.bat', 'activate_this.py']
  1616                   'activate', 'activate.bat', 'activate_this.py',
  1562 
  1617                   'activate.fish', 'activate.csh']
  1563 def fixup_scripts(home_dir):
  1618 
       
  1619 def fixup_scripts(home_dir, bin_dir):
       
  1620     if is_win:
       
  1621         new_shebang_args = (
       
  1622             '%s /c' % os.path.normcase(os.environ.get('COMSPEC', 'cmd.exe')),
       
  1623             '', '.exe')
       
  1624     else:
       
  1625         new_shebang_args = ('/usr/bin/env', sys.version[:3], '')
       
  1626 
  1564     # This is what we expect at the top of scripts:
  1627     # This is what we expect at the top of scripts:
  1565     shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  1628     shebang = '#!%s' % os.path.normcase(os.path.join(
       
  1629         os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2]))
  1566     # This is what we'll put:
  1630     # This is what we'll put:
  1567     new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  1631     new_shebang = '#!%s python%s%s' % new_shebang_args
  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"
  1632 
  1569     if sys.platform == 'win32':
       
  1570         bin_suffix = 'Scripts'
       
  1571     else:
       
  1572         bin_suffix = 'bin'
       
  1573     bin_dir = os.path.join(home_dir, bin_suffix)
       
  1574     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
       
  1575     for filename in os.listdir(bin_dir):
  1633     for filename in os.listdir(bin_dir):
  1576         filename = os.path.join(bin_dir, filename)
  1634         filename = os.path.join(bin_dir, filename)
  1577         if not os.path.isfile(filename):
  1635         if not os.path.isfile(filename):
  1578             # ignore subdirs, e.g. .svn ones.
  1636             # ignore subdirs, e.g. .svn ones.
  1579             continue
  1637             continue
  1588         finally:
  1646         finally:
  1589             f.close()
  1647             f.close()
  1590         if not lines:
  1648         if not lines:
  1591             logger.warn('Script %s is an empty file' % filename)
  1649             logger.warn('Script %s is an empty file' % filename)
  1592             continue
  1650             continue
  1593         if not lines[0].strip().startswith(shebang):
  1651 
       
  1652         old_shebang = lines[0].strip()
       
  1653         old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:])
       
  1654 
       
  1655         if not old_shebang.startswith(shebang):
  1594             if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1656             if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1595                 logger.debug('Cannot make script %s relative' % filename)
  1657                 logger.debug('Cannot make script %s relative' % filename)
  1596             elif lines[0].strip() == new_shebang:
  1658             elif lines[0].strip() == new_shebang:
  1597                 logger.info('Script %s has already been made relative' % filename)
  1659                 logger.info('Script %s has already been made relative' % filename)
  1598             else:
  1660             else:
  1599                 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1661                 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1600                             % (filename, shebang))
  1662                             % (filename, shebang))
  1601             continue
  1663             continue
  1602         logger.notify('Making script %s relative' % filename)
  1664         logger.notify('Making script %s relative' % filename)
  1603         lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
  1665         script = relative_script([new_shebang] + lines[1:])
  1604         f = open(filename, 'wb')
  1666         f = open(filename, 'wb')
  1605         f.write('\n'.join(lines).encode('utf-8'))
  1667         f.write('\n'.join(script).encode('utf-8'))
  1606         f.close()
  1668         f.close()
       
  1669 
       
  1670 def relative_script(lines):
       
  1671     "Return a script that'll work in a relocatable environment."
       
  1672     activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
       
  1673     # Find the last future statement in the script. If we insert the activation
       
  1674     # line before a future statement, Python will raise a SyntaxError.
       
  1675     activate_at = None
       
  1676     for idx, line in reversed(list(enumerate(lines))):
       
  1677         if line.split()[:3] == ['from', '__future__', 'import']:
       
  1678             activate_at = idx + 1
       
  1679             break
       
  1680     if activate_at is None:
       
  1681         # Activate after the shebang.
       
  1682         activate_at = 1
       
  1683     return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]
  1607 
  1684 
  1608 def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1685 def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1609     """Makes .pth and .egg-link files use relative paths"""
  1686     """Makes .pth and .egg-link files use relative paths"""
  1610     home_dir = os.path.normcase(os.path.abspath(home_dir))
  1687     home_dir = os.path.normcase(os.path.abspath(home_dir))
  1611     if sys_path is None:
  1688     if sys_path is None:
  1656     f.write('\n'.join(lines) + '\n')
  1733     f.write('\n'.join(lines) + '\n')
  1657     f.close()
  1734     f.close()
  1658 
  1735 
  1659 def fixup_egg_link(filename):
  1736 def fixup_egg_link(filename):
  1660     f = open(filename)
  1737     f = open(filename)
  1661     link = f.read().strip()
  1738     link = f.readline().strip()
  1662     f.close()
  1739     f.close()
  1663     if os.path.abspath(link) != link:
  1740     if os.path.abspath(link) != link:
  1664         logger.debug('Link in %s already relative' % filename)
  1741         logger.debug('Link in %s already relative' % filename)
  1665         return
  1742         return
  1666     new_link = make_relative_path(filename, link)
  1743     new_link = make_relative_path(filename, link)
  1740                                  'setup', home_dir])
  1817                                  'setup', home_dir])
  1741 
  1818 
  1742         This example immediately installs a package, and runs a setup
  1819         This example immediately installs a package, and runs a setup
  1743         script from that package.
  1820         script from that package.
  1744 
  1821 
  1745     If you provide something like ``python_version='2.4'`` then the
  1822     If you provide something like ``python_version='2.5'`` then the
  1746     script will start with ``#!/usr/bin/env python2.4`` instead of
  1823     script will start with ``#!/usr/bin/env python2.5`` instead of
  1747     ``#!/usr/bin/env python``.  You can use this when the script must
  1824     ``#!/usr/bin/env python``.  You can use this when the script must
  1748     be run with a particular Python version.
  1825     be run with a particular Python version.
  1749     """
  1826     """
  1750     filename = __file__
  1827     filename = __file__
  1751     if filename.endswith('.pyc'):
  1828     if filename.endswith('.pyc'):
  1752         filename = filename[:-1]
  1829         filename = filename[:-1]
  1753     f = open(filename, 'rb')
  1830     f = codecs.open(filename, 'r', encoding='utf-8')
  1754     content = f.read()
  1831     content = f.read()
  1755     f.close()
  1832     f.close()
  1756     py_exe = 'python%s' % python_version
  1833     py_exe = 'python%s' % python_version
  1757     content = (('#!/usr/bin/env %s\n' % py_exe)
  1834     content = (('#!/usr/bin/env %s\n' % py_exe)
  1758                + '## WARNING: This file is generated\n'
  1835                + '## WARNING: This file is generated\n'
  1765     b = base64.b64decode(s.encode('ascii'))
  1842     b = base64.b64decode(s.encode('ascii'))
  1766     return zlib.decompress(b).decode('utf-8')
  1843     return zlib.decompress(b).decode('utf-8')
  1767 
  1844 
  1768 ##file site.py
  1845 ##file site.py
  1769 SITE_PY = convert("""
  1846 SITE_PY = convert("""
  1770 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
  1905 Q7wQmAIMcman2gOwRiH4P2ts6wE=
  1982 quzUPQ65h7qnh6pNcZ9jgTFLc1s9qXhNkPk4U9AFX57zgWfoetsPX28vXxzZwwXkd3ztKBLKJhs4
  1906 """)
  1983 hv3Sycbceamk052YpRxTuh7u1ZyQsG5x5UBln2Db3qZTkrJl/2PyHBjSwHvfHzIzPbyr9wdtTC3r
  1907 
  1984 HcGUxPCJGtG0nCIejbt9MupOt1FbXSBckPQAIB0VCLAQTEc3OgmiG87yHj7Xu8FpTdfxuidMoSMV
  1908 ##file ez_setup.py
  1985 lCzmcwT3ML5fg1+7OxUSP6g7o2j6c4M2B+olB+Fm34FbjbxQyHaT0J56wwdbXACuye7v/+IB/btp
  1909 EZ_SETUP_PY = convert("""
  1986 jLb74S6/2rZ62VsHyL4sZr5iZlCLROZxBEYG9OaQtDWWSxhBx2toGjq6DNXMDfkCHT/KpsXLtmmD
  1910 eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt
  1987 Qc7sRHsA1igE/wfVIOdx
  1911 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
       
  1967 TOsyF6jViUG46+NBJqZXv+rRK7Evv2i81ZEw33DQ8y6YowH05r+BuxfN92SX3RbVP8bNymDOGnY7
       
  1968 16PfvzG+4ecrzfzkjPZya/H/ScnXyqwX/JtSrrL5pbrryu1hPKFrZzsrJD6sUuyPwDGdKerJyxmq
       
  1969 dvmdHNCrrzU/+2W0pQ6gSvPl/Mertmi+7hBlDhB80kRUqcNeJCGapHNCz1cvCFwsf0A/Ne++jGMf
       
  1970 TuOJcm6+ZnP9TRR7tWjHreOhZ6huiKnPAP2zfmqpIqHHLG/emnNhyHxSs+JJYfIwj6t2AlLdVneO
       
  1971 3Is9u0R33ef+Wv2pVizPfbUW0rGhps1FRRfnZ/2xsnr3oT2Slh2tvngsLXu6M0OgIen7ufrjprrD
       
  1972 vzXQAgNE22ualqzbyAb97uvl6qF/2a5hcU+eBzVWzOdmVjA0PXQMQoAhsulmBv39oU13134SjSlb
       
  1973 dX85nKW3umfYbtu8713Sylhb2i3v2qaoc8C7S2P3pME8uIGedi1IxXbL+adi+P2fT8Xy/m+/PrxZ
       
  1974 /TrXDcpqOMjotwdo9AJmg8r1N7BySygc+Gp+XaYdJhpV8f/7Oy3Y1s330l09YBDTjnyjn5qHGF7x
       
  1975 6O7hZfMXz21OyLZB6lUfOGAGMzo/bjaL7VaV7Ha76D/1yJVEqKmr+L2nCbH7+959wDtv38JZplQG
       
  1976 BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
       
  1977 """)
       
  1978 
       
  1979 ##file distribute_setup.py
       
  1980 DISTRIBUTE_SETUP_PY = convert("""
       
  1981 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
       
  2060 """)
  1988 """)
  2061 
  1989 
  2062 ##file activate.sh
  1990 ##file activate.sh
  2063 ACTIVATE_SH = convert("""
  1991 ACTIVATE_SH = convert("""
  2064 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
       
  2006 +n8O9H8f5vsGOWXsL1+1k3g=
  2078 """)
  2007 """)
  2079 
  2008 
  2080 ##file activate.fish
  2009 ##file activate.fish
  2081 ACTIVATE_FISH = convert("""
  2010 ACTIVATE_FISH = convert("""
  2082 eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
  2011 eJydVW2P2jgQ/s6vmAZQoVpA9/WkqqJaTou0u6x2uZVOVWWZZEKsS+yc7UDpr+84bziQbauLxEvs
  2083 Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
  2012 eXnsZ56ZIWwTYSAWKUJWGAs7hMJgBEdhEwiMKnSIsBNywUMrDtziPBYmCeBDrFUG7v8HmCTW5n8u
  2084 pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
  2013 Fu7NJJim81Bl08EQTqqAkEupLOhCgrAQCY2hTU+DQVxIiqgkRNiEBphFEKy+kd1BaFvwFOUBuIxA
  2085 lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
  2014 oy20BKtAKp3xFMo0QNtCK5mhtMEA6BmSpUELKo38TThwLfguRVNaiRgs0llnEoIR29zfstf18/bv
  2086 g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
  2015 5T17Wm7vAiiN3ONCzfbfwC3DtWXXDqHfAGX0q6z/bO82j3ebh1VwnbrduwTQbvwcRtesAfMGor/W
  2087 grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
  2016 L3fs6Xnz8LRlm9fV8/P61sM0LDNwCZjl9gSpCokJRzpryGQ5t8kNGFUt51QjOZGu0Mj35FlYlXEr
  2088 xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
  2017 yC09EVOp4lEXfF84Lz1qbhBsgl59vDedXI3rTV03xipduSgt9kLytI3XmBp3aV6MPoMQGNUU62T6
  2089 MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
  2018 uQdeefTy1Hfj10zVHg2pq8fXDoHBiOv94csfXwN49xECqWREy7pwukKfvxdMY2j23vXDPuuxxeE+
  2090 H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
  2019 JOdCOhxCE3N44B1ZeSLuZh8Mmkr2wEPAmPfKWHA2uxIRjEopdbQYjDz3BWOf14/scfmwoki1eQvX
  2091 L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
  2020 ExBdF60Mqh+Y/QcX4uiH4Amwzx79KOVFtbL63sXJbtcvy8/3q5rupmO5CnE91wBviQAhjUUegYpL
  2092 fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
  2021 vVEbpLt2/W+PklRgq5Ku6mp+rpMhhCo/lXthQTxJ2ysO4Ka0ad97S7VT/n6YXus6fzk3fLnBZW5C
  2093 pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
  2022 KDC6gSO62QDqgFqLCCtPmjegjnLeAdArtSE8VYGbAJ/aLb+vnQutFhk768E9uRbSxhCMzdgEveYw
  2094 MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
  2023 IZ5ZqFKl6+kz7UR4U+buqQZXu9SIujrAfD7f0FXpozB4Q0gwp31H9mVTZGGC4b871/wm7lvyDLu1
  2095 O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
  2024 FUyvTj/yvD66k3UPTs08x1AQQaGziOl0S1qRkPG9COtBTSTWM9NzQ4R64B+Px/l3tDzCgxv5C6Ni
  2096 7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
  2025 e+QaF9xFWrxx0V/G5uvYQOdiZzvYpQUVQSIsTr1TTghI33GnPbTA7/GCqcE3oE3GZurq4HeQXQD6
  2097 m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
  2026 32XS1ITj/qLjN72ob0hc5C9bzw8MhfmL
  2098 djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
       
  2099 mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
       
  2100 jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
       
  2101 """)
  2027 """)
  2102 
  2028 
  2103 ##file activate.csh
  2029 ##file activate.csh
  2104 ACTIVATE_CSH = convert("""
  2030 ACTIVATE_CSH = convert("""
  2105 eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
  2031 eJx9VG1P2zAQ/u5fcYQKNgTNPtN1WxlIQ4KCUEGaxuQ6yYVYSuzKdhqVX7+zk3bpy5YPUXL3PPfc
  2106 XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
  2032 ne98DLNCWshliVDV1kGCUFvMoJGugMjq2qQIiVSxSJ1cCofD1BYRnOVGV0CfZ0N2DD91DalQSjsw
  2107 kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
  2033 tQLpIJMGU1euvPe7QeJlkKzgWixlhnAt4aoUVsLnLBiy5NtbJWQ5THX1ZciYKKWwkOFaE04dUm6D
  2108 pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
  2034 r/zh7pq/3D7Nnid3/HEy+wFHY/gEJydg0aFaQrBFgz1c5DG1IhTs+UZgsBC2GMFBlaeH+8dZXwcW
  2109 sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
  2035 VPvCjXdlAvCfQsE7al0+07XjZvrSCUevR5dnkVeKlFYZmUztG4BdzL2u9KyLVabTU0bdfg7a0hgs
  2110 yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
  2036 cSmUg6UwUiQl2iHrcbcVGNvPCiLOe7+cRwG13z9qRGgx2z6DHjfm/Op2yqeT+xvOLzs0PTKHDz2V
  2111 E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
  2037 tkckFHoQfQRXoGJAj9el0FyJCmEMhzgMS4sB7KPOE2ExoLcSieYwDvR+cP8cg11gKkVJc2wRcm1g
  2112 lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
  2038 QhYFlXiTaTfO2ki0fQoiFM4tLuO4aZrhOzqR4dIPcWx17hphMBY+Srwh7RTyN83XOWkcSPh1Pg/k
  2113 r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
  2039 TXX/jbJTbMtUmcxZ+/bbqOsy82suFQg/BhdSOTRhMNBHlUarCpU7JzBhmkKmRejKOQzayQe6MWoa
       
  2040 n1wqWmuh6LZAaHxcdeqIlVLhIBJdO9/kbl0It2oEXQj+eGjJOuvOIR/YGRqvFhttUB2XTvLXYN2H
       
  2041 37CBdbW2W7j2r2+VsCn0doVWcFG1/4y1VwBjfwAyoZhD
  2114 """)
  2042 """)
  2115 
  2043 
  2116 ##file activate.bat
  2044 ##file activate.bat
  2117 ACTIVATE_BAT = convert("""
  2045 ACTIVATE_BAT = convert("""
  2118 eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
  2046 eJx9UdEKgjAUfW6wfxjiIH+hEDKUFHSKLCMI7kNOEkIf9P9pTJ3OLJ/03HPPPed4Es9XS9qqwqgT
  2119 qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
  2047 PbGKKOdXL4aAFS7A4gvAwgijuiKlqOpGlATS2NeMLE+TjJM9RkQ+SmqAXLrBo1LLIeLdiWlD6jZt
  2120 sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
  2048 r7VNubWkndkXaxg5GO3UaOOKS6drO3luDDiO5my3iA0YAKGzPRV1ack8cOdhysI0CYzIPzjSiH5X
  2121 ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
  2049 0QcvC8Lfaj0emsVKYF2rhL5L3fCkVjV76kShi59NHwDniAHzkgDgqBcwOgTMx+gDQQqXCw==
  2122 """)
  2050 """)
  2123 
  2051 
  2124 ##file deactivate.bat
  2052 ##file deactivate.bat
  2125 DEACTIVATE_BAT = convert("""
  2053 DEACTIVATE_BAT = convert("""
  2126 eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
  2054 eJxzSE3OyFfIT0vj4ipOLVEI8wwKCXX0iXf1C7Pl4spMU0hJTcvMS01RiPf3cYmHyQYE+fsGhCho
  2127 FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
  2055 cCkAAUibEkTEVhWLMlUlLk6QGixStlyaeCyJDPHw9/Pw93VFsQguim4ZXAJoIUw5DhX47XUM8UCx
  2128 i2dASrm4rFz9XLgAwJNbyQ==
  2056 EchHtwsohN1bILUgw61c/Vy4AJYPYm4=
  2129 """)
  2057 """)
  2130 
  2058 
  2131 ##file activate.ps1
  2059 ##file activate.ps1
  2132 ACTIVATE_PS = convert("""
  2060 ACTIVATE_PS = convert("""
  2133 eJylWdmS40Z2fVeE/oHT6rCloNUEAXDThB6wAyQAEjsB29GBjdgXYiWgmC/zgz/Jv+AEWNVd3S2N
  2061 eJylWdmS40Z2fVeE/oHT6rCloNUEAXDThB6wAyQAEjsB29GBjdgXYiWgmC/zgz/Jv+AEWNVd3S2N
  2219 QastYw==
  2147 QastYw==
  2220 """)
  2148 """)
  2221 
  2149 
  2222 ##file distutils-init.py
  2150 ##file distutils-init.py
  2223 DISTUTILS_INIT = convert("""
  2151 DISTUTILS_INIT = convert("""
  2224 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
  2245 5C4rFgwLGfMvJuAMew==
  2173 kzp1/+7hGBuY4pk0XD/0Ao/oTe/XGrfyM773aB7iUhgkpy+dwAMalxMP0DrBcsVw/6p25+/hobP9
       
  2174 GBknrWExDhLJ1bwt1NcCNblaFbMKCyvmX0PeRaQ=
  2246 """)
  2175 """)
  2247 
  2176 
  2248 ##file distutils.cfg
  2177 ##file distutils.cfg
  2249 DISTUTILS_CFG = convert("""
  2178 DISTUTILS_CFG = convert("""
  2250 eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  2179 eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  2264 PyRfJkZRgj+VbFv+EzHFi5pKwUEepa4JslMnwkowSRCXI+m5XvEOvtuBrxHdhLalG0JofYBok6qj
  2193 PyRfJkZRgj+VbFv+EzHFi5pKwUEepa4JslMnwkowSRCXI+m5XvEOvtuBrxHdhLalG0JofYBok6qj
  2265 YdN2dEngUlbC4PG60M1WEN0piu7Nq7on0mgyyUw3iV1etLo6r/81biWdQ9MWHFaePWZYaq+nmp+t
  2194 YdN2dEngUlbC4PG60M1WEN0piu7Nq7on0mgyyUw3iV1etLo6r/81biWdQ9MWHFaePWZYaq+nmp+t
  2266 s3az+sj7eA0jfgPfeoN1
  2195 s3az+sj7eA0jfgPfeoN1
  2267 """)
  2196 """)
  2268 
  2197 
       
  2198 MH_MAGIC = 0xfeedface
       
  2199 MH_CIGAM = 0xcefaedfe
       
  2200 MH_MAGIC_64 = 0xfeedfacf
       
  2201 MH_CIGAM_64 = 0xcffaedfe
       
  2202 FAT_MAGIC = 0xcafebabe
       
  2203 BIG_ENDIAN = '>'
       
  2204 LITTLE_ENDIAN = '<'
       
  2205 LC_LOAD_DYLIB = 0xc
       
  2206 maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint')
       
  2207 
       
  2208 
       
  2209 class fileview(object):
       
  2210     """
       
  2211     A proxy for file-like objects that exposes a given view of a file.
       
  2212     Modified from macholib.
       
  2213     """
       
  2214 
       
  2215     def __init__(self, fileobj, start=0, size=maxint):
       
  2216         if isinstance(fileobj, fileview):
       
  2217             self._fileobj = fileobj._fileobj
       
  2218         else:
       
  2219             self._fileobj = fileobj
       
  2220         self._start = start
       
  2221         self._end = start + size
       
  2222         self._pos = 0
       
  2223 
       
  2224     def __repr__(self):
       
  2225         return '<fileview [%d, %d] %r>' % (
       
  2226             self._start, self._end, self._fileobj)
       
  2227 
       
  2228     def tell(self):
       
  2229         return self._pos
       
  2230 
       
  2231     def _checkwindow(self, seekto, op):
       
  2232         if not (self._start <= seekto <= self._end):
       
  2233             raise IOError("%s to offset %d is outside window [%d, %d]" % (
       
  2234                 op, seekto, self._start, self._end))
       
  2235 
       
  2236     def seek(self, offset, whence=0):
       
  2237         seekto = offset
       
  2238         if whence == os.SEEK_SET:
       
  2239             seekto += self._start
       
  2240         elif whence == os.SEEK_CUR:
       
  2241             seekto += self._start + self._pos
       
  2242         elif whence == os.SEEK_END:
       
  2243             seekto += self._end
       
  2244         else:
       
  2245             raise IOError("Invalid whence argument to seek: %r" % (whence,))
       
  2246         self._checkwindow(seekto, 'seek')
       
  2247         self._fileobj.seek(seekto)
       
  2248         self._pos = seekto - self._start
       
  2249 
       
  2250     def write(self, bytes):
       
  2251         here = self._start + self._pos
       
  2252         self._checkwindow(here, 'write')
       
  2253         self._checkwindow(here + len(bytes), 'write')
       
  2254         self._fileobj.seek(here, os.SEEK_SET)
       
  2255         self._fileobj.write(bytes)
       
  2256         self._pos += len(bytes)
       
  2257 
       
  2258     def read(self, size=maxint):
       
  2259         assert size >= 0
       
  2260         here = self._start + self._pos
       
  2261         self._checkwindow(here, 'read')
       
  2262         size = min(size, self._end - here)
       
  2263         self._fileobj.seek(here, os.SEEK_SET)
       
  2264         bytes = self._fileobj.read(size)
       
  2265         self._pos += len(bytes)
       
  2266         return bytes
       
  2267 
       
  2268 
       
  2269 def read_data(file, endian, num=1):
       
  2270     """
       
  2271     Read a given number of 32-bits unsigned integers from the given file
       
  2272     with the given endianness.
       
  2273     """
       
  2274     res = struct.unpack(endian + 'L' * num, file.read(num * 4))
       
  2275     if len(res) == 1:
       
  2276         return res[0]
       
  2277     return res
       
  2278 
       
  2279 
       
  2280 def mach_o_change(path, what, value):
       
  2281     """
       
  2282     Replace a given name (what) in any LC_LOAD_DYLIB command found in
       
  2283     the given binary with a new name (value), provided it's shorter.
       
  2284     """
       
  2285 
       
  2286     def do_macho(file, bits, endian):
       
  2287         # Read Mach-O header (the magic number is assumed read by the caller)
       
  2288         cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = read_data(file, endian, 6)
       
  2289         # 64-bits header has one more field.
       
  2290         if bits == 64:
       
  2291             read_data(file, endian)
       
  2292         # The header is followed by ncmds commands
       
  2293         for n in range(ncmds):
       
  2294             where = file.tell()
       
  2295             # Read command header
       
  2296             cmd, cmdsize = read_data(file, endian, 2)
       
  2297             if cmd == LC_LOAD_DYLIB:
       
  2298                 # The first data field in LC_LOAD_DYLIB commands is the
       
  2299                 # offset of the name, starting from the beginning of the
       
  2300                 # command.
       
  2301                 name_offset = read_data(file, endian)
       
  2302                 file.seek(where + name_offset, os.SEEK_SET)
       
  2303                 # Read the NUL terminated string
       
  2304                 load = file.read(cmdsize - name_offset).decode()
       
  2305                 load = load[:load.index('\0')]
       
  2306                 # If the string is what is being replaced, overwrite it.
       
  2307                 if load == what:
       
  2308                     file.seek(where + name_offset, os.SEEK_SET)
       
  2309                     file.write(value.encode() + '\0'.encode())
       
  2310             # Seek to the next command
       
  2311             file.seek(where + cmdsize, os.SEEK_SET)
       
  2312 
       
  2313     def do_file(file, offset=0, size=maxint):
       
  2314         file = fileview(file, offset, size)
       
  2315         # Read magic number
       
  2316         magic = read_data(file, BIG_ENDIAN)
       
  2317         if magic == FAT_MAGIC:
       
  2318             # Fat binaries contain nfat_arch Mach-O binaries
       
  2319             nfat_arch = read_data(file, BIG_ENDIAN)
       
  2320             for n in range(nfat_arch):
       
  2321                 # Read arch header
       
  2322                 cputype, cpusubtype, offset, size, align = read_data(file, BIG_ENDIAN, 5)
       
  2323                 do_file(file, offset, size)
       
  2324         elif magic == MH_MAGIC:
       
  2325             do_macho(file, 32, BIG_ENDIAN)
       
  2326         elif magic == MH_CIGAM:
       
  2327             do_macho(file, 32, LITTLE_ENDIAN)
       
  2328         elif magic == MH_MAGIC_64:
       
  2329             do_macho(file, 64, BIG_ENDIAN)
       
  2330         elif magic == MH_CIGAM_64:
       
  2331             do_macho(file, 64, LITTLE_ENDIAN)
       
  2332 
       
  2333     assert(len(what) >= len(value))
       
  2334     do_file(open(path, 'r+b'))
       
  2335 
       
  2336 
  2269 if __name__ == '__main__':
  2337 if __name__ == '__main__':
  2270     main()
  2338     main()
  2271 
  2339 
  2272 ## TODO:
  2340 ## TODO:
  2273 ## Copy python.exe.manifest
  2341 ## Copy python.exe.manifest