Merge lp:~ubuntu-branches/ubuntu/oneiric/python-virtualenv/oneiric-201109082106 into lp:ubuntu/oneiric/python-virtualenv

Proposed by Ubuntu Package Importer
Status: Rejected
Rejected by: James Westby
Proposed branch: lp:~ubuntu-branches/ubuntu/oneiric/python-virtualenv/oneiric-201109082106
Merge into: lp:ubuntu/oneiric/python-virtualenv
Diff against target: 5794 lines (+5746/-2) (has conflicts)
5 files modified
.pc/add_distribute.patch/virtualenv.py (+1892/-0)
.pc/applied-patches (+8/-2)
.pc/look_for_external_files.patch/setup.py (+59/-0)
.pc/look_for_external_files.patch/virtualenv.py (+1891/-0)
.pc/remove_syspath0_on_reinvoke.patch/virtualenv.py (+1896/-0)
Text conflict in .pc/add_distribute.patch/virtualenv.py
Text conflict in .pc/applied-patches
Text conflict in .pc/look_for_external_files.patch/setup.py
Text conflict in .pc/look_for_external_files.patch/virtualenv.py
To merge this branch: bzr merge lp:~ubuntu-branches/ubuntu/oneiric/python-virtualenv/oneiric-201109082106
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+74696@code.launchpad.net

Description of the change

The package importer has detected a possible inconsistency between the package history in the archve and the history in bzr. As the archive is authoritative the importer has made lp:ubuntu/oneiric/python-virtualenv reflect what is in the archive and the old bzr branch has been pushed to lp:~ubuntu-branches/ubuntu/oneiric/python-virtualenv/oneiric-201109082106. This merge proposal was created so that an Ubuntu developer can review the situations and perform a merge/upload if necessary. There are three typical cases where this can happen.
  1. Where someone pushes a change to bzr and someone else uploads the package without that change. This is the reason that this check is done by the importer. If this appears to be the case then a merge/upload should be done if the changes that were in bzr are still desirable.
  2. The importer incorrectly detected the above situation when someone made a change in bzr and then uploaded it.
  3. The importer incorrectly detected the above situation when someone just uploaded a package and didn't touch bzr.

If this case doesn't appear to be the first situation then set the status of the merge proposal to "Rejected" and help avoid the problem in future by filing a bug at https://bugs.launchpad.net/udd linking to this merge proposal.

(this is an automatically generated message)

To post a comment you must log in.

Unmerged revisions

13. By Barry Warsaw

