virtualenv/web/virtualenv.py
changeset 101 71532a54d1c4
parent 0 81e7900b06a7
child 165 64aae3fee9d5
equal deleted inserted replaced
89:49fda47ceb16 101:71532a54d1c4
     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.10.1"
     6 # and docs/conf.py as well.
     6 virtualenv_version = __version__  # legacy
     7 __version__ = "1.9.1"  # following best practices
       
     8 virtualenv_version = __version__  # legacy, again
       
     9 
     7 
    10 import base64
     8 import base64
    11 import sys
     9 import sys
    12 import os
    10 import os
    13 import codecs
    11 import codecs
    21 import glob
    19 import glob
    22 import distutils.sysconfig
    20 import distutils.sysconfig
    23 from distutils.util import strtobool
    21 from distutils.util import strtobool
    24 import struct
    22 import struct
    25 import subprocess
    23 import subprocess
    26 
    24 import tarfile
    27 if sys.version_info < (2, 5):
    25 
       
    26 if sys.version_info < (2, 6):
    28     print('ERROR: %s' % sys.exc_info()[1])
    27     print('ERROR: %s' % sys.exc_info()[1])
    29     print('ERROR: this script requires Python 2.5 or greater.')
    28     print('ERROR: this script requires Python 2.6 or greater.')
    30     sys.exit(101)
    29     sys.exit(101)
    31 
    30 
    32 try:
    31 try:
    33     set
    32     set
    34 except NameError:
    33 except NameError:
    65 elif is_jython:
    64 elif is_jython:
    66     expected_exe = 'jython'
    65     expected_exe = 'jython'
    67 else:
    66 else:
    68     expected_exe = 'python'
    67     expected_exe = 'python'
    69 
    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
    70 
   105 
    71 REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
   106 REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
    72                     'fnmatch', 'locale', 'encodings', 'codecs',
   107                     'fnmatch', 'locale', 'encodings', 'codecs',
    73                     'stat', 'UserDict', 'readline', 'copy_reg', 'types',
   108                     'stat', 'UserDict', 'readline', 'copy_reg', 'types',
    74                     're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
   109                     're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
   405         logger.info('Creating %s', path)
   440         logger.info('Creating %s', path)
   406         os.makedirs(path)
   441         os.makedirs(path)
   407     else:
   442     else:
   408         logger.info('Directory %s already exists', path)
   443         logger.info('Directory %s already exists', path)
   409 
   444 
   410 def copyfileordir(src, dest):
   445 def copyfileordir(src, dest, symlink=True):
   411     if os.path.isdir(src):
   446     if os.path.isdir(src):
   412         shutil.copytree(src, dest, True)
   447         shutil.copytree(src, dest, symlink)
   413     else:
   448     else:
   414         shutil.copy2(src, dest)
   449         shutil.copy2(src, dest)
   415 
   450 
   416 def copyfile(src, dest, symlink=True):
   451 def copyfile(src, dest, symlink=True):
   417     if not os.path.exists(src):
   452     if not os.path.exists(src):
   420         return
   455         return
   421     if os.path.exists(dest):
   456     if os.path.exists(dest):
   422         logger.debug('File %s already exists', dest)
   457         logger.debug('File %s already exists', dest)
   423         return
   458         return
   424     if not os.path.exists(os.path.dirname(dest)):
   459     if not os.path.exists(os.path.dirname(dest)):
   425         logger.info('Creating parent directories for %s' % os.path.dirname(dest))
   460         logger.info('Creating parent directories for %s', os.path.dirname(dest))
   426         os.makedirs(os.path.dirname(dest))
   461         os.makedirs(os.path.dirname(dest))
   427     if not os.path.islink(src):
   462     if not os.path.islink(src):
   428         srcpath = os.path.abspath(src)
   463         srcpath = os.path.abspath(src)
   429     else:
   464     else:
   430         srcpath = os.readlink(src)
   465         srcpath = os.readlink(src)
   432         logger.info('Symlinking %s', dest)
   467         logger.info('Symlinking %s', dest)
   433         try:
   468         try:
   434             os.symlink(srcpath, dest)
   469             os.symlink(srcpath, dest)
   435         except (OSError, NotImplementedError):
   470         except (OSError, NotImplementedError):
   436             logger.info('Symlinking failed, copying to %s', dest)
   471             logger.info('Symlinking failed, copying to %s', dest)
   437             copyfileordir(src, dest)
   472             copyfileordir(src, dest, symlink)
   438     else:
   473     else:
   439         logger.info('Copying to %s', dest)
   474         logger.info('Copying to %s', dest)
   440         copyfileordir(src, dest)
   475         copyfileordir(src, dest, symlink)
   441 
   476 
   442 def writefile(dest, content, overwrite=True):
   477 def writefile(dest, content, overwrite=True):
   443     if not os.path.exists(dest):
   478     if not os.path.exists(dest):
   444         logger.info('Writing %s', dest)
   479         logger.info('Writing %s', dest)
   445         f = open(dest, 'wb')
   480         f = open(dest, 'wb')
   480         files = glob.glob(os.path.join(dir, filename))
   515         files = glob.glob(os.path.join(dir, filename))
   481         if files and os.path.isfile(files[0]):
   516         if files and os.path.isfile(files[0]):
   482             return True, files[0]
   517             return True, files[0]
   483     return False, filename
   518     return False, filename
   484 
   519 
   485 def _install_req(py_executable, unzip=False, distribute=False,
       
   486                  search_dirs=None, never_download=False):
       
   487 
       
   488     if search_dirs is None:
       
   489         search_dirs = file_search_dirs()
       
   490 
       
   491     if not distribute:
       
   492         egg_path = 'setuptools-*-py%s.egg' % sys.version[:3]
       
   493         found, egg_path = _find_file(egg_path, search_dirs)
       
   494         project_name = 'setuptools'
       
   495         bootstrap_script = EZ_SETUP_PY
       
   496         tgz_path = None
       
   497     else:
       
   498         # Look for a distribute egg (these are not distributed by default,
       
   499         # but can be made available by the user)
       
   500         egg_path = 'distribute-*-py%s.egg' % sys.version[:3]
       
   501         found, egg_path = _find_file(egg_path, search_dirs)
       
   502         project_name = 'distribute'
       
   503         if found:
       
   504             tgz_path = None
       
   505             bootstrap_script = DISTRIBUTE_FROM_EGG_PY
       
   506         else:
       
   507             # Fall back to sdist
       
   508             # NB: egg_path is not None iff tgz_path is None
       
   509             # iff bootstrap_script is a generic setup script accepting
       
   510             # the standard arguments.
       
   511             egg_path = None
       
   512             tgz_path = 'distribute-*.tar.gz'
       
   513             found, tgz_path = _find_file(tgz_path, search_dirs)
       
   514             bootstrap_script = DISTRIBUTE_SETUP_PY
       
   515 
       
   516     if is_jython and os._name == 'nt':
       
   517         # Jython's .bat sys.executable can't handle a command line
       
   518         # argument with newlines
       
   519         fd, ez_setup = tempfile.mkstemp('.py')
       
   520         os.write(fd, bootstrap_script)
       
   521         os.close(fd)
       
   522         cmd = [py_executable, ez_setup]
       
   523     else:
       
   524         cmd = [py_executable, '-c', bootstrap_script]
       
   525     if unzip and egg_path:
       
   526         cmd.append('--always-unzip')
       
   527     env = {}
       
   528     remove_from_env = ['__PYVENV_LAUNCHER__']
       
   529     if logger.stdout_level_matches(logger.DEBUG) and egg_path:
       
   530         cmd.append('-v')
       
   531 
       
   532     old_chdir = os.getcwd()
       
   533     if egg_path is not None and os.path.exists(egg_path):
       
   534         logger.info('Using existing %s egg: %s' % (project_name, egg_path))
       
   535         cmd.append(egg_path)
       
   536         if os.environ.get('PYTHONPATH'):
       
   537             env['PYTHONPATH'] = egg_path + os.path.pathsep + os.environ['PYTHONPATH']
       
   538         else:
       
   539             env['PYTHONPATH'] = egg_path
       
   540     elif tgz_path is not None and os.path.exists(tgz_path):
       
   541         # Found a tgz source dist, let's chdir
       
   542         logger.info('Using existing %s egg: %s' % (project_name, tgz_path))
       
   543         os.chdir(os.path.dirname(tgz_path))
       
   544         # in this case, we want to be sure that PYTHONPATH is unset (not
       
   545         # just empty, really unset), else CPython tries to import the
       
   546         # site.py that it's in virtualenv_support
       
   547         remove_from_env.append('PYTHONPATH')
       
   548     elif never_download:
       
   549         logger.fatal("Can't find any local distributions of %s to install "
       
   550                      "and --never-download is set.  Either re-run virtualenv "
       
   551                      "without the --never-download option, or place a %s "
       
   552                      "distribution (%s) in one of these "
       
   553                      "locations: %r" % (project_name, project_name,
       
   554                                         egg_path or tgz_path,
       
   555                                         search_dirs))
       
   556         sys.exit(1)
       
   557     elif egg_path:
       
   558         logger.info('No %s egg found; downloading' % project_name)
       
   559         cmd.extend(['--always-copy', '-U', project_name])
       
   560     else:
       
   561         logger.info('No %s tgz found; downloading' % project_name)
       
   562     logger.start_progress('Installing %s...' % project_name)
       
   563     logger.indent += 2
       
   564     cwd = None
       
   565     if project_name == 'distribute':
       
   566         env['DONT_PATCH_SETUPTOOLS'] = 'true'
       
   567 
       
   568     def _filter_ez_setup(line):
       
   569         return filter_ez_setup(line, project_name)
       
   570 
       
   571     if not os.access(os.getcwd(), os.W_OK):
       
   572         cwd = tempfile.mkdtemp()
       
   573         if tgz_path is not None and os.path.exists(tgz_path):
       
   574             # the current working dir is hostile, let's copy the
       
   575             # tarball to a temp dir
       
   576             target = os.path.join(cwd, os.path.split(tgz_path)[-1])
       
   577             shutil.copy(tgz_path, target)
       
   578     try:
       
   579         call_subprocess(cmd, show_stdout=False,
       
   580                         filter_stdout=_filter_ez_setup,
       
   581                         extra_env=env,
       
   582                         remove_from_env=remove_from_env,
       
   583                         cwd=cwd)
       
   584     finally:
       
   585         logger.indent -= 2
       
   586         logger.end_progress()
       
   587         if cwd is not None:
       
   588             shutil.rmtree(cwd)
       
   589         if os.getcwd() != old_chdir:
       
   590             os.chdir(old_chdir)
       
   591         if is_jython and os._name == 'nt':
       
   592             os.remove(ez_setup)
       
   593 
       
   594 def file_search_dirs():
   520 def file_search_dirs():
   595     here = os.path.dirname(os.path.abspath(__file__))
   521     here = os.path.dirname(os.path.abspath(__file__))
   596     dirs = ['.', here,
   522     dirs = ['.', here,
   597             join(here, 'virtualenv_support')]
   523             join(here, 'virtualenv_support')]
   598     if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
   524     if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
   603             pass
   529             pass
   604         else:
   530         else:
   605             dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
   531             dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
   606     return [d for d in dirs if os.path.isdir(d)]
   532     return [d for d in dirs if os.path.isdir(d)]
   607 
   533 
   608 def install_setuptools(py_executable, unzip=False,
       
   609                        search_dirs=None, never_download=False):
       
   610     _install_req(py_executable, unzip,
       
   611                  search_dirs=search_dirs, never_download=never_download)
       
   612 
       
   613 def install_distribute(py_executable, unzip=False,
       
   614                        search_dirs=None, never_download=False):
       
   615     _install_req(py_executable, unzip, distribute=True,
       
   616                  search_dirs=search_dirs, never_download=never_download)
       
   617 
       
   618 _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
       
   619 def install_pip(py_executable, search_dirs=None, never_download=False):
       
   620     if search_dirs is None:
       
   621         search_dirs = file_search_dirs()
       
   622 
       
   623     filenames = []
       
   624     for dir in search_dirs:
       
   625         filenames.extend([join(dir, fn) for fn in os.listdir(dir)
       
   626                           if _pip_re.search(fn)])
       
   627     filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
       
   628     filenames.sort()
       
   629     filenames = [filename for basename, i, filename in filenames]
       
   630     if not filenames:
       
   631         filename = 'pip'
       
   632     else:
       
   633         filename = filenames[-1]
       
   634     easy_install_script = 'easy_install'
       
   635     if is_win:
       
   636         easy_install_script = 'easy_install-script.py'
       
   637     # There's two subtle issues here when invoking easy_install.
       
   638     # 1. On unix-like systems the easy_install script can *only* be executed
       
   639     #    directly if its full filesystem path is no longer than 78 characters.
       
   640     # 2. A work around to [1] is to use the `python path/to/easy_install foo`
       
   641     #    pattern, but that breaks if the path contains non-ASCII characters, as
       
   642     #    you can't put the file encoding declaration before the shebang line.
       
   643     # The solution is to use Python's -x flag to skip the first line of the
       
   644     # script (and any ASCII decoding errors that may have occurred in that line)
       
   645     cmd = [py_executable, '-x', join(os.path.dirname(py_executable), easy_install_script), filename]
       
   646     # jython and pypy don't yet support -x
       
   647     if is_jython or is_pypy:
       
   648         cmd.remove('-x')
       
   649     if filename == 'pip':
       
   650         if never_download:
       
   651             logger.fatal("Can't find any local distributions of pip to install "
       
   652                          "and --never-download is set.  Either re-run virtualenv "
       
   653                          "without the --never-download option, or place a pip "
       
   654                          "source distribution (zip/tar.gz/tar.bz2) in one of these "
       
   655                          "locations: %r" % search_dirs)
       
   656             sys.exit(1)
       
   657         logger.info('Installing pip from network...')
       
   658     else:
       
   659         logger.info('Installing existing %s distribution: %s' % (
       
   660                 os.path.basename(filename), filename))
       
   661     logger.start_progress('Installing pip...')
       
   662     logger.indent += 2
       
   663     def _filter_setup(line):
       
   664         return filter_ez_setup(line, 'pip')
       
   665     try:
       
   666         call_subprocess(cmd, show_stdout=False,
       
   667                         filter_stdout=_filter_setup)
       
   668     finally:
       
   669         logger.indent -= 2
       
   670         logger.end_progress()
       
   671 
       
   672 def filter_ez_setup(line, project_name='setuptools'):
       
   673     if not line.strip():
       
   674         return Logger.DEBUG
       
   675     if project_name == 'distribute':
       
   676         for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
       
   677                        'Scanning', 'Setuptools', 'Egg', 'Already',
       
   678                        'running', 'writing', 'reading', 'installing',
       
   679                        'creating', 'copying', 'byte-compiling', 'removing',
       
   680                        'Processing'):
       
   681             if line.startswith(prefix):
       
   682                 return Logger.DEBUG
       
   683         return Logger.DEBUG
       
   684     for prefix in ['Reading ', 'Best match', 'Processing setuptools',
       
   685                    'Copying setuptools', 'Adding setuptools',
       
   686                    'Installing ', 'Installed ']:
       
   687         if line.startswith(prefix):
       
   688             return Logger.DEBUG
       
   689     return Logger.INFO
       
   690 
       
   691 
   534 
   692 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
   535 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
   693     """
   536     """
   694     Custom help formatter for use in ConfigOptionParser that updates
   537     Custom help formatter for use in ConfigOptionParser that updates
   695     the defaults before expanding them, allowing them to show up correctly
   538     the defaults before expanding them, allowing them to show up correctly
   701         return optparse.IndentedHelpFormatter.expand_default(self, option)
   544         return optparse.IndentedHelpFormatter.expand_default(self, option)
   702 
   545 
   703 
   546 
   704 class ConfigOptionParser(optparse.OptionParser):
   547 class ConfigOptionParser(optparse.OptionParser):
   705     """
   548     """
   706     Custom option parser which updates its defaults by by checking the
   549     Custom option parser which updates its defaults by checking the
   707     configuration files and environmental variables
   550     configuration files and environmental variables
   708     """
   551     """
   709     def __init__(self, *args, **kwargs):
   552     def __init__(self, *args, **kwargs):
   710         self.config = ConfigParser.RawConfigParser()
   553         self.config = ConfigParser.RawConfigParser()
   711         self.files = self.get_config_files()
   554         self.files = self.get_config_files()
   840         action='store_true',
   683         action='store_true',
   841         help="Give access to the global site-packages dir to the "
   684         help="Give access to the global site-packages dir to the "
   842              "virtual environment")
   685              "virtual environment")
   843 
   686 
   844     parser.add_option(
   687     parser.add_option(
       
   688         '--always-copy',
       
   689         dest='symlink',
       
   690         action='store_false',
       
   691         default=True,
       
   692         help="Always copy files rather than symlinking")
       
   693 
       
   694     parser.add_option(
   845         '--unzip-setuptools',
   695         '--unzip-setuptools',
   846         dest='unzip_setuptools',
   696         dest='unzip_setuptools',
   847         action='store_true',
   697         action='store_true',
   848         help="Unzip Setuptools or Distribute when installing it")
   698         help="Unzip Setuptools when installing it")
   849 
   699 
   850     parser.add_option(
   700     parser.add_option(
   851         '--relocatable',
   701         '--relocatable',
   852         dest='relocatable',
   702         dest='relocatable',
   853         action='store_true',
   703         action='store_true',
   854         help='Make an EXISTING virtualenv environment relocatable.  '
   704         help='Make an EXISTING virtualenv environment relocatable.  '
   855         'This fixes up scripts and makes all .pth files relative')
   705         'This fixes up scripts and makes all .pth files relative')
   856 
   706 
   857     parser.add_option(
   707     parser.add_option(
   858         '--distribute', '--use-distribute',  # the second option is for legacy reasons here. Hi Kenneth!
       
   859         dest='use_distribute',
       
   860         action='store_true',
       
   861         help='Use Distribute instead of Setuptools. Set environ variable '
       
   862         'VIRTUALENV_DISTRIBUTE to make it the default ')
       
   863 
       
   864     parser.add_option(
       
   865         '--no-setuptools',
   708         '--no-setuptools',
   866         dest='no_setuptools',
   709         dest='no_setuptools',
   867         action='store_true',
   710         action='store_true',
   868         help='Do not install distribute/setuptools (or pip) '
   711         help='Do not install setuptools (or pip) '
   869         'in the new virtualenv.')
   712         'in the new virtualenv.')
   870 
   713 
   871     parser.add_option(
   714     parser.add_option(
   872         '--no-pip',
   715         '--no-pip',
   873         dest='no_pip',
   716         dest='no_pip',
   874         action='store_true',
   717         action='store_true',
   875         help='Do not install pip in the new virtualenv.')
   718         help='Do not install pip in the new virtualenv.')
   876 
       
   877     parser.add_option(
       
   878         '--setuptools',
       
   879         dest='use_distribute',
       
   880         action='store_false',
       
   881         help='Use Setuptools instead of Distribute.  Set environ variable '
       
   882         'VIRTUALENV_SETUPTOOLS to make it the default ')
       
   883 
       
   884     # Set this to True to use distribute by default, even in Python 2.
       
   885     parser.set_defaults(use_distribute=False)
       
   886 
   719 
   887     default_search_dirs = file_search_dirs()
   720     default_search_dirs = file_search_dirs()
   888     parser.add_option(
   721     parser.add_option(
   889         '--extra-search-dir',
   722         '--extra-search-dir',
   890         dest="search_dirs",
   723         dest="search_dirs",
   891         action="append",
   724         action="append",
   892         default=default_search_dirs,
   725         default=default_search_dirs,
   893         help="Directory to look for setuptools/distribute/pip distributions in. "
   726         help="Directory to look for setuptools/pip distributions in. "
   894         "You can add any number of additional --extra-search-dir paths.")
   727         "You can add any number of additional --extra-search-dir paths.")
   895 
   728 
   896     parser.add_option(
   729     parser.add_option(
   897         '--never-download',
   730         '--never-download',
   898         dest="never_download",
   731         dest="never_download",
   899         action="store_true",
   732         action="store_true",
   900         help="Never download anything from the network.  Instead, virtualenv will fail "
   733         default=True,
   901         "if local distributions of setuptools/distribute/pip are not present.")
   734         help="Never download anything from the network. This is now always "
       
   735         "the case. The option is only retained for backward compatibility, "
       
   736         "and does nothing. Virtualenv will fail if local distributions "
       
   737         "of setuptools/pip are not present.")
   902 
   738 
   903     parser.add_option(
   739     parser.add_option(
   904         '--prompt',
   740         '--prompt',
   905         dest='prompt',
   741         dest='prompt',
   906         help='Provides an alternative prompt prefix for this environment')
   742         help='Provides an alternative prompt prefix for this environment')
       
   743 
       
   744     parser.add_option(
       
   745         '--setuptools',
       
   746         dest='setuptools',
       
   747         action='store_true',
       
   748         help="Backward compatibility. Does nothing.")
       
   749 
       
   750     parser.add_option(
       
   751         '--distribute',
       
   752         dest='distribute',
       
   753         action='store_true',
       
   754         help="Backward compatibility. Does nothing.")
   907 
   755 
   908     if 'extend_parser' in globals():
   756     if 'extend_parser' in globals():
   909         extend_parser(parser)
   757         extend_parser(parser)
   910 
   758 
   911     options, args = parser.parse_args()
   759     options, args = parser.parse_args()
   930             if file.endswith('.pyc'):
   778             if file.endswith('.pyc'):
   931                 file = file[:-1]
   779                 file = file[:-1]
   932             popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
   780             popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
   933             raise SystemExit(popen.wait())
   781             raise SystemExit(popen.wait())
   934 
   782 
   935     # Force --distribute on Python 3, since setuptools is not available.
       
   936     if majver > 2:
       
   937         options.use_distribute = True
       
   938 
       
   939     if os.environ.get('PYTHONDONTWRITEBYTECODE') and not options.use_distribute:
       
   940         print(
       
   941             "The PYTHONDONTWRITEBYTECODE environment variable is "
       
   942             "not compatible with setuptools. Either use --distribute "
       
   943             "or unset PYTHONDONTWRITEBYTECODE.")
       
   944         sys.exit(2)
       
   945     if not args:
   783     if not args:
   946         print('You must provide a DEST_DIR')
   784         print('You must provide a DEST_DIR')
   947         parser.print_help()
   785         parser.print_help()
   948         sys.exit(2)
   786         sys.exit(2)
   949     if len(args) > 1:
   787     if len(args) > 1:
   965 
   803 
   966     if options.relocatable:
   804     if options.relocatable:
   967         make_environment_relocatable(home_dir)
   805         make_environment_relocatable(home_dir)
   968         return
   806         return
   969 
   807 
       
   808     if not options.never_download:
       
   809         logger.warn('The --never-download option is for backward compatibility only.')
       
   810         logger.warn('Setting it to false is no longer supported, and will be ignored.')
       
   811 
   970     create_environment(home_dir,
   812     create_environment(home_dir,
   971                        site_packages=options.system_site_packages,
   813                        site_packages=options.system_site_packages,
   972                        clear=options.clear,
   814                        clear=options.clear,
   973                        unzip_setuptools=options.unzip_setuptools,
   815                        unzip_setuptools=options.unzip_setuptools,
   974                        use_distribute=options.use_distribute,
       
   975                        prompt=options.prompt,
   816                        prompt=options.prompt,
   976                        search_dirs=options.search_dirs,
   817                        search_dirs=options.search_dirs,
   977                        never_download=options.never_download,
   818                        never_download=True,
   978                        no_setuptools=options.no_setuptools,
   819                        no_setuptools=options.no_setuptools,
   979                        no_pip=options.no_pip)
   820                        no_pip=options.no_pip,
       
   821                        symlink=options.symlink)
   980     if 'after_install' in globals():
   822     if 'after_install' in globals():
   981         after_install(options, home_dir)
   823         after_install(options, home_dir)
   982 
   824 
   983 def call_subprocess(cmd, show_stdout=True,
   825 def call_subprocess(cmd, show_stdout=True,
   984                     filter_stdout=None, cwd=None,
   826                     filter_stdout=None, cwd=None,
  1058         else:
   900         else:
  1059             logger.warn(
   901             logger.warn(
  1060                 "Command %s had error code %s"
   902                 "Command %s had error code %s"
  1061                 % (cmd_desc, proc.returncode))
   903                 % (cmd_desc, proc.returncode))
  1062 
   904 
       
   905 def filter_install_output(line):
       
   906     if line.strip().startswith('running'):
       
   907         return Logger.INFO
       
   908     return Logger.DEBUG
       
   909 
       
   910 def install_sdist(project_name, sdist, py_executable, search_dirs=None):
       
   911 
       
   912     if search_dirs is None:
       
   913         search_dirs = file_search_dirs()
       
   914     found, sdist_path = _find_file(sdist, search_dirs)
       
   915     if not found:
       
   916         logger.fatal("Cannot find sdist %s" % (sdist,))
       
   917         return
       
   918 
       
   919     tmpdir = tempfile.mkdtemp()
       
   920     try:
       
   921         tar = tarfile.open(sdist_path)
       
   922         tar.extractall(tmpdir)
       
   923         tar.close()
       
   924         srcdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
       
   925         cmd = [py_executable, 'setup.py', 'install',
       
   926             '--single-version-externally-managed',
       
   927             '--record', 'record']
       
   928         logger.start_progress('Installing %s...' % project_name)
       
   929         logger.indent += 2
       
   930         try:
       
   931             call_subprocess(cmd, show_stdout=False, cwd=srcdir,
       
   932                     filter_stdout=filter_install_output)
       
   933         finally:
       
   934             logger.indent -= 2
       
   935             logger.end_progress()
       
   936     finally:
       
   937         shutil.rmtree(tmpdir)
  1063 
   938 
  1064 def create_environment(home_dir, site_packages=False, clear=False,
   939 def create_environment(home_dir, site_packages=False, clear=False,
  1065                        unzip_setuptools=False, use_distribute=False,
   940                        unzip_setuptools=False,
  1066                        prompt=None, search_dirs=None, never_download=False,
   941                        prompt=None, search_dirs=None, never_download=False,
  1067                        no_setuptools=False, no_pip=False):
   942                        no_setuptools=False, no_pip=False, symlink=True):
  1068     """
   943     """
  1069     Creates a new environment in ``home_dir``.
   944     Creates a new environment in ``home_dir``.
  1070 
   945 
  1071     If ``site_packages`` is true, then the global ``site-packages/``
   946     If ``site_packages`` is true, then the global ``site-packages/``
  1072     directory will be on the path.
   947     directory will be on the path.
  1076     """
   951     """
  1077     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
   952     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1078 
   953 
  1079     py_executable = os.path.abspath(install_python(
   954     py_executable = os.path.abspath(install_python(
  1080         home_dir, lib_dir, inc_dir, bin_dir,
   955         home_dir, lib_dir, inc_dir, bin_dir,
  1081         site_packages=site_packages, clear=clear))
   956         site_packages=site_packages, clear=clear, symlink=symlink))
  1082 
   957 
  1083     install_distutils(home_dir)
   958     install_distutils(home_dir)
  1084 
   959 
  1085     if not no_setuptools:
   960     if not no_setuptools:
  1086         if use_distribute:
   961         install_sdist('Setuptools', 'setuptools-*.tar.gz', py_executable, search_dirs)
  1087             install_distribute(py_executable, unzip=unzip_setuptools,
       
  1088                                search_dirs=search_dirs, never_download=never_download)
       
  1089         else:
       
  1090             install_setuptools(py_executable, unzip=unzip_setuptools,
       
  1091                                search_dirs=search_dirs, never_download=never_download)
       
  1092 
       
  1093         if not no_pip:
   962         if not no_pip:
  1094             install_pip(py_executable, search_dirs=search_dirs, never_download=never_download)
   963             install_sdist('Pip', 'pip-*.tar.gz', py_executable, search_dirs)
  1095 
   964 
  1096     install_activate(home_dir, bin_dir, prompt)
   965     install_activate(home_dir, bin_dir, prompt)
  1097 
   966 
  1098 def is_executable_file(fpath):
   967 def is_executable_file(fpath):
  1099     return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
   968     return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
  1182                 relpath = relpath[1:]
  1051                 relpath = relpath[1:]
  1183             return join(dst_prefix, relpath)
  1052             return join(dst_prefix, relpath)
  1184     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1053     assert False, "Filename %s does not start with any of these prefixes: %s" % \
  1185         (filename, prefixes)
  1054         (filename, prefixes)
  1186 
  1055 
  1187 def copy_required_modules(dst_prefix):
  1056 def copy_required_modules(dst_prefix, symlink):
  1188     import imp
  1057     import imp
  1189     # If we are running under -p, we need to remove the current
  1058     # If we are running under -p, we need to remove the current
  1190     # directory from sys.path temporarily here, so that we
  1059     # directory from sys.path temporarily here, so that we
  1191     # definitely get the modules from the site directory of
  1060     # definitely get the modules from the site directory of
  1192     # the interpreter we are running under, not the one
  1061     # the interpreter we are running under, not the one
  1209                     f.close()
  1078                     f.close()
  1210                 # special-case custom readline.so on OS X, but not for pypy:
  1079                 # special-case custom readline.so on OS X, but not for pypy:
  1211                 if modname == 'readline' and sys.platform == 'darwin' and not (
  1080                 if modname == 'readline' and sys.platform == 'darwin' and not (
  1212                         is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))):
  1081                         is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))):
  1213                     dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so')
  1082                     dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so')
       
  1083                 elif modname == 'readline' and sys.platform == 'win32':
       
  1084                     # special-case for Windows, where readline is not a
       
  1085                     # standard module, though it may have been installed in
       
  1086                     # site-packages by a third-party package
       
  1087                     pass
  1214                 else:
  1088                 else:
  1215                     dst_filename = change_prefix(filename, dst_prefix)
  1089                     dst_filename = change_prefix(filename, dst_prefix)
  1216                 copyfile(filename, dst_filename)
  1090                 copyfile(filename, dst_filename, symlink)
  1217                 if filename.endswith('.pyc'):
  1091                 if filename.endswith('.pyc'):
  1218                     pyfile = filename[:-1]
  1092                     pyfile = filename[:-1]
  1219                     if os.path.exists(pyfile):
  1093                     if os.path.exists(pyfile):
  1220                         copyfile(pyfile, dst_filename[:-1])
  1094                         copyfile(pyfile, dst_filename[:-1], symlink)
  1221     finally:
  1095     finally:
  1222         sys.path = _prev_sys_path
  1096         sys.path = _prev_sys_path
  1223 
  1097 
  1224 
  1098 
  1225 def subst_path(prefix_path, prefix, home_dir):
  1099 def subst_path(prefix_path, prefix, home_dir):
  1230         logger.warn('Path not in prefix %r %r', prefix_path, prefix)
  1104         logger.warn('Path not in prefix %r %r', prefix_path, prefix)
  1231         return
  1105         return
  1232     return prefix_path.replace(prefix, home_dir, 1)
  1106     return prefix_path.replace(prefix, home_dir, 1)
  1233 
  1107 
  1234 
  1108 
  1235 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
  1109 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, symlink=True):
  1236     """Install just the base environment, no distutils patches etc"""
  1110     """Install just the base environment, no distutils patches etc"""
  1237     if sys.executable.startswith(bin_dir):
  1111     if sys.executable.startswith(bin_dir):
  1238         print('Please use the *system* python to run this script')
  1112         print('Please use the *system* python to run this script')
  1239         return
  1113         return
  1240 
  1114 
  1251         logger.notify('Using base prefix %r' % sys.base_prefix)
  1125         logger.notify('Using base prefix %r' % sys.base_prefix)
  1252         prefix = sys.base_prefix
  1126         prefix = sys.base_prefix
  1253     else:
  1127     else:
  1254         prefix = sys.prefix
  1128         prefix = sys.prefix
  1255     mkdir(lib_dir)
  1129     mkdir(lib_dir)
  1256     fix_lib64(lib_dir)
  1130     fix_lib64(lib_dir, symlink)
  1257     stdlib_dirs = [os.path.dirname(os.__file__)]
  1131     stdlib_dirs = [os.path.dirname(os.__file__)]
  1258     if is_win:
  1132     if is_win:
  1259         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1133         stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1260     elif is_darwin:
  1134     elif is_darwin:
  1261         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1135         stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1270             if not os.path.isdir(stdlib_dir):
  1144             if not os.path.isdir(stdlib_dir):
  1271                 continue
  1145                 continue
  1272             for fn in os.listdir(stdlib_dir):
  1146             for fn in os.listdir(stdlib_dir):
  1273                 bn = os.path.splitext(fn)[0]
  1147                 bn = os.path.splitext(fn)[0]
  1274                 if fn != 'site-packages' and bn in REQUIRED_FILES:
  1148                 if fn != 'site-packages' and bn in REQUIRED_FILES:
  1275                     copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
  1149                     copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink)
  1276         # ...and modules
  1150         # ...and modules
  1277         copy_required_modules(home_dir)
  1151         copy_required_modules(home_dir, symlink)
  1278     finally:
  1152     finally:
  1279         logger.indent -= 2
  1153         logger.indent -= 2
  1280     mkdir(join(lib_dir, 'site-packages'))
  1154     mkdir(join(lib_dir, 'site-packages'))
  1281     import site
  1155     import site
  1282     site_filename = site.__file__
  1156     site_filename = site.__file__
  1295     if is_pypy or is_win:
  1169     if is_pypy or is_win:
  1296         stdinc_dir = join(prefix, 'include')
  1170         stdinc_dir = join(prefix, 'include')
  1297     else:
  1171     else:
  1298         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1172         stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1299     if os.path.exists(stdinc_dir):
  1173     if os.path.exists(stdinc_dir):
  1300         copyfile(stdinc_dir, inc_dir)
  1174         copyfile(stdinc_dir, inc_dir, symlink)
  1301     else:
  1175     else:
  1302         logger.debug('No include dir %s' % stdinc_dir)
  1176         logger.debug('No include dir %s' % stdinc_dir)
  1303 
  1177 
  1304     platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
  1178     platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
  1305     if platinc_dir != stdinc_dir:
  1179     if platinc_dir != stdinc_dir:
  1312         if platinc_dest:
  1186         if platinc_dest:
  1313             # PyPy's stdinc_dir and prefix are relative to the original binary
  1187             # PyPy's stdinc_dir and prefix are relative to the original binary
  1314             # (traversing virtualenvs), whereas the platinc_dir is relative to
  1188             # (traversing virtualenvs), whereas the platinc_dir is relative to
  1315             # the inner virtualenv and ignores the prefix argument.
  1189             # the inner virtualenv and ignores the prefix argument.
  1316             # This seems more evolved than designed.
  1190             # This seems more evolved than designed.
  1317             copyfile(platinc_dir, platinc_dest)
  1191             copyfile(platinc_dir, platinc_dest, symlink)
  1318 
  1192 
  1319     # pypy never uses exec_prefix, just ignore it
  1193     # pypy never uses exec_prefix, just ignore it
  1320     if sys.exec_prefix != prefix and not is_pypy:
  1194     if sys.exec_prefix != prefix and not is_pypy:
  1321         if is_win:
  1195         if is_win:
  1322             exec_dir = join(sys.exec_prefix, 'lib')
  1196             exec_dir = join(sys.exec_prefix, 'lib')
  1323         elif is_jython:
  1197         elif is_jython:
  1324             exec_dir = join(sys.exec_prefix, 'Lib')
  1198             exec_dir = join(sys.exec_prefix, 'Lib')
  1325         else:
  1199         else:
  1326             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1200             exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1327         for fn in os.listdir(exec_dir):
  1201         for fn in os.listdir(exec_dir):
  1328             copyfile(join(exec_dir, fn), join(lib_dir, fn))
  1202             copyfile(join(exec_dir, fn), join(lib_dir, fn), symlink)
  1329 
  1203 
  1330     if is_jython:
  1204     if is_jython:
  1331         # Jython has either jython-dev.jar and javalib/ dir, or just
  1205         # Jython has either jython-dev.jar and javalib/ dir, or just
  1332         # jython.jar
  1206         # jython.jar
  1333         for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1207         for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1334             src = join(prefix, name)
  1208             src = join(prefix, name)
  1335             if os.path.exists(src):
  1209             if os.path.exists(src):
  1336                 copyfile(src, join(home_dir, name))
  1210                 copyfile(src, join(home_dir, name), symlink)
  1337         # XXX: registry should always exist after Jython 2.5rc1
  1211         # XXX: registry should always exist after Jython 2.5rc1
  1338         src = join(prefix, 'registry')
  1212         src = join(prefix, 'registry')
  1339         if os.path.exists(src):
  1213         if os.path.exists(src):
  1340             copyfile(src, join(home_dir, 'registry'), symlink=False)
  1214             copyfile(src, join(home_dir, 'registry'), symlink=False)
  1341         copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1215         copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1407             # make a symlink python --> pypy-c
  1281             # make a symlink python --> pypy-c
  1408             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1282             python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1409             if sys.platform in ('win32', 'cygwin'):
  1283             if sys.platform in ('win32', 'cygwin'):
  1410                 python_executable += '.exe'
  1284                 python_executable += '.exe'
  1411             logger.info('Also created executable %s' % python_executable)
  1285             logger.info('Also created executable %s' % python_executable)
  1412             copyfile(py_executable, python_executable)
  1286             copyfile(py_executable, python_executable, symlink)
  1413 
  1287 
  1414             if is_win:
  1288             if is_win:
  1415                 for name in 'libexpat.dll', 'libpypy.dll', 'libpypy-c.dll', 'libeay32.dll', 'ssleay32.dll', 'sqlite.dll':
  1289                 for name in 'libexpat.dll', 'libpypy.dll', 'libpypy-c.dll', 'libeay32.dll', 'ssleay32.dll', 'sqlite.dll':
  1416                     src = join(prefix, name)
  1290                     src = join(prefix, name)
  1417                     if os.path.exists(src):
  1291                     if os.path.exists(src):
  1418                         copyfile(src, join(bin_dir, name))
  1292                         copyfile(src, join(bin_dir, name), symlink)
  1419 
  1293 
  1420     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1294     if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1421         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1295         secondary_exe = os.path.join(os.path.dirname(py_executable),
  1422                                      expected_exe)
  1296                                      expected_exe)
  1423         py_executable_ext = os.path.splitext(py_executable)[1]
  1297         py_executable_ext = os.path.splitext(py_executable)[1]
  1424         if py_executable_ext == '.exe':
  1298         if py_executable_ext.lower() == '.exe':
  1425             # python2.4 gives an extension of '.4' :P
  1299             # python2.4 gives an extension of '.4' :P
  1426             secondary_exe += py_executable_ext
  1300             secondary_exe += py_executable_ext
  1427         if os.path.exists(secondary_exe):
  1301         if os.path.exists(secondary_exe):
  1428             logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1302             logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1429                         % (expected_exe, secondary_exe, py_executable))
  1303                         % (expected_exe, secondary_exe, py_executable))
  1453 
  1327 
  1454         if os.path.exists(virtual_lib):
  1328         if os.path.exists(virtual_lib):
  1455             os.unlink(virtual_lib)
  1329             os.unlink(virtual_lib)
  1456         copyfile(
  1330         copyfile(
  1457             os.path.join(prefix, 'Python'),
  1331             os.path.join(prefix, 'Python'),
  1458             virtual_lib)
  1332             virtual_lib,
       
  1333             symlink)
  1459 
  1334 
  1460         # And then change the install_name of the copied python executable
  1335         # And then change the install_name of the copied python executable
  1461         try:
  1336         try:
  1462             mach_o_change(py_executable,
  1337             mach_o_change(py_executable,
  1463                           os.path.join(prefix, 'Python'),
  1338                           os.path.join(prefix, 'Python'),
  1494 
  1369 
  1495         for pth in required_symlinks:
  1370         for pth in required_symlinks:
  1496             full_pth = join(bin_dir, pth)
  1371             full_pth = join(bin_dir, pth)
  1497             if os.path.exists(full_pth):
  1372             if os.path.exists(full_pth):
  1498                 os.unlink(full_pth)
  1373                 os.unlink(full_pth)
  1499             os.symlink(py_executable_base, full_pth)
  1374             if symlink:
       
  1375                 os.symlink(py_executable_base, full_pth)
       
  1376             else:
       
  1377                 shutil.copyfile(py_executable_base, full_pth)
  1500 
  1378 
  1501     if is_win and ' ' in py_executable:
  1379     if is_win and ' ' in py_executable:
  1502         # There's a bug with subprocess on Windows when using a first
  1380         # There's a bug with subprocess on Windows when using a first
  1503         # argument that has a space in it.  Instead we have to quote
  1381         # argument that has a space in it.  Instead we have to quote
  1504         # the value:
  1382         # the value:
  1547     if os.path.exists(pydistutils):
  1425     if os.path.exists(pydistutils):
  1548         logger.notify('Please make sure you remove any previous custom paths from '
  1426         logger.notify('Please make sure you remove any previous custom paths from '
  1549                       'your %s file.' % pydistutils)
  1427                       'your %s file.' % pydistutils)
  1550     ## FIXME: really this should be calculated earlier
  1428     ## FIXME: really this should be calculated earlier
  1551 
  1429 
  1552     fix_local_scheme(home_dir)
  1430     fix_local_scheme(home_dir, symlink)
  1553 
  1431 
  1554     if site_packages:
  1432     if site_packages:
  1555         if os.path.exists(site_packages_filename):
  1433         if os.path.exists(site_packages_filename):
  1556             logger.info('Deleting %s' % site_packages_filename)
  1434             logger.info('Deleting %s' % site_packages_filename)
  1557             os.unlink(site_packages_filename)
  1435             os.unlink(site_packages_filename)
  1608     ## FIXME: this is breaking things, removing for now:
  1486     ## FIXME: this is breaking things, removing for now:
  1609     #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1487     #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1610     writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1488     writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1611     writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1489     writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1612 
  1490 
  1613 def fix_local_scheme(home_dir):
  1491 def fix_local_scheme(home_dir, symlink=True):
  1614     """
  1492     """
  1615     Platforms that use the "posix_local" install scheme (like Ubuntu with
  1493     Platforms that use the "posix_local" install scheme (like Ubuntu with
  1616     Python 2.7) need to be given an additional "local" location, sigh.
  1494     Python 2.7) need to be given an additional "local" location, sigh.
  1617     """
  1495     """
  1618     try:
  1496     try:
  1625             if not os.path.exists(local_path):
  1503             if not os.path.exists(local_path):
  1626                 os.mkdir(local_path)
  1504                 os.mkdir(local_path)
  1627                 for subdir_name in os.listdir(home_dir):
  1505                 for subdir_name in os.listdir(home_dir):
  1628                     if subdir_name == 'local':
  1506                     if subdir_name == 'local':
  1629                         continue
  1507                         continue
  1630                     os.symlink(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1508                     cp_or_ln = (os.symlink if symlink else copyfile)
       
  1509                     cp_or_ln(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1631                                                             os.path.join(local_path, subdir_name))
  1510                                                             os.path.join(local_path, subdir_name))
  1632 
  1511 
  1633 def fix_lib64(lib_dir):
  1512 def fix_lib64(lib_dir, symlink=True):
  1634     """
  1513     """
  1635     Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1514     Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1636     instead of lib/pythonX.Y.  If this is such a platform we'll just create a
  1515     instead of lib/pythonX.Y.  If this is such a platform we'll just create a
  1637     symlink so lib64 points to lib
  1516     symlink so lib64 points to lib
  1638     """
  1517     """
  1639     if [p for p in distutils.sysconfig.get_config_vars().values()
  1518     if [p for p in distutils.sysconfig.get_config_vars().values()
  1640         if isinstance(p, basestring) and 'lib64' in p]:
  1519         if isinstance(p, basestring) and 'lib64' in p]:
       
  1520         # PyPy's library path scheme is not affected by this.
       
  1521         # Return early or we will die on the following assert.
       
  1522         if is_pypy:
       
  1523             logger.debug('PyPy detected, skipping lib64 symlinking')
       
  1524             return
       
  1525 
  1641         logger.debug('This system uses lib64; symlinking lib64 to lib')
  1526         logger.debug('This system uses lib64; symlinking lib64 to lib')
       
  1527 
  1642         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1528         assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1643             "Unexpected python lib dir: %r" % lib_dir)
  1529             "Unexpected python lib dir: %r" % lib_dir)
  1644         lib_parent = os.path.dirname(lib_dir)
  1530         lib_parent = os.path.dirname(lib_dir)
  1645         top_level = os.path.dirname(lib_parent)
  1531         top_level = os.path.dirname(lib_parent)
  1646         lib_dir = os.path.join(top_level, 'lib')
  1532         lib_dir = os.path.join(top_level, 'lib')
  1647         lib64_link = os.path.join(top_level, 'lib64')
  1533         lib64_link = os.path.join(top_level, 'lib64')
  1648         assert os.path.basename(lib_parent) == 'lib', (
  1534         assert os.path.basename(lib_parent) == 'lib', (
  1649             "Unexpected parent dir: %r" % lib_parent)
  1535             "Unexpected parent dir: %r" % lib_parent)
  1650         if os.path.lexists(lib64_link):
  1536         if os.path.lexists(lib64_link):
  1651             return
  1537             return
  1652         os.symlink('lib', lib64_link)
  1538         cp_or_ln = (os.symlink if symlink else copyfile)
       
  1539         cp_or_ln('lib', lib64_link)
  1653 
  1540 
  1654 def resolve_interpreter(exe):
  1541 def resolve_interpreter(exe):
  1655     """
  1542     """
  1656     If the executable given isn't an absolute path, search $PATH for the interpreter
  1543     If the executable given isn't an absolute path, search $PATH for the interpreter
  1657     """
  1544     """
       
  1545     # If the "executable" is a version number, get the installed executable for
       
  1546     # that version
       
  1547     python_versions = get_installed_pythons()
       
  1548     if exe in python_versions:
       
  1549         exe = python_versions[exe]
       
  1550 
  1658     if os.path.abspath(exe) != exe:
  1551     if os.path.abspath(exe) != exe:
  1659         paths = os.environ.get('PATH', '').split(os.pathsep)
  1552         paths = os.environ.get('PATH', '').split(os.pathsep)
  1660         for path in paths:
  1553         for path in paths:
  1661             if os.path.exists(os.path.join(path, exe)):
  1554             if os.path.exists(os.path.join(path, exe)):
  1662                 exe = os.path.join(path, exe)
  1555                 exe = os.path.join(path, exe)
  1685     activate_this = os.path.join(bin_dir, 'activate_this.py')
  1578     activate_this = os.path.join(bin_dir, 'activate_this.py')
  1686     if not os.path.exists(activate_this):
  1579     if not os.path.exists(activate_this):
  1687         logger.fatal(
  1580         logger.fatal(
  1688             'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1581             'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1689             'on this environment to update it' % activate_this)
  1582             'on this environment to update it' % activate_this)
  1690     fixup_scripts(home_dir)
  1583     fixup_scripts(home_dir, bin_dir)
  1691     fixup_pth_and_egg_link(home_dir)
  1584     fixup_pth_and_egg_link(home_dir)
  1692     ## FIXME: need to fix up distutils.cfg
  1585     ## FIXME: need to fix up distutils.cfg
  1693 
  1586 
  1694 OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1587 OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1695                   'activate', 'activate.bat', 'activate_this.py']
  1588                   'activate', 'activate.bat', 'activate_this.py']
  1696 
  1589 
  1697 def fixup_scripts(home_dir):
  1590 def fixup_scripts(home_dir, bin_dir):
       
  1591     if is_win:
       
  1592         new_shebang_args = (
       
  1593             '%s /c' % os.path.normcase(os.environ.get('COMSPEC', 'cmd.exe')),
       
  1594             '', '.exe')
       
  1595     else:
       
  1596         new_shebang_args = ('/usr/bin/env', sys.version[:3], '')
       
  1597 
  1698     # This is what we expect at the top of scripts:
  1598     # This is what we expect at the top of scripts:
  1699     shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  1599     shebang = '#!%s' % os.path.normcase(os.path.join(
       
  1600         os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2]))
  1700     # This is what we'll put:
  1601     # This is what we'll put:
  1701     new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  1602     new_shebang = '#!%s python%s%s' % new_shebang_args
  1702     if is_win:
  1603 
  1703         bin_suffix = 'Scripts'
       
  1704     else:
       
  1705         bin_suffix = 'bin'
       
  1706     bin_dir = os.path.join(home_dir, bin_suffix)
       
  1707     home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
       
  1708     for filename in os.listdir(bin_dir):
  1604     for filename in os.listdir(bin_dir):
  1709         filename = os.path.join(bin_dir, filename)
  1605         filename = os.path.join(bin_dir, filename)
  1710         if not os.path.isfile(filename):
  1606         if not os.path.isfile(filename):
  1711             # ignore subdirs, e.g. .svn ones.
  1607             # ignore subdirs, e.g. .svn ones.
  1712             continue
  1608             continue
  1721         finally:
  1617         finally:
  1722             f.close()
  1618             f.close()
  1723         if not lines:
  1619         if not lines:
  1724             logger.warn('Script %s is an empty file' % filename)
  1620             logger.warn('Script %s is an empty file' % filename)
  1725             continue
  1621             continue
  1726         if not lines[0].strip().startswith(shebang):
  1622 
       
  1623         old_shebang = lines[0].strip()
       
  1624         old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:])
       
  1625 
       
  1626         if not old_shebang.startswith(shebang):
  1727             if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1627             if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1728                 logger.debug('Cannot make script %s relative' % filename)
  1628                 logger.debug('Cannot make script %s relative' % filename)
  1729             elif lines[0].strip() == new_shebang:
  1629             elif lines[0].strip() == new_shebang:
  1730                 logger.info('Script %s has already been made relative' % filename)
  1630                 logger.info('Script %s has already been made relative' % filename)
  1731             else:
  1631             else:
  1738         f.write('\n'.join(script).encode('utf-8'))
  1638         f.write('\n'.join(script).encode('utf-8'))
  1739         f.close()
  1639         f.close()
  1740 
  1640 
  1741 def relative_script(lines):
  1641 def relative_script(lines):
  1742     "Return a script that'll work in a relocatable environment."
  1642     "Return a script that'll work in a relocatable environment."
  1743     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"
  1643     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"
  1744     # Find the last future statement in the script. If we insert the activation
  1644     # Find the last future statement in the script. If we insert the activation
  1745     # line before a future statement, Python will raise a SyntaxError.
  1645     # line before a future statement, Python will raise a SyntaxError.
  1746     activate_at = None
  1646     activate_at = None
  1747     for idx, line in reversed(list(enumerate(lines))):
  1647     for idx, line in reversed(list(enumerate(lines))):
  1748         if line.split()[:3] == ['from', '__future__', 'import']:
  1648         if line.split()[:3] == ['from', '__future__', 'import']:
  1913     b = base64.b64decode(s.encode('ascii'))
  1813     b = base64.b64decode(s.encode('ascii'))
  1914     return zlib.decompress(b).decode('utf-8')
  1814     return zlib.decompress(b).decode('utf-8')
  1915 
  1815 
  1916 ##file site.py
  1816 ##file site.py
  1917 SITE_PY = convert("""
  1817 SITE_PY = convert("""
  1918 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
  2057 UM3ckC/Q8aP8VLy+mjYY5MxOtAdgjULwf2RtvCc=
  1957 /V88oH83n9F2P9zlV9tWL3sLAtmXxRRYzAxqkcg8jsDIgN4ckrbGugkj6HgfTUNHl6GauSFfoONH
  2058 """)
  1958 abV46zZtMMiZnWgPwBqF4P8ACHXrHw==
  2059 
       
  2060 ##file ez_setup.py
       
  2061 EZ_SETUP_PY = convert("""
       
  2062 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
       
  2128 qL7+C1AkCcw=
       
  2129 """)
       
  2130 
       
  2131 ##file distribute_from_egg.py
       
  2132 DISTRIBUTE_FROM_EGG_PY = convert("""
       
  2133 eJw9j8tqAzEMRfcG/4MgmxQyptkGusonZBmGoGTUGYFfWPKE6dfXTkM3gqt7rh47OKP3NMF3SQFW
       
  2134 LlrRU1zhybpAxoKBlIqcrNnBdRjQP3GTocYfzmNrrCPQPN9iwzpxSQfQhWBi0cL3qtRtYIG/4Mv0
       
  2135 KApY5hooqrOGQ05FQTaxptF9Fnx16Rq0XofjaE1XGXVxHIWK7j8P8EY/rHndLqQ1a0pe3COFgHFy
       
  2136 hLLdWkDbi/DeEpCjNb3u/zccT2Ob8gtnwVyI
       
  2137 """)
       
  2138 
       
  2139 ##file distribute_setup.py
       
  2140 DISTRIBUTE_SETUP_PY = convert("""
       
  2141 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
       
  2228 """)
  1959 """)
  2229 
  1960 
  2230 ##file activate.sh
  1961 ##file activate.sh
  2231 ACTIVATE_SH = convert("""
  1962 ACTIVATE_SH = convert("""
  2232 eJytVVFvokAQfudXTLEPtTlLeo9tvMSmJpq02hSvl7u2wRUG2QR2DSxSe7n/frOACEVNLlceRHa+
  1963 eJytVVFvokAQfudXTLEPtTlLeo9tvMSmJpq02hSvl7u2wRUG2QR2DSxSe7n/frOACEVNLlceRHa+