* New upstream release.
  - This version includes the upstream fix for posix_local layouts,
    used in Debian and Ubuntu. (LP: #839588)
  - debian/patches/remove_syspath0_on_reinvoke.patch (or its moral
    equivalent) has been applied upstream and is no longer necessary.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.pc/add_distribute.patch/virtualenv.py' (properties changed: -x to +x)
--- .pc/add_distribute.patch/virtualenv.py 2011-09-08 15:38:18 +0000
+++ .pc/add_distribute.patch/virtualenv.py 2011-09-08 21:10:23 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
1#!/usr/bin/env python2#!/usr/bin/env python
2"""Create a "virtual" Python installation3"""Create a "virtual" Python installation
3"""4"""
@@ -1955,3 +1956,1894 @@
1955## TODO:1956## TODO:
1956## Copy python.exe.manifest1957## Copy python.exe.manifest
1957## Monkeypatch distutils.sysconfig1958## Monkeypatch distutils.sysconfig
1959=======
1960"""Create a "virtual" Python installation
1961"""
1962
1963# If you change the version here, change it in setup.py
1964# and docs/conf.py as well.
1965virtualenv_version = "1.6"
1966
1967import base64
1968import sys
1969import os
1970import optparse
1971import re
1972import shutil
1973import logging
1974import tempfile
1975import zlib
1976import errno
1977import distutils.sysconfig
1978try:
1979 import subprocess
1980except ImportError:
1981 if sys.version_info <= (2, 3):
1982 print('ERROR: %s' % sys.exc_info()[1])
1983 print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
1984 print('If you copy subprocess.py from a newer version of Python this script will probably work')
1985 sys.exit(101)
1986 else:
1987 raise
1988try:
1989 set
1990except NameError:
1991 from sets import Set as set
1992try:
1993 basestring
1994except NameError:
1995 basestring = str
1996
1997join = os.path.join
1998py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
1999
2000is_jython = sys.platform.startswith('java')
2001is_pypy = hasattr(sys, 'pypy_version_info')
2002abiflags = getattr(sys, 'abiflags', '')
2003
2004if is_pypy:
2005 expected_exe = 'pypy'
2006elif is_jython:
2007 expected_exe = 'jython'
2008else:
2009 expected_exe = 'python'
2010
2011
2012REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
2013 'fnmatch', 'locale', 'encodings', 'codecs',
2014 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
2015 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
2016 'zlib']
2017
2018REQUIRED_FILES = ['lib-dynload', 'config']
2019
2020majver, minver = sys.version_info[:2]
2021if majver == 2:
2022 if minver >= 6:
2023 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
2024 if minver >= 7:
2025 REQUIRED_MODULES.extend(['_weakrefset'])
2026 if minver <= 3:
2027 REQUIRED_MODULES.extend(['sets', '__future__'])
2028elif majver == 3:
2029 # Some extra modules are needed for Python 3, but different ones
2030 # for different versions.
2031 REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
2032 '_weakrefset', 'copyreg', 'tempfile', 'random',
2033 '__future__', 'collections', 'keyword', 'tarfile',
2034 'shutil', 'struct', 'copy'])
2035 if minver >= 2:
2036 REQUIRED_FILES[-1] = 'config-%s' % majver
2037 if minver == 3:
2038 # The whole list of 3.3 modules is reproduced below - the current
2039 # uncommented ones are required for 3.3 as of now, but more may be
2040 # added as 3.3 development continues.
2041 REQUIRED_MODULES.extend([
2042 #"aifc",
2043 #"antigravity",
2044 #"argparse",
2045 #"ast",
2046 #"asynchat",
2047 #"asyncore",
2048 "base64",
2049 #"bdb",
2050 #"binhex",
2051 "bisect",
2052 #"calendar",
2053 #"cgi",
2054 #"cgitb",
2055 #"chunk",
2056 #"cmd",
2057 #"codeop",
2058 #"code",
2059 #"colorsys",
2060 #"_compat_pickle",
2061 #"compileall",
2062 #"concurrent",
2063 #"configparser",
2064 #"contextlib",
2065 #"cProfile",
2066 #"crypt",
2067 #"csv",
2068 #"ctypes",
2069 #"curses",
2070 #"datetime",
2071 #"dbm",
2072 #"decimal",
2073 #"difflib",
2074 #"dis",
2075 #"doctest",
2076 #"dummy_threading",
2077 #"_dummy_thread",
2078 #"email",
2079 #"filecmp",
2080 #"fileinput",
2081 #"formatter",
2082 #"fractions",
2083 #"ftplib",
2084 #"functools",
2085 #"getopt",
2086 #"getpass",
2087 #"gettext",
2088 #"glob",
2089 #"gzip",
2090 "hashlib",
2091 "heapq",
2092 "hmac",
2093 #"html",
2094 #"http",
2095 #"idlelib",
2096 #"imaplib",
2097 #"imghdr",
2098 #"importlib",
2099 #"inspect",
2100 #"json",
2101 #"lib2to3",
2102 #"logging",
2103 #"macpath",
2104 #"macurl2path",
2105 #"mailbox",
2106 #"mailcap",
2107 #"_markupbase",
2108 #"mimetypes",
2109 #"modulefinder",
2110 #"multiprocessing",
2111 #"netrc",
2112 #"nntplib",
2113 #"nturl2path",
2114 #"numbers",
2115 #"opcode",
2116 #"optparse",
2117 #"os2emxpath",
2118 #"pdb",
2119 #"pickle",
2120 #"pickletools",
2121 #"pipes",
2122 #"pkgutil",
2123 #"platform",
2124 #"plat-linux2",
2125 #"plistlib",
2126 #"poplib",
2127 #"pprint",
2128 #"profile",
2129 #"pstats",
2130 #"pty",
2131 #"pyclbr",
2132 #"py_compile",
2133 #"pydoc_data",
2134 #"pydoc",
2135 #"_pyio",
2136 #"queue",
2137 #"quopri",
2138 "reprlib",
2139 "rlcompleter",
2140 #"runpy",
2141 #"sched",
2142 #"shelve",
2143 #"shlex",
2144 #"smtpd",
2145 #"smtplib",
2146 #"sndhdr",
2147 #"socket",
2148 #"socketserver",
2149 #"sqlite3",
2150 #"ssl",
2151 #"stringprep",
2152 #"string",
2153 #"_strptime",
2154 #"subprocess",
2155 #"sunau",
2156 #"symbol",
2157 #"symtable",
2158 #"sysconfig",
2159 #"tabnanny",
2160 #"telnetlib",
2161 #"test",
2162 #"textwrap",
2163 #"this",
2164 #"_threading_local",
2165 #"threading",
2166 #"timeit",
2167 #"tkinter",
2168 #"tokenize",
2169 #"token",
2170 #"traceback",
2171 #"trace",
2172 #"tty",
2173 #"turtledemo",
2174 #"turtle",
2175 #"unittest",
2176 #"urllib",
2177 #"uuid",
2178 #"uu",
2179 #"wave",
2180 "weakref",
2181 #"webbrowser",
2182 #"wsgiref",
2183 #"xdrlib",
2184 #"xml",
2185 #"xmlrpc",
2186 #"zipfile",
2187 ])
2188
2189if is_pypy:
2190 # these are needed to correctly display the exceptions that may happen
2191 # during the bootstrap
2192 REQUIRED_MODULES.extend(['traceback', 'linecache'])
2193
2194class Logger(object):
2195
2196 """
2197 Logging object for use in command-line script. Allows ranges of
2198 levels, to avoid some redundancy of displayed information.
2199 """
2200
2201 DEBUG = logging.DEBUG
2202 INFO = logging.INFO
2203 NOTIFY = (logging.INFO+logging.WARN)/2
2204 WARN = WARNING = logging.WARN
2205 ERROR = logging.ERROR
2206 FATAL = logging.FATAL
2207
2208 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
2209
2210 def __init__(self, consumers):
2211 self.consumers = consumers
2212 self.indent = 0
2213 self.in_progress = None
2214 self.in_progress_hanging = False
2215
2216 def debug(self, msg, *args, **kw):
2217 self.log(self.DEBUG, msg, *args, **kw)
2218 def info(self, msg, *args, **kw):
2219 self.log(self.INFO, msg, *args, **kw)
2220 def notify(self, msg, *args, **kw):
2221 self.log(self.NOTIFY, msg, *args, **kw)
2222 def warn(self, msg, *args, **kw):
2223 self.log(self.WARN, msg, *args, **kw)
2224 def error(self, msg, *args, **kw):
2225 self.log(self.WARN, msg, *args, **kw)
2226 def fatal(self, msg, *args, **kw):
2227 self.log(self.FATAL, msg, *args, **kw)
2228 def log(self, level, msg, *args, **kw):
2229 if args:
2230 if kw:
2231 raise TypeError(
2232 "You may give positional or keyword arguments, not both")
2233 args = args or kw
2234 rendered = None
2235 for consumer_level, consumer in self.consumers:
2236 if self.level_matches(level, consumer_level):
2237 if (self.in_progress_hanging
2238 and consumer in (sys.stdout, sys.stderr)):
2239 self.in_progress_hanging = False
2240 sys.stdout.write('\n')
2241 sys.stdout.flush()
2242 if rendered is None:
2243 if args:
2244 rendered = msg % args
2245 else:
2246 rendered = msg
2247 rendered = ' '*self.indent + rendered
2248 if hasattr(consumer, 'write'):
2249 consumer.write(rendered+'\n')
2250 else:
2251 consumer(rendered)
2252
2253 def start_progress(self, msg):
2254 assert not self.in_progress, (
2255 "Tried to start_progress(%r) while in_progress %r"
2256 % (msg, self.in_progress))
2257 if self.level_matches(self.NOTIFY, self._stdout_level()):
2258 sys.stdout.write(msg)
2259 sys.stdout.flush()
2260 self.in_progress_hanging = True
2261 else:
2262 self.in_progress_hanging = False
2263 self.in_progress = msg
2264
2265 def end_progress(self, msg='done.'):
2266 assert self.in_progress, (
2267 "Tried to end_progress without start_progress")
2268 if self.stdout_level_matches(self.NOTIFY):
2269 if not self.in_progress_hanging:
2270 # Some message has been printed out since start_progress
2271 sys.stdout.write('...' + self.in_progress + msg + '\n')
2272 sys.stdout.flush()
2273 else:
2274 sys.stdout.write(msg + '\n')
2275 sys.stdout.flush()
2276 self.in_progress = None
2277 self.in_progress_hanging = False
2278
2279 def show_progress(self):
2280 """If we are in a progress scope, and no log messages have been
2281 shown, write out another '.'"""
2282 if self.in_progress_hanging:
2283 sys.stdout.write('.')
2284 sys.stdout.flush()
2285
2286 def stdout_level_matches(self, level):
2287 """Returns true if a message at this level will go to stdout"""
2288 return self.level_matches(level, self._stdout_level())
2289
2290 def _stdout_level(self):
2291 """Returns the level that stdout runs at"""
2292 for level, consumer in self.consumers:
2293 if consumer is sys.stdout:
2294 return level
2295 return self.FATAL
2296
2297 def level_matches(self, level, consumer_level):
2298 """
2299 >>> l = Logger()
2300 >>> l.level_matches(3, 4)
2301 False
2302 >>> l.level_matches(3, 2)
2303 True
2304 >>> l.level_matches(slice(None, 3), 3)
2305 False
2306 >>> l.level_matches(slice(None, 3), 2)
2307 True
2308 >>> l.level_matches(slice(1, 3), 1)
2309 True
2310 >>> l.level_matches(slice(2, 3), 1)
2311 False
2312 """
2313 if isinstance(level, slice):
2314 start, stop = level.start, level.stop
2315 if start is not None and start > consumer_level:
2316 return False
2317 if stop is not None or stop <= consumer_level:
2318 return False
2319 return True
2320 else:
2321 return level >= consumer_level
2322
2323 #@classmethod
2324 def level_for_integer(cls, level):
2325 levels = cls.LEVELS
2326 if level < 0:
2327 return levels[0]
2328 if level >= len(levels):
2329 return levels[-1]
2330 return levels[level]
2331
2332 level_for_integer = classmethod(level_for_integer)
2333
2334# create a silent logger just to prevent this from being undefined
2335# will be overridden with requested verbosity main() is called.
2336logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
2337
2338def mkdir(path):
2339 if not os.path.exists(path):
2340 logger.info('Creating %s', path)
2341 os.makedirs(path)
2342 else:
2343 logger.info('Directory %s already exists', path)
2344
2345def copyfileordir(src, dest):
2346 if os.path.isdir(src):
2347 shutil.copytree(src, dest, True)
2348 else:
2349 shutil.copy2(src, dest)
2350
2351def copyfile(src, dest, symlink=True):
2352 if not os.path.exists(src):
2353 # Some bad symlink in the src
2354 logger.warn('Cannot find file %s (bad symlink)', src)
2355 return
2356 if os.path.exists(dest):
2357 logger.debug('File %s already exists', dest)
2358 return
2359 if not os.path.exists(os.path.dirname(dest)):
2360 logger.info('Creating parent directories for %s' % os.path.dirname(dest))
2361 os.makedirs(os.path.dirname(dest))
2362 if not os.path.islink(src):
2363 srcpath = os.path.abspath(src)
2364 else:
2365 srcpath = os.readlink(src)
2366 if symlink and hasattr(os, 'symlink'):
2367 logger.info('Symlinking %s', dest)
2368 try:
2369 os.symlink(srcpath, dest)
2370 except (OSError, NotImplementedError):
2371 logger.info('Symlinking failed, copying to %s', dest)
2372 copyfileordir(src, dest)
2373 else:
2374 logger.info('Copying to %s', dest)
2375 copyfileordir(src, dest)
2376
2377def writefile(dest, content, overwrite=True):
2378 if not os.path.exists(dest):
2379 logger.info('Writing %s', dest)
2380 f = open(dest, 'wb')
2381 f.write(content.encode('utf-8'))
2382 f.close()
2383 return
2384 else:
2385 f = open(dest, 'rb')
2386 c = f.read()
2387 f.close()
2388 if c != content:
2389 if not overwrite:
2390 logger.notify('File %s exists with different content; not overwriting', dest)
2391 return
2392 logger.notify('Overwriting %s with new content', dest)
2393 f = open(dest, 'wb')
2394 f.write(content.encode('utf-8'))
2395 f.close()
2396 else:
2397 logger.info('Content %s already in place', dest)
2398
2399def rmtree(dir):
2400 if os.path.exists(dir):
2401 logger.notify('Deleting tree %s', dir)
2402 shutil.rmtree(dir)
2403 else:
2404 logger.info('Do not need to delete %s; already gone', dir)
2405
2406def make_exe(fn):
2407 if hasattr(os, 'chmod'):
2408 oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
2409 newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
2410 os.chmod(fn, newmode)
2411 logger.info('Changed mode of %s to %s', fn, oct(newmode))
2412
2413def _find_file(filename, dirs):
2414 for dir in dirs:
2415 if os.path.exists(join(dir, filename)):
2416 return join(dir, filename)
2417 return filename
2418
2419def _install_req(py_executable, unzip=False, distribute=False):
2420 if not distribute:
2421 setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
2422 project_name = 'setuptools'
2423 bootstrap_script = EZ_SETUP_PY
2424 source = None
2425 else:
2426 setup_fn = None
2427 source = 'distribute-0.6.15.tar.gz'
2428 project_name = 'distribute'
2429 bootstrap_script = DISTRIBUTE_SETUP_PY
2430 try:
2431 # check if the global Python has distribute installed or plain
2432 # setuptools
2433 import pkg_resources
2434 if not hasattr(pkg_resources, '_distribute'):
2435 location = os.path.dirname(pkg_resources.__file__)
2436 logger.notify("A globally installed setuptools was found (in %s)" % location)
2437 logger.notify("Use the --no-site-packages option to use distribute in "
2438 "the virtualenv.")
2439 except ImportError:
2440 pass
2441
2442 search_dirs = file_search_dirs()
2443
2444 if setup_fn is not None:
2445 setup_fn = _find_file(setup_fn, search_dirs)
2446
2447 if source is not None:
2448 source = _find_file(source, search_dirs)
2449
2450 if is_jython and os._name == 'nt':
2451 # Jython's .bat sys.executable can't handle a command line
2452 # argument with newlines
2453 fd, ez_setup = tempfile.mkstemp('.py')
2454 os.write(fd, bootstrap_script)
2455 os.close(fd)
2456 cmd = [py_executable, ez_setup]
2457 else:
2458 cmd = [py_executable, '-c', bootstrap_script]
2459 if unzip:
2460 cmd.append('--always-unzip')
2461 env = {}
2462 remove_from_env = []
2463 if logger.stdout_level_matches(logger.DEBUG):
2464 cmd.append('-v')
2465
2466 old_chdir = os.getcwd()
2467 if setup_fn is not None and os.path.exists(setup_fn):
2468 logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
2469 cmd.append(setup_fn)
2470 if os.environ.get('PYTHONPATH'):
2471 env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
2472 else:
2473 env['PYTHONPATH'] = setup_fn
2474 else:
2475 # the source is found, let's chdir
2476 if source is not None and os.path.exists(source):
2477 os.chdir(os.path.dirname(source))
2478 # in this case, we want to be sure that PYTHONPATH is unset (not
2479 # just empty, really unset), else CPython tries to import the
2480 # site.py that it's in virtualenv_support
2481 remove_from_env.append('PYTHONPATH')
2482 else:
2483 logger.info('No %s egg found; downloading' % project_name)
2484 cmd.extend(['--always-copy', '-U', project_name])
2485 logger.start_progress('Installing %s...' % project_name)
2486 logger.indent += 2
2487 cwd = None
2488 if project_name == 'distribute':
2489 env['DONT_PATCH_SETUPTOOLS'] = 'true'
2490
2491 def _filter_ez_setup(line):
2492 return filter_ez_setup(line, project_name)
2493
2494 if not os.access(os.getcwd(), os.W_OK):
2495 cwd = tempfile.mkdtemp()
2496 if source is not None and os.path.exists(source):
2497 # the current working dir is hostile, let's copy the
2498 # tarball to a temp dir
2499 target = os.path.join(cwd, os.path.split(source)[-1])
2500 shutil.copy(source, target)
2501 try:
2502 call_subprocess(cmd, show_stdout=False,
2503 filter_stdout=_filter_ez_setup,
2504 extra_env=env,
2505 remove_from_env=remove_from_env,
2506 cwd=cwd)
2507 finally:
2508 logger.indent -= 2
2509 logger.end_progress()
2510 if os.getcwd() != old_chdir:
2511 os.chdir(old_chdir)
2512 if is_jython and os._name == 'nt':
2513 os.remove(ez_setup)
2514
2515def file_search_dirs():
2516 here = os.path.dirname(os.path.abspath(__file__))
2517 dirs = ['.', here,
2518 #join(here, 'virtualenv_support')]
2519 '/usr/share/python-virtualenv/']
2520 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
2521 # Probably some boot script; just in case virtualenv is installed...
2522 try:
2523 import virtualenv
2524 except ImportError:
2525 pass
2526 else:
2527 dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
2528 return [d for d in dirs if os.path.isdir(d)]
2529
2530def install_setuptools(py_executable, unzip=False):
2531 _install_req(py_executable, unzip)
2532
2533def install_distribute(py_executable, unzip=False):
2534 _install_req(py_executable, unzip, distribute=True)
2535
2536_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
2537def install_pip(py_executable):
2538 filenames = []
2539 for dir in file_search_dirs():
2540 filenames.extend([join(dir, fn) for fn in os.listdir(dir)
2541 if _pip_re.search(fn)])
2542 filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
2543 filenames.sort()
2544 filenames = [filename for basename, i, filename in filenames]
2545 if not filenames:
2546 filename = 'pip'
2547 else:
2548 filename = filenames[-1]
2549 easy_install_script = 'easy_install'
2550 if sys.platform == 'win32':
2551 easy_install_script = 'easy_install-script.py'
2552 cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
2553 if filename == 'pip':
2554 logger.info('Installing pip from network...')
2555 else:
2556 logger.info('Installing %s' % os.path.basename(filename))
2557 logger.indent += 2
2558 def _filter_setup(line):
2559 return filter_ez_setup(line, 'pip')
2560 try:
2561 call_subprocess(cmd, show_stdout=False,
2562 filter_stdout=_filter_setup)
2563 finally:
2564 logger.indent -= 2
2565
2566def filter_ez_setup(line, project_name='setuptools'):
2567 if not line.strip():
2568 return Logger.DEBUG
2569 if project_name == 'distribute':
2570 for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
2571 'Scanning', 'Setuptools', 'Egg', 'Already',
2572 'running', 'writing', 'reading', 'installing',
2573 'creating', 'copying', 'byte-compiling', 'removing',
2574 'Processing'):
2575 if line.startswith(prefix):
2576 return Logger.DEBUG
2577 return Logger.DEBUG
2578 for prefix in ['Reading ', 'Best match', 'Processing setuptools',
2579 'Copying setuptools', 'Adding setuptools',
2580 'Installing ', 'Installed ']:
2581 if line.startswith(prefix):
2582 return Logger.DEBUG
2583 return Logger.INFO
2584
2585def main():
2586 parser = optparse.OptionParser(
2587 version=virtualenv_version,
2588 usage="%prog [OPTIONS] DEST_DIR")
2589
2590 parser.add_option(
2591 '-v', '--verbose',
2592 action='count',
2593 dest='verbose',
2594 default=0,
2595 help="Increase verbosity")
2596
2597 parser.add_option(
2598 '-q', '--quiet',
2599 action='count',
2600 dest='quiet',
2601 default=0,
2602 help='Decrease verbosity')
2603
2604 parser.add_option(
2605 '-p', '--python',
2606 dest='python',
2607 metavar='PYTHON_EXE',
2608 help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
2609 'interpreter to create the new environment. The default is the interpreter that '
2610 'virtualenv was installed with (%s)' % sys.executable)
2611
2612 parser.add_option(
2613 '--clear',
2614 dest='clear',
2615 action='store_true',
2616 help="Clear out the non-root install and start from scratch")
2617
2618 parser.add_option(
2619 '--no-site-packages',
2620 dest='no_site_packages',
2621 action='store_true',
2622 help="Don't give access to the global site-packages dir to the "
2623 "virtual environment")
2624
2625 parser.add_option(
2626 '--unzip-setuptools',
2627 dest='unzip_setuptools',
2628 action='store_true',
2629 help="Unzip Setuptools or Distribute when installing it")
2630
2631 parser.add_option(
2632 '--relocatable',
2633 dest='relocatable',
2634 action='store_true',
2635 help='Make an EXISTING virtualenv environment relocatable. '
2636 'This fixes up scripts and makes all .pth files relative')
2637
2638 parser.add_option(
2639 '--distribute',
2640 dest='use_distribute',
2641 action='store_true',
2642 help='Use Distribute instead of Setuptools. Set environ variable '
2643 'VIRTUALENV_USE_DISTRIBUTE to make it the default ')
2644
2645 parser.add_option(
2646 '--prompt=',
2647 dest='prompt',
2648 help='Provides an alternative prompt prefix for this environment')
2649
2650 if 'extend_parser' in globals():
2651 extend_parser(parser)
2652
2653 options, args = parser.parse_args()
2654
2655 global logger
2656
2657 if 'adjust_options' in globals():
2658 adjust_options(options, args)
2659
2660 verbosity = options.verbose - options.quiet
2661 logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
2662
2663 if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
2664 env = os.environ.copy()
2665 interpreter = resolve_interpreter(options.python)
2666 if interpreter == sys.executable:
2667 logger.warn('Already using interpreter %s' % interpreter)
2668 else:
2669 logger.notify('Running virtualenv with interpreter %s' % interpreter)
2670 env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
2671 file = __file__
2672 if file.endswith('.pyc'):
2673 file = file[:-1]
2674 popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
2675 raise SystemExit(popen.wait())
2676
2677 if not args:
2678 print('You must provide a DEST_DIR')
2679 parser.print_help()
2680 sys.exit(2)
2681 if len(args) > 1:
2682 print('There must be only one argument: DEST_DIR (you gave %s)' % (
2683 ' '.join(args)))
2684 parser.print_help()
2685 sys.exit(2)
2686
2687 home_dir = args[0]
2688
2689 if os.environ.get('WORKING_ENV'):
2690 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
2691 logger.fatal('Please deactivate your workingenv, then re-run this script')
2692 sys.exit(3)
2693
2694 if 'PYTHONHOME' in os.environ:
2695 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
2696 del os.environ['PYTHONHOME']
2697
2698 if options.relocatable:
2699 make_environment_relocatable(home_dir)
2700 return
2701
2702 create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
2703 unzip_setuptools=options.unzip_setuptools,
2704 use_distribute=options.use_distribute or majver > 2,
2705 prompt=options.prompt)
2706 if 'after_install' in globals():
2707 after_install(options, home_dir)
2708
2709def call_subprocess(cmd, show_stdout=True,
2710 filter_stdout=None, cwd=None,
2711 raise_on_returncode=True, extra_env=None,
2712 remove_from_env=None):
2713 cmd_parts = []
2714 for part in cmd:
2715 if len(part) > 45:
2716 part = part[:20]+"..."+part[-20:]
2717 if ' ' in part or '\n' in part or '"' in part or "'" in part:
2718 part = '"%s"' % part.replace('"', '\\"')
2719 cmd_parts.append(part)
2720 cmd_desc = ' '.join(cmd_parts)
2721 if show_stdout:
2722 stdout = None
2723 else:
2724 stdout = subprocess.PIPE
2725 logger.debug("Running command %s" % cmd_desc)
2726 if extra_env or remove_from_env:
2727 env = os.environ.copy()
2728 if extra_env:
2729 env.update(extra_env)
2730 if remove_from_env:
2731 for varname in remove_from_env:
2732 env.pop(varname, None)
2733 else:
2734 env = None
2735 try:
2736 proc = subprocess.Popen(
2737 cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
2738 cwd=cwd, env=env)
2739 except Exception:
2740 e = sys.exc_info()[1]
2741 logger.fatal(
2742 "Error %s while executing command %s" % (e, cmd_desc))
2743 raise
2744 all_output = []
2745 if stdout is not None:
2746 stdout = proc.stdout
2747 encoding = sys.getdefaultencoding()
2748 while 1:
2749 line = stdout.readline().decode(encoding)
2750 if not line:
2751 break
2752 line = line.rstrip()
2753 all_output.append(line)
2754 if filter_stdout:
2755 level = filter_stdout(line)
2756 if isinstance(level, tuple):
2757 level, line = level
2758 logger.log(level, line)
2759 if not logger.stdout_level_matches(level):
2760 logger.show_progress()
2761 else:
2762 logger.info(line)
2763 else:
2764 proc.communicate()
2765 proc.wait()
2766 if proc.returncode:
2767 if raise_on_returncode:
2768 if all_output:
2769 logger.notify('Complete output from command %s:' % cmd_desc)
2770 logger.notify('\n'.join(all_output) + '\n----------------------------------------')
2771 raise OSError(
2772 "Command %s failed with error code %s"
2773 % (cmd_desc, proc.returncode))
2774 else:
2775 logger.warn(
2776 "Command %s had error code %s"
2777 % (cmd_desc, proc.returncode))
2778
2779
2780def create_environment(home_dir, site_packages=True, clear=False,
2781 unzip_setuptools=False, use_distribute=False,
2782 prompt=None):
2783 """
2784 Creates a new environment in ``home_dir``.
2785
2786 If ``site_packages`` is true (the default) then the global
2787 ``site-packages/`` directory will be on the path.
2788
2789 If ``clear`` is true (default False) then the environment will
2790 first be cleared.
2791 """
2792 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
2793
2794 py_executable = os.path.abspath(install_python(
2795 home_dir, lib_dir, inc_dir, bin_dir,
2796 site_packages=site_packages, clear=clear))
2797
2798 install_distutils(home_dir)
2799
2800 if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
2801 install_distribute(py_executable, unzip=unzip_setuptools)
2802 else:
2803 install_setuptools(py_executable, unzip=unzip_setuptools)
2804
2805 install_pip(py_executable)
2806
2807 install_activate(home_dir, bin_dir, prompt)
2808
2809def path_locations(home_dir):
2810 """Return the path locations for the environment (where libraries are,
2811 where scripts go, etc)"""
2812 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
2813 # prefix arg is broken: http://bugs.python.org/issue3386
2814 if sys.platform == 'win32':
2815 # Windows has lots of problems with executables with spaces in
2816 # the name; this function will remove them (using the ~1
2817 # format):
2818 mkdir(home_dir)
2819 if ' ' in home_dir:
2820 try:
2821 import win32api
2822 except ImportError:
2823 print('Error: the path "%s" has a space in it' % home_dir)
2824 print('To handle these kinds of paths, the win32api module must be installed:')
2825 print(' http://sourceforge.net/projects/pywin32/')
2826 sys.exit(3)
2827 home_dir = win32api.GetShortPathName(home_dir)
2828 lib_dir = join(home_dir, 'Lib')
2829 inc_dir = join(home_dir, 'Include')
2830 bin_dir = join(home_dir, 'Scripts')
2831 elif is_jython:
2832 lib_dir = join(home_dir, 'Lib')
2833 inc_dir = join(home_dir, 'Include')
2834 bin_dir = join(home_dir, 'bin')
2835 elif is_pypy:
2836 lib_dir = home_dir
2837 inc_dir = join(home_dir, 'include')
2838 bin_dir = join(home_dir, 'bin')
2839 else:
2840 lib_dir = join(home_dir, 'lib', py_version)
2841 inc_dir = join(home_dir, 'include', py_version + abiflags)
2842 bin_dir = join(home_dir, 'bin')
2843 return home_dir, lib_dir, inc_dir, bin_dir
2844
2845
2846def change_prefix(filename, dst_prefix):
2847 prefixes = [sys.prefix]
2848
2849 if sys.platform == "darwin":
2850 prefixes.extend((
2851 os.path.join("/Library/Python", sys.version[:3], "site-packages"),
2852 os.path.join(sys.prefix, "Extras", "lib", "python"),
2853 os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
2854
2855 if hasattr(sys, 'real_prefix'):
2856 prefixes.append(sys.real_prefix)
2857 prefixes = list(map(os.path.abspath, prefixes))
2858 filename = os.path.abspath(filename)
2859 for src_prefix in prefixes:
2860 if filename.startswith(src_prefix):
2861 _, relpath = filename.split(src_prefix, 1)
2862 assert relpath[0] == os.sep
2863 relpath = relpath[1:]
2864 return join(dst_prefix, relpath)
2865 assert False, "Filename %s does not start with any of these prefixes: %s" % \
2866 (filename, prefixes)
2867
2868def copy_required_modules(dst_prefix):
2869 import imp
2870 for modname in REQUIRED_MODULES:
2871 if modname in sys.builtin_module_names:
2872 logger.info("Ignoring built-in bootstrap module: %s" % modname)
2873 continue
2874 try:
2875 f, filename, _ = imp.find_module(modname)
2876 except ImportError:
2877 logger.info("Cannot import bootstrap module: %s" % modname)
2878 else:
2879 if f is not None:
2880 f.close()
2881 dst_filename = change_prefix(filename, dst_prefix)
2882 copyfile(filename, dst_filename)
2883 if filename.endswith('.pyc'):
2884 pyfile = filename[:-1]
2885 if os.path.exists(pyfile):
2886 copyfile(pyfile, dst_filename[:-1])
2887
2888
2889def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
2890 """Install just the base environment, no distutils patches etc"""
2891 if sys.executable.startswith(bin_dir):
2892 print('Please use the *system* python to run this script')
2893 return
2894
2895 if clear:
2896 rmtree(lib_dir)
2897 ## FIXME: why not delete it?
2898 ## Maybe it should delete everything with #!/path/to/venv/python in it
2899 logger.notify('Not deleting %s', bin_dir)
2900
2901 if hasattr(sys, 'real_prefix'):
2902 logger.notify('Using real prefix %r' % sys.real_prefix)
2903 prefix = sys.real_prefix
2904 else:
2905 prefix = sys.prefix
2906 mkdir(lib_dir)
2907 fix_lib64(lib_dir)
2908 stdlib_dirs = [os.path.dirname(os.__file__)]
2909 if sys.platform == 'win32':
2910 stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
2911 elif sys.platform == 'darwin':
2912 stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
2913 if hasattr(os, 'symlink'):
2914 logger.info('Symlinking Python bootstrap modules')
2915 else:
2916 logger.info('Copying Python bootstrap modules')
2917 logger.indent += 2
2918 try:
2919 # copy required files...
2920 for stdlib_dir in stdlib_dirs:
2921 if not os.path.isdir(stdlib_dir):
2922 continue
2923 for fn in os.listdir(stdlib_dir):
2924 bn = os.path.splitext(fn)[0]
2925 if fn != 'site-packages' and bn in REQUIRED_FILES:
2926 copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
2927 # ...and modules
2928 copy_required_modules(home_dir)
2929 finally:
2930 logger.indent -= 2
2931 mkdir(join(lib_dir, 'site-packages'))
2932 import site
2933 site_filename = site.__file__
2934 if site_filename.endswith('.pyc'):
2935 site_filename = site_filename[:-1]
2936 elif site_filename.endswith('$py.class'):
2937 site_filename = site_filename.replace('$py.class', '.py')
2938 site_filename_dst = change_prefix(site_filename, home_dir)
2939 site_dir = os.path.dirname(site_filename_dst)
2940 writefile(site_filename_dst, SITE_PY)
2941 writefile(join(site_dir, 'orig-prefix.txt'), prefix)
2942 site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
2943 if not site_packages:
2944 writefile(site_packages_filename, '')
2945 else:
2946 if os.path.exists(site_packages_filename):
2947 logger.info('Deleting %s' % site_packages_filename)
2948 os.unlink(site_packages_filename)
2949
2950 if is_pypy:
2951 stdinc_dir = join(prefix, 'include')
2952 else:
2953 stdinc_dir = join(prefix, 'include', py_version + abiflags)
2954 if os.path.exists(stdinc_dir):
2955 copyfile(stdinc_dir, inc_dir)
2956 else:
2957 logger.debug('No include dir %s' % stdinc_dir)
2958
2959 # pypy never uses exec_prefix, just ignore it
2960 if sys.exec_prefix != prefix and not is_pypy:
2961 if sys.platform == 'win32':
2962 exec_dir = join(sys.exec_prefix, 'lib')
2963 elif is_jython:
2964 exec_dir = join(sys.exec_prefix, 'Lib')
2965 else:
2966 exec_dir = join(sys.exec_prefix, 'lib', py_version)
2967 for fn in os.listdir(exec_dir):
2968 copyfile(join(exec_dir, fn), join(lib_dir, fn))
2969
2970 if is_jython:
2971 # Jython has either jython-dev.jar and javalib/ dir, or just
2972 # jython.jar
2973 for name in 'jython-dev.jar', 'javalib', 'jython.jar':
2974 src = join(prefix, name)
2975 if os.path.exists(src):
2976 copyfile(src, join(home_dir, name))
2977 # XXX: registry should always exist after Jython 2.5rc1
2978 src = join(prefix, 'registry')
2979 if os.path.exists(src):
2980 copyfile(src, join(home_dir, 'registry'), symlink=False)
2981 copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
2982 symlink=False)
2983
2984 mkdir(bin_dir)
2985 py_executable = join(bin_dir, os.path.basename(sys.executable))
2986 if 'Python.framework' in prefix:
2987 if re.search(r'/Python(?:-32|-64)*$', py_executable):
2988 # The name of the python executable is not quite what
2989 # we want, rename it.
2990 py_executable = os.path.join(
2991 os.path.dirname(py_executable), 'python')
2992
2993 logger.notify('New %s executable in %s', expected_exe, py_executable)
2994 if sys.executable != py_executable:
2995 ## FIXME: could I just hard link?
2996 executable = sys.executable
2997 if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
2998 # Cygwin misreports sys.executable sometimes
2999 executable += '.exe'
3000 py_executable += '.exe'
3001 logger.info('Executable actually exists in %s' % executable)
3002 shutil.copyfile(executable, py_executable)
3003 make_exe(py_executable)
3004 if sys.platform == 'win32' or sys.platform == 'cygwin':
3005 pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
3006 if os.path.exists(pythonw):
3007 logger.info('Also created pythonw.exe')
3008 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
3009 if is_pypy:
3010 # make a symlink python --> pypy-c
3011 python_executable = os.path.join(os.path.dirname(py_executable), 'python')
3012 logger.info('Also created executable %s' % python_executable)
3013 copyfile(py_executable, python_executable)
3014
3015 if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
3016 secondary_exe = os.path.join(os.path.dirname(py_executable),
3017 expected_exe)
3018 py_executable_ext = os.path.splitext(py_executable)[1]
3019 if py_executable_ext == '.exe':
3020 # python2.4 gives an extension of '.4' :P
3021 secondary_exe += py_executable_ext
3022 if os.path.exists(secondary_exe):
3023 logger.warn('Not overwriting existing %s script %s (you must use %s)'
3024 % (expected_exe, secondary_exe, py_executable))
3025 else:
3026 logger.notify('Also creating executable in %s' % secondary_exe)
3027 shutil.copyfile(sys.executable, secondary_exe)
3028 make_exe(secondary_exe)
3029
3030 if 'Python.framework' in prefix:
3031 logger.debug('MacOSX Python framework detected')
3032
3033 # Make sure we use the the embedded interpreter inside
3034 # the framework, even if sys.executable points to
3035 # the stub executable in ${sys.prefix}/bin
3036 # See http://groups.google.com/group/python-virtualenv/
3037 # browse_thread/thread/17cab2f85da75951
3038 original_python = os.path.join(
3039 prefix, 'Resources/Python.app/Contents/MacOS/Python')
3040 shutil.copy(original_python, py_executable)
3041
3042 # Copy the framework's dylib into the virtual
3043 # environment
3044 virtual_lib = os.path.join(home_dir, '.Python')
3045
3046 if os.path.exists(virtual_lib):
3047 os.unlink(virtual_lib)
3048 copyfile(
3049 os.path.join(prefix, 'Python'),
3050 virtual_lib)
3051
3052 # And then change the install_name of the copied python executable
3053 try:
3054 call_subprocess(
3055 ["install_name_tool", "-change",
3056 os.path.join(prefix, 'Python'),
3057 '@executable_path/../.Python',
3058 py_executable])
3059 except:
3060 logger.fatal(
3061 "Could not call install_name_tool -- you must have Apple's development tools installed")
3062 raise
3063
3064 # Some tools depend on pythonX.Y being present
3065 py_executable_version = '%s.%s' % (
3066 sys.version_info[0], sys.version_info[1])
3067 if not py_executable.endswith(py_executable_version):
3068 # symlinking pythonX.Y > python
3069 pth = py_executable + '%s.%s' % (
3070 sys.version_info[0], sys.version_info[1])
3071 if os.path.exists(pth):
3072 os.unlink(pth)
3073 os.symlink('python', pth)
3074 else:
3075 # reverse symlinking python -> pythonX.Y (with --python)
3076 pth = join(bin_dir, 'python')
3077 if os.path.exists(pth):
3078 os.unlink(pth)
3079 os.symlink(os.path.basename(py_executable), pth)
3080
3081 if sys.platform == 'win32' and ' ' in py_executable:
3082 # There's a bug with subprocess on Windows when using a first
3083 # argument that has a space in it. Instead we have to quote
3084 # the value:
3085 py_executable = '"%s"' % py_executable
3086 cmd = [py_executable, '-c', 'import sys; print(sys.prefix)']
3087 logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
3088 try:
3089 proc = subprocess.Popen(cmd,
3090 stdout=subprocess.PIPE)
3091 proc_stdout, proc_stderr = proc.communicate()
3092 except OSError:
3093 e = sys.exc_info()[1]
3094 if e.errno == errno.EACCES:
3095 logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
3096 sys.exit(100)
3097 else:
3098 raise e
3099
3100 proc_stdout = proc_stdout.strip().decode(sys.getdefaultencoding())
3101 proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
3102 if proc_stdout != os.path.normcase(os.path.abspath(home_dir)):
3103 logger.fatal(
3104 'ERROR: The executable %s is not functioning' % py_executable)
3105 logger.fatal(
3106 'ERROR: It thinks sys.prefix is %r (should be %r)'
3107 % (proc_stdout, os.path.normcase(os.path.abspath(home_dir))))
3108 logger.fatal(
3109 'ERROR: virtualenv is not compatible with this system or executable')
3110 if sys.platform == 'win32':
3111 logger.fatal(
3112 'Note: some Windows users have reported this error when they installed Python for "Only this user". The problem may be resolvable if you install Python "For all users". (See https://bugs.launchpad.net/virtualenv/+bug/352844)')
3113 sys.exit(100)
3114 else:
3115 logger.info('Got sys.prefix result: %r' % proc_stdout)
3116
3117 pydistutils = os.path.expanduser('~/.pydistutils.cfg')
3118 if os.path.exists(pydistutils):
3119 logger.notify('Please make sure you remove any previous custom paths from '
3120 'your %s file.' % pydistutils)
3121 ## FIXME: really this should be calculated earlier
3122 return py_executable
3123
3124def install_activate(home_dir, bin_dir, prompt=None):
3125 if sys.platform == 'win32' or is_jython and os._name == 'nt':
3126 files = {'activate.bat': ACTIVATE_BAT,
3127 'deactivate.bat': DEACTIVATE_BAT}
3128 if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin':
3129 files['activate'] = ACTIVATE_SH
3130 else:
3131 files = {'activate': ACTIVATE_SH}
3132
3133 # suppling activate.fish in addition to, not instead of, the
3134 # bash script support.
3135 files['activate.fish'] = ACTIVATE_FISH
3136
3137 # same for csh/tcsh support...
3138 files['activate.csh'] = ACTIVATE_CSH
3139
3140
3141
3142 files['activate_this.py'] = ACTIVATE_THIS
3143 vname = os.path.basename(os.path.abspath(home_dir))
3144 for name, content in files.items():
3145 content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
3146 content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
3147 content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir))
3148 content = content.replace('__VIRTUAL_NAME__', vname)
3149 content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
3150 writefile(os.path.join(bin_dir, name), content)
3151
3152def install_distutils(home_dir):
3153 distutils_path = change_prefix(distutils.__path__[0], home_dir)
3154 mkdir(distutils_path)
3155 ## FIXME: maybe this prefix setting should only be put in place if
3156 ## there's a local distutils.cfg with a prefix setting?
3157 home_dir = os.path.abspath(home_dir)
3158 ## FIXME: this is breaking things, removing for now:
3159 #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
3160 writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
3161 writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
3162
3163def fix_lib64(lib_dir):
3164 """
3165 Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
3166 instead of lib/pythonX.Y. If this is such a platform we'll just create a
3167 symlink so lib64 points to lib
3168 """
3169 if [p for p in distutils.sysconfig.get_config_vars().values()
3170 if isinstance(p, basestring) and 'lib64' in p]:
3171 logger.debug('This system uses lib64; symlinking lib64 to lib')
3172 assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
3173 "Unexpected python lib dir: %r" % lib_dir)
3174 lib_parent = os.path.dirname(lib_dir)
3175 assert os.path.basename(lib_parent) == 'lib', (
3176 "Unexpected parent dir: %r" % lib_parent)
3177 copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
3178
3179def resolve_interpreter(exe):
3180 """
3181 If the executable given isn't an absolute path, search $PATH for the interpreter
3182 """
3183 if os.path.abspath(exe) != exe:
3184 paths = os.environ.get('PATH', '').split(os.pathsep)
3185 for path in paths:
3186 if os.path.exists(os.path.join(path, exe)):
3187 exe = os.path.join(path, exe)
3188 break
3189 if not os.path.exists(exe):
3190 logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
3191 sys.exit(3)
3192 return exe
3193
3194############################################################
3195## Relocating the environment:
3196
3197def make_environment_relocatable(home_dir):
3198 """
3199 Makes the already-existing environment use relative paths, and takes out
3200 the #!-based environment selection in scripts.
3201 """
3202 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3203 activate_this = os.path.join(bin_dir, 'activate_this.py')
3204 if not os.path.exists(activate_this):
3205 logger.fatal(
3206 'The environment doesn\'t have a file %s -- please re-run virtualenv '
3207 'on this environment to update it' % activate_this)
3208 fixup_scripts(home_dir)
3209 fixup_pth_and_egg_link(home_dir)
3210 ## FIXME: need to fix up distutils.cfg
3211
3212OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
3213 'activate', 'activate.bat', 'activate_this.py']
3214
3215def fixup_scripts(home_dir):
3216 # This is what we expect at the top of scripts:
3217 shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
3218 # This is what we'll put:
3219 new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
3220 activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
3221 if sys.platform == 'win32':
3222 bin_suffix = 'Scripts'
3223 else:
3224 bin_suffix = 'bin'
3225 bin_dir = os.path.join(home_dir, bin_suffix)
3226 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3227 for filename in os.listdir(bin_dir):
3228 filename = os.path.join(bin_dir, filename)
3229 if not os.path.isfile(filename):
3230 # ignore subdirs, e.g. .svn ones.
3231 continue
3232 f = open(filename, 'rb')
3233 lines = f.readlines()
3234 f.close()
3235 if not lines:
3236 logger.warn('Script %s is an empty file' % filename)
3237 continue
3238 if not lines[0].strip().startswith(shebang):
3239 if os.path.basename(filename) in OK_ABS_SCRIPTS:
3240 logger.debug('Cannot make script %s relative' % filename)
3241 elif lines[0].strip() == new_shebang:
3242 logger.info('Script %s has already been made relative' % filename)
3243 else:
3244 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
3245 % (filename, shebang))
3246 continue
3247 logger.notify('Making script %s relative' % filename)
3248 lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
3249 f = open(filename, 'wb')
3250 f.writelines(lines)
3251 f.close()
3252
3253def fixup_pth_and_egg_link(home_dir, sys_path=None):
3254 """Makes .pth and .egg-link files use relative paths"""
3255 home_dir = os.path.normcase(os.path.abspath(home_dir))
3256 if sys_path is None:
3257 sys_path = sys.path
3258 for path in sys_path:
3259 if not path:
3260 path = '.'
3261 if not os.path.isdir(path):
3262 continue
3263 path = os.path.normcase(os.path.abspath(path))
3264 if not path.startswith(home_dir):
3265 logger.debug('Skipping system (non-environment) directory %s' % path)
3266 continue
3267 for filename in os.listdir(path):
3268 filename = os.path.join(path, filename)
3269 if filename.endswith('.pth'):
3270 if not os.access(filename, os.W_OK):
3271 logger.warn('Cannot write .pth file %s, skipping' % filename)
3272 else:
3273 fixup_pth_file(filename)
3274 if filename.endswith('.egg-link'):
3275 if not os.access(filename, os.W_OK):
3276 logger.warn('Cannot write .egg-link file %s, skipping' % filename)
3277 else:
3278 fixup_egg_link(filename)
3279
3280def fixup_pth_file(filename):
3281 lines = []
3282 prev_lines = []
3283 f = open(filename)
3284 prev_lines = f.readlines()
3285 f.close()
3286 for line in prev_lines:
3287 line = line.strip()
3288 if (not line or line.startswith('#') or line.startswith('import ')
3289 or os.path.abspath(line) != line):
3290 lines.append(line)
3291 else:
3292 new_value = make_relative_path(filename, line)
3293 if line != new_value:
3294 logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
3295 lines.append(new_value)
3296 if lines == prev_lines:
3297 logger.info('No changes to .pth file %s' % filename)
3298 return
3299 logger.notify('Making paths in .pth file %s relative' % filename)
3300 f = open(filename, 'w')
3301 f.write('\n'.join(lines) + '\n')
3302 f.close()
3303
3304def fixup_egg_link(filename):
3305 f = open(filename)
3306 link = f.read().strip()
3307 f.close()
3308 if os.path.abspath(link) != link:
3309 logger.debug('Link in %s already relative' % filename)
3310 return
3311 new_link = make_relative_path(filename, link)
3312 logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
3313 f = open(filename, 'w')
3314 f.write(new_link)
3315 f.close()
3316
3317def make_relative_path(source, dest, dest_is_directory=True):
3318 """
3319 Make a filename relative, where the filename is dest, and it is
3320 being referred to from the filename source.
3321
3322 >>> make_relative_path('/usr/share/something/a-file.pth',
3323 ... '/usr/share/another-place/src/Directory')
3324 '../another-place/src/Directory'
3325 >>> make_relative_path('/usr/share/something/a-file.pth',
3326 ... '/home/user/src/Directory')
3327 '../../../home/user/src/Directory'
3328 >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
3329 './'
3330 """
3331 source = os.path.dirname(source)
3332 if not dest_is_directory:
3333 dest_filename = os.path.basename(dest)
3334 dest = os.path.dirname(dest)
3335 dest = os.path.normpath(os.path.abspath(dest))
3336 source = os.path.normpath(os.path.abspath(source))
3337 dest_parts = dest.strip(os.path.sep).split(os.path.sep)
3338 source_parts = source.strip(os.path.sep).split(os.path.sep)
3339 while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
3340 dest_parts.pop(0)
3341 source_parts.pop(0)
3342 full_parts = ['..']*len(source_parts) + dest_parts
3343 if not dest_is_directory:
3344 full_parts.append(dest_filename)
3345 if not full_parts:
3346 # Special case for the current directory (otherwise it'd be '')
3347 return './'
3348 return os.path.sep.join(full_parts)
3349
3350
3351
3352############################################################
3353## Bootstrap script creation:
3354
3355def create_bootstrap_script(extra_text, python_version=''):
3356 """
3357 Creates a bootstrap script, which is like this script but with
3358 extend_parser, adjust_options, and after_install hooks.
3359
3360 This returns a string that (written to disk of course) can be used
3361 as a bootstrap script with your own customizations. The script
3362 will be the standard virtualenv.py script, with your extra text
3363 added (your extra text should be Python code).
3364
3365 If you include these functions, they will be called:
3366
3367 ``extend_parser(optparse_parser)``:
3368 You can add or remove options from the parser here.
3369
3370 ``adjust_options(options, args)``:
3371 You can change options here, or change the args (if you accept
3372 different kinds of arguments, be sure you modify ``args`` so it is
3373 only ``[DEST_DIR]``).
3374
3375 ``after_install(options, home_dir)``:
3376
3377 After everything is installed, this function is called. This
3378 is probably the function you are most likely to use. An
3379 example would be::
3380
3381 def after_install(options, home_dir):
3382 subprocess.call([join(home_dir, 'bin', 'easy_install'),
3383 'MyPackage'])
3384 subprocess.call([join(home_dir, 'bin', 'my-package-script'),
3385 'setup', home_dir])
3386
3387 This example immediately installs a package, and runs a setup
3388 script from that package.
3389
3390 If you provide something like ``python_version='2.4'`` then the
3391 script will start with ``#!/usr/bin/env python2.4`` instead of
3392 ``#!/usr/bin/env python``. You can use this when the script must
3393 be run with a particular Python version.
3394 """
3395 filename = __file__
3396 if filename.endswith('.pyc'):
3397 filename = filename[:-1]
3398 f = open(filename, 'rb')
3399 content = f.read()
3400 f.close()
3401 py_exe = 'python%s' % python_version
3402 content = (('#!/usr/bin/env %s\n' % py_exe)
3403 + '## WARNING: This file is generated\n'
3404 + content)
3405 return content.replace('##EXT' 'END##', extra_text)
3406
3407##EXTEND##
3408
3409def convert(s):
3410 b = base64.b64decode(s.encode('ascii'))
3411 return zlib.decompress(b).decode('utf-8')
3412
3413##file site.py
3414SITE_PY = convert("""
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
3490X4UuruF1rMoshUjuVWhlSXfDcoyWcfRDu6HKeA1pQKc7jKwb8qz3YoFW61XIc9P9xy2j/dYAhi2D
3491vYV555LKEahGF4upRIiNeOcglF/gq116vQYKFgw3lmpcRMN0Kcw+geBarFMIIIAn12B9MU4ACJ2V
34928BPQx052QBZYDRC+2SwO/xpqgvitf/lloHldZYd/FyVEQYJLV8IBYrqN30LgE8tYnH14Nw4ZOSoF
3493FX9tsIAcHBLK8jnSTvUyvGM7jZTMlrqewdcH+EL7CfS6072SZaW7D7vGIUrAExWR1/BEGfqFWF5k
3494YU9wKuMOaKyNt5jhGTN329t8DsTHtcwyXRF9/vbiDHxHLNdHCeJ9njMYjvMluGWri734DFwHFG7o
3495wusK2bhCF5Y29Rex12wwM4siR729OgC7TpT97PfqpTqrJFUu2hFOm2GZgvMYWRnWwiwrs3anDVLY
3496bUMUR5lhlpheVlQw6fME8DI9TTgkglgJDwOYNDPvWqZ5bSrksnQOehRULijUCQgJEhdPvBHnFTkn
3497eotKmYMy8LDcVelqXWMyHTrHVKSPzX88/Xxx/p4K11+8bL3uAeacUCQw4aKFEyxJw2wHfHHLzJCr
3498ptMhntWvEAZqH/jTfcXVECc8QK8fJxbxT/cVn1Q6cSJBngEoqKbsigcGAE63IblpZYFxtXEwftyS
3499sxYzHwzlIvFghC4scOfX50TbsmNKKO9jXj5il2JZahpGprNbAtX96DkuS9xWWUTDjeDtkGyZzwy6
35003vTe7Cu2cj89KcRDk4BRv7U/hqlG6jXV03GYbR+3UFirbewvuZMrddrNcxRlIGLkdh67TDashHVz
35015kCvbLcHTHyr0TWSOKjKR7/kI+1heJhYYvfiFNORjk2QEcBMhtSnQxrwodAigAKhatPIkdzJ+OkL
3502b46ONbh/jlp3gW38ARShrv2kMwVFBZwIX35jx5FfEVqoR49F6HgqucwLW5eEn+0avcrn/hwHZYCS
3503mCh2VZKvZMSwJgbmVz6x96RgSdt6pL5Kr4cMizgH5/TLHg7vy8XwxolBrcMIvXY3ctdVRz55sMHg
35040YM7CeaDr5It6P6yqSNeyWGRHz5ttR/q/RCx2g2a6s3eKMR0zG/hnvVpAQ9SQ8NCD++3gd0i/PDa
3505GEfW2sfOKZrQvtAe7LyC0KxWtC3jHF8zvqj1AlqDe9Ka/JF9qgtT7O+Bc0lOTsgC5cFdkN7cRrpB
3506J50w4uMxfLYwpfLr9vSGfreQtzIrwPWCqA6r63+11fXj2KZTBuuOfjd2l7vL3TBu9KbF7NiU/6Nn
3507pkpYvziX9RGiM5jxuQuzFhlc6l90SJLkN+Qlv/nb+US8ef8T/P9afoC4Co/HTcTfAQ3xpqggvuTz
3508nXTwHk8O1Bw4Fo3CM3QEjbYq+I4CdNsuPTrjtog+0uCfZbCaUmAVZ7XhizEARZ4gnXlu/QRTqA+/
3509zUmijjdqPMWhRRnpl0iD/Ycr8EDCkW4Zr+tNhvbCyZK0q3k1ujh/c/b+41lcf0EONz9HThbFLwDC
35106eg94gr3wybCPpk3+OTacZx/kFk54DfroNMc1MCgU4QQl5Q20ORLFxIbXCQVZg5EuVsU8xhbAsvz
35112bB6C4702Ikv7zX0npVFWNFY76K13jw+BmqIX7qKaAQNqY+eE/UkhJIZHlLix/Fo2BRPBKW24c/T
3512m+3CzYzr0yY0wS6m7awjv7vVhWums4ZnOYnwOrHLYA4gZmmiNrO5ezDtQy70nRmg5WifQy6TJquF
3513zEFyKcinywtA07tnyVhCmFXYnNEBK0rTZNtkp5xKm0SJEY46ovPXuCFDGUOIwX9Mbtge4CE30fBp
3514WYBOiFL8VDhdVTNfswRzSETUGyg82Kb5yxdhj8I8KEfI89aRhXmi28gYrWSt588PovHV87bSgbLS
3515c+8k6bwEq+eyyQGozvLp06cj8W/3ez+MSpwVxQ24ZQB70Gu5oNd7LLeenF2tvmdv3sTAj/O1vIIH
351615Q9t8+bnFKTd3SlBZH2r4ER4tqElhlN+45d5qRdxRvN3II3rLTl+DlP6WYcTC1JVLb6giFMOxlp
3517IpYExRAmap6mIacpYD12RYOHwDDNqPlFfgGOTxHMBN/iDhmH2mv0MKlg03KPRedEjAjwiAqoeDQ6
3518RUvHoADP6eVOozk9z9O6Pb/wzN081afFa3vhjeYrkWxRMsw8OsRwzhN6rNp62MWdLOpFLMX8yk04
3519dmbJr+/DHVgbJK1YLg2m8NAs0ryQ1dyYU1yxdJ7WDhjTDuFwZ7rnh6xPHAygNAL1TlZhYSXavv2T
3520XRcX0w+0j3xoRtLlQ7W9O4mTQ0neqaKL43Z8SkNZQlq+NV/GMMp7SmtrT8AbS/xJJ1WxeN274sE9
3521R9fk+uoGrt9o73MAOHRdkFWQlh09HeHcUWXhM9PuuXABPxSiE263aVU3STbVNwRM0WGb2o11jac9
3522f3XnyULrrYCTX4AHfKhLxcFxMFU2SE+s9DRHAU7EUqcoYvdIk3/6pyzQy3vBvhL4FEiZxdQcxDVJ
3523pCvLrvaE4zO+gsBR8QjqK3Nq5iE2wZzd6B17cKcxoaKncNwt5ey1wg0WU5tvPe9uZPCoITuwfC9+
3524Xu7wKiGY1pNFTP9C382jaxxwR+zRg2fpjAYLhyqe7++rSxAxHNyAJC1TuTh8ohA7xvn3QtVQ2nnt
35255xuaMR6IPrA1UPoscHtCgg5CzcDH37bqxVE0xhu1g5hDxlor8HlMFGG2R/YMuSlD6ZQC2nu+sExQ
3526o+erauTZ6dBWFX7DuzrgvSaoy+J7tzB1UbcFOxCh65N7vCHVNhwI0R7BQyHdK0KL9lVnk/aPXDyu
3527E9+31dfD8puv78LTNauDRfIDBPWI6bT6A5lqL8s8dmEesHt+P/89nPfu4rtHU0n3GqYVBjZYVrxO
3528+A0aqKY8toG/EUncmIncYjP81DeDxzBYHFE31TfhXdPn/nfNXbcI7MzNXmtv7v5xK5cGuu9+fhmi
3529AQddmhAPquBuBXZYF7hiPNFb/MMJRP1B8rudcKZ7tMJ9YExBAaYjiU019kZrbpK5+x3rVQ75RlH3
3530dN2gru5Mu3fcsMvxD1G0vDePz+2BWyq4WGgOZC+OroiacgnfVK5Waprg9WRTcv2p3KTn0xln8h3d
3531LiUTtTM+IN7hASAMN+nCQLf2FxgDwgu+JpWrNZzLGgQNTTWNTpGkShecz9EOJ4CLOY9D/U2ekKsc
3532R5nE9JtqqrICH32kL9PkMoKhyssWqEkrbBJ1Y1A3PSb6bkUcgmtXzIk8zh6x3+9RBwjBB3Wcm4K4
3533bHg6te+AX561J4/TiWUImTcbWSV1e+uGv2mZiu+cEegcJi6wkzhoJbPDKS5iqeUPBykM3e33r7TL
353467n8dxw3Hlut93C2oh46IfWYk8yO7THcnH6xt265t70s6I5W18jbZi332ZtGYCnMFVKkK3Ukz2/1
3535tTZ8WSLnGdFNcPgI5N49BeUXy1q1xk6KRcN55iqG/j0meJCWbPHQ9WQ9LuhfROYzQzu+rzcss/R2
3536qPY0tlTUrtWg4mlHG7fxLda13RPf+rXLj4xvPfgPjG/1ZXJgcDQ+Wh8MVjPfEwizmnBvZmsZAfpM
3537gUi4z9a518uYzMitDYYgNP0ysjejss50DhwZM4Ec2b+yh0DwDWzKLaT0bkgy4w7Fl7500ePvLz68
3538Pr0gWkwvT9/8x+n3VDuCydyOzXpwAiAvDpnah16VqpsM0Pv9Q4O32A5cdchHLTSE3vveVukAhOFj
3539NUML2lVk7ut9HXrHE/qdAPG7p92Buk9lD0Lu+We6FN7d5e+Ukwb6Kdf+mV/OBqp5ZPYRWBzafQLz
3540vk3tahntZb72LZxThddXJ9pv1Zfj7cnKjW0tKK0AZnSRv2xC1xT227QhOyrd++qpgBUPRZmLJUAK
354159K54IzuNmNQtX8xfgXKLsFdKXYYJ/aSWWrHyWtlb0/Gnam5jA1BvFNJo/78XGFfyGwPFYKAFZ6+
3542vosRMfpPb/fYzdEnSlwd0vnHQ1Q21/YXrpl2cv+W4hZoba/BUVxHwZtA0HjZZO62pu3T60DOH+XK
3543i6VTcA+a7wjo3IqnAvZGn4kV4mwnQggk9fYd1vARHfUdVg7yaDcd7A2tnonDfafj3NNhQjzf33DR
3544OYCme7zgHuqeHqoxZ5AcC4zFZPuOvYnvCDJvtgi698ZzPnCHT1+3Cl9vr54f29Qn8ju+dhQJFb2M
3545HMN+5RSN3XnXmtOdmKWaUFURxmzOoUnd4tqByj7BvhinVzm/Jw4yu7AMaeS9Hy65MT28O6RHXUwt
35466x3DlET0RI1pWs5ZA427fTLuT7dVW30gfG7iAUB6KhBgIZiebnTq2HZcjBo901HhrKFbKt38d+hI
3547BdW0+BzBPYzv1+LX7U7nHR/UnVE0/blBlwP1koNws+/ArcZeSmS/SehOveWDPS4AHx0d7v/8Af37
35481Va2+4u7/Grb6uXgcSX2ZbFAD+sWOiQyj2MwMqA3I9LWWNVtBB2vhGjp6DJUOzfkC3T8qOgP76Cl
3549AIOc2an2AKxRCP4P1A2QJQ==
3550""")
3551
3552
3553
3554##file ez_setup.py
3555EZ_SETUP_PY = convert("""
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
3622BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
3623""")
3624
3625
3626
3627##file distribute_setup.py
3628DISTRIBUTE_SETUP_PY = convert("""
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
3708""")
3709
3710
3711
3712##file activate.sh
3713ACTIVATE_SH = convert("""
3714eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9
3715H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq
3716DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs
3717cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY
3718G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T
3719EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs
3720wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG
37215eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/
3722JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR
3723huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx
3724Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L
3725Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw
3726WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX
3727LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2
3728""")
3729
3730
3731
3732##file activate.fish
3733ACTIVATE_FISH = convert("""
3734eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
3735Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
3736pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
3737lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
3738g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
3739grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
3740xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
3741MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
3742H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
3743L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
3744fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
3745pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
3746MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
3747O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
37487SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
3749m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
3750djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
3751mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
3752jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
3753""")
3754
3755
3756
3757##file activate.csh
3758ACTIVATE_CSH = convert("""
3759eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
3760XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
3761kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
3762pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
3763sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
3764yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
3765E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
3766lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
3767r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
3768""")
3769
3770
3771
3772##file activate.bat
3773ACTIVATE_BAT = convert("""
3774eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
3775qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
3776sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
3777ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
3778""")
3779
3780
3781
3782##file deactivate.bat
3783DEACTIVATE_BAT = convert("""
3784eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
3785FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
3786i2dASrm4rFz9XLgAwJNbyQ==
3787""")
3788
3789
3790
3791##file distutils-init.py
3792DISTUTILS_INIT = convert("""
3793eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
3794luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
3795KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
3796ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
3797QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
3798yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
3799bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
3800bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
3801yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
3802Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
3803Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
3804/n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
3805FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
3806AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
3807hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
3808UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
38098h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
3810XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
3811azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
38128dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
3813gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
38145C4rFgwLGfMvJuAMew==
3815""")
3816
3817
3818
3819##file distutils.cfg
3820DISTUTILS_CFG = convert("""
3821eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
3822xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
38239FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
3824""")
3825
3826
3827
3828##file activate_this.py
3829ACTIVATE_THIS = convert("""
3830eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ
3831VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a
3832Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE
3833qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX
38344lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7
3835HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n
3836xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96
38371Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI
38383vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU=
3839""")
3840
3841
3842
3843if __name__ == '__main__':
3844 main()
3845
3846## TODO:
3847## Copy python.exe.manifest
3848## Monkeypatch distutils.sysconfig
3849>>>>>>> MERGE-SOURCE
19583850
=== modified file '.pc/applied-patches'
--- .pc/applied-patches 2011-09-08 15:38:18 +0000
+++ .pc/applied-patches 2011-09-08 21:10:23 +0000
@@ -1,2 +1,8 @@
1look_for_external_files.patch1<<<<<<< TREE
2add_distribute.patch2look_for_external_files.patch
3add_distribute.patch
4=======
5look_for_external_files.patch
6add_distribute.patch
7remove_syspath0_on_reinvoke.patch
8>>>>>>> MERGE-SOURCE
39
=== modified file '.pc/look_for_external_files.patch/setup.py'
--- .pc/look_for_external_files.patch/setup.py 2011-09-08 15:38:18 +0000
+++ .pc/look_for_external_files.patch/setup.py 2011-09-08 21:10:23 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
1import sys, os2import sys, os
2try:3try:
3 from setuptools import setup4 from setuptools import setup
@@ -56,3 +57,61 @@
56 tests_require=['nose', 'Mock'],57 tests_require=['nose', 'Mock'],
57 **kw58 **kw
58 )59 )
60=======
61import sys, os
62try:
63 from setuptools import setup
64 kw = {'entry_points':
65 """[console_scripts]\nvirtualenv = virtualenv:main\n""",
66 'zip_safe': False}
67except ImportError:
68 from distutils.core import setup
69 if sys.platform == 'win32':
70 print('Note: without Setuptools installed you will have to use "python -m virtualenv ENV"')
71 kw = {}
72 else:
73 kw = {'scripts': ['scripts/virtualenv']}
74
75here = os.path.dirname(os.path.abspath(__file__))
76
77## Get long_description from index.txt:
78f = open(os.path.join(here, 'docs', 'index.txt'))
79long_description = f.read().strip()
80long_description = long_description.split('split here', 1)[1]
81f.close()
82f = open(os.path.join(here, 'docs', 'news.txt'))
83long_description += "\n\n" + f.read()
84f.close()
85
86setup(name='virtualenv',
87 # If you change the version here, change it in virtualenv.py and
88 # docs/conf.py as well
89 version="1.6",
90 description="Virtual Python Environment builder",
91 long_description=long_description,
92 classifiers=[
93 'Development Status :: 4 - Beta',
94 'Intended Audience :: Developers',
95 'License :: OSI Approved :: MIT License',
96 'Programming Language :: Python :: 2',
97 'Programming Language :: Python :: 2.4',
98 'Programming Language :: Python :: 2.5',
99 'Programming Language :: Python :: 2.6',
100 'Programming Language :: Python :: 2.7',
101 'Programming Language :: Python :: 3',
102 'Programming Language :: Python :: 3.1',
103 'Programming Language :: Python :: 3.2',
104 ],
105 keywords='setuptools deployment installation distutils',
106 author='Ian Bicking',
107 author_email='ianb@colorstudy.com',
108 maintainer='Jannis Leidel, Carl Meyer and Brian Rosner',
109 maintainer_email='python-virtualenv@groups.google.com',
110 url='http://www.virtualenv.org',
111 license='MIT',
112 py_modules=['virtualenv'],
113 packages=['virtualenv_support'],
114 package_data={'virtualenv_support': ['*-py%s.egg' % sys.version[:3], '*.tar.gz']},
115 **kw
116 )
117>>>>>>> MERGE-SOURCE
59118
=== modified file '.pc/look_for_external_files.patch/virtualenv.py' (properties changed: -x to +x)
--- .pc/look_for_external_files.patch/virtualenv.py 2011-09-08 15:38:18 +0000
+++ .pc/look_for_external_files.patch/virtualenv.py 2011-09-08 21:10:23 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
1#!/usr/bin/env python2#!/usr/bin/env python
2"""Create a "virtual" Python installation3"""Create a "virtual" Python installation
3"""4"""
@@ -1954,3 +1955,1893 @@
1954## TODO:1955## TODO:
1955## Copy python.exe.manifest1956## Copy python.exe.manifest
1956## Monkeypatch distutils.sysconfig1957## Monkeypatch distutils.sysconfig
1958=======
1959"""Create a "virtual" Python installation
1960"""
1961
1962# If you change the version here, change it in setup.py
1963# and docs/conf.py as well.
1964virtualenv_version = "1.6"
1965
1966import base64
1967import sys
1968import os
1969import optparse
1970import re
1971import shutil
1972import logging
1973import tempfile
1974import zlib
1975import errno
1976import distutils.sysconfig
1977try:
1978 import subprocess
1979except ImportError:
1980 if sys.version_info <= (2, 3):
1981 print('ERROR: %s' % sys.exc_info()[1])
1982 print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
1983 print('If you copy subprocess.py from a newer version of Python this script will probably work')
1984 sys.exit(101)
1985 else:
1986 raise
1987try:
1988 set
1989except NameError:
1990 from sets import Set as set
1991try:
1992 basestring
1993except NameError:
1994 basestring = str
1995
1996join = os.path.join
1997py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
1998
1999is_jython = sys.platform.startswith('java')
2000is_pypy = hasattr(sys, 'pypy_version_info')
2001abiflags = getattr(sys, 'abiflags', '')
2002
2003if is_pypy:
2004 expected_exe = 'pypy'
2005elif is_jython:
2006 expected_exe = 'jython'
2007else:
2008 expected_exe = 'python'
2009
2010
2011REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
2012 'fnmatch', 'locale', 'encodings', 'codecs',
2013 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
2014 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
2015 'zlib']
2016
2017REQUIRED_FILES = ['lib-dynload', 'config']
2018
2019majver, minver = sys.version_info[:2]
2020if majver == 2:
2021 if minver >= 6:
2022 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
2023 if minver >= 7:
2024 REQUIRED_MODULES.extend(['_weakrefset'])
2025 if minver <= 3:
2026 REQUIRED_MODULES.extend(['sets', '__future__'])
2027elif majver == 3:
2028 # Some extra modules are needed for Python 3, but different ones
2029 # for different versions.
2030 REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
2031 '_weakrefset', 'copyreg', 'tempfile', 'random',
2032 '__future__', 'collections', 'keyword', 'tarfile',
2033 'shutil', 'struct', 'copy'])
2034 if minver >= 2:
2035 REQUIRED_FILES[-1] = 'config-%s' % majver
2036 if minver == 3:
2037 # The whole list of 3.3 modules is reproduced below - the current
2038 # uncommented ones are required for 3.3 as of now, but more may be
2039 # added as 3.3 development continues.
2040 REQUIRED_MODULES.extend([
2041 #"aifc",
2042 #"antigravity",
2043 #"argparse",
2044 #"ast",
2045 #"asynchat",
2046 #"asyncore",
2047 "base64",
2048 #"bdb",
2049 #"binhex",
2050 "bisect",
2051 #"calendar",
2052 #"cgi",
2053 #"cgitb",
2054 #"chunk",
2055 #"cmd",
2056 #"codeop",
2057 #"code",
2058 #"colorsys",
2059 #"_compat_pickle",
2060 #"compileall",
2061 #"concurrent",
2062 #"configparser",
2063 #"contextlib",
2064 #"cProfile",
2065 #"crypt",
2066 #"csv",
2067 #"ctypes",
2068 #"curses",
2069 #"datetime",
2070 #"dbm",
2071 #"decimal",
2072 #"difflib",
2073 #"dis",
2074 #"doctest",
2075 #"dummy_threading",
2076 #"_dummy_thread",
2077 #"email",
2078 #"filecmp",
2079 #"fileinput",
2080 #"formatter",
2081 #"fractions",
2082 #"ftplib",
2083 #"functools",
2084 #"getopt",
2085 #"getpass",
2086 #"gettext",
2087 #"glob",
2088 #"gzip",
2089 "hashlib",
2090 "heapq",
2091 "hmac",
2092 #"html",
2093 #"http",
2094 #"idlelib",
2095 #"imaplib",
2096 #"imghdr",
2097 #"importlib",
2098 #"inspect",
2099 #"json",
2100 #"lib2to3",
2101 #"logging",
2102 #"macpath",
2103 #"macurl2path",
2104 #"mailbox",
2105 #"mailcap",
2106 #"_markupbase",
2107 #"mimetypes",
2108 #"modulefinder",
2109 #"multiprocessing",
2110 #"netrc",
2111 #"nntplib",
2112 #"nturl2path",
2113 #"numbers",
2114 #"opcode",
2115 #"optparse",
2116 #"os2emxpath",
2117 #"pdb",
2118 #"pickle",
2119 #"pickletools",
2120 #"pipes",
2121 #"pkgutil",
2122 #"platform",
2123 #"plat-linux2",
2124 #"plistlib",
2125 #"poplib",
2126 #"pprint",
2127 #"profile",
2128 #"pstats",
2129 #"pty",
2130 #"pyclbr",
2131 #"py_compile",
2132 #"pydoc_data",
2133 #"pydoc",
2134 #"_pyio",
2135 #"queue",
2136 #"quopri",
2137 "reprlib",
2138 "rlcompleter",
2139 #"runpy",
2140 #"sched",
2141 #"shelve",
2142 #"shlex",
2143 #"smtpd",
2144 #"smtplib",
2145 #"sndhdr",
2146 #"socket",
2147 #"socketserver",
2148 #"sqlite3",
2149 #"ssl",
2150 #"stringprep",
2151 #"string",
2152 #"_strptime",
2153 #"subprocess",
2154 #"sunau",
2155 #"symbol",
2156 #"symtable",
2157 #"sysconfig",
2158 #"tabnanny",
2159 #"telnetlib",
2160 #"test",
2161 #"textwrap",
2162 #"this",
2163 #"_threading_local",
2164 #"threading",
2165 #"timeit",
2166 #"tkinter",
2167 #"tokenize",
2168 #"token",
2169 #"traceback",
2170 #"trace",
2171 #"tty",
2172 #"turtledemo",
2173 #"turtle",
2174 #"unittest",
2175 #"urllib",
2176 #"uuid",
2177 #"uu",
2178 #"wave",
2179 "weakref",
2180 #"webbrowser",
2181 #"wsgiref",
2182 #"xdrlib",
2183 #"xml",
2184 #"xmlrpc",
2185 #"zipfile",
2186 ])
2187
2188if is_pypy:
2189 # these are needed to correctly display the exceptions that may happen
2190 # during the bootstrap
2191 REQUIRED_MODULES.extend(['traceback', 'linecache'])
2192
2193class Logger(object):
2194
2195 """
2196 Logging object for use in command-line script. Allows ranges of
2197 levels, to avoid some redundancy of displayed information.
2198 """
2199
2200 DEBUG = logging.DEBUG
2201 INFO = logging.INFO
2202 NOTIFY = (logging.INFO+logging.WARN)/2
2203 WARN = WARNING = logging.WARN
2204 ERROR = logging.ERROR
2205 FATAL = logging.FATAL
2206
2207 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
2208
2209 def __init__(self, consumers):
2210 self.consumers = consumers
2211 self.indent = 0
2212 self.in_progress = None
2213 self.in_progress_hanging = False
2214
2215 def debug(self, msg, *args, **kw):
2216 self.log(self.DEBUG, msg, *args, **kw)
2217 def info(self, msg, *args, **kw):
2218 self.log(self.INFO, msg, *args, **kw)
2219 def notify(self, msg, *args, **kw):
2220 self.log(self.NOTIFY, msg, *args, **kw)
2221 def warn(self, msg, *args, **kw):
2222 self.log(self.WARN, msg, *args, **kw)
2223 def error(self, msg, *args, **kw):
2224 self.log(self.WARN, msg, *args, **kw)
2225 def fatal(self, msg, *args, **kw):
2226 self.log(self.FATAL, msg, *args, **kw)
2227 def log(self, level, msg, *args, **kw):
2228 if args:
2229 if kw:
2230 raise TypeError(
2231 "You may give positional or keyword arguments, not both")
2232 args = args or kw
2233 rendered = None
2234 for consumer_level, consumer in self.consumers:
2235 if self.level_matches(level, consumer_level):
2236 if (self.in_progress_hanging
2237 and consumer in (sys.stdout, sys.stderr)):
2238 self.in_progress_hanging = False
2239 sys.stdout.write('\n')
2240 sys.stdout.flush()
2241 if rendered is None:
2242 if args:
2243 rendered = msg % args
2244 else:
2245 rendered = msg
2246 rendered = ' '*self.indent + rendered
2247 if hasattr(consumer, 'write'):
2248 consumer.write(rendered+'\n')
2249 else:
2250 consumer(rendered)
2251
2252 def start_progress(self, msg):
2253 assert not self.in_progress, (
2254 "Tried to start_progress(%r) while in_progress %r"
2255 % (msg, self.in_progress))
2256 if self.level_matches(self.NOTIFY, self._stdout_level()):
2257 sys.stdout.write(msg)
2258 sys.stdout.flush()
2259 self.in_progress_hanging = True
2260 else:
2261 self.in_progress_hanging = False
2262 self.in_progress = msg
2263
2264 def end_progress(self, msg='done.'):
2265 assert self.in_progress, (
2266 "Tried to end_progress without start_progress")
2267 if self.stdout_level_matches(self.NOTIFY):
2268 if not self.in_progress_hanging:
2269 # Some message has been printed out since start_progress
2270 sys.stdout.write('...' + self.in_progress + msg + '\n')
2271 sys.stdout.flush()
2272 else:
2273 sys.stdout.write(msg + '\n')
2274 sys.stdout.flush()
2275 self.in_progress = None
2276 self.in_progress_hanging = False
2277
2278 def show_progress(self):
2279 """If we are in a progress scope, and no log messages have been
2280 shown, write out another '.'"""
2281 if self.in_progress_hanging:
2282 sys.stdout.write('.')
2283 sys.stdout.flush()
2284
2285 def stdout_level_matches(self, level):
2286 """Returns true if a message at this level will go to stdout"""
2287 return self.level_matches(level, self._stdout_level())
2288
2289 def _stdout_level(self):
2290 """Returns the level that stdout runs at"""
2291 for level, consumer in self.consumers:
2292 if consumer is sys.stdout:
2293 return level
2294 return self.FATAL
2295
2296 def level_matches(self, level, consumer_level):
2297 """
2298 >>> l = Logger()
2299 >>> l.level_matches(3, 4)
2300 False
2301 >>> l.level_matches(3, 2)
2302 True
2303 >>> l.level_matches(slice(None, 3), 3)
2304 False
2305 >>> l.level_matches(slice(None, 3), 2)
2306 True
2307 >>> l.level_matches(slice(1, 3), 1)
2308 True
2309 >>> l.level_matches(slice(2, 3), 1)
2310 False
2311 """
2312 if isinstance(level, slice):
2313 start, stop = level.start, level.stop
2314 if start is not None and start > consumer_level:
2315 return False
2316 if stop is not None or stop <= consumer_level:
2317 return False
2318 return True
2319 else:
2320 return level >= consumer_level
2321
2322 #@classmethod
2323 def level_for_integer(cls, level):
2324 levels = cls.LEVELS
2325 if level < 0:
2326 return levels[0]
2327 if level >= len(levels):
2328 return levels[-1]
2329 return levels[level]
2330
2331 level_for_integer = classmethod(level_for_integer)
2332
2333# create a silent logger just to prevent this from being undefined
2334# will be overridden with requested verbosity main() is called.
2335logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
2336
2337def mkdir(path):
2338 if not os.path.exists(path):
2339 logger.info('Creating %s', path)
2340 os.makedirs(path)
2341 else:
2342 logger.info('Directory %s already exists', path)
2343
2344def copyfileordir(src, dest):
2345 if os.path.isdir(src):
2346 shutil.copytree(src, dest, True)
2347 else:
2348 shutil.copy2(src, dest)
2349
2350def copyfile(src, dest, symlink=True):
2351 if not os.path.exists(src):
2352 # Some bad symlink in the src
2353 logger.warn('Cannot find file %s (bad symlink)', src)
2354 return
2355 if os.path.exists(dest):
2356 logger.debug('File %s already exists', dest)
2357 return
2358 if not os.path.exists(os.path.dirname(dest)):
2359 logger.info('Creating parent directories for %s' % os.path.dirname(dest))
2360 os.makedirs(os.path.dirname(dest))
2361 if not os.path.islink(src):
2362 srcpath = os.path.abspath(src)
2363 else:
2364 srcpath = os.readlink(src)
2365 if symlink and hasattr(os, 'symlink'):
2366 logger.info('Symlinking %s', dest)
2367 try:
2368 os.symlink(srcpath, dest)
2369 except (OSError, NotImplementedError):
2370 logger.info('Symlinking failed, copying to %s', dest)
2371 copyfileordir(src, dest)
2372 else:
2373 logger.info('Copying to %s', dest)
2374 copyfileordir(src, dest)
2375
2376def writefile(dest, content, overwrite=True):
2377 if not os.path.exists(dest):
2378 logger.info('Writing %s', dest)
2379 f = open(dest, 'wb')
2380 f.write(content.encode('utf-8'))
2381 f.close()
2382 return
2383 else:
2384 f = open(dest, 'rb')
2385 c = f.read()
2386 f.close()
2387 if c != content:
2388 if not overwrite:
2389 logger.notify('File %s exists with different content; not overwriting', dest)
2390 return
2391 logger.notify('Overwriting %s with new content', dest)
2392 f = open(dest, 'wb')
2393 f.write(content.encode('utf-8'))
2394 f.close()
2395 else:
2396 logger.info('Content %s already in place', dest)
2397
2398def rmtree(dir):
2399 if os.path.exists(dir):
2400 logger.notify('Deleting tree %s', dir)
2401 shutil.rmtree(dir)
2402 else:
2403 logger.info('Do not need to delete %s; already gone', dir)
2404
2405def make_exe(fn):
2406 if hasattr(os, 'chmod'):
2407 oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
2408 newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
2409 os.chmod(fn, newmode)
2410 logger.info('Changed mode of %s to %s', fn, oct(newmode))
2411
2412def _find_file(filename, dirs):
2413 for dir in dirs:
2414 if os.path.exists(join(dir, filename)):
2415 return join(dir, filename)
2416 return filename
2417
2418def _install_req(py_executable, unzip=False, distribute=False):
2419 if not distribute:
2420 setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
2421 project_name = 'setuptools'
2422 bootstrap_script = EZ_SETUP_PY
2423 source = None
2424 else:
2425 setup_fn = None
2426 source = 'distribute-0.6.15.tar.gz'
2427 project_name = 'distribute'
2428 bootstrap_script = DISTRIBUTE_SETUP_PY
2429 try:
2430 # check if the global Python has distribute installed or plain
2431 # setuptools
2432 import pkg_resources
2433 if not hasattr(pkg_resources, '_distribute'):
2434 location = os.path.dirname(pkg_resources.__file__)
2435 logger.notify("A globally installed setuptools was found (in %s)" % location)
2436 logger.notify("Use the --no-site-packages option to use distribute in "
2437 "the virtualenv.")
2438 except ImportError:
2439 pass
2440
2441 search_dirs = file_search_dirs()
2442
2443 if setup_fn is not None:
2444 setup_fn = _find_file(setup_fn, search_dirs)
2445
2446 if source is not None:
2447 source = _find_file(source, search_dirs)
2448
2449 if is_jython and os._name == 'nt':
2450 # Jython's .bat sys.executable can't handle a command line
2451 # argument with newlines
2452 fd, ez_setup = tempfile.mkstemp('.py')
2453 os.write(fd, bootstrap_script)
2454 os.close(fd)
2455 cmd = [py_executable, ez_setup]
2456 else:
2457 cmd = [py_executable, '-c', bootstrap_script]
2458 if unzip:
2459 cmd.append('--always-unzip')
2460 env = {}
2461 remove_from_env = []
2462 if logger.stdout_level_matches(logger.DEBUG):
2463 cmd.append('-v')
2464
2465 old_chdir = os.getcwd()
2466 if setup_fn is not None and os.path.exists(setup_fn):
2467 logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
2468 cmd.append(setup_fn)
2469 if os.environ.get('PYTHONPATH'):
2470 env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
2471 else:
2472 env['PYTHONPATH'] = setup_fn
2473 else:
2474 # the source is found, let's chdir
2475 if source is not None and os.path.exists(source):
2476 os.chdir(os.path.dirname(source))
2477 # in this case, we want to be sure that PYTHONPATH is unset (not
2478 # just empty, really unset), else CPython tries to import the
2479 # site.py that it's in virtualenv_support
2480 remove_from_env.append('PYTHONPATH')
2481 else:
2482 logger.info('No %s egg found; downloading' % project_name)
2483 cmd.extend(['--always-copy', '-U', project_name])
2484 logger.start_progress('Installing %s...' % project_name)
2485 logger.indent += 2
2486 cwd = None
2487 if project_name == 'distribute':
2488 env['DONT_PATCH_SETUPTOOLS'] = 'true'
2489
2490 def _filter_ez_setup(line):
2491 return filter_ez_setup(line, project_name)
2492
2493 if not os.access(os.getcwd(), os.W_OK):
2494 cwd = tempfile.mkdtemp()
2495 if source is not None and os.path.exists(source):
2496 # the current working dir is hostile, let's copy the
2497 # tarball to a temp dir
2498 target = os.path.join(cwd, os.path.split(source)[-1])
2499 shutil.copy(source, target)
2500 try:
2501 call_subprocess(cmd, show_stdout=False,
2502 filter_stdout=_filter_ez_setup,
2503 extra_env=env,
2504 remove_from_env=remove_from_env,
2505 cwd=cwd)
2506 finally:
2507 logger.indent -= 2
2508 logger.end_progress()
2509 if os.getcwd() != old_chdir:
2510 os.chdir(old_chdir)
2511 if is_jython and os._name == 'nt':
2512 os.remove(ez_setup)
2513
2514def file_search_dirs():
2515 here = os.path.dirname(os.path.abspath(__file__))
2516 dirs = ['.', here,
2517 join(here, 'virtualenv_support')]
2518 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
2519 # Probably some boot script; just in case virtualenv is installed...
2520 try:
2521 import virtualenv
2522 except ImportError:
2523 pass
2524 else:
2525 dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
2526 return [d for d in dirs if os.path.isdir(d)]
2527
2528def install_setuptools(py_executable, unzip=False):
2529 _install_req(py_executable, unzip)
2530
2531def install_distribute(py_executable, unzip=False):
2532 _install_req(py_executable, unzip, distribute=True)
2533
2534_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
2535def install_pip(py_executable):
2536 filenames = []
2537 for dir in file_search_dirs():
2538 filenames.extend([join(dir, fn) for fn in os.listdir(dir)
2539 if _pip_re.search(fn)])
2540 filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
2541 filenames.sort()
2542 filenames = [filename for basename, i, filename in filenames]
2543 if not filenames:
2544 filename = 'pip'
2545 else:
2546 filename = filenames[-1]
2547 easy_install_script = 'easy_install'
2548 if sys.platform == 'win32':
2549 easy_install_script = 'easy_install-script.py'
2550 cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
2551 if filename == 'pip':
2552 logger.info('Installing pip from network...')
2553 else:
2554 logger.info('Installing %s' % os.path.basename(filename))
2555 logger.indent += 2
2556 def _filter_setup(line):
2557 return filter_ez_setup(line, 'pip')
2558 try:
2559 call_subprocess(cmd, show_stdout=False,
2560 filter_stdout=_filter_setup)
2561 finally:
2562 logger.indent -= 2
2563
2564def filter_ez_setup(line, project_name='setuptools'):
2565 if not line.strip():
2566 return Logger.DEBUG
2567 if project_name == 'distribute':
2568 for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
2569 'Scanning', 'Setuptools', 'Egg', 'Already',
2570 'running', 'writing', 'reading', 'installing',
2571 'creating', 'copying', 'byte-compiling', 'removing',
2572 'Processing'):
2573 if line.startswith(prefix):
2574 return Logger.DEBUG
2575 return Logger.DEBUG
2576 for prefix in ['Reading ', 'Best match', 'Processing setuptools',
2577 'Copying setuptools', 'Adding setuptools',
2578 'Installing ', 'Installed ']:
2579 if line.startswith(prefix):
2580 return Logger.DEBUG
2581 return Logger.INFO
2582
2583def main():
2584 parser = optparse.OptionParser(
2585 version=virtualenv_version,
2586 usage="%prog [OPTIONS] DEST_DIR")
2587
2588 parser.add_option(
2589 '-v', '--verbose',
2590 action='count',
2591 dest='verbose',
2592 default=0,
2593 help="Increase verbosity")
2594
2595 parser.add_option(
2596 '-q', '--quiet',
2597 action='count',
2598 dest='quiet',
2599 default=0,
2600 help='Decrease verbosity')
2601
2602 parser.add_option(
2603 '-p', '--python',
2604 dest='python',
2605 metavar='PYTHON_EXE',
2606 help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
2607 'interpreter to create the new environment. The default is the interpreter that '
2608 'virtualenv was installed with (%s)' % sys.executable)
2609
2610 parser.add_option(
2611 '--clear',
2612 dest='clear',
2613 action='store_true',
2614 help="Clear out the non-root install and start from scratch")
2615
2616 parser.add_option(
2617 '--no-site-packages',
2618 dest='no_site_packages',
2619 action='store_true',
2620 help="Don't give access to the global site-packages dir to the "
2621 "virtual environment")
2622
2623 parser.add_option(
2624 '--unzip-setuptools',
2625 dest='unzip_setuptools',
2626 action='store_true',
2627 help="Unzip Setuptools or Distribute when installing it")
2628
2629 parser.add_option(
2630 '--relocatable',
2631 dest='relocatable',
2632 action='store_true',
2633 help='Make an EXISTING virtualenv environment relocatable. '
2634 'This fixes up scripts and makes all .pth files relative')
2635
2636 parser.add_option(
2637 '--distribute',
2638 dest='use_distribute',
2639 action='store_true',
2640 help='Use Distribute instead of Setuptools. Set environ variable '
2641 'VIRTUALENV_USE_DISTRIBUTE to make it the default ')
2642
2643 parser.add_option(
2644 '--prompt=',
2645 dest='prompt',
2646 help='Provides an alternative prompt prefix for this environment')
2647
2648 if 'extend_parser' in globals():
2649 extend_parser(parser)
2650
2651 options, args = parser.parse_args()
2652
2653 global logger
2654
2655 if 'adjust_options' in globals():
2656 adjust_options(options, args)
2657
2658 verbosity = options.verbose - options.quiet
2659 logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
2660
2661 if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
2662 env = os.environ.copy()
2663 interpreter = resolve_interpreter(options.python)
2664 if interpreter == sys.executable:
2665 logger.warn('Already using interpreter %s' % interpreter)
2666 else:
2667 logger.notify('Running virtualenv with interpreter %s' % interpreter)
2668 env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
2669 file = __file__
2670 if file.endswith('.pyc'):
2671 file = file[:-1]
2672 popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
2673 raise SystemExit(popen.wait())
2674
2675 if not args:
2676 print('You must provide a DEST_DIR')
2677 parser.print_help()
2678 sys.exit(2)
2679 if len(args) > 1:
2680 print('There must be only one argument: DEST_DIR (you gave %s)' % (
2681 ' '.join(args)))
2682 parser.print_help()
2683 sys.exit(2)
2684
2685 home_dir = args[0]
2686
2687 if os.environ.get('WORKING_ENV'):
2688 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
2689 logger.fatal('Please deactivate your workingenv, then re-run this script')
2690 sys.exit(3)
2691
2692 if 'PYTHONHOME' in os.environ:
2693 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
2694 del os.environ['PYTHONHOME']
2695
2696 if options.relocatable:
2697 make_environment_relocatable(home_dir)
2698 return
2699
2700 create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
2701 unzip_setuptools=options.unzip_setuptools,
2702 use_distribute=options.use_distribute or majver > 2,
2703 prompt=options.prompt)
2704 if 'after_install' in globals():
2705 after_install(options, home_dir)
2706
2707def call_subprocess(cmd, show_stdout=True,
2708 filter_stdout=None, cwd=None,
2709 raise_on_returncode=True, extra_env=None,
2710 remove_from_env=None):
2711 cmd_parts = []
2712 for part in cmd:
2713 if len(part) > 45:
2714 part = part[:20]+"..."+part[-20:]
2715 if ' ' in part or '\n' in part or '"' in part or "'" in part:
2716 part = '"%s"' % part.replace('"', '\\"')
2717 cmd_parts.append(part)
2718 cmd_desc = ' '.join(cmd_parts)
2719 if show_stdout:
2720 stdout = None
2721 else:
2722 stdout = subprocess.PIPE
2723 logger.debug("Running command %s" % cmd_desc)
2724 if extra_env or remove_from_env:
2725 env = os.environ.copy()
2726 if extra_env:
2727 env.update(extra_env)
2728 if remove_from_env:
2729 for varname in remove_from_env:
2730 env.pop(varname, None)
2731 else:
2732 env = None
2733 try:
2734 proc = subprocess.Popen(
2735 cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
2736 cwd=cwd, env=env)
2737 except Exception:
2738 e = sys.exc_info()[1]
2739 logger.fatal(
2740 "Error %s while executing command %s" % (e, cmd_desc))
2741 raise
2742 all_output = []
2743 if stdout is not None:
2744 stdout = proc.stdout
2745 encoding = sys.getdefaultencoding()
2746 while 1:
2747 line = stdout.readline().decode(encoding)
2748 if not line:
2749 break
2750 line = line.rstrip()
2751 all_output.append(line)
2752 if filter_stdout:
2753 level = filter_stdout(line)
2754 if isinstance(level, tuple):
2755 level, line = level
2756 logger.log(level, line)
2757 if not logger.stdout_level_matches(level):
2758 logger.show_progress()
2759 else:
2760 logger.info(line)
2761 else:
2762 proc.communicate()
2763 proc.wait()
2764 if proc.returncode:
2765 if raise_on_returncode:
2766 if all_output:
2767 logger.notify('Complete output from command %s:' % cmd_desc)
2768 logger.notify('\n'.join(all_output) + '\n----------------------------------------')
2769 raise OSError(
2770 "Command %s failed with error code %s"
2771 % (cmd_desc, proc.returncode))
2772 else:
2773 logger.warn(
2774 "Command %s had error code %s"
2775 % (cmd_desc, proc.returncode))
2776
2777
2778def create_environment(home_dir, site_packages=True, clear=False,
2779 unzip_setuptools=False, use_distribute=False,
2780 prompt=None):
2781 """
2782 Creates a new environment in ``home_dir``.
2783
2784 If ``site_packages`` is true (the default) then the global
2785 ``site-packages/`` directory will be on the path.
2786
2787 If ``clear`` is true (default False) then the environment will
2788 first be cleared.
2789 """
2790 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
2791
2792 py_executable = os.path.abspath(install_python(
2793 home_dir, lib_dir, inc_dir, bin_dir,
2794 site_packages=site_packages, clear=clear))
2795
2796 install_distutils(home_dir)
2797
2798 if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
2799 install_distribute(py_executable, unzip=unzip_setuptools)
2800 else:
2801 install_setuptools(py_executable, unzip=unzip_setuptools)
2802
2803 install_pip(py_executable)
2804
2805 install_activate(home_dir, bin_dir, prompt)
2806
2807def path_locations(home_dir):
2808 """Return the path locations for the environment (where libraries are,
2809 where scripts go, etc)"""
2810 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
2811 # prefix arg is broken: http://bugs.python.org/issue3386
2812 if sys.platform == 'win32':
2813 # Windows has lots of problems with executables with spaces in
2814 # the name; this function will remove them (using the ~1
2815 # format):
2816 mkdir(home_dir)
2817 if ' ' in home_dir:
2818 try:
2819 import win32api
2820 except ImportError:
2821 print('Error: the path "%s" has a space in it' % home_dir)
2822 print('To handle these kinds of paths, the win32api module must be installed:')
2823 print(' http://sourceforge.net/projects/pywin32/')
2824 sys.exit(3)
2825 home_dir = win32api.GetShortPathName(home_dir)
2826 lib_dir = join(home_dir, 'Lib')
2827 inc_dir = join(home_dir, 'Include')
2828 bin_dir = join(home_dir, 'Scripts')
2829 elif is_jython:
2830 lib_dir = join(home_dir, 'Lib')
2831 inc_dir = join(home_dir, 'Include')
2832 bin_dir = join(home_dir, 'bin')
2833 elif is_pypy:
2834 lib_dir = home_dir
2835 inc_dir = join(home_dir, 'include')
2836 bin_dir = join(home_dir, 'bin')
2837 else:
2838 lib_dir = join(home_dir, 'lib', py_version)
2839 inc_dir = join(home_dir, 'include', py_version + abiflags)
2840 bin_dir = join(home_dir, 'bin')
2841 return home_dir, lib_dir, inc_dir, bin_dir
2842
2843
2844def change_prefix(filename, dst_prefix):
2845 prefixes = [sys.prefix]
2846
2847 if sys.platform == "darwin":
2848 prefixes.extend((
2849 os.path.join("/Library/Python", sys.version[:3], "site-packages"),
2850 os.path.join(sys.prefix, "Extras", "lib", "python"),
2851 os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
2852
2853 if hasattr(sys, 'real_prefix'):
2854 prefixes.append(sys.real_prefix)
2855 prefixes = list(map(os.path.abspath, prefixes))
2856 filename = os.path.abspath(filename)
2857 for src_prefix in prefixes:
2858 if filename.startswith(src_prefix):
2859 _, relpath = filename.split(src_prefix, 1)
2860 assert relpath[0] == os.sep
2861 relpath = relpath[1:]
2862 return join(dst_prefix, relpath)
2863 assert False, "Filename %s does not start with any of these prefixes: %s" % \
2864 (filename, prefixes)
2865
2866def copy_required_modules(dst_prefix):
2867 import imp
2868 for modname in REQUIRED_MODULES:
2869 if modname in sys.builtin_module_names:
2870 logger.info("Ignoring built-in bootstrap module: %s" % modname)
2871 continue
2872 try:
2873 f, filename, _ = imp.find_module(modname)
2874 except ImportError:
2875 logger.info("Cannot import bootstrap module: %s" % modname)
2876 else:
2877 if f is not None:
2878 f.close()
2879 dst_filename = change_prefix(filename, dst_prefix)
2880 copyfile(filename, dst_filename)
2881 if filename.endswith('.pyc'):
2882 pyfile = filename[:-1]
2883 if os.path.exists(pyfile):
2884 copyfile(pyfile, dst_filename[:-1])
2885
2886
2887def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
2888 """Install just the base environment, no distutils patches etc"""
2889 if sys.executable.startswith(bin_dir):
2890 print('Please use the *system* python to run this script')
2891 return
2892
2893 if clear:
2894 rmtree(lib_dir)
2895 ## FIXME: why not delete it?
2896 ## Maybe it should delete everything with #!/path/to/venv/python in it
2897 logger.notify('Not deleting %s', bin_dir)
2898
2899 if hasattr(sys, 'real_prefix'):
2900 logger.notify('Using real prefix %r' % sys.real_prefix)
2901 prefix = sys.real_prefix
2902 else:
2903 prefix = sys.prefix
2904 mkdir(lib_dir)
2905 fix_lib64(lib_dir)
2906 stdlib_dirs = [os.path.dirname(os.__file__)]
2907 if sys.platform == 'win32':
2908 stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
2909 elif sys.platform == 'darwin':
2910 stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
2911 if hasattr(os, 'symlink'):
2912 logger.info('Symlinking Python bootstrap modules')
2913 else:
2914 logger.info('Copying Python bootstrap modules')
2915 logger.indent += 2
2916 try:
2917 # copy required files...
2918 for stdlib_dir in stdlib_dirs:
2919 if not os.path.isdir(stdlib_dir):
2920 continue
2921 for fn in os.listdir(stdlib_dir):
2922 bn = os.path.splitext(fn)[0]
2923 if fn != 'site-packages' and bn in REQUIRED_FILES:
2924 copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
2925 # ...and modules
2926 copy_required_modules(home_dir)
2927 finally:
2928 logger.indent -= 2
2929 mkdir(join(lib_dir, 'site-packages'))
2930 import site
2931 site_filename = site.__file__
2932 if site_filename.endswith('.pyc'):
2933 site_filename = site_filename[:-1]
2934 elif site_filename.endswith('$py.class'):
2935 site_filename = site_filename.replace('$py.class', '.py')
2936 site_filename_dst = change_prefix(site_filename, home_dir)
2937 site_dir = os.path.dirname(site_filename_dst)
2938 writefile(site_filename_dst, SITE_PY)
2939 writefile(join(site_dir, 'orig-prefix.txt'), prefix)
2940 site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
2941 if not site_packages:
2942 writefile(site_packages_filename, '')
2943 else:
2944 if os.path.exists(site_packages_filename):
2945 logger.info('Deleting %s' % site_packages_filename)
2946 os.unlink(site_packages_filename)
2947
2948 if is_pypy:
2949 stdinc_dir = join(prefix, 'include')
2950 else:
2951 stdinc_dir = join(prefix, 'include', py_version + abiflags)
2952 if os.path.exists(stdinc_dir):
2953 copyfile(stdinc_dir, inc_dir)
2954 else:
2955 logger.debug('No include dir %s' % stdinc_dir)
2956
2957 # pypy never uses exec_prefix, just ignore it
2958 if sys.exec_prefix != prefix and not is_pypy:
2959 if sys.platform == 'win32':
2960 exec_dir = join(sys.exec_prefix, 'lib')
2961 elif is_jython:
2962 exec_dir = join(sys.exec_prefix, 'Lib')
2963 else:
2964 exec_dir = join(sys.exec_prefix, 'lib', py_version)
2965 for fn in os.listdir(exec_dir):
2966 copyfile(join(exec_dir, fn), join(lib_dir, fn))
2967
2968 if is_jython:
2969 # Jython has either jython-dev.jar and javalib/ dir, or just
2970 # jython.jar
2971 for name in 'jython-dev.jar', 'javalib', 'jython.jar':
2972 src = join(prefix, name)
2973 if os.path.exists(src):
2974 copyfile(src, join(home_dir, name))
2975 # XXX: registry should always exist after Jython 2.5rc1
2976 src = join(prefix, 'registry')
2977 if os.path.exists(src):
2978 copyfile(src, join(home_dir, 'registry'), symlink=False)
2979 copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
2980 symlink=False)
2981
2982 mkdir(bin_dir)
2983 py_executable = join(bin_dir, os.path.basename(sys.executable))
2984 if 'Python.framework' in prefix:
2985 if re.search(r'/Python(?:-32|-64)*$', py_executable):
2986 # The name of the python executable is not quite what
2987 # we want, rename it.
2988 py_executable = os.path.join(
2989 os.path.dirname(py_executable), 'python')
2990
2991 logger.notify('New %s executable in %s', expected_exe, py_executable)
2992 if sys.executable != py_executable:
2993 ## FIXME: could I just hard link?
2994 executable = sys.executable
2995 if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
2996 # Cygwin misreports sys.executable sometimes
2997 executable += '.exe'
2998 py_executable += '.exe'
2999 logger.info('Executable actually exists in %s' % executable)
3000 shutil.copyfile(executable, py_executable)
3001 make_exe(py_executable)
3002 if sys.platform == 'win32' or sys.platform == 'cygwin':
3003 pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
3004 if os.path.exists(pythonw):
3005 logger.info('Also created pythonw.exe')
3006 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
3007 if is_pypy:
3008 # make a symlink python --> pypy-c
3009 python_executable = os.path.join(os.path.dirname(py_executable), 'python')
3010 logger.info('Also created executable %s' % python_executable)
3011 copyfile(py_executable, python_executable)
3012
3013 if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
3014 secondary_exe = os.path.join(os.path.dirname(py_executable),
3015 expected_exe)
3016 py_executable_ext = os.path.splitext(py_executable)[1]
3017 if py_executable_ext == '.exe':
3018 # python2.4 gives an extension of '.4' :P
3019 secondary_exe += py_executable_ext
3020 if os.path.exists(secondary_exe):
3021 logger.warn('Not overwriting existing %s script %s (you must use %s)'
3022 % (expected_exe, secondary_exe, py_executable))
3023 else:
3024 logger.notify('Also creating executable in %s' % secondary_exe)
3025 shutil.copyfile(sys.executable, secondary_exe)
3026 make_exe(secondary_exe)
3027
3028 if 'Python.framework' in prefix:
3029 logger.debug('MacOSX Python framework detected')
3030
3031 # Make sure we use the the embedded interpreter inside
3032 # the framework, even if sys.executable points to
3033 # the stub executable in ${sys.prefix}/bin
3034 # See http://groups.google.com/group/python-virtualenv/
3035 # browse_thread/thread/17cab2f85da75951
3036 original_python = os.path.join(
3037 prefix, 'Resources/Python.app/Contents/MacOS/Python')
3038 shutil.copy(original_python, py_executable)
3039
3040 # Copy the framework's dylib into the virtual
3041 # environment
3042 virtual_lib = os.path.join(home_dir, '.Python')
3043
3044 if os.path.exists(virtual_lib):
3045 os.unlink(virtual_lib)
3046 copyfile(
3047 os.path.join(prefix, 'Python'),
3048 virtual_lib)
3049
3050 # And then change the install_name of the copied python executable
3051 try:
3052 call_subprocess(
3053 ["install_name_tool", "-change",
3054 os.path.join(prefix, 'Python'),
3055 '@executable_path/../.Python',
3056 py_executable])
3057 except:
3058 logger.fatal(
3059 "Could not call install_name_tool -- you must have Apple's development tools installed")
3060 raise
3061
3062 # Some tools depend on pythonX.Y being present
3063 py_executable_version = '%s.%s' % (
3064 sys.version_info[0], sys.version_info[1])
3065 if not py_executable.endswith(py_executable_version):
3066 # symlinking pythonX.Y > python
3067 pth = py_executable + '%s.%s' % (
3068 sys.version_info[0], sys.version_info[1])
3069 if os.path.exists(pth):
3070 os.unlink(pth)
3071 os.symlink('python', pth)
3072 else:
3073 # reverse symlinking python -> pythonX.Y (with --python)
3074 pth = join(bin_dir, 'python')
3075 if os.path.exists(pth):
3076 os.unlink(pth)
3077 os.symlink(os.path.basename(py_executable), pth)
3078
3079 if sys.platform == 'win32' and ' ' in py_executable:
3080 # There's a bug with subprocess on Windows when using a first
3081 # argument that has a space in it. Instead we have to quote
3082 # the value:
3083 py_executable = '"%s"' % py_executable
3084 cmd = [py_executable, '-c', 'import sys; print(sys.prefix)']
3085 logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
3086 try:
3087 proc = subprocess.Popen(cmd,
3088 stdout=subprocess.PIPE)
3089 proc_stdout, proc_stderr = proc.communicate()
3090 except OSError:
3091 e = sys.exc_info()[1]
3092 if e.errno == errno.EACCES:
3093 logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
3094 sys.exit(100)
3095 else:
3096 raise e
3097
3098 proc_stdout = proc_stdout.strip().decode(sys.getdefaultencoding())
3099 proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
3100 if proc_stdout != os.path.normcase(os.path.abspath(home_dir)):
3101 logger.fatal(
3102 'ERROR: The executable %s is not functioning' % py_executable)
3103 logger.fatal(
3104 'ERROR: It thinks sys.prefix is %r (should be %r)'
3105 % (proc_stdout, os.path.normcase(os.path.abspath(home_dir))))
3106 logger.fatal(
3107 'ERROR: virtualenv is not compatible with this system or executable')
3108 if sys.platform == 'win32':
3109 logger.fatal(
3110 'Note: some Windows users have reported this error when they installed Python for "Only this user". The problem may be resolvable if you install Python "For all users". (See https://bugs.launchpad.net/virtualenv/+bug/352844)')
3111 sys.exit(100)
3112 else:
3113 logger.info('Got sys.prefix result: %r' % proc_stdout)
3114
3115 pydistutils = os.path.expanduser('~/.pydistutils.cfg')
3116 if os.path.exists(pydistutils):
3117 logger.notify('Please make sure you remove any previous custom paths from '
3118 'your %s file.' % pydistutils)
3119 ## FIXME: really this should be calculated earlier
3120 return py_executable
3121
3122def install_activate(home_dir, bin_dir, prompt=None):
3123 if sys.platform == 'win32' or is_jython and os._name == 'nt':
3124 files = {'activate.bat': ACTIVATE_BAT,
3125 'deactivate.bat': DEACTIVATE_BAT}
3126 if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin':
3127 files['activate'] = ACTIVATE_SH
3128 else:
3129 files = {'activate': ACTIVATE_SH}
3130
3131 # suppling activate.fish in addition to, not instead of, the
3132 # bash script support.
3133 files['activate.fish'] = ACTIVATE_FISH
3134
3135 # same for csh/tcsh support...
3136 files['activate.csh'] = ACTIVATE_CSH
3137
3138
3139
3140 files['activate_this.py'] = ACTIVATE_THIS
3141 vname = os.path.basename(os.path.abspath(home_dir))
3142 for name, content in files.items():
3143 content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
3144 content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
3145 content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir))
3146 content = content.replace('__VIRTUAL_NAME__', vname)
3147 content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
3148 writefile(os.path.join(bin_dir, name), content)
3149
3150def install_distutils(home_dir):
3151 distutils_path = change_prefix(distutils.__path__[0], home_dir)
3152 mkdir(distutils_path)
3153 ## FIXME: maybe this prefix setting should only be put in place if
3154 ## there's a local distutils.cfg with a prefix setting?
3155 home_dir = os.path.abspath(home_dir)
3156 ## FIXME: this is breaking things, removing for now:
3157 #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
3158 writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
3159 writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
3160
3161def fix_lib64(lib_dir):
3162 """
3163 Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
3164 instead of lib/pythonX.Y. If this is such a platform we'll just create a
3165 symlink so lib64 points to lib
3166 """
3167 if [p for p in distutils.sysconfig.get_config_vars().values()
3168 if isinstance(p, basestring) and 'lib64' in p]:
3169 logger.debug('This system uses lib64; symlinking lib64 to lib')
3170 assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
3171 "Unexpected python lib dir: %r" % lib_dir)
3172 lib_parent = os.path.dirname(lib_dir)
3173 assert os.path.basename(lib_parent) == 'lib', (
3174 "Unexpected parent dir: %r" % lib_parent)
3175 copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
3176
3177def resolve_interpreter(exe):
3178 """
3179 If the executable given isn't an absolute path, search $PATH for the interpreter
3180 """
3181 if os.path.abspath(exe) != exe:
3182 paths = os.environ.get('PATH', '').split(os.pathsep)
3183 for path in paths:
3184 if os.path.exists(os.path.join(path, exe)):
3185 exe = os.path.join(path, exe)
3186 break
3187 if not os.path.exists(exe):
3188 logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
3189 sys.exit(3)
3190 return exe
3191
3192############################################################
3193## Relocating the environment:
3194
3195def make_environment_relocatable(home_dir):
3196 """
3197 Makes the already-existing environment use relative paths, and takes out
3198 the #!-based environment selection in scripts.
3199 """
3200 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3201 activate_this = os.path.join(bin_dir, 'activate_this.py')
3202 if not os.path.exists(activate_this):
3203 logger.fatal(
3204 'The environment doesn\'t have a file %s -- please re-run virtualenv '
3205 'on this environment to update it' % activate_this)
3206 fixup_scripts(home_dir)
3207 fixup_pth_and_egg_link(home_dir)
3208 ## FIXME: need to fix up distutils.cfg
3209
3210OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
3211 'activate', 'activate.bat', 'activate_this.py']
3212
3213def fixup_scripts(home_dir):
3214 # This is what we expect at the top of scripts:
3215 shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
3216 # This is what we'll put:
3217 new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
3218 activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
3219 if sys.platform == 'win32':
3220 bin_suffix = 'Scripts'
3221 else:
3222 bin_suffix = 'bin'
3223 bin_dir = os.path.join(home_dir, bin_suffix)
3224 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3225 for filename in os.listdir(bin_dir):
3226 filename = os.path.join(bin_dir, filename)
3227 if not os.path.isfile(filename):
3228 # ignore subdirs, e.g. .svn ones.
3229 continue
3230 f = open(filename, 'rb')
3231 lines = f.readlines()
3232 f.close()
3233 if not lines:
3234 logger.warn('Script %s is an empty file' % filename)
3235 continue
3236 if not lines[0].strip().startswith(shebang):
3237 if os.path.basename(filename) in OK_ABS_SCRIPTS:
3238 logger.debug('Cannot make script %s relative' % filename)
3239 elif lines[0].strip() == new_shebang:
3240 logger.info('Script %s has already been made relative' % filename)
3241 else:
3242 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
3243 % (filename, shebang))
3244 continue
3245 logger.notify('Making script %s relative' % filename)
3246 lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
3247 f = open(filename, 'wb')
3248 f.writelines(lines)
3249 f.close()
3250
3251def fixup_pth_and_egg_link(home_dir, sys_path=None):
3252 """Makes .pth and .egg-link files use relative paths"""
3253 home_dir = os.path.normcase(os.path.abspath(home_dir))
3254 if sys_path is None:
3255 sys_path = sys.path
3256 for path in sys_path:
3257 if not path:
3258 path = '.'
3259 if not os.path.isdir(path):
3260 continue
3261 path = os.path.normcase(os.path.abspath(path))
3262 if not path.startswith(home_dir):
3263 logger.debug('Skipping system (non-environment) directory %s' % path)
3264 continue
3265 for filename in os.listdir(path):
3266 filename = os.path.join(path, filename)
3267 if filename.endswith('.pth'):
3268 if not os.access(filename, os.W_OK):
3269 logger.warn('Cannot write .pth file %s, skipping' % filename)
3270 else:
3271 fixup_pth_file(filename)
3272 if filename.endswith('.egg-link'):
3273 if not os.access(filename, os.W_OK):
3274 logger.warn('Cannot write .egg-link file %s, skipping' % filename)
3275 else:
3276 fixup_egg_link(filename)
3277
3278def fixup_pth_file(filename):
3279 lines = []
3280 prev_lines = []
3281 f = open(filename)
3282 prev_lines = f.readlines()
3283 f.close()
3284 for line in prev_lines:
3285 line = line.strip()
3286 if (not line or line.startswith('#') or line.startswith('import ')
3287 or os.path.abspath(line) != line):
3288 lines.append(line)
3289 else:
3290 new_value = make_relative_path(filename, line)
3291 if line != new_value:
3292 logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
3293 lines.append(new_value)
3294 if lines == prev_lines:
3295 logger.info('No changes to .pth file %s' % filename)
3296 return
3297 logger.notify('Making paths in .pth file %s relative' % filename)
3298 f = open(filename, 'w')
3299 f.write('\n'.join(lines) + '\n')
3300 f.close()
3301
3302def fixup_egg_link(filename):
3303 f = open(filename)
3304 link = f.read().strip()
3305 f.close()
3306 if os.path.abspath(link) != link:
3307 logger.debug('Link in %s already relative' % filename)
3308 return
3309 new_link = make_relative_path(filename, link)
3310 logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
3311 f = open(filename, 'w')
3312 f.write(new_link)
3313 f.close()
3314
3315def make_relative_path(source, dest, dest_is_directory=True):
3316 """
3317 Make a filename relative, where the filename is dest, and it is
3318 being referred to from the filename source.
3319
3320 >>> make_relative_path('/usr/share/something/a-file.pth',
3321 ... '/usr/share/another-place/src/Directory')
3322 '../another-place/src/Directory'
3323 >>> make_relative_path('/usr/share/something/a-file.pth',
3324 ... '/home/user/src/Directory')
3325 '../../../home/user/src/Directory'
3326 >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
3327 './'
3328 """
3329 source = os.path.dirname(source)
3330 if not dest_is_directory:
3331 dest_filename = os.path.basename(dest)
3332 dest = os.path.dirname(dest)
3333 dest = os.path.normpath(os.path.abspath(dest))
3334 source = os.path.normpath(os.path.abspath(source))
3335 dest_parts = dest.strip(os.path.sep).split(os.path.sep)
3336 source_parts = source.strip(os.path.sep).split(os.path.sep)
3337 while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
3338 dest_parts.pop(0)
3339 source_parts.pop(0)
3340 full_parts = ['..']*len(source_parts) + dest_parts
3341 if not dest_is_directory:
3342 full_parts.append(dest_filename)
3343 if not full_parts:
3344 # Special case for the current directory (otherwise it'd be '')
3345 return './'
3346 return os.path.sep.join(full_parts)
3347
3348
3349
3350############################################################
3351## Bootstrap script creation:
3352
3353def create_bootstrap_script(extra_text, python_version=''):
3354 """
3355 Creates a bootstrap script, which is like this script but with
3356 extend_parser, adjust_options, and after_install hooks.
3357
3358 This returns a string that (written to disk of course) can be used
3359 as a bootstrap script with your own customizations. The script
3360 will be the standard virtualenv.py script, with your extra text
3361 added (your extra text should be Python code).
3362
3363 If you include these functions, they will be called:
3364
3365 ``extend_parser(optparse_parser)``:
3366 You can add or remove options from the parser here.
3367
3368 ``adjust_options(options, args)``:
3369 You can change options here, or change the args (if you accept
3370 different kinds of arguments, be sure you modify ``args`` so it is
3371 only ``[DEST_DIR]``).
3372
3373 ``after_install(options, home_dir)``:
3374
3375 After everything is installed, this function is called. This
3376 is probably the function you are most likely to use. An
3377 example would be::
3378
3379 def after_install(options, home_dir):
3380 subprocess.call([join(home_dir, 'bin', 'easy_install'),
3381 'MyPackage'])
3382 subprocess.call([join(home_dir, 'bin', 'my-package-script'),
3383 'setup', home_dir])
3384
3385 This example immediately installs a package, and runs a setup
3386 script from that package.
3387
3388 If you provide something like ``python_version='2.4'`` then the
3389 script will start with ``#!/usr/bin/env python2.4`` instead of
3390 ``#!/usr/bin/env python``. You can use this when the script must
3391 be run with a particular Python version.
3392 """
3393 filename = __file__
3394 if filename.endswith('.pyc'):
3395 filename = filename[:-1]
3396 f = open(filename, 'rb')
3397 content = f.read()
3398 f.close()
3399 py_exe = 'python%s' % python_version
3400 content = (('#!/usr/bin/env %s\n' % py_exe)
3401 + '## WARNING: This file is generated\n'
3402 + content)
3403 return content.replace('##EXT' 'END##', extra_text)
3404
3405##EXTEND##
3406
3407def convert(s):
3408 b = base64.b64decode(s.encode('ascii'))
3409 return zlib.decompress(b).decode('utf-8')
3410
3411##file site.py
3412SITE_PY = convert("""
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
3488X4UuruF1rMoshUjuVWhlSXfDcoyWcfRDu6HKeA1pQKc7jKwb8qz3YoFW61XIc9P9xy2j/dYAhi2D
3489vYV555LKEahGF4upRIiNeOcglF/gq116vQYKFgw3lmpcRMN0Kcw+geBarFMIIIAn12B9MU4ACJ2V
34908BPQx052QBZYDRC+2SwO/xpqgvitf/lloHldZYd/FyVEQYJLV8IBYrqN30LgE8tYnH14Nw4ZOSoF
3491FX9tsIAcHBLK8jnSTvUyvGM7jZTMlrqewdcH+EL7CfS6072SZaW7D7vGIUrAExWR1/BEGfqFWF5k
3492YU9wKuMOaKyNt5jhGTN329t8DsTHtcwyXRF9/vbiDHxHLNdHCeJ9njMYjvMluGWri734DFwHFG7o
3493wusK2bhCF5Y29Rex12wwM4siR729OgC7TpT97PfqpTqrJFUu2hFOm2GZgvMYWRnWwiwrs3anDVLY
3494bUMUR5lhlpheVlQw6fME8DI9TTgkglgJDwOYNDPvWqZ5bSrksnQOehRULijUCQgJEhdPvBHnFTkn
3495eotKmYMy8LDcVelqXWMyHTrHVKSPzX88/Xxx/p4K11+8bL3uAeacUCQw4aKFEyxJw2wHfHHLzJCr
3496ptMhntWvEAZqH/jTfcXVECc8QK8fJxbxT/cVn1Q6cSJBngEoqKbsigcGAE63IblpZYFxtXEwftyS
3497sxYzHwzlIvFghC4scOfX50TbsmNKKO9jXj5il2JZahpGprNbAtX96DkuS9xWWUTDjeDtkGyZzwy6
34983vTe7Cu2cj89KcRDk4BRv7U/hqlG6jXV03GYbR+3UFirbewvuZMrddrNcxRlIGLkdh67TDashHVz
34995kCvbLcHTHyr0TWSOKjKR7/kI+1heJhYYvfiFNORjk2QEcBMhtSnQxrwodAigAKhatPIkdzJ+OkL
3500b46ONbh/jlp3gW38ARShrv2kMwVFBZwIX35jx5FfEVqoR49F6HgqucwLW5eEn+0avcrn/hwHZYCS
3501mCh2VZKvZMSwJgbmVz6x96RgSdt6pL5Kr4cMizgH5/TLHg7vy8XwxolBrcMIvXY3ctdVRz55sMHg
35020YM7CeaDr5It6P6yqSNeyWGRHz5ttR/q/RCx2g2a6s3eKMR0zG/hnvVpAQ9SQ8NCD++3gd0i/PDa
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
3547AIOc2an2AKxRCP4P1A2QJQ==
3548""")
3549
3550
3551
3552##file ez_setup.py
3553EZ_SETUP_PY = convert("""
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
3620BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
3621""")
3622
3623
3624
3625##file distribute_setup.py
3626DISTRIBUTE_SETUP_PY = convert("""
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
3706""")
3707
3708
3709
3710##file activate.sh
3711ACTIVATE_SH = convert("""
3712eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9
3713H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq
3714DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs
3715cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY
3716G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T
3717EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs
3718wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG
37195eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/
3720JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR
3721huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx
3722Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L
3723Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw
3724WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX
3725LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2
3726""")
3727
3728
3729
3730##file activate.fish
3731ACTIVATE_FISH = convert("""
3732eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
3733Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
3734pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
3735lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
3736g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
3737grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
3738xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
3739MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
3740H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
3741L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
3742fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
3743pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
3744MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
3745O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
37467SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
3747m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
3748djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
3749mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
3750jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
3751""")
3752
3753
3754
3755##file activate.csh
3756ACTIVATE_CSH = convert("""
3757eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
3758XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
3759kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
3760pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
3761sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
3762yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
3763E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
3764lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
3765r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
3766""")
3767
3768
3769
3770##file activate.bat
3771ACTIVATE_BAT = convert("""
3772eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
3773qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
3774sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
3775ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
3776""")
3777
3778
3779
3780##file deactivate.bat
3781DEACTIVATE_BAT = convert("""
3782eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
3783FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
3784i2dASrm4rFz9XLgAwJNbyQ==
3785""")
3786
3787
3788
3789##file distutils-init.py
3790DISTUTILS_INIT = convert("""
3791eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
3792luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
3793KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
3794ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
3795QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
3796yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
3797bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
3798bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
3799yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
3800Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
3801Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
3802/n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
3803FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
3804AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
3805hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
3806UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
38078h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
3808XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
3809azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
38108dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
3811gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
38125C4rFgwLGfMvJuAMew==
3813""")
3814
3815
3816
3817##file distutils.cfg
3818DISTUTILS_CFG = convert("""
3819eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
3820xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
38219FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
3822""")
3823
3824
3825
3826##file activate_this.py
3827ACTIVATE_THIS = convert("""
3828eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ
3829VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a
3830Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE
3831qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX
38324lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7
3833HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n
3834xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96
38351Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI
38363vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU=
3837""")
3838
3839
3840
3841if __name__ == '__main__':
3842 main()
3843
3844## TODO:
3845## Copy python.exe.manifest
3846## Monkeypatch distutils.sysconfig
3847>>>>>>> MERGE-SOURCE
19573848
=== added directory '.pc/remove_syspath0_on_reinvoke.patch'
=== added file '.pc/remove_syspath0_on_reinvoke.patch/virtualenv.py'
--- .pc/remove_syspath0_on_reinvoke.patch/virtualenv.py 1970-01-01 00:00:00 +0000
+++ .pc/remove_syspath0_on_reinvoke.patch/virtualenv.py 2011-09-08 21:10:23 +0000
@@ -0,0 +1,1896 @@
1"""Create a "virtual" Python installation
2"""
3
4# If you change the version here, change it in setup.py
5# and docs/conf.py as well.
6virtualenv_version = "1.6"
7
8import base64
9import sys
10import os
11import optparse
12import re
13import shutil
14import logging
15import tempfile
16import zlib
17import errno
18import distutils.sysconfig
19try:
20 import subprocess
21except ImportError:
22 if sys.version_info <= (2, 3):
23 print('ERROR: %s' % sys.exc_info()[1])
24 print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
25 print('If you copy subprocess.py from a newer version of Python this script will probably work')
26 sys.exit(101)
27 else:
28 raise
29try:
30 set
31except NameError:
32 from sets import Set as set
33try:
34 basestring
35except NameError:
36 basestring = str
37
38join = os.path.join
39py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
40
41is_jython = sys.platform.startswith('java')
42is_pypy = hasattr(sys, 'pypy_version_info')
43abiflags = getattr(sys, 'abiflags', '')
44
45if is_pypy:
46 expected_exe = 'pypy'
47elif is_jython:
48 expected_exe = 'jython'
49else:
50 expected_exe = 'python'
51
52
53REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
54 'fnmatch', 'locale', 'encodings', 'codecs',
55 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
56 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
57 'zlib']
58
59REQUIRED_FILES = ['lib-dynload', 'config']
60
61majver, minver = sys.version_info[:2]
62if majver == 2:
63 if minver >= 6:
64 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
65 if minver >= 7:
66 REQUIRED_MODULES.extend(['_weakrefset'])
67 if minver <= 3:
68 REQUIRED_MODULES.extend(['sets', '__future__'])
69elif majver == 3:
70 # Some extra modules are needed for Python 3, but different ones
71 # for different versions.
72 REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
73 '_weakrefset', 'copyreg', 'tempfile', 'random',
74 '__future__', 'collections', 'keyword', 'tarfile',
75 'shutil', 'struct', 'copy'])
76 if minver >= 2:
77 REQUIRED_FILES[-1] = 'config-%s' % majver
78 if minver == 3:
79 # The whole list of 3.3 modules is reproduced below - the current
80 # uncommented ones are required for 3.3 as of now, but more may be
81 # added as 3.3 development continues.
82 REQUIRED_MODULES.extend([
83 #"aifc",
84 #"antigravity",
85 #"argparse",
86 #"ast",
87 #"asynchat",
88 #"asyncore",
89 "base64",
90 #"bdb",
91 #"binhex",
92 "bisect",
93 #"calendar",
94 #"cgi",
95 #"cgitb",
96 #"chunk",
97 #"cmd",
98 #"codeop",
99 #"code",
100 #"colorsys",
101 #"_compat_pickle",
102 #"compileall",
103 #"concurrent",
104 #"configparser",
105 #"contextlib",
106 #"cProfile",
107 #"crypt",
108 #"csv",
109 #"ctypes",
110 #"curses",
111 #"datetime",
112 #"dbm",
113 #"decimal",
114 #"difflib",
115 #"dis",
116 #"doctest",
117 #"dummy_threading",
118 #"_dummy_thread",
119 #"email",
120 #"filecmp",
121 #"fileinput",
122 #"formatter",
123 #"fractions",
124 #"ftplib",
125 #"functools",
126 #"getopt",
127 #"getpass",
128 #"gettext",
129 #"glob",
130 #"gzip",
131 "hashlib",
132 "heapq",
133 "hmac",
134 #"html",
135 #"http",
136 #"idlelib",
137 #"imaplib",
138 #"imghdr",
139 #"importlib",
140 #"inspect",
141 #"json",
142 #"lib2to3",
143 #"logging",
144 #"macpath",
145 #"macurl2path",
146 #"mailbox",
147 #"mailcap",
148 #"_markupbase",
149 #"mimetypes",
150 #"modulefinder",
151 #"multiprocessing",
152 #"netrc",
153 #"nntplib",
154 #"nturl2path",
155 #"numbers",
156 #"opcode",
157 #"optparse",
158 #"os2emxpath",
159 #"pdb",
160 #"pickle",
161 #"pickletools",
162 #"pipes",
163 #"pkgutil",
164 #"platform",
165 #"plat-linux2",
166 #"plistlib",
167 #"poplib",
168 #"pprint",
169 #"profile",
170 #"pstats",
171 #"pty",
172 #"pyclbr",
173 #"py_compile",
174 #"pydoc_data",
175 #"pydoc",
176 #"_pyio",
177 #"queue",
178 #"quopri",
179 "reprlib",
180 "rlcompleter",
181 #"runpy",
182 #"sched",
183 #"shelve",
184 #"shlex",
185 #"smtpd",
186 #"smtplib",
187 #"sndhdr",
188 #"socket",
189 #"socketserver",
190 #"sqlite3",
191 #"ssl",
192 #"stringprep",
193 #"string",
194 #"_strptime",
195 #"subprocess",
196 #"sunau",
197 #"symbol",
198 #"symtable",
199 #"sysconfig",
200 #"tabnanny",
201 #"telnetlib",
202 #"test",
203 #"textwrap",
204 #"this",
205 #"_threading_local",
206 #"threading",
207 #"timeit",
208 #"tkinter",
209 #"tokenize",
210 #"token",
211 #"traceback",
212 #"trace",
213 #"tty",
214 #"turtledemo",
215 #"turtle",
216 #"unittest",
217 #"urllib",
218 #"uuid",
219 #"uu",
220 #"wave",
221 "weakref",
222 #"webbrowser",
223 #"wsgiref",
224 #"xdrlib",
225 #"xml",
226 #"xmlrpc",
227 #"zipfile",
228 ])
229
230if is_pypy:
231 # these are needed to correctly display the exceptions that may happen
232 # during the bootstrap
233 REQUIRED_MODULES.extend(['traceback', 'linecache'])
234
235class Logger(object):
236
237 """
238 Logging object for use in command-line script. Allows ranges of
239 levels, to avoid some redundancy of displayed information.
240 """
241
242 DEBUG = logging.DEBUG
243 INFO = logging.INFO
244 NOTIFY = (logging.INFO+logging.WARN)/2
245 WARN = WARNING = logging.WARN
246 ERROR = logging.ERROR
247 FATAL = logging.FATAL
248
249 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
250
251 def __init__(self, consumers):
252 self.consumers = consumers
253 self.indent = 0
254 self.in_progress = None
255 self.in_progress_hanging = False
256
257 def debug(self, msg, *args, **kw):
258 self.log(self.DEBUG, msg, *args, **kw)
259 def info(self, msg, *args, **kw):
260 self.log(self.INFO, msg, *args, **kw)
261 def notify(self, msg, *args, **kw):
262 self.log(self.NOTIFY, msg, *args, **kw)
263 def warn(self, msg, *args, **kw):
264 self.log(self.WARN, msg, *args, **kw)
265 def error(self, msg, *args, **kw):
266 self.log(self.WARN, msg, *args, **kw)
267 def fatal(self, msg, *args, **kw):
268 self.log(self.FATAL, msg, *args, **kw)
269 def log(self, level, msg, *args, **kw):
270 if args:
271 if kw:
272 raise TypeError(
273 "You may give positional or keyword arguments, not both")
274 args = args or kw
275 rendered = None
276 for consumer_level, consumer in self.consumers:
277 if self.level_matches(level, consumer_level):
278 if (self.in_progress_hanging
279 and consumer in (sys.stdout, sys.stderr)):
280 self.in_progress_hanging = False
281 sys.stdout.write('\n')
282 sys.stdout.flush()
283 if rendered is None:
284 if args:
285 rendered = msg % args
286 else:
287 rendered = msg
288 rendered = ' '*self.indent + rendered
289 if hasattr(consumer, 'write'):
290 consumer.write(rendered+'\n')
291 else:
292 consumer(rendered)
293
294 def start_progress(self, msg):
295 assert not self.in_progress, (
296 "Tried to start_progress(%r) while in_progress %r"
297 % (msg, self.in_progress))
298 if self.level_matches(self.NOTIFY, self._stdout_level()):
299 sys.stdout.write(msg)
300 sys.stdout.flush()
301 self.in_progress_hanging = True
302 else:
303 self.in_progress_hanging = False
304 self.in_progress = msg
305
306 def end_progress(self, msg='done.'):
307 assert self.in_progress, (
308 "Tried to end_progress without start_progress")
309 if self.stdout_level_matches(self.NOTIFY):
310 if not self.in_progress_hanging:
311 # Some message has been printed out since start_progress
312 sys.stdout.write('...' + self.in_progress + msg + '\n')
313 sys.stdout.flush()
314 else:
315 sys.stdout.write(msg + '\n')
316 sys.stdout.flush()
317 self.in_progress = None
318 self.in_progress_hanging = False
319
320 def show_progress(self):
321 """If we are in a progress scope, and no log messages have been
322 shown, write out another '.'"""
323 if self.in_progress_hanging:
324 sys.stdout.write('.')
325 sys.stdout.flush()
326
327 def stdout_level_matches(self, level):
328 """Returns true if a message at this level will go to stdout"""
329 return self.level_matches(level, self._stdout_level())
330
331 def _stdout_level(self):
332 """Returns the level that stdout runs at"""
333 for level, consumer in self.consumers:
334 if consumer is sys.stdout:
335 return level
336 return self.FATAL
337
338 def level_matches(self, level, consumer_level):
339 """
340 >>> l = Logger()
341 >>> l.level_matches(3, 4)
342 False
343 >>> l.level_matches(3, 2)
344 True
345 >>> l.level_matches(slice(None, 3), 3)
346 False
347 >>> l.level_matches(slice(None, 3), 2)
348 True
349 >>> l.level_matches(slice(1, 3), 1)
350 True
351 >>> l.level_matches(slice(2, 3), 1)
352 False
353 """
354 if isinstance(level, slice):
355 start, stop = level.start, level.stop
356 if start is not None and start > consumer_level:
357 return False
358 if stop is not None or stop <= consumer_level:
359 return False
360 return True
361 else:
362 return level >= consumer_level
363
364 #@classmethod
365 def level_for_integer(cls, level):
366 levels = cls.LEVELS
367 if level < 0:
368 return levels[0]
369 if level >= len(levels):
370 return levels[-1]
371 return levels[level]
372
373 level_for_integer = classmethod(level_for_integer)
374
375# create a silent logger just to prevent this from being undefined
376# will be overridden with requested verbosity main() is called.
377logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
378
379def mkdir(path):
380 if not os.path.exists(path):
381 logger.info('Creating %s', path)
382 os.makedirs(path)
383 else:
384 logger.info('Directory %s already exists', path)
385
386def copyfileordir(src, dest):
387 if os.path.isdir(src):
388 shutil.copytree(src, dest, True)
389 else:
390 shutil.copy2(src, dest)
391
392def copyfile(src, dest, symlink=True):
393 if not os.path.exists(src):
394 # Some bad symlink in the src
395 logger.warn('Cannot find file %s (bad symlink)', src)
396 return
397 if os.path.exists(dest):
398 logger.debug('File %s already exists', dest)
399 return
400 if not os.path.exists(os.path.dirname(dest)):
401 logger.info('Creating parent directories for %s' % os.path.dirname(dest))
402 os.makedirs(os.path.dirname(dest))
403 if not os.path.islink(src):
404 srcpath = os.path.abspath(src)
405 else:
406 srcpath = os.readlink(src)
407 if symlink and hasattr(os, 'symlink'):
408 logger.info('Symlinking %s', dest)
409 try:
410 os.symlink(srcpath, dest)
411 except (OSError, NotImplementedError):
412 logger.info('Symlinking failed, copying to %s', dest)
413 copyfileordir(src, dest)
414 else:
415 logger.info('Copying to %s', dest)
416 copyfileordir(src, dest)
417
418def writefile(dest, content, overwrite=True):
419 if not os.path.exists(dest):
420 logger.info('Writing %s', dest)
421 f = open(dest, 'wb')
422 f.write(content.encode('utf-8'))
423 f.close()
424 return
425 else:
426 f = open(dest, 'rb')
427 c = f.read()
428 f.close()
429 if c != content:
430 if not overwrite:
431 logger.notify('File %s exists with different content; not overwriting', dest)
432 return
433 logger.notify('Overwriting %s with new content', dest)
434 f = open(dest, 'wb')
435 f.write(content.encode('utf-8'))
436 f.close()
437 else:
438 logger.info('Content %s already in place', dest)
439
440def rmtree(dir):
441 if os.path.exists(dir):
442 logger.notify('Deleting tree %s', dir)
443 shutil.rmtree(dir)
444 else:
445 logger.info('Do not need to delete %s; already gone', dir)
446
447def make_exe(fn):
448 if hasattr(os, 'chmod'):
449 oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
450 newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
451 os.chmod(fn, newmode)
452 logger.info('Changed mode of %s to %s', fn, oct(newmode))
453
454def _find_file(filename, dirs):
455 for dir in dirs:
456 if os.path.exists(join(dir, filename)):
457 return join(dir, filename)
458 return filename
459
460def _install_req(py_executable, unzip=False, distribute=False):
461 if not distribute:
462 setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
463 project_name = 'setuptools'
464 bootstrap_script = EZ_SETUP_PY
465 source = None
466 else:
467 setup_fn = None
468 source = 'distribute-0.6.15.tar.gz'
469 project_name = 'distribute'
470 bootstrap_script = DISTRIBUTE_SETUP_PY
471 try:
472 # check if the global Python has distribute installed or plain
473 # setuptools
474 import pkg_resources
475 if not hasattr(pkg_resources, '_distribute'):
476 location = os.path.dirname(pkg_resources.__file__)
477 logger.notify("A globally installed setuptools was found (in %s)" % location)
478 logger.notify("Use the --no-site-packages option to use distribute in "
479 "the virtualenv.")
480 except ImportError:
481 pass
482
483 search_dirs = file_search_dirs()
484
485 if setup_fn is not None:
486 setup_fn = _find_file(setup_fn, search_dirs)
487
488 if source is not None:
489 source = _find_file(source, search_dirs)
490
491 if is_jython and os._name == 'nt':
492 # Jython's .bat sys.executable can't handle a command line
493 # argument with newlines
494 fd, ez_setup = tempfile.mkstemp('.py')
495 os.write(fd, bootstrap_script)
496 os.close(fd)
497 cmd = [py_executable, ez_setup]
498 else:
499 cmd = [py_executable, '-c', bootstrap_script]
500 if unzip:
501 cmd.append('--always-unzip')
502 env = {}
503 remove_from_env = []
504 if logger.stdout_level_matches(logger.DEBUG):
505 cmd.append('-v')
506
507 old_chdir = os.getcwd()
508 if setup_fn is not None and os.path.exists(setup_fn):
509 logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
510 cmd.append(setup_fn)
511 if os.environ.get('PYTHONPATH'):
512 env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
513 else:
514 env['PYTHONPATH'] = setup_fn
515 else:
516 # the source is found, let's chdir
517 if source is not None and os.path.exists(source):
518 os.chdir(os.path.dirname(source))
519 # in this case, we want to be sure that PYTHONPATH is unset (not
520 # just empty, really unset), else CPython tries to import the
521 # site.py that it's in virtualenv_support
522 remove_from_env.append('PYTHONPATH')
523 else:
524 logger.info('No %s egg found; downloading' % project_name)
525 cmd.extend(['--always-copy', '-U', project_name])
526 logger.start_progress('Installing %s...' % project_name)
527 logger.indent += 2
528 cwd = None
529 if project_name == 'distribute':
530 env['DONT_PATCH_SETUPTOOLS'] = 'true'
531
532 def _filter_ez_setup(line):
533 return filter_ez_setup(line, project_name)
534
535 if not os.access(os.getcwd(), os.W_OK):
536 cwd = tempfile.mkdtemp()
537 if source is not None and os.path.exists(source):
538 # the current working dir is hostile, let's copy the
539 # tarball to a temp dir
540 target = os.path.join(cwd, os.path.split(source)[-1])
541 shutil.copy(source, target)
542 try:
543 call_subprocess(cmd, show_stdout=False,
544 filter_stdout=_filter_ez_setup,
545 extra_env=env,
546 remove_from_env=remove_from_env,
547 cwd=cwd)
548 finally:
549 logger.indent -= 2
550 logger.end_progress()
551 if os.getcwd() != old_chdir:
552 os.chdir(old_chdir)
553 if is_jython and os._name == 'nt':
554 os.remove(ez_setup)
555
556def file_search_dirs():
557 here = os.path.dirname(os.path.abspath(__file__))
558 dirs = ['.', here,
559 #join(here, 'virtualenv_support')]
560 '/usr/share/python-virtualenv/']
561 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
562 # Probably some boot script; just in case virtualenv is installed...
563 try:
564 import virtualenv
565 except ImportError:
566 pass
567 else:
568 dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
569 return [d for d in dirs if os.path.isdir(d)]
570
571def install_setuptools(py_executable, unzip=False):
572 _install_req(py_executable, unzip)
573
574def install_distribute(py_executable, unzip=False):
575 _install_req(py_executable, unzip, distribute=True)
576
577_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
578def install_pip(py_executable):
579 filenames = []
580 for dir in file_search_dirs():
581 filenames.extend([join(dir, fn) for fn in os.listdir(dir)
582 if _pip_re.search(fn)])
583 filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
584 filenames.sort()
585 filenames = [filename for basename, i, filename in filenames]
586 if not filenames:
587 filename = 'pip'
588 else:
589 filename = filenames[-1]
590 easy_install_script = 'easy_install'
591 if sys.platform == 'win32':
592 easy_install_script = 'easy_install-script.py'
593 cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
594 if filename == 'pip':
595 logger.info('Installing pip from network...')
596 else:
597 logger.info('Installing %s' % os.path.basename(filename))
598 logger.indent += 2
599 def _filter_setup(line):
600 return filter_ez_setup(line, 'pip')
601 try:
602 call_subprocess(cmd, show_stdout=False,
603 filter_stdout=_filter_setup)
604 finally:
605 logger.indent -= 2
606
607def filter_ez_setup(line, project_name='setuptools'):
608 if not line.strip():
609 return Logger.DEBUG
610 if project_name == 'distribute':
611 for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
612 'Scanning', 'Setuptools', 'Egg', 'Already',
613 'running', 'writing', 'reading', 'installing',
614 'creating', 'copying', 'byte-compiling', 'removing',
615 'Processing'):
616 if line.startswith(prefix):
617 return Logger.DEBUG
618 return Logger.DEBUG
619 for prefix in ['Reading ', 'Best match', 'Processing setuptools',
620 'Copying setuptools', 'Adding setuptools',
621 'Installing ', 'Installed ']:
622 if line.startswith(prefix):
623 return Logger.DEBUG
624 return Logger.INFO
625
626def main():
627 parser = optparse.OptionParser(
628 version=virtualenv_version,
629 usage="%prog [OPTIONS] DEST_DIR")
630
631 parser.add_option(
632 '-v', '--verbose',
633 action='count',
634 dest='verbose',
635 default=0,
636 help="Increase verbosity")
637
638 parser.add_option(
639 '-q', '--quiet',
640 action='count',
641 dest='quiet',
642 default=0,
643 help='Decrease verbosity')
644
645 parser.add_option(
646 '-p', '--python',
647 dest='python',
648 metavar='PYTHON_EXE',
649 help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
650 'interpreter to create the new environment. The default is the interpreter that '
651 'virtualenv was installed with (%s)' % sys.executable)
652
653 parser.add_option(
654 '--clear',
655 dest='clear',
656 action='store_true',
657 help="Clear out the non-root install and start from scratch")
658
659 parser.add_option(
660 '--no-site-packages',
661 dest='no_site_packages',
662 action='store_true',
663 help="Don't give access to the global site-packages dir to the "
664 "virtual environment")
665
666 parser.add_option(
667 '--unzip-setuptools',
668 dest='unzip_setuptools',
669 action='store_true',
670 help="Unzip Setuptools or Distribute when installing it")
671
672 parser.add_option(
673 '--relocatable',
674 dest='relocatable',
675 action='store_true',
676 help='Make an EXISTING virtualenv environment relocatable. '
677 'This fixes up scripts and makes all .pth files relative')
678
679 parser.add_option(
680 '--distribute',
681 dest='use_distribute',
682 action='store_true', default=True,
683 help='Ignored. Distribute is used by default. See --setuptools '
684 'to use Setuptools instead of Distribute.')
685
686 parser.add_option(
687 '--setuptools',
688 dest='use_distribute',
689 action='store_false',
690 help='Use Setuptools instead of Distribute. Set environ variable '
691 'VIRTUALENV_USE_SETUPTOOLS to make it the default.')
692
693 parser.add_option(
694 '--prompt=',
695 dest='prompt',
696 help='Provides an alternative prompt prefix for this environment')
697
698 if 'extend_parser' in globals():
699 extend_parser(parser)
700
701 options, args = parser.parse_args()
702
703 global logger
704
705 if 'adjust_options' in globals():
706 adjust_options(options, args)
707
708 verbosity = options.verbose - options.quiet
709 logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
710
711 if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
712 env = os.environ.copy()
713 interpreter = resolve_interpreter(options.python)
714 if interpreter == sys.executable:
715 logger.warn('Already using interpreter %s' % interpreter)
716 else:
717 logger.notify('Running virtualenv with interpreter %s' % interpreter)
718 env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
719 file = __file__
720 if file.endswith('.pyc'):
721 file = file[:-1]
722 popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
723 raise SystemExit(popen.wait())
724
725 if not args:
726 print('You must provide a DEST_DIR')
727 parser.print_help()
728 sys.exit(2)
729 if len(args) > 1:
730 print('There must be only one argument: DEST_DIR (you gave %s)' % (
731 ' '.join(args)))
732 parser.print_help()
733 sys.exit(2)
734
735 home_dir = args[0]
736
737 if os.environ.get('WORKING_ENV'):
738 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
739 logger.fatal('Please deactivate your workingenv, then re-run this script')
740 sys.exit(3)
741
742 if 'PYTHONHOME' in os.environ:
743 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
744 del os.environ['PYTHONHOME']
745
746 if options.relocatable:
747 make_environment_relocatable(home_dir)
748 return
749
750 create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
751 unzip_setuptools=options.unzip_setuptools,
752 use_distribute=options.use_distribute or majver > 2,
753 prompt=options.prompt)
754 if 'after_install' in globals():
755 after_install(options, home_dir)
756
757def call_subprocess(cmd, show_stdout=True,
758 filter_stdout=None, cwd=None,
759 raise_on_returncode=True, extra_env=None,
760 remove_from_env=None):
761 cmd_parts = []
762 for part in cmd:
763 if len(part) > 45:
764 part = part[:20]+"..."+part[-20:]
765 if ' ' in part or '\n' in part or '"' in part or "'" in part:
766 part = '"%s"' % part.replace('"', '\\"')
767 cmd_parts.append(part)
768 cmd_desc = ' '.join(cmd_parts)
769 if show_stdout:
770 stdout = None
771 else:
772 stdout = subprocess.PIPE
773 logger.debug("Running command %s" % cmd_desc)
774 if extra_env or remove_from_env:
775 env = os.environ.copy()
776 if extra_env:
777 env.update(extra_env)
778 if remove_from_env:
779 for varname in remove_from_env:
780 env.pop(varname, None)
781 else:
782 env = None
783 try:
784 proc = subprocess.Popen(
785 cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
786 cwd=cwd, env=env)
787 except Exception:
788 e = sys.exc_info()[1]
789 logger.fatal(
790 "Error %s while executing command %s" % (e, cmd_desc))
791 raise
792 all_output = []
793 if stdout is not None:
794 stdout = proc.stdout
795 encoding = sys.getdefaultencoding()
796 while 1:
797 line = stdout.readline().decode(encoding)
798 if not line:
799 break
800 line = line.rstrip()
801 all_output.append(line)
802 if filter_stdout:
803 level = filter_stdout(line)
804 if isinstance(level, tuple):
805 level, line = level
806 logger.log(level, line)
807 if not logger.stdout_level_matches(level):
808 logger.show_progress()
809 else:
810 logger.info(line)
811 else:
812 proc.communicate()
813 proc.wait()
814 if proc.returncode:
815 if raise_on_returncode:
816 if all_output:
817 logger.notify('Complete output from command %s:' % cmd_desc)
818 logger.notify('\n'.join(all_output) + '\n----------------------------------------')
819 raise OSError(
820 "Command %s failed with error code %s"
821 % (cmd_desc, proc.returncode))
822 else:
823 logger.warn(
824 "Command %s had error code %s"
825 % (cmd_desc, proc.returncode))
826
827
828def create_environment(home_dir, site_packages=True, clear=False,
829 unzip_setuptools=False, use_distribute=True,
830 prompt=None):
831 """
832 Creates a new environment in ``home_dir``.
833
834 If ``site_packages`` is true (the default) then the global
835 ``site-packages/`` directory will be on the path.
836
837 If ``clear`` is true (default False) then the environment will
838 first be cleared.
839 """
840 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
841
842 py_executable = os.path.abspath(install_python(
843 home_dir, lib_dir, inc_dir, bin_dir,
844 site_packages=site_packages, clear=clear))
845
846 install_distutils(home_dir)
847
848 if not use_distribute or os.environ.get('VIRTUALENV_USE_SETUPTOOLS'):
849 install_setuptools(py_executable, unzip=unzip_setuptools)
850 else:
851 install_distribute(py_executable, unzip=unzip_setuptools)
852
853 install_pip(py_executable)
854
855 install_activate(home_dir, bin_dir, prompt)
856
857def path_locations(home_dir):
858 """Return the path locations for the environment (where libraries are,
859 where scripts go, etc)"""
860 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
861 # prefix arg is broken: http://bugs.python.org/issue3386
862 if sys.platform == 'win32':
863 # Windows has lots of problems with executables with spaces in
864 # the name; this function will remove them (using the ~1
865 # format):
866 mkdir(home_dir)
867 if ' ' in home_dir:
868 try:
869 import win32api
870 except ImportError:
871 print('Error: the path "%s" has a space in it' % home_dir)
872 print('To handle these kinds of paths, the win32api module must be installed:')
873 print(' http://sourceforge.net/projects/pywin32/')
874 sys.exit(3)
875 home_dir = win32api.GetShortPathName(home_dir)
876 lib_dir = join(home_dir, 'Lib')
877 inc_dir = join(home_dir, 'Include')
878 bin_dir = join(home_dir, 'Scripts')
879 elif is_jython:
880 lib_dir = join(home_dir, 'Lib')
881 inc_dir = join(home_dir, 'Include')
882 bin_dir = join(home_dir, 'bin')
883 elif is_pypy:
884 lib_dir = home_dir
885 inc_dir = join(home_dir, 'include')
886 bin_dir = join(home_dir, 'bin')
887 else:
888 lib_dir = join(home_dir, 'lib', py_version)
889 inc_dir = join(home_dir, 'include', py_version + abiflags)
890 bin_dir = join(home_dir, 'bin')
891 return home_dir, lib_dir, inc_dir, bin_dir
892
893
894def change_prefix(filename, dst_prefix):
895 prefixes = [sys.prefix]
896
897 if sys.platform == "darwin":
898 prefixes.extend((
899 os.path.join("/Library/Python", sys.version[:3], "site-packages"),
900 os.path.join(sys.prefix, "Extras", "lib", "python"),
901 os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
902
903 if hasattr(sys, 'real_prefix'):
904 prefixes.append(sys.real_prefix)
905 prefixes = list(map(os.path.abspath, prefixes))
906 filename = os.path.abspath(filename)
907 for src_prefix in prefixes:
908 if filename.startswith(src_prefix):
909 _, relpath = filename.split(src_prefix, 1)
910 assert relpath[0] == os.sep
911 relpath = relpath[1:]
912 return join(dst_prefix, relpath)
913 assert False, "Filename %s does not start with any of these prefixes: %s" % \
914 (filename, prefixes)
915
916def copy_required_modules(dst_prefix):
917 import imp
918 for modname in REQUIRED_MODULES:
919 if modname in sys.builtin_module_names:
920 logger.info("Ignoring built-in bootstrap module: %s" % modname)
921 continue
922 try:
923 f, filename, _ = imp.find_module(modname)
924 except ImportError:
925 logger.info("Cannot import bootstrap module: %s" % modname)
926 else:
927 if f is not None:
928 f.close()
929 dst_filename = change_prefix(filename, dst_prefix)
930 copyfile(filename, dst_filename)
931 if filename.endswith('.pyc'):
932 pyfile = filename[:-1]
933 if os.path.exists(pyfile):
934 copyfile(pyfile, dst_filename[:-1])
935
936
937def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
938 """Install just the base environment, no distutils patches etc"""
939 if sys.executable.startswith(bin_dir):
940 print('Please use the *system* python to run this script')
941 return
942
943 if clear:
944 rmtree(lib_dir)
945 ## FIXME: why not delete it?
946 ## Maybe it should delete everything with #!/path/to/venv/python in it
947 logger.notify('Not deleting %s', bin_dir)
948
949 if hasattr(sys, 'real_prefix'):
950 logger.notify('Using real prefix %r' % sys.real_prefix)
951 prefix = sys.real_prefix
952 else:
953 prefix = sys.prefix
954 mkdir(lib_dir)
955 fix_lib64(lib_dir)
956 stdlib_dirs = [os.path.dirname(os.__file__)]
957 if sys.platform == 'win32':
958 stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
959 elif sys.platform == 'darwin':
960 stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
961 if hasattr(os, 'symlink'):
962 logger.info('Symlinking Python bootstrap modules')
963 else:
964 logger.info('Copying Python bootstrap modules')
965 logger.indent += 2
966 try:
967 # copy required files...
968 for stdlib_dir in stdlib_dirs:
969 if not os.path.isdir(stdlib_dir):
970 continue
971 for fn in os.listdir(stdlib_dir):
972 bn = os.path.splitext(fn)[0]
973 if fn != 'site-packages' and bn in REQUIRED_FILES:
974 copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
975 # ...and modules
976 copy_required_modules(home_dir)
977 finally:
978 logger.indent -= 2
979 mkdir(join(lib_dir, 'site-packages'))
980 import site
981 site_filename = site.__file__
982 if site_filename.endswith('.pyc'):
983 site_filename = site_filename[:-1]
984 elif site_filename.endswith('$py.class'):
985 site_filename = site_filename.replace('$py.class', '.py')
986 site_filename_dst = change_prefix(site_filename, home_dir)
987 site_dir = os.path.dirname(site_filename_dst)
988 writefile(site_filename_dst, SITE_PY)
989 writefile(join(site_dir, 'orig-prefix.txt'), prefix)
990 site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
991 if not site_packages:
992 writefile(site_packages_filename, '')
993 else:
994 if os.path.exists(site_packages_filename):
995 logger.info('Deleting %s' % site_packages_filename)
996 os.unlink(site_packages_filename)
997
998 if is_pypy:
999 stdinc_dir = join(prefix, 'include')
1000 else:
1001 stdinc_dir = join(prefix, 'include', py_version + abiflags)
1002 if os.path.exists(stdinc_dir):
1003 copyfile(stdinc_dir, inc_dir)
1004 else:
1005 logger.debug('No include dir %s' % stdinc_dir)
1006
1007 # pypy never uses exec_prefix, just ignore it
1008 if sys.exec_prefix != prefix and not is_pypy:
1009 if sys.platform == 'win32':
1010 exec_dir = join(sys.exec_prefix, 'lib')
1011 elif is_jython:
1012 exec_dir = join(sys.exec_prefix, 'Lib')
1013 else:
1014 exec_dir = join(sys.exec_prefix, 'lib', py_version)
1015 for fn in os.listdir(exec_dir):
1016 copyfile(join(exec_dir, fn), join(lib_dir, fn))
1017
1018 if is_jython:
1019 # Jython has either jython-dev.jar and javalib/ dir, or just
1020 # jython.jar
1021 for name in 'jython-dev.jar', 'javalib', 'jython.jar':
1022 src = join(prefix, name)
1023 if os.path.exists(src):
1024 copyfile(src, join(home_dir, name))
1025 # XXX: registry should always exist after Jython 2.5rc1
1026 src = join(prefix, 'registry')
1027 if os.path.exists(src):
1028 copyfile(src, join(home_dir, 'registry'), symlink=False)
1029 copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
1030 symlink=False)
1031
1032 mkdir(bin_dir)
1033 py_executable = join(bin_dir, os.path.basename(sys.executable))
1034 if 'Python.framework' in prefix:
1035 if re.search(r'/Python(?:-32|-64)*$', py_executable):
1036 # The name of the python executable is not quite what
1037 # we want, rename it.
1038 py_executable = os.path.join(
1039 os.path.dirname(py_executable), 'python')
1040
1041 logger.notify('New %s executable in %s', expected_exe, py_executable)
1042 if sys.executable != py_executable:
1043 ## FIXME: could I just hard link?
1044 executable = sys.executable
1045 if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
1046 # Cygwin misreports sys.executable sometimes
1047 executable += '.exe'
1048 py_executable += '.exe'
1049 logger.info('Executable actually exists in %s' % executable)
1050 shutil.copyfile(executable, py_executable)
1051 make_exe(py_executable)
1052 if sys.platform == 'win32' or sys.platform == 'cygwin':
1053 pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
1054 if os.path.exists(pythonw):
1055 logger.info('Also created pythonw.exe')
1056 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
1057 if is_pypy:
1058 # make a symlink python --> pypy-c
1059 python_executable = os.path.join(os.path.dirname(py_executable), 'python')
1060 logger.info('Also created executable %s' % python_executable)
1061 copyfile(py_executable, python_executable)
1062
1063 if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
1064 secondary_exe = os.path.join(os.path.dirname(py_executable),
1065 expected_exe)
1066 py_executable_ext = os.path.splitext(py_executable)[1]
1067 if py_executable_ext == '.exe':
1068 # python2.4 gives an extension of '.4' :P
1069 secondary_exe += py_executable_ext
1070 if os.path.exists(secondary_exe):
1071 logger.warn('Not overwriting existing %s script %s (you must use %s)'
1072 % (expected_exe, secondary_exe, py_executable))
1073 else:
1074 logger.notify('Also creating executable in %s' % secondary_exe)
1075 shutil.copyfile(sys.executable, secondary_exe)
1076 make_exe(secondary_exe)
1077
1078 if 'Python.framework' in prefix:
1079 logger.debug('MacOSX Python framework detected')
1080
1081 # Make sure we use the the embedded interpreter inside
1082 # the framework, even if sys.executable points to
1083 # the stub executable in ${sys.prefix}/bin
1084 # See http://groups.google.com/group/python-virtualenv/
1085 # browse_thread/thread/17cab2f85da75951
1086 original_python = os.path.join(
1087 prefix, 'Resources/Python.app/Contents/MacOS/Python')
1088 shutil.copy(original_python, py_executable)
1089
1090 # Copy the framework's dylib into the virtual
1091 # environment
1092 virtual_lib = os.path.join(home_dir, '.Python')
1093
1094 if os.path.exists(virtual_lib):
1095 os.unlink(virtual_lib)
1096 copyfile(
1097 os.path.join(prefix, 'Python'),
1098 virtual_lib)
1099
1100 # And then change the install_name of the copied python executable
1101 try:
1102 call_subprocess(
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: