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
1=== modified file '.pc/add_distribute.patch/virtualenv.py' (properties changed: -x to +x)
2--- .pc/add_distribute.patch/virtualenv.py 2011-09-08 15:38:18 +0000
3+++ .pc/add_distribute.patch/virtualenv.py 2011-09-08 21:10:23 +0000
4@@ -1,3 +1,4 @@
5+<<<<<<< TREE
6 #!/usr/bin/env python
7 """Create a "virtual" Python installation
8 """
9@@ -1955,3 +1956,1894 @@
10 ## TODO:
11 ## Copy python.exe.manifest
12 ## Monkeypatch distutils.sysconfig
13+=======
14+"""Create a "virtual" Python installation
15+"""
16+
17+# If you change the version here, change it in setup.py
18+# and docs/conf.py as well.
19+virtualenv_version = "1.6"
20+
21+import base64
22+import sys
23+import os
24+import optparse
25+import re
26+import shutil
27+import logging
28+import tempfile
29+import zlib
30+import errno
31+import distutils.sysconfig
32+try:
33+ import subprocess
34+except ImportError:
35+ if sys.version_info <= (2, 3):
36+ print('ERROR: %s' % sys.exc_info()[1])
37+ print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
38+ print('If you copy subprocess.py from a newer version of Python this script will probably work')
39+ sys.exit(101)
40+ else:
41+ raise
42+try:
43+ set
44+except NameError:
45+ from sets import Set as set
46+try:
47+ basestring
48+except NameError:
49+ basestring = str
50+
51+join = os.path.join
52+py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
53+
54+is_jython = sys.platform.startswith('java')
55+is_pypy = hasattr(sys, 'pypy_version_info')
56+abiflags = getattr(sys, 'abiflags', '')
57+
58+if is_pypy:
59+ expected_exe = 'pypy'
60+elif is_jython:
61+ expected_exe = 'jython'
62+else:
63+ expected_exe = 'python'
64+
65+
66+REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
67+ 'fnmatch', 'locale', 'encodings', 'codecs',
68+ 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
69+ 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
70+ 'zlib']
71+
72+REQUIRED_FILES = ['lib-dynload', 'config']
73+
74+majver, minver = sys.version_info[:2]
75+if majver == 2:
76+ if minver >= 6:
77+ REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
78+ if minver >= 7:
79+ REQUIRED_MODULES.extend(['_weakrefset'])
80+ if minver <= 3:
81+ REQUIRED_MODULES.extend(['sets', '__future__'])
82+elif majver == 3:
83+ # Some extra modules are needed for Python 3, but different ones
84+ # for different versions.
85+ REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
86+ '_weakrefset', 'copyreg', 'tempfile', 'random',
87+ '__future__', 'collections', 'keyword', 'tarfile',
88+ 'shutil', 'struct', 'copy'])
89+ if minver >= 2:
90+ REQUIRED_FILES[-1] = 'config-%s' % majver
91+ if minver == 3:
92+ # The whole list of 3.3 modules is reproduced below - the current
93+ # uncommented ones are required for 3.3 as of now, but more may be
94+ # added as 3.3 development continues.
95+ REQUIRED_MODULES.extend([
96+ #"aifc",
97+ #"antigravity",
98+ #"argparse",
99+ #"ast",
100+ #"asynchat",
101+ #"asyncore",
102+ "base64",
103+ #"bdb",
104+ #"binhex",
105+ "bisect",
106+ #"calendar",
107+ #"cgi",
108+ #"cgitb",
109+ #"chunk",
110+ #"cmd",
111+ #"codeop",
112+ #"code",
113+ #"colorsys",
114+ #"_compat_pickle",
115+ #"compileall",
116+ #"concurrent",
117+ #"configparser",
118+ #"contextlib",
119+ #"cProfile",
120+ #"crypt",
121+ #"csv",
122+ #"ctypes",
123+ #"curses",
124+ #"datetime",
125+ #"dbm",
126+ #"decimal",
127+ #"difflib",
128+ #"dis",
129+ #"doctest",
130+ #"dummy_threading",
131+ #"_dummy_thread",
132+ #"email",
133+ #"filecmp",
134+ #"fileinput",
135+ #"formatter",
136+ #"fractions",
137+ #"ftplib",
138+ #"functools",
139+ #"getopt",
140+ #"getpass",
141+ #"gettext",
142+ #"glob",
143+ #"gzip",
144+ "hashlib",
145+ "heapq",
146+ "hmac",
147+ #"html",
148+ #"http",
149+ #"idlelib",
150+ #"imaplib",
151+ #"imghdr",
152+ #"importlib",
153+ #"inspect",
154+ #"json",
155+ #"lib2to3",
156+ #"logging",
157+ #"macpath",
158+ #"macurl2path",
159+ #"mailbox",
160+ #"mailcap",
161+ #"_markupbase",
162+ #"mimetypes",
163+ #"modulefinder",
164+ #"multiprocessing",
165+ #"netrc",
166+ #"nntplib",
167+ #"nturl2path",
168+ #"numbers",
169+ #"opcode",
170+ #"optparse",
171+ #"os2emxpath",
172+ #"pdb",
173+ #"pickle",
174+ #"pickletools",
175+ #"pipes",
176+ #"pkgutil",
177+ #"platform",
178+ #"plat-linux2",
179+ #"plistlib",
180+ #"poplib",
181+ #"pprint",
182+ #"profile",
183+ #"pstats",
184+ #"pty",
185+ #"pyclbr",
186+ #"py_compile",
187+ #"pydoc_data",
188+ #"pydoc",
189+ #"_pyio",
190+ #"queue",
191+ #"quopri",
192+ "reprlib",
193+ "rlcompleter",
194+ #"runpy",
195+ #"sched",
196+ #"shelve",
197+ #"shlex",
198+ #"smtpd",
199+ #"smtplib",
200+ #"sndhdr",
201+ #"socket",
202+ #"socketserver",
203+ #"sqlite3",
204+ #"ssl",
205+ #"stringprep",
206+ #"string",
207+ #"_strptime",
208+ #"subprocess",
209+ #"sunau",
210+ #"symbol",
211+ #"symtable",
212+ #"sysconfig",
213+ #"tabnanny",
214+ #"telnetlib",
215+ #"test",
216+ #"textwrap",
217+ #"this",
218+ #"_threading_local",
219+ #"threading",
220+ #"timeit",
221+ #"tkinter",
222+ #"tokenize",
223+ #"token",
224+ #"traceback",
225+ #"trace",
226+ #"tty",
227+ #"turtledemo",
228+ #"turtle",
229+ #"unittest",
230+ #"urllib",
231+ #"uuid",
232+ #"uu",
233+ #"wave",
234+ "weakref",
235+ #"webbrowser",
236+ #"wsgiref",
237+ #"xdrlib",
238+ #"xml",
239+ #"xmlrpc",
240+ #"zipfile",
241+ ])
242+
243+if is_pypy:
244+ # these are needed to correctly display the exceptions that may happen
245+ # during the bootstrap
246+ REQUIRED_MODULES.extend(['traceback', 'linecache'])
247+
248+class Logger(object):
249+
250+ """
251+ Logging object for use in command-line script. Allows ranges of
252+ levels, to avoid some redundancy of displayed information.
253+ """
254+
255+ DEBUG = logging.DEBUG
256+ INFO = logging.INFO
257+ NOTIFY = (logging.INFO+logging.WARN)/2
258+ WARN = WARNING = logging.WARN
259+ ERROR = logging.ERROR
260+ FATAL = logging.FATAL
261+
262+ LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
263+
264+ def __init__(self, consumers):
265+ self.consumers = consumers
266+ self.indent = 0
267+ self.in_progress = None
268+ self.in_progress_hanging = False
269+
270+ def debug(self, msg, *args, **kw):
271+ self.log(self.DEBUG, msg, *args, **kw)
272+ def info(self, msg, *args, **kw):
273+ self.log(self.INFO, msg, *args, **kw)
274+ def notify(self, msg, *args, **kw):
275+ self.log(self.NOTIFY, msg, *args, **kw)
276+ def warn(self, msg, *args, **kw):
277+ self.log(self.WARN, msg, *args, **kw)
278+ def error(self, msg, *args, **kw):
279+ self.log(self.WARN, msg, *args, **kw)
280+ def fatal(self, msg, *args, **kw):
281+ self.log(self.FATAL, msg, *args, **kw)
282+ def log(self, level, msg, *args, **kw):
283+ if args:
284+ if kw:
285+ raise TypeError(
286+ "You may give positional or keyword arguments, not both")
287+ args = args or kw
288+ rendered = None
289+ for consumer_level, consumer in self.consumers:
290+ if self.level_matches(level, consumer_level):
291+ if (self.in_progress_hanging
292+ and consumer in (sys.stdout, sys.stderr)):
293+ self.in_progress_hanging = False
294+ sys.stdout.write('\n')
295+ sys.stdout.flush()
296+ if rendered is None:
297+ if args:
298+ rendered = msg % args
299+ else:
300+ rendered = msg
301+ rendered = ' '*self.indent + rendered
302+ if hasattr(consumer, 'write'):
303+ consumer.write(rendered+'\n')
304+ else:
305+ consumer(rendered)
306+
307+ def start_progress(self, msg):
308+ assert not self.in_progress, (
309+ "Tried to start_progress(%r) while in_progress %r"
310+ % (msg, self.in_progress))
311+ if self.level_matches(self.NOTIFY, self._stdout_level()):
312+ sys.stdout.write(msg)
313+ sys.stdout.flush()
314+ self.in_progress_hanging = True
315+ else:
316+ self.in_progress_hanging = False
317+ self.in_progress = msg
318+
319+ def end_progress(self, msg='done.'):
320+ assert self.in_progress, (
321+ "Tried to end_progress without start_progress")
322+ if self.stdout_level_matches(self.NOTIFY):
323+ if not self.in_progress_hanging:
324+ # Some message has been printed out since start_progress
325+ sys.stdout.write('...' + self.in_progress + msg + '\n')
326+ sys.stdout.flush()
327+ else:
328+ sys.stdout.write(msg + '\n')
329+ sys.stdout.flush()
330+ self.in_progress = None
331+ self.in_progress_hanging = False
332+
333+ def show_progress(self):
334+ """If we are in a progress scope, and no log messages have been
335+ shown, write out another '.'"""
336+ if self.in_progress_hanging:
337+ sys.stdout.write('.')
338+ sys.stdout.flush()
339+
340+ def stdout_level_matches(self, level):
341+ """Returns true if a message at this level will go to stdout"""
342+ return self.level_matches(level, self._stdout_level())
343+
344+ def _stdout_level(self):
345+ """Returns the level that stdout runs at"""
346+ for level, consumer in self.consumers:
347+ if consumer is sys.stdout:
348+ return level
349+ return self.FATAL
350+
351+ def level_matches(self, level, consumer_level):
352+ """
353+ >>> l = Logger()
354+ >>> l.level_matches(3, 4)
355+ False
356+ >>> l.level_matches(3, 2)
357+ True
358+ >>> l.level_matches(slice(None, 3), 3)
359+ False
360+ >>> l.level_matches(slice(None, 3), 2)
361+ True
362+ >>> l.level_matches(slice(1, 3), 1)
363+ True
364+ >>> l.level_matches(slice(2, 3), 1)
365+ False
366+ """
367+ if isinstance(level, slice):
368+ start, stop = level.start, level.stop
369+ if start is not None and start > consumer_level:
370+ return False
371+ if stop is not None or stop <= consumer_level:
372+ return False
373+ return True
374+ else:
375+ return level >= consumer_level
376+
377+ #@classmethod
378+ def level_for_integer(cls, level):
379+ levels = cls.LEVELS
380+ if level < 0:
381+ return levels[0]
382+ if level >= len(levels):
383+ return levels[-1]
384+ return levels[level]
385+
386+ level_for_integer = classmethod(level_for_integer)
387+
388+# create a silent logger just to prevent this from being undefined
389+# will be overridden with requested verbosity main() is called.
390+logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
391+
392+def mkdir(path):
393+ if not os.path.exists(path):
394+ logger.info('Creating %s', path)
395+ os.makedirs(path)
396+ else:
397+ logger.info('Directory %s already exists', path)
398+
399+def copyfileordir(src, dest):
400+ if os.path.isdir(src):
401+ shutil.copytree(src, dest, True)
402+ else:
403+ shutil.copy2(src, dest)
404+
405+def copyfile(src, dest, symlink=True):
406+ if not os.path.exists(src):
407+ # Some bad symlink in the src
408+ logger.warn('Cannot find file %s (bad symlink)', src)
409+ return
410+ if os.path.exists(dest):
411+ logger.debug('File %s already exists', dest)
412+ return
413+ if not os.path.exists(os.path.dirname(dest)):
414+ logger.info('Creating parent directories for %s' % os.path.dirname(dest))
415+ os.makedirs(os.path.dirname(dest))
416+ if not os.path.islink(src):
417+ srcpath = os.path.abspath(src)
418+ else:
419+ srcpath = os.readlink(src)
420+ if symlink and hasattr(os, 'symlink'):
421+ logger.info('Symlinking %s', dest)
422+ try:
423+ os.symlink(srcpath, dest)
424+ except (OSError, NotImplementedError):
425+ logger.info('Symlinking failed, copying to %s', dest)
426+ copyfileordir(src, dest)
427+ else:
428+ logger.info('Copying to %s', dest)
429+ copyfileordir(src, dest)
430+
431+def writefile(dest, content, overwrite=True):
432+ if not os.path.exists(dest):
433+ logger.info('Writing %s', dest)
434+ f = open(dest, 'wb')
435+ f.write(content.encode('utf-8'))
436+ f.close()
437+ return
438+ else:
439+ f = open(dest, 'rb')
440+ c = f.read()
441+ f.close()
442+ if c != content:
443+ if not overwrite:
444+ logger.notify('File %s exists with different content; not overwriting', dest)
445+ return
446+ logger.notify('Overwriting %s with new content', dest)
447+ f = open(dest, 'wb')
448+ f.write(content.encode('utf-8'))
449+ f.close()
450+ else:
451+ logger.info('Content %s already in place', dest)
452+
453+def rmtree(dir):
454+ if os.path.exists(dir):
455+ logger.notify('Deleting tree %s', dir)
456+ shutil.rmtree(dir)
457+ else:
458+ logger.info('Do not need to delete %s; already gone', dir)
459+
460+def make_exe(fn):
461+ if hasattr(os, 'chmod'):
462+ oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
463+ newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
464+ os.chmod(fn, newmode)
465+ logger.info('Changed mode of %s to %s', fn, oct(newmode))
466+
467+def _find_file(filename, dirs):
468+ for dir in dirs:
469+ if os.path.exists(join(dir, filename)):
470+ return join(dir, filename)
471+ return filename
472+
473+def _install_req(py_executable, unzip=False, distribute=False):
474+ if not distribute:
475+ setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
476+ project_name = 'setuptools'
477+ bootstrap_script = EZ_SETUP_PY
478+ source = None
479+ else:
480+ setup_fn = None
481+ source = 'distribute-0.6.15.tar.gz'
482+ project_name = 'distribute'
483+ bootstrap_script = DISTRIBUTE_SETUP_PY
484+ try:
485+ # check if the global Python has distribute installed or plain
486+ # setuptools
487+ import pkg_resources
488+ if not hasattr(pkg_resources, '_distribute'):
489+ location = os.path.dirname(pkg_resources.__file__)
490+ logger.notify("A globally installed setuptools was found (in %s)" % location)
491+ logger.notify("Use the --no-site-packages option to use distribute in "
492+ "the virtualenv.")
493+ except ImportError:
494+ pass
495+
496+ search_dirs = file_search_dirs()
497+
498+ if setup_fn is not None:
499+ setup_fn = _find_file(setup_fn, search_dirs)
500+
501+ if source is not None:
502+ source = _find_file(source, search_dirs)
503+
504+ if is_jython and os._name == 'nt':
505+ # Jython's .bat sys.executable can't handle a command line
506+ # argument with newlines
507+ fd, ez_setup = tempfile.mkstemp('.py')
508+ os.write(fd, bootstrap_script)
509+ os.close(fd)
510+ cmd = [py_executable, ez_setup]
511+ else:
512+ cmd = [py_executable, '-c', bootstrap_script]
513+ if unzip:
514+ cmd.append('--always-unzip')
515+ env = {}
516+ remove_from_env = []
517+ if logger.stdout_level_matches(logger.DEBUG):
518+ cmd.append('-v')
519+
520+ old_chdir = os.getcwd()
521+ if setup_fn is not None and os.path.exists(setup_fn):
522+ logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
523+ cmd.append(setup_fn)
524+ if os.environ.get('PYTHONPATH'):
525+ env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
526+ else:
527+ env['PYTHONPATH'] = setup_fn
528+ else:
529+ # the source is found, let's chdir
530+ if source is not None and os.path.exists(source):
531+ os.chdir(os.path.dirname(source))
532+ # in this case, we want to be sure that PYTHONPATH is unset (not
533+ # just empty, really unset), else CPython tries to import the
534+ # site.py that it's in virtualenv_support
535+ remove_from_env.append('PYTHONPATH')
536+ else:
537+ logger.info('No %s egg found; downloading' % project_name)
538+ cmd.extend(['--always-copy', '-U', project_name])
539+ logger.start_progress('Installing %s...' % project_name)
540+ logger.indent += 2
541+ cwd = None
542+ if project_name == 'distribute':
543+ env['DONT_PATCH_SETUPTOOLS'] = 'true'
544+
545+ def _filter_ez_setup(line):
546+ return filter_ez_setup(line, project_name)
547+
548+ if not os.access(os.getcwd(), os.W_OK):
549+ cwd = tempfile.mkdtemp()
550+ if source is not None and os.path.exists(source):
551+ # the current working dir is hostile, let's copy the
552+ # tarball to a temp dir
553+ target = os.path.join(cwd, os.path.split(source)[-1])
554+ shutil.copy(source, target)
555+ try:
556+ call_subprocess(cmd, show_stdout=False,
557+ filter_stdout=_filter_ez_setup,
558+ extra_env=env,
559+ remove_from_env=remove_from_env,
560+ cwd=cwd)
561+ finally:
562+ logger.indent -= 2
563+ logger.end_progress()
564+ if os.getcwd() != old_chdir:
565+ os.chdir(old_chdir)
566+ if is_jython and os._name == 'nt':
567+ os.remove(ez_setup)
568+
569+def file_search_dirs():
570+ here = os.path.dirname(os.path.abspath(__file__))
571+ dirs = ['.', here,
572+ #join(here, 'virtualenv_support')]
573+ '/usr/share/python-virtualenv/']
574+ if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
575+ # Probably some boot script; just in case virtualenv is installed...
576+ try:
577+ import virtualenv
578+ except ImportError:
579+ pass
580+ else:
581+ dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
582+ return [d for d in dirs if os.path.isdir(d)]
583+
584+def install_setuptools(py_executable, unzip=False):
585+ _install_req(py_executable, unzip)
586+
587+def install_distribute(py_executable, unzip=False):
588+ _install_req(py_executable, unzip, distribute=True)
589+
590+_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
591+def install_pip(py_executable):
592+ filenames = []
593+ for dir in file_search_dirs():
594+ filenames.extend([join(dir, fn) for fn in os.listdir(dir)
595+ if _pip_re.search(fn)])
596+ filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
597+ filenames.sort()
598+ filenames = [filename for basename, i, filename in filenames]
599+ if not filenames:
600+ filename = 'pip'
601+ else:
602+ filename = filenames[-1]
603+ easy_install_script = 'easy_install'
604+ if sys.platform == 'win32':
605+ easy_install_script = 'easy_install-script.py'
606+ cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
607+ if filename == 'pip':
608+ logger.info('Installing pip from network...')
609+ else:
610+ logger.info('Installing %s' % os.path.basename(filename))
611+ logger.indent += 2
612+ def _filter_setup(line):
613+ return filter_ez_setup(line, 'pip')
614+ try:
615+ call_subprocess(cmd, show_stdout=False,
616+ filter_stdout=_filter_setup)
617+ finally:
618+ logger.indent -= 2
619+
620+def filter_ez_setup(line, project_name='setuptools'):
621+ if not line.strip():
622+ return Logger.DEBUG
623+ if project_name == 'distribute':
624+ for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
625+ 'Scanning', 'Setuptools', 'Egg', 'Already',
626+ 'running', 'writing', 'reading', 'installing',
627+ 'creating', 'copying', 'byte-compiling', 'removing',
628+ 'Processing'):
629+ if line.startswith(prefix):
630+ return Logger.DEBUG
631+ return Logger.DEBUG
632+ for prefix in ['Reading ', 'Best match', 'Processing setuptools',
633+ 'Copying setuptools', 'Adding setuptools',
634+ 'Installing ', 'Installed ']:
635+ if line.startswith(prefix):
636+ return Logger.DEBUG
637+ return Logger.INFO
638+
639+def main():
640+ parser = optparse.OptionParser(
641+ version=virtualenv_version,
642+ usage="%prog [OPTIONS] DEST_DIR")
643+
644+ parser.add_option(
645+ '-v', '--verbose',
646+ action='count',
647+ dest='verbose',
648+ default=0,
649+ help="Increase verbosity")
650+
651+ parser.add_option(
652+ '-q', '--quiet',
653+ action='count',
654+ dest='quiet',
655+ default=0,
656+ help='Decrease verbosity')
657+
658+ parser.add_option(
659+ '-p', '--python',
660+ dest='python',
661+ metavar='PYTHON_EXE',
662+ help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
663+ 'interpreter to create the new environment. The default is the interpreter that '
664+ 'virtualenv was installed with (%s)' % sys.executable)
665+
666+ parser.add_option(
667+ '--clear',
668+ dest='clear',
669+ action='store_true',
670+ help="Clear out the non-root install and start from scratch")
671+
672+ parser.add_option(
673+ '--no-site-packages',
674+ dest='no_site_packages',
675+ action='store_true',
676+ help="Don't give access to the global site-packages dir to the "
677+ "virtual environment")
678+
679+ parser.add_option(
680+ '--unzip-setuptools',
681+ dest='unzip_setuptools',
682+ action='store_true',
683+ help="Unzip Setuptools or Distribute when installing it")
684+
685+ parser.add_option(
686+ '--relocatable',
687+ dest='relocatable',
688+ action='store_true',
689+ help='Make an EXISTING virtualenv environment relocatable. '
690+ 'This fixes up scripts and makes all .pth files relative')
691+
692+ parser.add_option(
693+ '--distribute',
694+ dest='use_distribute',
695+ action='store_true',
696+ help='Use Distribute instead of Setuptools. Set environ variable '
697+ 'VIRTUALENV_USE_DISTRIBUTE to make it the default ')
698+
699+ parser.add_option(
700+ '--prompt=',
701+ dest='prompt',
702+ help='Provides an alternative prompt prefix for this environment')
703+
704+ if 'extend_parser' in globals():
705+ extend_parser(parser)
706+
707+ options, args = parser.parse_args()
708+
709+ global logger
710+
711+ if 'adjust_options' in globals():
712+ adjust_options(options, args)
713+
714+ verbosity = options.verbose - options.quiet
715+ logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
716+
717+ if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
718+ env = os.environ.copy()
719+ interpreter = resolve_interpreter(options.python)
720+ if interpreter == sys.executable:
721+ logger.warn('Already using interpreter %s' % interpreter)
722+ else:
723+ logger.notify('Running virtualenv with interpreter %s' % interpreter)
724+ env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
725+ file = __file__
726+ if file.endswith('.pyc'):
727+ file = file[:-1]
728+ popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
729+ raise SystemExit(popen.wait())
730+
731+ if not args:
732+ print('You must provide a DEST_DIR')
733+ parser.print_help()
734+ sys.exit(2)
735+ if len(args) > 1:
736+ print('There must be only one argument: DEST_DIR (you gave %s)' % (
737+ ' '.join(args)))
738+ parser.print_help()
739+ sys.exit(2)
740+
741+ home_dir = args[0]
742+
743+ if os.environ.get('WORKING_ENV'):
744+ logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
745+ logger.fatal('Please deactivate your workingenv, then re-run this script')
746+ sys.exit(3)
747+
748+ if 'PYTHONHOME' in os.environ:
749+ logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
750+ del os.environ['PYTHONHOME']
751+
752+ if options.relocatable:
753+ make_environment_relocatable(home_dir)
754+ return
755+
756+ create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
757+ unzip_setuptools=options.unzip_setuptools,
758+ use_distribute=options.use_distribute or majver > 2,
759+ prompt=options.prompt)
760+ if 'after_install' in globals():
761+ after_install(options, home_dir)
762+
763+def call_subprocess(cmd, show_stdout=True,
764+ filter_stdout=None, cwd=None,
765+ raise_on_returncode=True, extra_env=None,
766+ remove_from_env=None):
767+ cmd_parts = []
768+ for part in cmd:
769+ if len(part) > 45:
770+ part = part[:20]+"..."+part[-20:]
771+ if ' ' in part or '\n' in part or '"' in part or "'" in part:
772+ part = '"%s"' % part.replace('"', '\\"')
773+ cmd_parts.append(part)
774+ cmd_desc = ' '.join(cmd_parts)
775+ if show_stdout:
776+ stdout = None
777+ else:
778+ stdout = subprocess.PIPE
779+ logger.debug("Running command %s" % cmd_desc)
780+ if extra_env or remove_from_env:
781+ env = os.environ.copy()
782+ if extra_env:
783+ env.update(extra_env)
784+ if remove_from_env:
785+ for varname in remove_from_env:
786+ env.pop(varname, None)
787+ else:
788+ env = None
789+ try:
790+ proc = subprocess.Popen(
791+ cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
792+ cwd=cwd, env=env)
793+ except Exception:
794+ e = sys.exc_info()[1]
795+ logger.fatal(
796+ "Error %s while executing command %s" % (e, cmd_desc))
797+ raise
798+ all_output = []
799+ if stdout is not None:
800+ stdout = proc.stdout
801+ encoding = sys.getdefaultencoding()
802+ while 1:
803+ line = stdout.readline().decode(encoding)
804+ if not line:
805+ break
806+ line = line.rstrip()
807+ all_output.append(line)
808+ if filter_stdout:
809+ level = filter_stdout(line)
810+ if isinstance(level, tuple):
811+ level, line = level
812+ logger.log(level, line)
813+ if not logger.stdout_level_matches(level):
814+ logger.show_progress()
815+ else:
816+ logger.info(line)
817+ else:
818+ proc.communicate()
819+ proc.wait()
820+ if proc.returncode:
821+ if raise_on_returncode:
822+ if all_output:
823+ logger.notify('Complete output from command %s:' % cmd_desc)
824+ logger.notify('\n'.join(all_output) + '\n----------------------------------------')
825+ raise OSError(
826+ "Command %s failed with error code %s"
827+ % (cmd_desc, proc.returncode))
828+ else:
829+ logger.warn(
830+ "Command %s had error code %s"
831+ % (cmd_desc, proc.returncode))
832+
833+
834+def create_environment(home_dir, site_packages=True, clear=False,
835+ unzip_setuptools=False, use_distribute=False,
836+ prompt=None):
837+ """
838+ Creates a new environment in ``home_dir``.
839+
840+ If ``site_packages`` is true (the default) then the global
841+ ``site-packages/`` directory will be on the path.
842+
843+ If ``clear`` is true (default False) then the environment will
844+ first be cleared.
845+ """
846+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
847+
848+ py_executable = os.path.abspath(install_python(
849+ home_dir, lib_dir, inc_dir, bin_dir,
850+ site_packages=site_packages, clear=clear))
851+
852+ install_distutils(home_dir)
853+
854+ if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
855+ install_distribute(py_executable, unzip=unzip_setuptools)
856+ else:
857+ install_setuptools(py_executable, unzip=unzip_setuptools)
858+
859+ install_pip(py_executable)
860+
861+ install_activate(home_dir, bin_dir, prompt)
862+
863+def path_locations(home_dir):
864+ """Return the path locations for the environment (where libraries are,
865+ where scripts go, etc)"""
866+ # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
867+ # prefix arg is broken: http://bugs.python.org/issue3386
868+ if sys.platform == 'win32':
869+ # Windows has lots of problems with executables with spaces in
870+ # the name; this function will remove them (using the ~1
871+ # format):
872+ mkdir(home_dir)
873+ if ' ' in home_dir:
874+ try:
875+ import win32api
876+ except ImportError:
877+ print('Error: the path "%s" has a space in it' % home_dir)
878+ print('To handle these kinds of paths, the win32api module must be installed:')
879+ print(' http://sourceforge.net/projects/pywin32/')
880+ sys.exit(3)
881+ home_dir = win32api.GetShortPathName(home_dir)
882+ lib_dir = join(home_dir, 'Lib')
883+ inc_dir = join(home_dir, 'Include')
884+ bin_dir = join(home_dir, 'Scripts')
885+ elif is_jython:
886+ lib_dir = join(home_dir, 'Lib')
887+ inc_dir = join(home_dir, 'Include')
888+ bin_dir = join(home_dir, 'bin')
889+ elif is_pypy:
890+ lib_dir = home_dir
891+ inc_dir = join(home_dir, 'include')
892+ bin_dir = join(home_dir, 'bin')
893+ else:
894+ lib_dir = join(home_dir, 'lib', py_version)
895+ inc_dir = join(home_dir, 'include', py_version + abiflags)
896+ bin_dir = join(home_dir, 'bin')
897+ return home_dir, lib_dir, inc_dir, bin_dir
898+
899+
900+def change_prefix(filename, dst_prefix):
901+ prefixes = [sys.prefix]
902+
903+ if sys.platform == "darwin":
904+ prefixes.extend((
905+ os.path.join("/Library/Python", sys.version[:3], "site-packages"),
906+ os.path.join(sys.prefix, "Extras", "lib", "python"),
907+ os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
908+
909+ if hasattr(sys, 'real_prefix'):
910+ prefixes.append(sys.real_prefix)
911+ prefixes = list(map(os.path.abspath, prefixes))
912+ filename = os.path.abspath(filename)
913+ for src_prefix in prefixes:
914+ if filename.startswith(src_prefix):
915+ _, relpath = filename.split(src_prefix, 1)
916+ assert relpath[0] == os.sep
917+ relpath = relpath[1:]
918+ return join(dst_prefix, relpath)
919+ assert False, "Filename %s does not start with any of these prefixes: %s" % \
920+ (filename, prefixes)
921+
922+def copy_required_modules(dst_prefix):
923+ import imp
924+ for modname in REQUIRED_MODULES:
925+ if modname in sys.builtin_module_names:
926+ logger.info("Ignoring built-in bootstrap module: %s" % modname)
927+ continue
928+ try:
929+ f, filename, _ = imp.find_module(modname)
930+ except ImportError:
931+ logger.info("Cannot import bootstrap module: %s" % modname)
932+ else:
933+ if f is not None:
934+ f.close()
935+ dst_filename = change_prefix(filename, dst_prefix)
936+ copyfile(filename, dst_filename)
937+ if filename.endswith('.pyc'):
938+ pyfile = filename[:-1]
939+ if os.path.exists(pyfile):
940+ copyfile(pyfile, dst_filename[:-1])
941+
942+
943+def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
944+ """Install just the base environment, no distutils patches etc"""
945+ if sys.executable.startswith(bin_dir):
946+ print('Please use the *system* python to run this script')
947+ return
948+
949+ if clear:
950+ rmtree(lib_dir)
951+ ## FIXME: why not delete it?
952+ ## Maybe it should delete everything with #!/path/to/venv/python in it
953+ logger.notify('Not deleting %s', bin_dir)
954+
955+ if hasattr(sys, 'real_prefix'):
956+ logger.notify('Using real prefix %r' % sys.real_prefix)
957+ prefix = sys.real_prefix
958+ else:
959+ prefix = sys.prefix
960+ mkdir(lib_dir)
961+ fix_lib64(lib_dir)
962+ stdlib_dirs = [os.path.dirname(os.__file__)]
963+ if sys.platform == 'win32':
964+ stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
965+ elif sys.platform == 'darwin':
966+ stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
967+ if hasattr(os, 'symlink'):
968+ logger.info('Symlinking Python bootstrap modules')
969+ else:
970+ logger.info('Copying Python bootstrap modules')
971+ logger.indent += 2
972+ try:
973+ # copy required files...
974+ for stdlib_dir in stdlib_dirs:
975+ if not os.path.isdir(stdlib_dir):
976+ continue
977+ for fn in os.listdir(stdlib_dir):
978+ bn = os.path.splitext(fn)[0]
979+ if fn != 'site-packages' and bn in REQUIRED_FILES:
980+ copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
981+ # ...and modules
982+ copy_required_modules(home_dir)
983+ finally:
984+ logger.indent -= 2
985+ mkdir(join(lib_dir, 'site-packages'))
986+ import site
987+ site_filename = site.__file__
988+ if site_filename.endswith('.pyc'):
989+ site_filename = site_filename[:-1]
990+ elif site_filename.endswith('$py.class'):
991+ site_filename = site_filename.replace('$py.class', '.py')
992+ site_filename_dst = change_prefix(site_filename, home_dir)
993+ site_dir = os.path.dirname(site_filename_dst)
994+ writefile(site_filename_dst, SITE_PY)
995+ writefile(join(site_dir, 'orig-prefix.txt'), prefix)
996+ site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
997+ if not site_packages:
998+ writefile(site_packages_filename, '')
999+ else:
1000+ if os.path.exists(site_packages_filename):
1001+ logger.info('Deleting %s' % site_packages_filename)
1002+ os.unlink(site_packages_filename)
1003+
1004+ if is_pypy:
1005+ stdinc_dir = join(prefix, 'include')
1006+ else:
1007+ stdinc_dir = join(prefix, 'include', py_version + abiflags)
1008+ if os.path.exists(stdinc_dir):
1009+ copyfile(stdinc_dir, inc_dir)
1010+ else:
1011+ logger.debug('No include dir %s' % stdinc_dir)
1012+
1013+ # pypy never uses exec_prefix, just ignore it
1014+ if sys.exec_prefix != prefix and not is_pypy:
1015+ if sys.platform == 'win32':
1016+ exec_dir = join(sys.exec_prefix, 'lib')
1017+ elif is_jython:
1018+ exec_dir = join(sys.exec_prefix, 'Lib')
1019+ else:
1020+ exec_dir = join(sys.exec_prefix, 'lib', py_version)
1021+ for fn in os.listdir(exec_dir):
1022+ copyfile(join(exec_dir, fn), join(lib_dir, fn))
1023+
1024+ if is_jython:
1025+ # Jython has either jython-dev.jar and javalib/ dir, or just
1026+ # jython.jar
1027+ for name in 'jython-dev.jar', 'javalib', 'jython.jar':
1028+ src = join(prefix, name)
1029+ if os.path.exists(src):
1030+ copyfile(src, join(home_dir, name))
1031+ # XXX: registry should always exist after Jython 2.5rc1
1032+ src = join(prefix, 'registry')
1033+ if os.path.exists(src):
1034+ copyfile(src, join(home_dir, 'registry'), symlink=False)
1035+ copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
1036+ symlink=False)
1037+
1038+ mkdir(bin_dir)
1039+ py_executable = join(bin_dir, os.path.basename(sys.executable))
1040+ if 'Python.framework' in prefix:
1041+ if re.search(r'/Python(?:-32|-64)*$', py_executable):
1042+ # The name of the python executable is not quite what
1043+ # we want, rename it.
1044+ py_executable = os.path.join(
1045+ os.path.dirname(py_executable), 'python')
1046+
1047+ logger.notify('New %s executable in %s', expected_exe, py_executable)
1048+ if sys.executable != py_executable:
1049+ ## FIXME: could I just hard link?
1050+ executable = sys.executable
1051+ if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
1052+ # Cygwin misreports sys.executable sometimes
1053+ executable += '.exe'
1054+ py_executable += '.exe'
1055+ logger.info('Executable actually exists in %s' % executable)
1056+ shutil.copyfile(executable, py_executable)
1057+ make_exe(py_executable)
1058+ if sys.platform == 'win32' or sys.platform == 'cygwin':
1059+ pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
1060+ if os.path.exists(pythonw):
1061+ logger.info('Also created pythonw.exe')
1062+ shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
1063+ if is_pypy:
1064+ # make a symlink python --> pypy-c
1065+ python_executable = os.path.join(os.path.dirname(py_executable), 'python')
1066+ logger.info('Also created executable %s' % python_executable)
1067+ copyfile(py_executable, python_executable)
1068+
1069+ if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
1070+ secondary_exe = os.path.join(os.path.dirname(py_executable),
1071+ expected_exe)
1072+ py_executable_ext = os.path.splitext(py_executable)[1]
1073+ if py_executable_ext == '.exe':
1074+ # python2.4 gives an extension of '.4' :P
1075+ secondary_exe += py_executable_ext
1076+ if os.path.exists(secondary_exe):
1077+ logger.warn('Not overwriting existing %s script %s (you must use %s)'
1078+ % (expected_exe, secondary_exe, py_executable))
1079+ else:
1080+ logger.notify('Also creating executable in %s' % secondary_exe)
1081+ shutil.copyfile(sys.executable, secondary_exe)
1082+ make_exe(secondary_exe)
1083+
1084+ if 'Python.framework' in prefix:
1085+ logger.debug('MacOSX Python framework detected')
1086+
1087+ # Make sure we use the the embedded interpreter inside
1088+ # the framework, even if sys.executable points to
1089+ # the stub executable in ${sys.prefix}/bin
1090+ # See http://groups.google.com/group/python-virtualenv/
1091+ # browse_thread/thread/17cab2f85da75951
1092+ original_python = os.path.join(
1093+ prefix, 'Resources/Python.app/Contents/MacOS/Python')
1094+ shutil.copy(original_python, py_executable)
1095+
1096+ # Copy the framework's dylib into the virtual
1097+ # environment
1098+ virtual_lib = os.path.join(home_dir, '.Python')
1099+
1100+ if os.path.exists(virtual_lib):
1101+ os.unlink(virtual_lib)
1102+ copyfile(
1103+ os.path.join(prefix, 'Python'),
1104+ virtual_lib)
1105+
1106+ # And then change the install_name of the copied python executable
1107+ try:
1108+ call_subprocess(
1109+ ["install_name_tool", "-change",
1110+ os.path.join(prefix, 'Python'),
1111+ '@executable_path/../.Python',
1112+ py_executable])
1113+ except:
1114+ logger.fatal(
1115+ "Could not call install_name_tool -- you must have Apple's development tools installed")
1116+ raise
1117+
1118+ # Some tools depend on pythonX.Y being present
1119+ py_executable_version = '%s.%s' % (
1120+ sys.version_info[0], sys.version_info[1])
1121+ if not py_executable.endswith(py_executable_version):
1122+ # symlinking pythonX.Y > python
1123+ pth = py_executable + '%s.%s' % (
1124+ sys.version_info[0], sys.version_info[1])
1125+ if os.path.exists(pth):
1126+ os.unlink(pth)
1127+ os.symlink('python', pth)
1128+ else:
1129+ # reverse symlinking python -> pythonX.Y (with --python)
1130+ pth = join(bin_dir, 'python')
1131+ if os.path.exists(pth):
1132+ os.unlink(pth)
1133+ os.symlink(os.path.basename(py_executable), pth)
1134+
1135+ if sys.platform == 'win32' and ' ' in py_executable:
1136+ # There's a bug with subprocess on Windows when using a first
1137+ # argument that has a space in it. Instead we have to quote
1138+ # the value:
1139+ py_executable = '"%s"' % py_executable
1140+ cmd = [py_executable, '-c', 'import sys; print(sys.prefix)']
1141+ logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
1142+ try:
1143+ proc = subprocess.Popen(cmd,
1144+ stdout=subprocess.PIPE)
1145+ proc_stdout, proc_stderr = proc.communicate()
1146+ except OSError:
1147+ e = sys.exc_info()[1]
1148+ if e.errno == errno.EACCES:
1149+ logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
1150+ sys.exit(100)
1151+ else:
1152+ raise e
1153+
1154+ proc_stdout = proc_stdout.strip().decode(sys.getdefaultencoding())
1155+ proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
1156+ if proc_stdout != os.path.normcase(os.path.abspath(home_dir)):
1157+ logger.fatal(
1158+ 'ERROR: The executable %s is not functioning' % py_executable)
1159+ logger.fatal(
1160+ 'ERROR: It thinks sys.prefix is %r (should be %r)'
1161+ % (proc_stdout, os.path.normcase(os.path.abspath(home_dir))))
1162+ logger.fatal(
1163+ 'ERROR: virtualenv is not compatible with this system or executable')
1164+ if sys.platform == 'win32':
1165+ logger.fatal(
1166+ '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)')
1167+ sys.exit(100)
1168+ else:
1169+ logger.info('Got sys.prefix result: %r' % proc_stdout)
1170+
1171+ pydistutils = os.path.expanduser('~/.pydistutils.cfg')
1172+ if os.path.exists(pydistutils):
1173+ logger.notify('Please make sure you remove any previous custom paths from '
1174+ 'your %s file.' % pydistutils)
1175+ ## FIXME: really this should be calculated earlier
1176+ return py_executable
1177+
1178+def install_activate(home_dir, bin_dir, prompt=None):
1179+ if sys.platform == 'win32' or is_jython and os._name == 'nt':
1180+ files = {'activate.bat': ACTIVATE_BAT,
1181+ 'deactivate.bat': DEACTIVATE_BAT}
1182+ if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin':
1183+ files['activate'] = ACTIVATE_SH
1184+ else:
1185+ files = {'activate': ACTIVATE_SH}
1186+
1187+ # suppling activate.fish in addition to, not instead of, the
1188+ # bash script support.
1189+ files['activate.fish'] = ACTIVATE_FISH
1190+
1191+ # same for csh/tcsh support...
1192+ files['activate.csh'] = ACTIVATE_CSH
1193+
1194+
1195+
1196+ files['activate_this.py'] = ACTIVATE_THIS
1197+ vname = os.path.basename(os.path.abspath(home_dir))
1198+ for name, content in files.items():
1199+ content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
1200+ content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
1201+ content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir))
1202+ content = content.replace('__VIRTUAL_NAME__', vname)
1203+ content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
1204+ writefile(os.path.join(bin_dir, name), content)
1205+
1206+def install_distutils(home_dir):
1207+ distutils_path = change_prefix(distutils.__path__[0], home_dir)
1208+ mkdir(distutils_path)
1209+ ## FIXME: maybe this prefix setting should only be put in place if
1210+ ## there's a local distutils.cfg with a prefix setting?
1211+ home_dir = os.path.abspath(home_dir)
1212+ ## FIXME: this is breaking things, removing for now:
1213+ #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
1214+ writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
1215+ writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
1216+
1217+def fix_lib64(lib_dir):
1218+ """
1219+ Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
1220+ instead of lib/pythonX.Y. If this is such a platform we'll just create a
1221+ symlink so lib64 points to lib
1222+ """
1223+ if [p for p in distutils.sysconfig.get_config_vars().values()
1224+ if isinstance(p, basestring) and 'lib64' in p]:
1225+ logger.debug('This system uses lib64; symlinking lib64 to lib')
1226+ assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
1227+ "Unexpected python lib dir: %r" % lib_dir)
1228+ lib_parent = os.path.dirname(lib_dir)
1229+ assert os.path.basename(lib_parent) == 'lib', (
1230+ "Unexpected parent dir: %r" % lib_parent)
1231+ copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
1232+
1233+def resolve_interpreter(exe):
1234+ """
1235+ If the executable given isn't an absolute path, search $PATH for the interpreter
1236+ """
1237+ if os.path.abspath(exe) != exe:
1238+ paths = os.environ.get('PATH', '').split(os.pathsep)
1239+ for path in paths:
1240+ if os.path.exists(os.path.join(path, exe)):
1241+ exe = os.path.join(path, exe)
1242+ break
1243+ if not os.path.exists(exe):
1244+ logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
1245+ sys.exit(3)
1246+ return exe
1247+
1248+############################################################
1249+## Relocating the environment:
1250+
1251+def make_environment_relocatable(home_dir):
1252+ """
1253+ Makes the already-existing environment use relative paths, and takes out
1254+ the #!-based environment selection in scripts.
1255+ """
1256+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
1257+ activate_this = os.path.join(bin_dir, 'activate_this.py')
1258+ if not os.path.exists(activate_this):
1259+ logger.fatal(
1260+ 'The environment doesn\'t have a file %s -- please re-run virtualenv '
1261+ 'on this environment to update it' % activate_this)
1262+ fixup_scripts(home_dir)
1263+ fixup_pth_and_egg_link(home_dir)
1264+ ## FIXME: need to fix up distutils.cfg
1265+
1266+OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
1267+ 'activate', 'activate.bat', 'activate_this.py']
1268+
1269+def fixup_scripts(home_dir):
1270+ # This is what we expect at the top of scripts:
1271+ shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
1272+ # This is what we'll put:
1273+ new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
1274+ 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"
1275+ if sys.platform == 'win32':
1276+ bin_suffix = 'Scripts'
1277+ else:
1278+ bin_suffix = 'bin'
1279+ bin_dir = os.path.join(home_dir, bin_suffix)
1280+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
1281+ for filename in os.listdir(bin_dir):
1282+ filename = os.path.join(bin_dir, filename)
1283+ if not os.path.isfile(filename):
1284+ # ignore subdirs, e.g. .svn ones.
1285+ continue
1286+ f = open(filename, 'rb')
1287+ lines = f.readlines()
1288+ f.close()
1289+ if not lines:
1290+ logger.warn('Script %s is an empty file' % filename)
1291+ continue
1292+ if not lines[0].strip().startswith(shebang):
1293+ if os.path.basename(filename) in OK_ABS_SCRIPTS:
1294+ logger.debug('Cannot make script %s relative' % filename)
1295+ elif lines[0].strip() == new_shebang:
1296+ logger.info('Script %s has already been made relative' % filename)
1297+ else:
1298+ logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
1299+ % (filename, shebang))
1300+ continue
1301+ logger.notify('Making script %s relative' % filename)
1302+ lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
1303+ f = open(filename, 'wb')
1304+ f.writelines(lines)
1305+ f.close()
1306+
1307+def fixup_pth_and_egg_link(home_dir, sys_path=None):
1308+ """Makes .pth and .egg-link files use relative paths"""
1309+ home_dir = os.path.normcase(os.path.abspath(home_dir))
1310+ if sys_path is None:
1311+ sys_path = sys.path
1312+ for path in sys_path:
1313+ if not path:
1314+ path = '.'
1315+ if not os.path.isdir(path):
1316+ continue
1317+ path = os.path.normcase(os.path.abspath(path))
1318+ if not path.startswith(home_dir):
1319+ logger.debug('Skipping system (non-environment) directory %s' % path)
1320+ continue
1321+ for filename in os.listdir(path):
1322+ filename = os.path.join(path, filename)
1323+ if filename.endswith('.pth'):
1324+ if not os.access(filename, os.W_OK):
1325+ logger.warn('Cannot write .pth file %s, skipping' % filename)
1326+ else:
1327+ fixup_pth_file(filename)
1328+ if filename.endswith('.egg-link'):
1329+ if not os.access(filename, os.W_OK):
1330+ logger.warn('Cannot write .egg-link file %s, skipping' % filename)
1331+ else:
1332+ fixup_egg_link(filename)
1333+
1334+def fixup_pth_file(filename):
1335+ lines = []
1336+ prev_lines = []
1337+ f = open(filename)
1338+ prev_lines = f.readlines()
1339+ f.close()
1340+ for line in prev_lines:
1341+ line = line.strip()
1342+ if (not line or line.startswith('#') or line.startswith('import ')
1343+ or os.path.abspath(line) != line):
1344+ lines.append(line)
1345+ else:
1346+ new_value = make_relative_path(filename, line)
1347+ if line != new_value:
1348+ logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
1349+ lines.append(new_value)
1350+ if lines == prev_lines:
1351+ logger.info('No changes to .pth file %s' % filename)
1352+ return
1353+ logger.notify('Making paths in .pth file %s relative' % filename)
1354+ f = open(filename, 'w')
1355+ f.write('\n'.join(lines) + '\n')
1356+ f.close()
1357+
1358+def fixup_egg_link(filename):
1359+ f = open(filename)
1360+ link = f.read().strip()
1361+ f.close()
1362+ if os.path.abspath(link) != link:
1363+ logger.debug('Link in %s already relative' % filename)
1364+ return
1365+ new_link = make_relative_path(filename, link)
1366+ logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
1367+ f = open(filename, 'w')
1368+ f.write(new_link)
1369+ f.close()
1370+
1371+def make_relative_path(source, dest, dest_is_directory=True):
1372+ """
1373+ Make a filename relative, where the filename is dest, and it is
1374+ being referred to from the filename source.
1375+
1376+ >>> make_relative_path('/usr/share/something/a-file.pth',
1377+ ... '/usr/share/another-place/src/Directory')
1378+ '../another-place/src/Directory'
1379+ >>> make_relative_path('/usr/share/something/a-file.pth',
1380+ ... '/home/user/src/Directory')
1381+ '../../../home/user/src/Directory'
1382+ >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
1383+ './'
1384+ """
1385+ source = os.path.dirname(source)
1386+ if not dest_is_directory:
1387+ dest_filename = os.path.basename(dest)
1388+ dest = os.path.dirname(dest)
1389+ dest = os.path.normpath(os.path.abspath(dest))
1390+ source = os.path.normpath(os.path.abspath(source))
1391+ dest_parts = dest.strip(os.path.sep).split(os.path.sep)
1392+ source_parts = source.strip(os.path.sep).split(os.path.sep)
1393+ while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
1394+ dest_parts.pop(0)
1395+ source_parts.pop(0)
1396+ full_parts = ['..']*len(source_parts) + dest_parts
1397+ if not dest_is_directory:
1398+ full_parts.append(dest_filename)
1399+ if not full_parts:
1400+ # Special case for the current directory (otherwise it'd be '')
1401+ return './'
1402+ return os.path.sep.join(full_parts)
1403+
1404+
1405+
1406+############################################################
1407+## Bootstrap script creation:
1408+
1409+def create_bootstrap_script(extra_text, python_version=''):
1410+ """
1411+ Creates a bootstrap script, which is like this script but with
1412+ extend_parser, adjust_options, and after_install hooks.
1413+
1414+ This returns a string that (written to disk of course) can be used
1415+ as a bootstrap script with your own customizations. The script
1416+ will be the standard virtualenv.py script, with your extra text
1417+ added (your extra text should be Python code).
1418+
1419+ If you include these functions, they will be called:
1420+
1421+ ``extend_parser(optparse_parser)``:
1422+ You can add or remove options from the parser here.
1423+
1424+ ``adjust_options(options, args)``:
1425+ You can change options here, or change the args (if you accept
1426+ different kinds of arguments, be sure you modify ``args`` so it is
1427+ only ``[DEST_DIR]``).
1428+
1429+ ``after_install(options, home_dir)``:
1430+
1431+ After everything is installed, this function is called. This
1432+ is probably the function you are most likely to use. An
1433+ example would be::
1434+
1435+ def after_install(options, home_dir):
1436+ subprocess.call([join(home_dir, 'bin', 'easy_install'),
1437+ 'MyPackage'])
1438+ subprocess.call([join(home_dir, 'bin', 'my-package-script'),
1439+ 'setup', home_dir])
1440+
1441+ This example immediately installs a package, and runs a setup
1442+ script from that package.
1443+
1444+ If you provide something like ``python_version='2.4'`` then the
1445+ script will start with ``#!/usr/bin/env python2.4`` instead of
1446+ ``#!/usr/bin/env python``. You can use this when the script must
1447+ be run with a particular Python version.
1448+ """
1449+ filename = __file__
1450+ if filename.endswith('.pyc'):
1451+ filename = filename[:-1]
1452+ f = open(filename, 'rb')
1453+ content = f.read()
1454+ f.close()
1455+ py_exe = 'python%s' % python_version
1456+ content = (('#!/usr/bin/env %s\n' % py_exe)
1457+ + '## WARNING: This file is generated\n'
1458+ + content)
1459+ return content.replace('##EXT' 'END##', extra_text)
1460+
1461+##EXTEND##
1462+
1463+def convert(s):
1464+ b = base64.b64decode(s.encode('ascii'))
1465+ return zlib.decompress(b).decode('utf-8')
1466+
1467+##file site.py
1468+SITE_PY = convert("""
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
1603+AIOc2an2AKxRCP4P1A2QJQ==
1604+""")
1605+
1606+
1607+
1608+##file ez_setup.py
1609+EZ_SETUP_PY = convert("""
1610+eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt
1611+RT6UwcQ2ebjPfq6195G+/upwanZlMZvP538sy6ZuKnKwatEcD01Z5rWVFXVD8pw0GRbNPkrrVB6t
1612+Z1I0VlNax1qM16qnlXUg7DN5EovaPLQPp7X192PdYAHLj1xYzS6rZzLLhXql2UEI2QuLZ5VgTVmd
1613+rOes2VlZs7ZIwS3CuX5BbajWNuXBKqXZqZN/dzebWbhkVe4t8c+tvm9l+0NZNUrL7VlLvW58a7m6
1614+sqwS/zhCHYtY9UGwTGbM+iKqGk5Qe59fXavfsYqXz0VeEj7bZ1VVVmurrLR3SGGRvBFVQRrRLzpb
1615+utabMqzipVWXFj1Z9fFwyE9Z8TRTxpLDoSoPVaZeLw8qCNoPj4+XFjw+2rPZT8pN2q9Mb6wkCqs6
1616+4vdamcKq7KDNa6OqtTw8VYQP42irZJi1zqtP9ey7D3/65uc//7T964cffvz4P99bG2vu2BFz3Xn/
1617+6Ocf/qz8qh7tmuZwd3t7OB0y2ySXXVZPt21S1Lc39S3+63e7nVs3ahe79e/9nf8wm+15uOWkIRD4
1618+Lx2xxfmNt9icum8PJ8/2bfH0tLizFknieYzI1HG90OFJkNA0jWgsvZBFImJksX5FStBJoXFKEhI4
1619+vghCx5OUJqEQvnTTwI39kNEJKd5YlzAK4zhMeUIinkgWBE7skJQ7sRd7PE1fl9LrEsAAknA3SrlH
1620+RRS5kvgeiUToiUAm3pRF/lgXSn2XOZLFfpqSyA/jNI1DRngqQ+JEbvKqlF4XPyEJw10eCcY9zwti
1621+6capjDmJolQSNiElGOsSeU4QEi8QPBCuoCyOpXD8lJBARDIW4atSzn5h1CNuEkKPhBMmJfW4C30c
1622+n/rUZcHLUthFvlBfejQM/ZRHiGss44DwOHU9CCKpk0xYxC7zBfZwweHJKOYe96QUbuA4qR8F0iPB
1623+RKSZ64yVYXCHR2jIfeJ4YRSEEeLDXD9xHBI7qfO6mF6bMOZ4ETFKaeLEscfClIQ+SQLfJyHnk54x
1624+YsJODBdBRFgCX6YxS9IwjD0RiiREOgqasPh1MVGvTSJQSURIJ4KDPCaiwA0gzYORcPhEtAEqY994
1625+lAiCGnZ9jvdRRl4iYkpCGhJoxMXrYs6R4pGfypQ6EBawwAvS2PEDLpgnmMO8yUi5Y99EAUsD6VMZ
1626+kxhZ6AuW+MKhHsIdByn1XhfT+4ZKknqu41COMHHUBCQJzn0EPgqcJJoQc4Ez0nGigMqIEI/G3IFa
1627+8GyAxHYSN2beVKAucCZyIzf1hGB+KINYIGpuxHhEXA9SvXhKygXOSDcBQAF8uUSqEC9MWQop0uUx
1628+jRM5gVbsAmeEI3gcRInH0jShksbwdOIgex3EPHangu2Pg0SokG4kOYdhYRi6QRK4LAZ+8TRJo3BK
1629+ygVaUYemru8SRqjvOXAGcC6WQcBCAEXsylel9BYhSST2jHggqfRRUVSmQcQcuAqoJ6YSJhhblCi0
1630+BvD7HuM0ZbFHmQwAX14kvYTIKbQKxxYJkUqeOFAHBYmMlb4ApocxAIMnbjQV6XBsEZHAKi7BKm7s
1631+uELAuTHIKaQMhEeiKZQJL2KUcF9GAISAMUKS2A2QONyPKWPc5yGfkBKNLULBJGD5xHUjMFGSBLEH
1632+EWDMMEhR2lPAGV2wGwsjIsOYwr/oHlANkQNDgsBHgYVkChuisUXUkwmJQw9kD9ilPkjaQai5CCVa
1633+idCfkBJfwJ2DGMmUcOaTyA1F6LohyhAtRQIInMyX+IIJSCLTMAALcGC5I2kUM+lKD2HAI2+qAuKx
1634+RQE4lgBvJVoGFGDgB67rSi4S38W/eEqX5KIbclQv5KXwSMrBHyoFAeCJ76jGynldSm8Ro8RPgA3o
1635+OYLEZ47KWWQbnM3ALJM0kIwtcmPPjQFyCHTKmRs6YeqQMKG+QJ2n4VSk07FF0J0FDpoZV3mYBmkk
1636+AiapcBLYypypSKcXyIAkQ2MHbvWThEdAJyKEEwG8WOQHU/1dK6W3SAqE1hchcWPqegxhYmHg0hjc
1637+C+YXU0ySjvmIEZSNKxVqEk9wAJOb+mC2mIaphx4HUn6dDSYCjDf1rKlOd2bg2pF6l2e0m7fQu8/E
1638+L0xg1Pio73xQI1G7Fg+H62ZcSGv7heQZun2xxa0ldNoWmAfXlhoAVnfagExa3X01M3bjgXmoLp5h
1639+tmgwLigR+kV7J34xdzHfdcsgp1351aaXct+JfjjLUxfmLkyD79+r6aRuuKgw1y1HK9Q1Vya1FrTz
1640+4Q2mMIIxjH9lWcu/lHWd0Xww/mGkw9/7P6zmV8JuejNHj1ajv5Q+4pesWXrmfoXgVoV2l3HoxXCo
1641+F7Xj1eZimFv3am0pqcVmMNCtMSluMapuytpmxwq/mWTqX+AiJ6eNG87aIGFs/ObYlHv4gWG6PGEU
1642+Lfhtb/bgpEDN9XvyGbHE8PwFriLKQXCeMu1Amp0Z5x9bpR+telcec66mWWJ8PZTWTebFcU9FZTU7
1643+0lgYhHvBWpaagAvlXUti6u2VOhZcvyKsx5EjHi010i6fdxnbdbsLaK2OJow8a3G7WNlQ0njpUW2p
1644+5AyOMXaiGh2QPGeYuek5EwRfIyNNgmuVixL+yCtB+OmsPvb4KAfqabfr7dqzCS2mabXU0qjQqrQO
1645+0ScWrCx4bXzTqXEgSBTlVHhElVXWZAhd8TQ4zzARb+0vC6HPE8zZCDd6wallrnz44vmI0rI9bBCt
1646+MH2WU5VH7CSMKqbOiLUXdU2ehDngOBfd46POl4pktbB+PNWN2H/4RfmrMIEoLNLgnjnZIFRBizJe
1647+paAyxpx62F2G6p/PpN4aFIL9G2tx+Py0rURdHism6oVCGLX9vuTHXNTqlGQAoJePTU2g6jjyoHXb
1648+cnVGEpVym3PRDOqy9dhFCXZlt74otDMGdEViw7OiapbOWm0yALkWqPud3g1Pd2h3zLdtA7PVwLxR
1649+MkyAAOyXskYO0g9fQPj+pQ6Qhg5pH13vMBJtt8m1nJ81fr+Zv2ldtXrXyh6qMBbwV7Py27KQecaa
1650+QRxgokFOBstluVzduw9DYhgmxX9KBPOfdufCmCiF5fvNTb3qy7wrb33K+akYc8GckWLRqGrrqwdw
1651+ok72dPm0J3mqkI5FgSy3rb/kAsnTLb+Sp8pLVTmwScCWTkOZVXWzBmGoSllAwqnLCuvtzwPlF/aF
1652+vE/Fp2L57bGqIA1IbwTcVBeUtgKhndNc2KR6qu+dh9fp7MWwfpchZzN6VBT7fdn8qQRwD3KI1PWs
1653+LcR8/OZ6WKv3F5X+oF75Gk7RXFB+HtHpMHsNr75UxL83uapSR6aOWPW7FyhUFy05U4CVl8w0IBos
1654+jQ1ZY86DdUPxX0qpBpDViX9Hqb/FqOqe2vWaTg3KP54ZcoIFS8N9HfUpCmHNkeRnI1pKGdNG94FC
1655+BWahHjJrh3zMTdJ23enGGkDX25sanfZNrRrt+bAWLg68TeJD7pAplM+sN+OGsCZfBLTfoAE3FPD3
1656+MiuWHWF0S424umJKnO6Kvwd3d420Qp/uddRd3dRLI3Z1p4rhmy9lphLoIIhix06dui+2EXqrS6ci
1657+hyDljbrzUl4+jVap1lvFZfyuurDSfiZVsVR+fvv7XebzkBYrW3CuX8ryG50S6nOSpfgiCvUHzDlA
1658+2dlO5AfV5X002TboNPpUQSui8l99krNUrpgB5dcWoGqmbu1RzoWAI/EK6lD1uQBd8awglmB4rWv9
1659+9hDWNSjbs3ZLoHHb0Zx3hMq8y2Z7NlsCEcWd8rAWsydsp5orXgrDNTuEF0o0z2X1ud10bR0MYZS0
1660+Ie2ncAopNErcAEwVisADTPfoegEknyuxrZxKtAQ0NMBe/Z5RRFKsr1JmALpX7ZPOsrWqpqvX0D/o
1661+ZG0yNUe2bVIuxOGd+bG86LTG2dnBsKa6eq63uKAyXXItPtj4WR5Esbxa9rX1A1r82+cqawA+iDH8
1662+q5trYPjntfog8FlFT3UArFJlCGhkZVUddXLk4kKYjvswPVTP3Qi9vsPE7mo/VJsauWGArcaP5Wqs
1663+sUERbY3BivX8mc7hTjywtR1m6O5fwuinRsC7SwjABnd6F5aXtViuriCibu600OHzls060IKCufql
1664+g63Zv3Mp/t4j05foQb6spxj7zLkfX/uIVHPsB3RL7aqOIF5qnS8+en6tbzajQo/VVxLPa14fJ/Rc
1665+7lx3WeOhYTQz6Jip0hhMCqzc72GoPWoLu8Mb0o5f3dXGSLs4BxdoP6/eqLOVh5VO02exqHRaC0vR
1666++G+mirJU+fmCq5Ta1xyCRccC897nZW+WyGsxiMawF7e329Zb2621wQDo2I7tLv7jrv9/AfAaXNUU
1667+TOsyF6jViUG46+NBJqZXv+rRK7Evv2i81ZEw33DQ8y6YowH05r+BuxfN92SX3RbVP8bNymDOGnY7
1668+16PfvzG+4ecrzfzkjPZya/H/ScnXyqwX/JtSrrL5pbrryu1hPKFrZzsrJD6sUuyPwDGdKerJyxmq
1669+dvmdHNCrrzU/+2W0pQ6gSvPl/Mertmi+7hBlDhB80kRUqcNeJCGapHNCz1cvCFwsf0A/Ne++jGMf
1670+TuOJcm6+ZnP9TRR7tWjHreOhZ6huiKnPAP2zfmqpIqHHLG/emnNhyHxSs+JJYfIwj6t2AlLdVneO
1671+3Is9u0R33ef+Wv2pVizPfbUW0rGhps1FRRfnZ/2xsnr3oT2Slh2tvngsLXu6M0OgIen7ufrjprrD
1672+vzXQAgNE22ualqzbyAb97uvl6qF/2a5hcU+eBzVWzOdmVjA0PXQMQoAhsulmBv39oU13134SjSlb
1673+dX85nKW3umfYbtu8713Sylhb2i3v2qaoc8C7S2P3pME8uIGedi1IxXbL+adi+P2fT8Xy/m+/PrxZ
1674+/TrXDcpqOMjotwdo9AJmg8r1N7BySygc+Gp+XaYdJhpV8f/7Oy3Y1s330l09YBDTjnyjn5qHGF7x
1675+6O7hZfMXz21OyLZB6lUfOGAGMzo/bjaL7VaV7Ha76D/1yJVEqKmr+L2nCbH7+959wDtv38JZplQG
1676+BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
1677+""")
1678+
1679+
1680+
1681+##file distribute_setup.py
1682+DISTRIBUTE_SETUP_PY = convert("""
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
1762+""")
1763+
1764+
1765+
1766+##file activate.sh
1767+ACTIVATE_SH = convert("""
1768+eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9
1769+H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq
1770+DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs
1771+cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY
1772+G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T
1773+EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs
1774+wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG
1775+5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/
1776+JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR
1777+huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx
1778+Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L
1779+Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw
1780+WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX
1781+LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2
1782+""")
1783+
1784+
1785+
1786+##file activate.fish
1787+ACTIVATE_FISH = convert("""
1788+eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
1789+Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
1790+pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
1791+lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
1792+g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
1793+grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
1794+xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
1795+MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
1796+H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
1797+L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
1798+fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
1799+pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
1800+MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
1801+O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
1802+7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
1803+m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
1804+djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
1805+mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
1806+jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
1807+""")
1808+
1809+
1810+
1811+##file activate.csh
1812+ACTIVATE_CSH = convert("""
1813+eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
1814+XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
1815+kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
1816+pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
1817+sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
1818+yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
1819+E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
1820+lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
1821+r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
1822+""")
1823+
1824+
1825+
1826+##file activate.bat
1827+ACTIVATE_BAT = convert("""
1828+eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
1829+qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
1830+sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
1831+ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
1832+""")
1833+
1834+
1835+
1836+##file deactivate.bat
1837+DEACTIVATE_BAT = convert("""
1838+eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
1839+FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
1840+i2dASrm4rFz9XLgAwJNbyQ==
1841+""")
1842+
1843+
1844+
1845+##file distutils-init.py
1846+DISTUTILS_INIT = convert("""
1847+eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
1848+luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
1849+KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
1850+ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
1851+QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
1852+yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
1853+bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
1854+bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
1855+yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
1856+Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
1857+Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
1858+/n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
1859+FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
1860+AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
1861+hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
1862+UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
1863+8h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
1864+XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
1865+azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
1866+8dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
1867+gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
1868+5C4rFgwLGfMvJuAMew==
1869+""")
1870+
1871+
1872+
1873+##file distutils.cfg
1874+DISTUTILS_CFG = convert("""
1875+eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
1876+xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
1877+9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
1878+""")
1879+
1880+
1881+
1882+##file activate_this.py
1883+ACTIVATE_THIS = convert("""
1884+eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ
1885+VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a
1886+Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE
1887+qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX
1888+4lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7
1889+HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n
1890+xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96
1891+1Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI
1892+3vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU=
1893+""")
1894+
1895+
1896+
1897+if __name__ == '__main__':
1898+ main()
1899+
1900+## TODO:
1901+## Copy python.exe.manifest
1902+## Monkeypatch distutils.sysconfig
1903+>>>>>>> MERGE-SOURCE
1904
1905=== modified file '.pc/applied-patches'
1906--- .pc/applied-patches 2011-09-08 15:38:18 +0000
1907+++ .pc/applied-patches 2011-09-08 21:10:23 +0000
1908@@ -1,2 +1,8 @@
1909-look_for_external_files.patch
1910-add_distribute.patch
1911+<<<<<<< TREE
1912+look_for_external_files.patch
1913+add_distribute.patch
1914+=======
1915+look_for_external_files.patch
1916+add_distribute.patch
1917+remove_syspath0_on_reinvoke.patch
1918+>>>>>>> MERGE-SOURCE
1919
1920=== modified file '.pc/look_for_external_files.patch/setup.py'
1921--- .pc/look_for_external_files.patch/setup.py 2011-09-08 15:38:18 +0000
1922+++ .pc/look_for_external_files.patch/setup.py 2011-09-08 21:10:23 +0000
1923@@ -1,3 +1,4 @@
1924+<<<<<<< TREE
1925 import sys, os
1926 try:
1927 from setuptools import setup
1928@@ -56,3 +57,61 @@
1929 tests_require=['nose', 'Mock'],
1930 **kw
1931 )
1932+=======
1933+import sys, os
1934+try:
1935+ from setuptools import setup
1936+ kw = {'entry_points':
1937+ """[console_scripts]\nvirtualenv = virtualenv:main\n""",
1938+ 'zip_safe': False}
1939+except ImportError:
1940+ from distutils.core import setup
1941+ if sys.platform == 'win32':
1942+ print('Note: without Setuptools installed you will have to use "python -m virtualenv ENV"')
1943+ kw = {}
1944+ else:
1945+ kw = {'scripts': ['scripts/virtualenv']}
1946+
1947+here = os.path.dirname(os.path.abspath(__file__))
1948+
1949+## Get long_description from index.txt:
1950+f = open(os.path.join(here, 'docs', 'index.txt'))
1951+long_description = f.read().strip()
1952+long_description = long_description.split('split here', 1)[1]
1953+f.close()
1954+f = open(os.path.join(here, 'docs', 'news.txt'))
1955+long_description += "\n\n" + f.read()
1956+f.close()
1957+
1958+setup(name='virtualenv',
1959+ # If you change the version here, change it in virtualenv.py and
1960+ # docs/conf.py as well
1961+ version="1.6",
1962+ description="Virtual Python Environment builder",
1963+ long_description=long_description,
1964+ classifiers=[
1965+ 'Development Status :: 4 - Beta',
1966+ 'Intended Audience :: Developers',
1967+ 'License :: OSI Approved :: MIT License',
1968+ 'Programming Language :: Python :: 2',
1969+ 'Programming Language :: Python :: 2.4',
1970+ 'Programming Language :: Python :: 2.5',
1971+ 'Programming Language :: Python :: 2.6',
1972+ 'Programming Language :: Python :: 2.7',
1973+ 'Programming Language :: Python :: 3',
1974+ 'Programming Language :: Python :: 3.1',
1975+ 'Programming Language :: Python :: 3.2',
1976+ ],
1977+ keywords='setuptools deployment installation distutils',
1978+ author='Ian Bicking',
1979+ author_email='ianb@colorstudy.com',
1980+ maintainer='Jannis Leidel, Carl Meyer and Brian Rosner',
1981+ maintainer_email='python-virtualenv@groups.google.com',
1982+ url='http://www.virtualenv.org',
1983+ license='MIT',
1984+ py_modules=['virtualenv'],
1985+ packages=['virtualenv_support'],
1986+ package_data={'virtualenv_support': ['*-py%s.egg' % sys.version[:3], '*.tar.gz']},
1987+ **kw
1988+ )
1989+>>>>>>> MERGE-SOURCE
1990
1991=== modified file '.pc/look_for_external_files.patch/virtualenv.py' (properties changed: -x to +x)
1992--- .pc/look_for_external_files.patch/virtualenv.py 2011-09-08 15:38:18 +0000
1993+++ .pc/look_for_external_files.patch/virtualenv.py 2011-09-08 21:10:23 +0000
1994@@ -1,3 +1,4 @@
1995+<<<<<<< TREE
1996 #!/usr/bin/env python
1997 """Create a "virtual" Python installation
1998 """
1999@@ -1954,3 +1955,1893 @@
2000 ## TODO:
2001 ## Copy python.exe.manifest
2002 ## Monkeypatch distutils.sysconfig
2003+=======
2004+"""Create a "virtual" Python installation
2005+"""
2006+
2007+# If you change the version here, change it in setup.py
2008+# and docs/conf.py as well.
2009+virtualenv_version = "1.6"
2010+
2011+import base64
2012+import sys
2013+import os
2014+import optparse
2015+import re
2016+import shutil
2017+import logging
2018+import tempfile
2019+import zlib
2020+import errno
2021+import distutils.sysconfig
2022+try:
2023+ import subprocess
2024+except ImportError:
2025+ if sys.version_info <= (2, 3):
2026+ print('ERROR: %s' % sys.exc_info()[1])
2027+ print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
2028+ print('If you copy subprocess.py from a newer version of Python this script will probably work')
2029+ sys.exit(101)
2030+ else:
2031+ raise
2032+try:
2033+ set
2034+except NameError:
2035+ from sets import Set as set
2036+try:
2037+ basestring
2038+except NameError:
2039+ basestring = str
2040+
2041+join = os.path.join
2042+py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
2043+
2044+is_jython = sys.platform.startswith('java')
2045+is_pypy = hasattr(sys, 'pypy_version_info')
2046+abiflags = getattr(sys, 'abiflags', '')
2047+
2048+if is_pypy:
2049+ expected_exe = 'pypy'
2050+elif is_jython:
2051+ expected_exe = 'jython'
2052+else:
2053+ expected_exe = 'python'
2054+
2055+
2056+REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
2057+ 'fnmatch', 'locale', 'encodings', 'codecs',
2058+ 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
2059+ 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
2060+ 'zlib']
2061+
2062+REQUIRED_FILES = ['lib-dynload', 'config']
2063+
2064+majver, minver = sys.version_info[:2]
2065+if majver == 2:
2066+ if minver >= 6:
2067+ REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
2068+ if minver >= 7:
2069+ REQUIRED_MODULES.extend(['_weakrefset'])
2070+ if minver <= 3:
2071+ REQUIRED_MODULES.extend(['sets', '__future__'])
2072+elif majver == 3:
2073+ # Some extra modules are needed for Python 3, but different ones
2074+ # for different versions.
2075+ REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
2076+ '_weakrefset', 'copyreg', 'tempfile', 'random',
2077+ '__future__', 'collections', 'keyword', 'tarfile',
2078+ 'shutil', 'struct', 'copy'])
2079+ if minver >= 2:
2080+ REQUIRED_FILES[-1] = 'config-%s' % majver
2081+ if minver == 3:
2082+ # The whole list of 3.3 modules is reproduced below - the current
2083+ # uncommented ones are required for 3.3 as of now, but more may be
2084+ # added as 3.3 development continues.
2085+ REQUIRED_MODULES.extend([
2086+ #"aifc",
2087+ #"antigravity",
2088+ #"argparse",
2089+ #"ast",
2090+ #"asynchat",
2091+ #"asyncore",
2092+ "base64",
2093+ #"bdb",
2094+ #"binhex",
2095+ "bisect",
2096+ #"calendar",
2097+ #"cgi",
2098+ #"cgitb",
2099+ #"chunk",
2100+ #"cmd",
2101+ #"codeop",
2102+ #"code",
2103+ #"colorsys",
2104+ #"_compat_pickle",
2105+ #"compileall",
2106+ #"concurrent",
2107+ #"configparser",
2108+ #"contextlib",
2109+ #"cProfile",
2110+ #"crypt",
2111+ #"csv",
2112+ #"ctypes",
2113+ #"curses",
2114+ #"datetime",
2115+ #"dbm",
2116+ #"decimal",
2117+ #"difflib",
2118+ #"dis",
2119+ #"doctest",
2120+ #"dummy_threading",
2121+ #"_dummy_thread",
2122+ #"email",
2123+ #"filecmp",
2124+ #"fileinput",
2125+ #"formatter",
2126+ #"fractions",
2127+ #"ftplib",
2128+ #"functools",
2129+ #"getopt",
2130+ #"getpass",
2131+ #"gettext",
2132+ #"glob",
2133+ #"gzip",
2134+ "hashlib",
2135+ "heapq",
2136+ "hmac",
2137+ #"html",
2138+ #"http",
2139+ #"idlelib",
2140+ #"imaplib",
2141+ #"imghdr",
2142+ #"importlib",
2143+ #"inspect",
2144+ #"json",
2145+ #"lib2to3",
2146+ #"logging",
2147+ #"macpath",
2148+ #"macurl2path",
2149+ #"mailbox",
2150+ #"mailcap",
2151+ #"_markupbase",
2152+ #"mimetypes",
2153+ #"modulefinder",
2154+ #"multiprocessing",
2155+ #"netrc",
2156+ #"nntplib",
2157+ #"nturl2path",
2158+ #"numbers",
2159+ #"opcode",
2160+ #"optparse",
2161+ #"os2emxpath",
2162+ #"pdb",
2163+ #"pickle",
2164+ #"pickletools",
2165+ #"pipes",
2166+ #"pkgutil",
2167+ #"platform",
2168+ #"plat-linux2",
2169+ #"plistlib",
2170+ #"poplib",
2171+ #"pprint",
2172+ #"profile",
2173+ #"pstats",
2174+ #"pty",
2175+ #"pyclbr",
2176+ #"py_compile",
2177+ #"pydoc_data",
2178+ #"pydoc",
2179+ #"_pyio",
2180+ #"queue",
2181+ #"quopri",
2182+ "reprlib",
2183+ "rlcompleter",
2184+ #"runpy",
2185+ #"sched",
2186+ #"shelve",
2187+ #"shlex",
2188+ #"smtpd",
2189+ #"smtplib",
2190+ #"sndhdr",
2191+ #"socket",
2192+ #"socketserver",
2193+ #"sqlite3",
2194+ #"ssl",
2195+ #"stringprep",
2196+ #"string",
2197+ #"_strptime",
2198+ #"subprocess",
2199+ #"sunau",
2200+ #"symbol",
2201+ #"symtable",
2202+ #"sysconfig",
2203+ #"tabnanny",
2204+ #"telnetlib",
2205+ #"test",
2206+ #"textwrap",
2207+ #"this",
2208+ #"_threading_local",
2209+ #"threading",
2210+ #"timeit",
2211+ #"tkinter",
2212+ #"tokenize",
2213+ #"token",
2214+ #"traceback",
2215+ #"trace",
2216+ #"tty",
2217+ #"turtledemo",
2218+ #"turtle",
2219+ #"unittest",
2220+ #"urllib",
2221+ #"uuid",
2222+ #"uu",
2223+ #"wave",
2224+ "weakref",
2225+ #"webbrowser",
2226+ #"wsgiref",
2227+ #"xdrlib",
2228+ #"xml",
2229+ #"xmlrpc",
2230+ #"zipfile",
2231+ ])
2232+
2233+if is_pypy:
2234+ # these are needed to correctly display the exceptions that may happen
2235+ # during the bootstrap
2236+ REQUIRED_MODULES.extend(['traceback', 'linecache'])
2237+
2238+class Logger(object):
2239+
2240+ """
2241+ Logging object for use in command-line script. Allows ranges of
2242+ levels, to avoid some redundancy of displayed information.
2243+ """
2244+
2245+ DEBUG = logging.DEBUG
2246+ INFO = logging.INFO
2247+ NOTIFY = (logging.INFO+logging.WARN)/2
2248+ WARN = WARNING = logging.WARN
2249+ ERROR = logging.ERROR
2250+ FATAL = logging.FATAL
2251+
2252+ LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
2253+
2254+ def __init__(self, consumers):
2255+ self.consumers = consumers
2256+ self.indent = 0
2257+ self.in_progress = None
2258+ self.in_progress_hanging = False
2259+
2260+ def debug(self, msg, *args, **kw):
2261+ self.log(self.DEBUG, msg, *args, **kw)
2262+ def info(self, msg, *args, **kw):
2263+ self.log(self.INFO, msg, *args, **kw)
2264+ def notify(self, msg, *args, **kw):
2265+ self.log(self.NOTIFY, msg, *args, **kw)
2266+ def warn(self, msg, *args, **kw):
2267+ self.log(self.WARN, msg, *args, **kw)
2268+ def error(self, msg, *args, **kw):
2269+ self.log(self.WARN, msg, *args, **kw)
2270+ def fatal(self, msg, *args, **kw):
2271+ self.log(self.FATAL, msg, *args, **kw)
2272+ def log(self, level, msg, *args, **kw):
2273+ if args:
2274+ if kw:
2275+ raise TypeError(
2276+ "You may give positional or keyword arguments, not both")
2277+ args = args or kw
2278+ rendered = None
2279+ for consumer_level, consumer in self.consumers:
2280+ if self.level_matches(level, consumer_level):
2281+ if (self.in_progress_hanging
2282+ and consumer in (sys.stdout, sys.stderr)):
2283+ self.in_progress_hanging = False
2284+ sys.stdout.write('\n')
2285+ sys.stdout.flush()
2286+ if rendered is None:
2287+ if args:
2288+ rendered = msg % args
2289+ else:
2290+ rendered = msg
2291+ rendered = ' '*self.indent + rendered
2292+ if hasattr(consumer, 'write'):
2293+ consumer.write(rendered+'\n')
2294+ else:
2295+ consumer(rendered)
2296+
2297+ def start_progress(self, msg):
2298+ assert not self.in_progress, (
2299+ "Tried to start_progress(%r) while in_progress %r"
2300+ % (msg, self.in_progress))
2301+ if self.level_matches(self.NOTIFY, self._stdout_level()):
2302+ sys.stdout.write(msg)
2303+ sys.stdout.flush()
2304+ self.in_progress_hanging = True
2305+ else:
2306+ self.in_progress_hanging = False
2307+ self.in_progress = msg
2308+
2309+ def end_progress(self, msg='done.'):
2310+ assert self.in_progress, (
2311+ "Tried to end_progress without start_progress")
2312+ if self.stdout_level_matches(self.NOTIFY):
2313+ if not self.in_progress_hanging:
2314+ # Some message has been printed out since start_progress
2315+ sys.stdout.write('...' + self.in_progress + msg + '\n')
2316+ sys.stdout.flush()
2317+ else:
2318+ sys.stdout.write(msg + '\n')
2319+ sys.stdout.flush()
2320+ self.in_progress = None
2321+ self.in_progress_hanging = False
2322+
2323+ def show_progress(self):
2324+ """If we are in a progress scope, and no log messages have been
2325+ shown, write out another '.'"""
2326+ if self.in_progress_hanging:
2327+ sys.stdout.write('.')
2328+ sys.stdout.flush()
2329+
2330+ def stdout_level_matches(self, level):
2331+ """Returns true if a message at this level will go to stdout"""
2332+ return self.level_matches(level, self._stdout_level())
2333+
2334+ def _stdout_level(self):
2335+ """Returns the level that stdout runs at"""
2336+ for level, consumer in self.consumers:
2337+ if consumer is sys.stdout:
2338+ return level
2339+ return self.FATAL
2340+
2341+ def level_matches(self, level, consumer_level):
2342+ """
2343+ >>> l = Logger()
2344+ >>> l.level_matches(3, 4)
2345+ False
2346+ >>> l.level_matches(3, 2)
2347+ True
2348+ >>> l.level_matches(slice(None, 3), 3)
2349+ False
2350+ >>> l.level_matches(slice(None, 3), 2)
2351+ True
2352+ >>> l.level_matches(slice(1, 3), 1)
2353+ True
2354+ >>> l.level_matches(slice(2, 3), 1)
2355+ False
2356+ """
2357+ if isinstance(level, slice):
2358+ start, stop = level.start, level.stop
2359+ if start is not None and start > consumer_level:
2360+ return False
2361+ if stop is not None or stop <= consumer_level:
2362+ return False
2363+ return True
2364+ else:
2365+ return level >= consumer_level
2366+
2367+ #@classmethod
2368+ def level_for_integer(cls, level):
2369+ levels = cls.LEVELS
2370+ if level < 0:
2371+ return levels[0]
2372+ if level >= len(levels):
2373+ return levels[-1]
2374+ return levels[level]
2375+
2376+ level_for_integer = classmethod(level_for_integer)
2377+
2378+# create a silent logger just to prevent this from being undefined
2379+# will be overridden with requested verbosity main() is called.
2380+logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
2381+
2382+def mkdir(path):
2383+ if not os.path.exists(path):
2384+ logger.info('Creating %s', path)
2385+ os.makedirs(path)
2386+ else:
2387+ logger.info('Directory %s already exists', path)
2388+
2389+def copyfileordir(src, dest):
2390+ if os.path.isdir(src):
2391+ shutil.copytree(src, dest, True)
2392+ else:
2393+ shutil.copy2(src, dest)
2394+
2395+def copyfile(src, dest, symlink=True):
2396+ if not os.path.exists(src):
2397+ # Some bad symlink in the src
2398+ logger.warn('Cannot find file %s (bad symlink)', src)
2399+ return
2400+ if os.path.exists(dest):
2401+ logger.debug('File %s already exists', dest)
2402+ return
2403+ if not os.path.exists(os.path.dirname(dest)):
2404+ logger.info('Creating parent directories for %s' % os.path.dirname(dest))
2405+ os.makedirs(os.path.dirname(dest))
2406+ if not os.path.islink(src):
2407+ srcpath = os.path.abspath(src)
2408+ else:
2409+ srcpath = os.readlink(src)
2410+ if symlink and hasattr(os, 'symlink'):
2411+ logger.info('Symlinking %s', dest)
2412+ try:
2413+ os.symlink(srcpath, dest)
2414+ except (OSError, NotImplementedError):
2415+ logger.info('Symlinking failed, copying to %s', dest)
2416+ copyfileordir(src, dest)
2417+ else:
2418+ logger.info('Copying to %s', dest)
2419+ copyfileordir(src, dest)
2420+
2421+def writefile(dest, content, overwrite=True):
2422+ if not os.path.exists(dest):
2423+ logger.info('Writing %s', dest)
2424+ f = open(dest, 'wb')
2425+ f.write(content.encode('utf-8'))
2426+ f.close()
2427+ return
2428+ else:
2429+ f = open(dest, 'rb')
2430+ c = f.read()
2431+ f.close()
2432+ if c != content:
2433+ if not overwrite:
2434+ logger.notify('File %s exists with different content; not overwriting', dest)
2435+ return
2436+ logger.notify('Overwriting %s with new content', dest)
2437+ f = open(dest, 'wb')
2438+ f.write(content.encode('utf-8'))
2439+ f.close()
2440+ else:
2441+ logger.info('Content %s already in place', dest)
2442+
2443+def rmtree(dir):
2444+ if os.path.exists(dir):
2445+ logger.notify('Deleting tree %s', dir)
2446+ shutil.rmtree(dir)
2447+ else:
2448+ logger.info('Do not need to delete %s; already gone', dir)
2449+
2450+def make_exe(fn):
2451+ if hasattr(os, 'chmod'):
2452+ oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
2453+ newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
2454+ os.chmod(fn, newmode)
2455+ logger.info('Changed mode of %s to %s', fn, oct(newmode))
2456+
2457+def _find_file(filename, dirs):
2458+ for dir in dirs:
2459+ if os.path.exists(join(dir, filename)):
2460+ return join(dir, filename)
2461+ return filename
2462+
2463+def _install_req(py_executable, unzip=False, distribute=False):
2464+ if not distribute:
2465+ setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
2466+ project_name = 'setuptools'
2467+ bootstrap_script = EZ_SETUP_PY
2468+ source = None
2469+ else:
2470+ setup_fn = None
2471+ source = 'distribute-0.6.15.tar.gz'
2472+ project_name = 'distribute'
2473+ bootstrap_script = DISTRIBUTE_SETUP_PY
2474+ try:
2475+ # check if the global Python has distribute installed or plain
2476+ # setuptools
2477+ import pkg_resources
2478+ if not hasattr(pkg_resources, '_distribute'):
2479+ location = os.path.dirname(pkg_resources.__file__)
2480+ logger.notify("A globally installed setuptools was found (in %s)" % location)
2481+ logger.notify("Use the --no-site-packages option to use distribute in "
2482+ "the virtualenv.")
2483+ except ImportError:
2484+ pass
2485+
2486+ search_dirs = file_search_dirs()
2487+
2488+ if setup_fn is not None:
2489+ setup_fn = _find_file(setup_fn, search_dirs)
2490+
2491+ if source is not None:
2492+ source = _find_file(source, search_dirs)
2493+
2494+ if is_jython and os._name == 'nt':
2495+ # Jython's .bat sys.executable can't handle a command line
2496+ # argument with newlines
2497+ fd, ez_setup = tempfile.mkstemp('.py')
2498+ os.write(fd, bootstrap_script)
2499+ os.close(fd)
2500+ cmd = [py_executable, ez_setup]
2501+ else:
2502+ cmd = [py_executable, '-c', bootstrap_script]
2503+ if unzip:
2504+ cmd.append('--always-unzip')
2505+ env = {}
2506+ remove_from_env = []
2507+ if logger.stdout_level_matches(logger.DEBUG):
2508+ cmd.append('-v')
2509+
2510+ old_chdir = os.getcwd()
2511+ if setup_fn is not None and os.path.exists(setup_fn):
2512+ logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
2513+ cmd.append(setup_fn)
2514+ if os.environ.get('PYTHONPATH'):
2515+ env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
2516+ else:
2517+ env['PYTHONPATH'] = setup_fn
2518+ else:
2519+ # the source is found, let's chdir
2520+ if source is not None and os.path.exists(source):
2521+ os.chdir(os.path.dirname(source))
2522+ # in this case, we want to be sure that PYTHONPATH is unset (not
2523+ # just empty, really unset), else CPython tries to import the
2524+ # site.py that it's in virtualenv_support
2525+ remove_from_env.append('PYTHONPATH')
2526+ else:
2527+ logger.info('No %s egg found; downloading' % project_name)
2528+ cmd.extend(['--always-copy', '-U', project_name])
2529+ logger.start_progress('Installing %s...' % project_name)
2530+ logger.indent += 2
2531+ cwd = None
2532+ if project_name == 'distribute':
2533+ env['DONT_PATCH_SETUPTOOLS'] = 'true'
2534+
2535+ def _filter_ez_setup(line):
2536+ return filter_ez_setup(line, project_name)
2537+
2538+ if not os.access(os.getcwd(), os.W_OK):
2539+ cwd = tempfile.mkdtemp()
2540+ if source is not None and os.path.exists(source):
2541+ # the current working dir is hostile, let's copy the
2542+ # tarball to a temp dir
2543+ target = os.path.join(cwd, os.path.split(source)[-1])
2544+ shutil.copy(source, target)
2545+ try:
2546+ call_subprocess(cmd, show_stdout=False,
2547+ filter_stdout=_filter_ez_setup,
2548+ extra_env=env,
2549+ remove_from_env=remove_from_env,
2550+ cwd=cwd)
2551+ finally:
2552+ logger.indent -= 2
2553+ logger.end_progress()
2554+ if os.getcwd() != old_chdir:
2555+ os.chdir(old_chdir)
2556+ if is_jython and os._name == 'nt':
2557+ os.remove(ez_setup)
2558+
2559+def file_search_dirs():
2560+ here = os.path.dirname(os.path.abspath(__file__))
2561+ dirs = ['.', here,
2562+ join(here, 'virtualenv_support')]
2563+ if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
2564+ # Probably some boot script; just in case virtualenv is installed...
2565+ try:
2566+ import virtualenv
2567+ except ImportError:
2568+ pass
2569+ else:
2570+ dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
2571+ return [d for d in dirs if os.path.isdir(d)]
2572+
2573+def install_setuptools(py_executable, unzip=False):
2574+ _install_req(py_executable, unzip)
2575+
2576+def install_distribute(py_executable, unzip=False):
2577+ _install_req(py_executable, unzip, distribute=True)
2578+
2579+_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
2580+def install_pip(py_executable):
2581+ filenames = []
2582+ for dir in file_search_dirs():
2583+ filenames.extend([join(dir, fn) for fn in os.listdir(dir)
2584+ if _pip_re.search(fn)])
2585+ filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
2586+ filenames.sort()
2587+ filenames = [filename for basename, i, filename in filenames]
2588+ if not filenames:
2589+ filename = 'pip'
2590+ else:
2591+ filename = filenames[-1]
2592+ easy_install_script = 'easy_install'
2593+ if sys.platform == 'win32':
2594+ easy_install_script = 'easy_install-script.py'
2595+ cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
2596+ if filename == 'pip':
2597+ logger.info('Installing pip from network...')
2598+ else:
2599+ logger.info('Installing %s' % os.path.basename(filename))
2600+ logger.indent += 2
2601+ def _filter_setup(line):
2602+ return filter_ez_setup(line, 'pip')
2603+ try:
2604+ call_subprocess(cmd, show_stdout=False,
2605+ filter_stdout=_filter_setup)
2606+ finally:
2607+ logger.indent -= 2
2608+
2609+def filter_ez_setup(line, project_name='setuptools'):
2610+ if not line.strip():
2611+ return Logger.DEBUG
2612+ if project_name == 'distribute':
2613+ for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
2614+ 'Scanning', 'Setuptools', 'Egg', 'Already',
2615+ 'running', 'writing', 'reading', 'installing',
2616+ 'creating', 'copying', 'byte-compiling', 'removing',
2617+ 'Processing'):
2618+ if line.startswith(prefix):
2619+ return Logger.DEBUG
2620+ return Logger.DEBUG
2621+ for prefix in ['Reading ', 'Best match', 'Processing setuptools',
2622+ 'Copying setuptools', 'Adding setuptools',
2623+ 'Installing ', 'Installed ']:
2624+ if line.startswith(prefix):
2625+ return Logger.DEBUG
2626+ return Logger.INFO
2627+
2628+def main():
2629+ parser = optparse.OptionParser(
2630+ version=virtualenv_version,
2631+ usage="%prog [OPTIONS] DEST_DIR")
2632+
2633+ parser.add_option(
2634+ '-v', '--verbose',
2635+ action='count',
2636+ dest='verbose',
2637+ default=0,
2638+ help="Increase verbosity")
2639+
2640+ parser.add_option(
2641+ '-q', '--quiet',
2642+ action='count',
2643+ dest='quiet',
2644+ default=0,
2645+ help='Decrease verbosity')
2646+
2647+ parser.add_option(
2648+ '-p', '--python',
2649+ dest='python',
2650+ metavar='PYTHON_EXE',
2651+ help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
2652+ 'interpreter to create the new environment. The default is the interpreter that '
2653+ 'virtualenv was installed with (%s)' % sys.executable)
2654+
2655+ parser.add_option(
2656+ '--clear',
2657+ dest='clear',
2658+ action='store_true',
2659+ help="Clear out the non-root install and start from scratch")
2660+
2661+ parser.add_option(
2662+ '--no-site-packages',
2663+ dest='no_site_packages',
2664+ action='store_true',
2665+ help="Don't give access to the global site-packages dir to the "
2666+ "virtual environment")
2667+
2668+ parser.add_option(
2669+ '--unzip-setuptools',
2670+ dest='unzip_setuptools',
2671+ action='store_true',
2672+ help="Unzip Setuptools or Distribute when installing it")
2673+
2674+ parser.add_option(
2675+ '--relocatable',
2676+ dest='relocatable',
2677+ action='store_true',
2678+ help='Make an EXISTING virtualenv environment relocatable. '
2679+ 'This fixes up scripts and makes all .pth files relative')
2680+
2681+ parser.add_option(
2682+ '--distribute',
2683+ dest='use_distribute',
2684+ action='store_true',
2685+ help='Use Distribute instead of Setuptools. Set environ variable '
2686+ 'VIRTUALENV_USE_DISTRIBUTE to make it the default ')
2687+
2688+ parser.add_option(
2689+ '--prompt=',
2690+ dest='prompt',
2691+ help='Provides an alternative prompt prefix for this environment')
2692+
2693+ if 'extend_parser' in globals():
2694+ extend_parser(parser)
2695+
2696+ options, args = parser.parse_args()
2697+
2698+ global logger
2699+
2700+ if 'adjust_options' in globals():
2701+ adjust_options(options, args)
2702+
2703+ verbosity = options.verbose - options.quiet
2704+ logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
2705+
2706+ if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
2707+ env = os.environ.copy()
2708+ interpreter = resolve_interpreter(options.python)
2709+ if interpreter == sys.executable:
2710+ logger.warn('Already using interpreter %s' % interpreter)
2711+ else:
2712+ logger.notify('Running virtualenv with interpreter %s' % interpreter)
2713+ env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
2714+ file = __file__
2715+ if file.endswith('.pyc'):
2716+ file = file[:-1]
2717+ popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
2718+ raise SystemExit(popen.wait())
2719+
2720+ if not args:
2721+ print('You must provide a DEST_DIR')
2722+ parser.print_help()
2723+ sys.exit(2)
2724+ if len(args) > 1:
2725+ print('There must be only one argument: DEST_DIR (you gave %s)' % (
2726+ ' '.join(args)))
2727+ parser.print_help()
2728+ sys.exit(2)
2729+
2730+ home_dir = args[0]
2731+
2732+ if os.environ.get('WORKING_ENV'):
2733+ logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
2734+ logger.fatal('Please deactivate your workingenv, then re-run this script')
2735+ sys.exit(3)
2736+
2737+ if 'PYTHONHOME' in os.environ:
2738+ logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
2739+ del os.environ['PYTHONHOME']
2740+
2741+ if options.relocatable:
2742+ make_environment_relocatable(home_dir)
2743+ return
2744+
2745+ create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
2746+ unzip_setuptools=options.unzip_setuptools,
2747+ use_distribute=options.use_distribute or majver > 2,
2748+ prompt=options.prompt)
2749+ if 'after_install' in globals():
2750+ after_install(options, home_dir)
2751+
2752+def call_subprocess(cmd, show_stdout=True,
2753+ filter_stdout=None, cwd=None,
2754+ raise_on_returncode=True, extra_env=None,
2755+ remove_from_env=None):
2756+ cmd_parts = []
2757+ for part in cmd:
2758+ if len(part) > 45:
2759+ part = part[:20]+"..."+part[-20:]
2760+ if ' ' in part or '\n' in part or '"' in part or "'" in part:
2761+ part = '"%s"' % part.replace('"', '\\"')
2762+ cmd_parts.append(part)
2763+ cmd_desc = ' '.join(cmd_parts)
2764+ if show_stdout:
2765+ stdout = None
2766+ else:
2767+ stdout = subprocess.PIPE
2768+ logger.debug("Running command %s" % cmd_desc)
2769+ if extra_env or remove_from_env:
2770+ env = os.environ.copy()
2771+ if extra_env:
2772+ env.update(extra_env)
2773+ if remove_from_env:
2774+ for varname in remove_from_env:
2775+ env.pop(varname, None)
2776+ else:
2777+ env = None
2778+ try:
2779+ proc = subprocess.Popen(
2780+ cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
2781+ cwd=cwd, env=env)
2782+ except Exception:
2783+ e = sys.exc_info()[1]
2784+ logger.fatal(
2785+ "Error %s while executing command %s" % (e, cmd_desc))
2786+ raise
2787+ all_output = []
2788+ if stdout is not None:
2789+ stdout = proc.stdout
2790+ encoding = sys.getdefaultencoding()
2791+ while 1:
2792+ line = stdout.readline().decode(encoding)
2793+ if not line:
2794+ break
2795+ line = line.rstrip()
2796+ all_output.append(line)
2797+ if filter_stdout:
2798+ level = filter_stdout(line)
2799+ if isinstance(level, tuple):
2800+ level, line = level
2801+ logger.log(level, line)
2802+ if not logger.stdout_level_matches(level):
2803+ logger.show_progress()
2804+ else:
2805+ logger.info(line)
2806+ else:
2807+ proc.communicate()
2808+ proc.wait()
2809+ if proc.returncode:
2810+ if raise_on_returncode:
2811+ if all_output:
2812+ logger.notify('Complete output from command %s:' % cmd_desc)
2813+ logger.notify('\n'.join(all_output) + '\n----------------------------------------')
2814+ raise OSError(
2815+ "Command %s failed with error code %s"
2816+ % (cmd_desc, proc.returncode))
2817+ else:
2818+ logger.warn(
2819+ "Command %s had error code %s"
2820+ % (cmd_desc, proc.returncode))
2821+
2822+
2823+def create_environment(home_dir, site_packages=True, clear=False,
2824+ unzip_setuptools=False, use_distribute=False,
2825+ prompt=None):
2826+ """
2827+ Creates a new environment in ``home_dir``.
2828+
2829+ If ``site_packages`` is true (the default) then the global
2830+ ``site-packages/`` directory will be on the path.
2831+
2832+ If ``clear`` is true (default False) then the environment will
2833+ first be cleared.
2834+ """
2835+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
2836+
2837+ py_executable = os.path.abspath(install_python(
2838+ home_dir, lib_dir, inc_dir, bin_dir,
2839+ site_packages=site_packages, clear=clear))
2840+
2841+ install_distutils(home_dir)
2842+
2843+ if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
2844+ install_distribute(py_executable, unzip=unzip_setuptools)
2845+ else:
2846+ install_setuptools(py_executable, unzip=unzip_setuptools)
2847+
2848+ install_pip(py_executable)
2849+
2850+ install_activate(home_dir, bin_dir, prompt)
2851+
2852+def path_locations(home_dir):
2853+ """Return the path locations for the environment (where libraries are,
2854+ where scripts go, etc)"""
2855+ # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
2856+ # prefix arg is broken: http://bugs.python.org/issue3386
2857+ if sys.platform == 'win32':
2858+ # Windows has lots of problems with executables with spaces in
2859+ # the name; this function will remove them (using the ~1
2860+ # format):
2861+ mkdir(home_dir)
2862+ if ' ' in home_dir:
2863+ try:
2864+ import win32api
2865+ except ImportError:
2866+ print('Error: the path "%s" has a space in it' % home_dir)
2867+ print('To handle these kinds of paths, the win32api module must be installed:')
2868+ print(' http://sourceforge.net/projects/pywin32/')
2869+ sys.exit(3)
2870+ home_dir = win32api.GetShortPathName(home_dir)
2871+ lib_dir = join(home_dir, 'Lib')
2872+ inc_dir = join(home_dir, 'Include')
2873+ bin_dir = join(home_dir, 'Scripts')
2874+ elif is_jython:
2875+ lib_dir = join(home_dir, 'Lib')
2876+ inc_dir = join(home_dir, 'Include')
2877+ bin_dir = join(home_dir, 'bin')
2878+ elif is_pypy:
2879+ lib_dir = home_dir
2880+ inc_dir = join(home_dir, 'include')
2881+ bin_dir = join(home_dir, 'bin')
2882+ else:
2883+ lib_dir = join(home_dir, 'lib', py_version)
2884+ inc_dir = join(home_dir, 'include', py_version + abiflags)
2885+ bin_dir = join(home_dir, 'bin')
2886+ return home_dir, lib_dir, inc_dir, bin_dir
2887+
2888+
2889+def change_prefix(filename, dst_prefix):
2890+ prefixes = [sys.prefix]
2891+
2892+ if sys.platform == "darwin":
2893+ prefixes.extend((
2894+ os.path.join("/Library/Python", sys.version[:3], "site-packages"),
2895+ os.path.join(sys.prefix, "Extras", "lib", "python"),
2896+ os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
2897+
2898+ if hasattr(sys, 'real_prefix'):
2899+ prefixes.append(sys.real_prefix)
2900+ prefixes = list(map(os.path.abspath, prefixes))
2901+ filename = os.path.abspath(filename)
2902+ for src_prefix in prefixes:
2903+ if filename.startswith(src_prefix):
2904+ _, relpath = filename.split(src_prefix, 1)
2905+ assert relpath[0] == os.sep
2906+ relpath = relpath[1:]
2907+ return join(dst_prefix, relpath)
2908+ assert False, "Filename %s does not start with any of these prefixes: %s" % \
2909+ (filename, prefixes)
2910+
2911+def copy_required_modules(dst_prefix):
2912+ import imp
2913+ for modname in REQUIRED_MODULES:
2914+ if modname in sys.builtin_module_names:
2915+ logger.info("Ignoring built-in bootstrap module: %s" % modname)
2916+ continue
2917+ try:
2918+ f, filename, _ = imp.find_module(modname)
2919+ except ImportError:
2920+ logger.info("Cannot import bootstrap module: %s" % modname)
2921+ else:
2922+ if f is not None:
2923+ f.close()
2924+ dst_filename = change_prefix(filename, dst_prefix)
2925+ copyfile(filename, dst_filename)
2926+ if filename.endswith('.pyc'):
2927+ pyfile = filename[:-1]
2928+ if os.path.exists(pyfile):
2929+ copyfile(pyfile, dst_filename[:-1])
2930+
2931+
2932+def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
2933+ """Install just the base environment, no distutils patches etc"""
2934+ if sys.executable.startswith(bin_dir):
2935+ print('Please use the *system* python to run this script')
2936+ return
2937+
2938+ if clear:
2939+ rmtree(lib_dir)
2940+ ## FIXME: why not delete it?
2941+ ## Maybe it should delete everything with #!/path/to/venv/python in it
2942+ logger.notify('Not deleting %s', bin_dir)
2943+
2944+ if hasattr(sys, 'real_prefix'):
2945+ logger.notify('Using real prefix %r' % sys.real_prefix)
2946+ prefix = sys.real_prefix
2947+ else:
2948+ prefix = sys.prefix
2949+ mkdir(lib_dir)
2950+ fix_lib64(lib_dir)
2951+ stdlib_dirs = [os.path.dirname(os.__file__)]
2952+ if sys.platform == 'win32':
2953+ stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
2954+ elif sys.platform == 'darwin':
2955+ stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
2956+ if hasattr(os, 'symlink'):
2957+ logger.info('Symlinking Python bootstrap modules')
2958+ else:
2959+ logger.info('Copying Python bootstrap modules')
2960+ logger.indent += 2
2961+ try:
2962+ # copy required files...
2963+ for stdlib_dir in stdlib_dirs:
2964+ if not os.path.isdir(stdlib_dir):
2965+ continue
2966+ for fn in os.listdir(stdlib_dir):
2967+ bn = os.path.splitext(fn)[0]
2968+ if fn != 'site-packages' and bn in REQUIRED_FILES:
2969+ copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
2970+ # ...and modules
2971+ copy_required_modules(home_dir)
2972+ finally:
2973+ logger.indent -= 2
2974+ mkdir(join(lib_dir, 'site-packages'))
2975+ import site
2976+ site_filename = site.__file__
2977+ if site_filename.endswith('.pyc'):
2978+ site_filename = site_filename[:-1]
2979+ elif site_filename.endswith('$py.class'):
2980+ site_filename = site_filename.replace('$py.class', '.py')
2981+ site_filename_dst = change_prefix(site_filename, home_dir)
2982+ site_dir = os.path.dirname(site_filename_dst)
2983+ writefile(site_filename_dst, SITE_PY)
2984+ writefile(join(site_dir, 'orig-prefix.txt'), prefix)
2985+ site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
2986+ if not site_packages:
2987+ writefile(site_packages_filename, '')
2988+ else:
2989+ if os.path.exists(site_packages_filename):
2990+ logger.info('Deleting %s' % site_packages_filename)
2991+ os.unlink(site_packages_filename)
2992+
2993+ if is_pypy:
2994+ stdinc_dir = join(prefix, 'include')
2995+ else:
2996+ stdinc_dir = join(prefix, 'include', py_version + abiflags)
2997+ if os.path.exists(stdinc_dir):
2998+ copyfile(stdinc_dir, inc_dir)
2999+ else:
3000+ logger.debug('No include dir %s' % stdinc_dir)
3001+
3002+ # pypy never uses exec_prefix, just ignore it
3003+ if sys.exec_prefix != prefix and not is_pypy:
3004+ if sys.platform == 'win32':
3005+ exec_dir = join(sys.exec_prefix, 'lib')
3006+ elif is_jython:
3007+ exec_dir = join(sys.exec_prefix, 'Lib')
3008+ else:
3009+ exec_dir = join(sys.exec_prefix, 'lib', py_version)
3010+ for fn in os.listdir(exec_dir):
3011+ copyfile(join(exec_dir, fn), join(lib_dir, fn))
3012+
3013+ if is_jython:
3014+ # Jython has either jython-dev.jar and javalib/ dir, or just
3015+ # jython.jar
3016+ for name in 'jython-dev.jar', 'javalib', 'jython.jar':
3017+ src = join(prefix, name)
3018+ if os.path.exists(src):
3019+ copyfile(src, join(home_dir, name))
3020+ # XXX: registry should always exist after Jython 2.5rc1
3021+ src = join(prefix, 'registry')
3022+ if os.path.exists(src):
3023+ copyfile(src, join(home_dir, 'registry'), symlink=False)
3024+ copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
3025+ symlink=False)
3026+
3027+ mkdir(bin_dir)
3028+ py_executable = join(bin_dir, os.path.basename(sys.executable))
3029+ if 'Python.framework' in prefix:
3030+ if re.search(r'/Python(?:-32|-64)*$', py_executable):
3031+ # The name of the python executable is not quite what
3032+ # we want, rename it.
3033+ py_executable = os.path.join(
3034+ os.path.dirname(py_executable), 'python')
3035+
3036+ logger.notify('New %s executable in %s', expected_exe, py_executable)
3037+ if sys.executable != py_executable:
3038+ ## FIXME: could I just hard link?
3039+ executable = sys.executable
3040+ if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
3041+ # Cygwin misreports sys.executable sometimes
3042+ executable += '.exe'
3043+ py_executable += '.exe'
3044+ logger.info('Executable actually exists in %s' % executable)
3045+ shutil.copyfile(executable, py_executable)
3046+ make_exe(py_executable)
3047+ if sys.platform == 'win32' or sys.platform == 'cygwin':
3048+ pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
3049+ if os.path.exists(pythonw):
3050+ logger.info('Also created pythonw.exe')
3051+ shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
3052+ if is_pypy:
3053+ # make a symlink python --> pypy-c
3054+ python_executable = os.path.join(os.path.dirname(py_executable), 'python')
3055+ logger.info('Also created executable %s' % python_executable)
3056+ copyfile(py_executable, python_executable)
3057+
3058+ if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
3059+ secondary_exe = os.path.join(os.path.dirname(py_executable),
3060+ expected_exe)
3061+ py_executable_ext = os.path.splitext(py_executable)[1]
3062+ if py_executable_ext == '.exe':
3063+ # python2.4 gives an extension of '.4' :P
3064+ secondary_exe += py_executable_ext
3065+ if os.path.exists(secondary_exe):
3066+ logger.warn('Not overwriting existing %s script %s (you must use %s)'
3067+ % (expected_exe, secondary_exe, py_executable))
3068+ else:
3069+ logger.notify('Also creating executable in %s' % secondary_exe)
3070+ shutil.copyfile(sys.executable, secondary_exe)
3071+ make_exe(secondary_exe)
3072+
3073+ if 'Python.framework' in prefix:
3074+ logger.debug('MacOSX Python framework detected')
3075+
3076+ # Make sure we use the the embedded interpreter inside
3077+ # the framework, even if sys.executable points to
3078+ # the stub executable in ${sys.prefix}/bin
3079+ # See http://groups.google.com/group/python-virtualenv/
3080+ # browse_thread/thread/17cab2f85da75951
3081+ original_python = os.path.join(
3082+ prefix, 'Resources/Python.app/Contents/MacOS/Python')
3083+ shutil.copy(original_python, py_executable)
3084+
3085+ # Copy the framework's dylib into the virtual
3086+ # environment
3087+ virtual_lib = os.path.join(home_dir, '.Python')
3088+
3089+ if os.path.exists(virtual_lib):
3090+ os.unlink(virtual_lib)
3091+ copyfile(
3092+ os.path.join(prefix, 'Python'),
3093+ virtual_lib)
3094+
3095+ # And then change the install_name of the copied python executable
3096+ try:
3097+ call_subprocess(
3098+ ["install_name_tool", "-change",
3099+ os.path.join(prefix, 'Python'),
3100+ '@executable_path/../.Python',
3101+ py_executable])
3102+ except:
3103+ logger.fatal(
3104+ "Could not call install_name_tool -- you must have Apple's development tools installed")
3105+ raise
3106+
3107+ # Some tools depend on pythonX.Y being present
3108+ py_executable_version = '%s.%s' % (
3109+ sys.version_info[0], sys.version_info[1])
3110+ if not py_executable.endswith(py_executable_version):
3111+ # symlinking pythonX.Y > python
3112+ pth = py_executable + '%s.%s' % (
3113+ sys.version_info[0], sys.version_info[1])
3114+ if os.path.exists(pth):
3115+ os.unlink(pth)
3116+ os.symlink('python', pth)
3117+ else:
3118+ # reverse symlinking python -> pythonX.Y (with --python)
3119+ pth = join(bin_dir, 'python')
3120+ if os.path.exists(pth):
3121+ os.unlink(pth)
3122+ os.symlink(os.path.basename(py_executable), pth)
3123+
3124+ if sys.platform == 'win32' and ' ' in py_executable:
3125+ # There's a bug with subprocess on Windows when using a first
3126+ # argument that has a space in it. Instead we have to quote
3127+ # the value:
3128+ py_executable = '"%s"' % py_executable
3129+ cmd = [py_executable, '-c', 'import sys; print(sys.prefix)']
3130+ logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
3131+ try:
3132+ proc = subprocess.Popen(cmd,
3133+ stdout=subprocess.PIPE)
3134+ proc_stdout, proc_stderr = proc.communicate()
3135+ except OSError:
3136+ e = sys.exc_info()[1]
3137+ if e.errno == errno.EACCES:
3138+ logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
3139+ sys.exit(100)
3140+ else:
3141+ raise e
3142+
3143+ proc_stdout = proc_stdout.strip().decode(sys.getdefaultencoding())
3144+ proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
3145+ if proc_stdout != os.path.normcase(os.path.abspath(home_dir)):
3146+ logger.fatal(
3147+ 'ERROR: The executable %s is not functioning' % py_executable)
3148+ logger.fatal(
3149+ 'ERROR: It thinks sys.prefix is %r (should be %r)'
3150+ % (proc_stdout, os.path.normcase(os.path.abspath(home_dir))))
3151+ logger.fatal(
3152+ 'ERROR: virtualenv is not compatible with this system or executable')
3153+ if sys.platform == 'win32':
3154+ logger.fatal(
3155+ '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)')
3156+ sys.exit(100)
3157+ else:
3158+ logger.info('Got sys.prefix result: %r' % proc_stdout)
3159+
3160+ pydistutils = os.path.expanduser('~/.pydistutils.cfg')
3161+ if os.path.exists(pydistutils):
3162+ logger.notify('Please make sure you remove any previous custom paths from '
3163+ 'your %s file.' % pydistutils)
3164+ ## FIXME: really this should be calculated earlier
3165+ return py_executable
3166+
3167+def install_activate(home_dir, bin_dir, prompt=None):
3168+ if sys.platform == 'win32' or is_jython and os._name == 'nt':
3169+ files = {'activate.bat': ACTIVATE_BAT,
3170+ 'deactivate.bat': DEACTIVATE_BAT}
3171+ if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin':
3172+ files['activate'] = ACTIVATE_SH
3173+ else:
3174+ files = {'activate': ACTIVATE_SH}
3175+
3176+ # suppling activate.fish in addition to, not instead of, the
3177+ # bash script support.
3178+ files['activate.fish'] = ACTIVATE_FISH
3179+
3180+ # same for csh/tcsh support...
3181+ files['activate.csh'] = ACTIVATE_CSH
3182+
3183+
3184+
3185+ files['activate_this.py'] = ACTIVATE_THIS
3186+ vname = os.path.basename(os.path.abspath(home_dir))
3187+ for name, content in files.items():
3188+ content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
3189+ content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
3190+ content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir))
3191+ content = content.replace('__VIRTUAL_NAME__', vname)
3192+ content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
3193+ writefile(os.path.join(bin_dir, name), content)
3194+
3195+def install_distutils(home_dir):
3196+ distutils_path = change_prefix(distutils.__path__[0], home_dir)
3197+ mkdir(distutils_path)
3198+ ## FIXME: maybe this prefix setting should only be put in place if
3199+ ## there's a local distutils.cfg with a prefix setting?
3200+ home_dir = os.path.abspath(home_dir)
3201+ ## FIXME: this is breaking things, removing for now:
3202+ #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
3203+ writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
3204+ writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
3205+
3206+def fix_lib64(lib_dir):
3207+ """
3208+ Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
3209+ instead of lib/pythonX.Y. If this is such a platform we'll just create a
3210+ symlink so lib64 points to lib
3211+ """
3212+ if [p for p in distutils.sysconfig.get_config_vars().values()
3213+ if isinstance(p, basestring) and 'lib64' in p]:
3214+ logger.debug('This system uses lib64; symlinking lib64 to lib')
3215+ assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
3216+ "Unexpected python lib dir: %r" % lib_dir)
3217+ lib_parent = os.path.dirname(lib_dir)
3218+ assert os.path.basename(lib_parent) == 'lib', (
3219+ "Unexpected parent dir: %r" % lib_parent)
3220+ copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
3221+
3222+def resolve_interpreter(exe):
3223+ """
3224+ If the executable given isn't an absolute path, search $PATH for the interpreter
3225+ """
3226+ if os.path.abspath(exe) != exe:
3227+ paths = os.environ.get('PATH', '').split(os.pathsep)
3228+ for path in paths:
3229+ if os.path.exists(os.path.join(path, exe)):
3230+ exe = os.path.join(path, exe)
3231+ break
3232+ if not os.path.exists(exe):
3233+ logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
3234+ sys.exit(3)
3235+ return exe
3236+
3237+############################################################
3238+## Relocating the environment:
3239+
3240+def make_environment_relocatable(home_dir):
3241+ """
3242+ Makes the already-existing environment use relative paths, and takes out
3243+ the #!-based environment selection in scripts.
3244+ """
3245+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3246+ activate_this = os.path.join(bin_dir, 'activate_this.py')
3247+ if not os.path.exists(activate_this):
3248+ logger.fatal(
3249+ 'The environment doesn\'t have a file %s -- please re-run virtualenv '
3250+ 'on this environment to update it' % activate_this)
3251+ fixup_scripts(home_dir)
3252+ fixup_pth_and_egg_link(home_dir)
3253+ ## FIXME: need to fix up distutils.cfg
3254+
3255+OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
3256+ 'activate', 'activate.bat', 'activate_this.py']
3257+
3258+def fixup_scripts(home_dir):
3259+ # This is what we expect at the top of scripts:
3260+ shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
3261+ # This is what we'll put:
3262+ new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
3263+ 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"
3264+ if sys.platform == 'win32':
3265+ bin_suffix = 'Scripts'
3266+ else:
3267+ bin_suffix = 'bin'
3268+ bin_dir = os.path.join(home_dir, bin_suffix)
3269+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
3270+ for filename in os.listdir(bin_dir):
3271+ filename = os.path.join(bin_dir, filename)
3272+ if not os.path.isfile(filename):
3273+ # ignore subdirs, e.g. .svn ones.
3274+ continue
3275+ f = open(filename, 'rb')
3276+ lines = f.readlines()
3277+ f.close()
3278+ if not lines:
3279+ logger.warn('Script %s is an empty file' % filename)
3280+ continue
3281+ if not lines[0].strip().startswith(shebang):
3282+ if os.path.basename(filename) in OK_ABS_SCRIPTS:
3283+ logger.debug('Cannot make script %s relative' % filename)
3284+ elif lines[0].strip() == new_shebang:
3285+ logger.info('Script %s has already been made relative' % filename)
3286+ else:
3287+ logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
3288+ % (filename, shebang))
3289+ continue
3290+ logger.notify('Making script %s relative' % filename)
3291+ lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
3292+ f = open(filename, 'wb')
3293+ f.writelines(lines)
3294+ f.close()
3295+
3296+def fixup_pth_and_egg_link(home_dir, sys_path=None):
3297+ """Makes .pth and .egg-link files use relative paths"""
3298+ home_dir = os.path.normcase(os.path.abspath(home_dir))
3299+ if sys_path is None:
3300+ sys_path = sys.path
3301+ for path in sys_path:
3302+ if not path:
3303+ path = '.'
3304+ if not os.path.isdir(path):
3305+ continue
3306+ path = os.path.normcase(os.path.abspath(path))
3307+ if not path.startswith(home_dir):
3308+ logger.debug('Skipping system (non-environment) directory %s' % path)
3309+ continue
3310+ for filename in os.listdir(path):
3311+ filename = os.path.join(path, filename)
3312+ if filename.endswith('.pth'):
3313+ if not os.access(filename, os.W_OK):
3314+ logger.warn('Cannot write .pth file %s, skipping' % filename)
3315+ else:
3316+ fixup_pth_file(filename)
3317+ if filename.endswith('.egg-link'):
3318+ if not os.access(filename, os.W_OK):
3319+ logger.warn('Cannot write .egg-link file %s, skipping' % filename)
3320+ else:
3321+ fixup_egg_link(filename)
3322+
3323+def fixup_pth_file(filename):
3324+ lines = []
3325+ prev_lines = []
3326+ f = open(filename)
3327+ prev_lines = f.readlines()
3328+ f.close()
3329+ for line in prev_lines:
3330+ line = line.strip()
3331+ if (not line or line.startswith('#') or line.startswith('import ')
3332+ or os.path.abspath(line) != line):
3333+ lines.append(line)
3334+ else:
3335+ new_value = make_relative_path(filename, line)
3336+ if line != new_value:
3337+ logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
3338+ lines.append(new_value)
3339+ if lines == prev_lines:
3340+ logger.info('No changes to .pth file %s' % filename)
3341+ return
3342+ logger.notify('Making paths in .pth file %s relative' % filename)
3343+ f = open(filename, 'w')
3344+ f.write('\n'.join(lines) + '\n')
3345+ f.close()
3346+
3347+def fixup_egg_link(filename):
3348+ f = open(filename)
3349+ link = f.read().strip()
3350+ f.close()
3351+ if os.path.abspath(link) != link:
3352+ logger.debug('Link in %s already relative' % filename)
3353+ return
3354+ new_link = make_relative_path(filename, link)
3355+ logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
3356+ f = open(filename, 'w')
3357+ f.write(new_link)
3358+ f.close()
3359+
3360+def make_relative_path(source, dest, dest_is_directory=True):
3361+ """
3362+ Make a filename relative, where the filename is dest, and it is
3363+ being referred to from the filename source.
3364+
3365+ >>> make_relative_path('/usr/share/something/a-file.pth',
3366+ ... '/usr/share/another-place/src/Directory')
3367+ '../another-place/src/Directory'
3368+ >>> make_relative_path('/usr/share/something/a-file.pth',
3369+ ... '/home/user/src/Directory')
3370+ '../../../home/user/src/Directory'
3371+ >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
3372+ './'
3373+ """
3374+ source = os.path.dirname(source)
3375+ if not dest_is_directory:
3376+ dest_filename = os.path.basename(dest)
3377+ dest = os.path.dirname(dest)
3378+ dest = os.path.normpath(os.path.abspath(dest))
3379+ source = os.path.normpath(os.path.abspath(source))
3380+ dest_parts = dest.strip(os.path.sep).split(os.path.sep)
3381+ source_parts = source.strip(os.path.sep).split(os.path.sep)
3382+ while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
3383+ dest_parts.pop(0)
3384+ source_parts.pop(0)
3385+ full_parts = ['..']*len(source_parts) + dest_parts
3386+ if not dest_is_directory:
3387+ full_parts.append(dest_filename)
3388+ if not full_parts:
3389+ # Special case for the current directory (otherwise it'd be '')
3390+ return './'
3391+ return os.path.sep.join(full_parts)
3392+
3393+
3394+
3395+############################################################
3396+## Bootstrap script creation:
3397+
3398+def create_bootstrap_script(extra_text, python_version=''):
3399+ """
3400+ Creates a bootstrap script, which is like this script but with
3401+ extend_parser, adjust_options, and after_install hooks.
3402+
3403+ This returns a string that (written to disk of course) can be used
3404+ as a bootstrap script with your own customizations. The script
3405+ will be the standard virtualenv.py script, with your extra text
3406+ added (your extra text should be Python code).
3407+
3408+ If you include these functions, they will be called:
3409+
3410+ ``extend_parser(optparse_parser)``:
3411+ You can add or remove options from the parser here.
3412+
3413+ ``adjust_options(options, args)``:
3414+ You can change options here, or change the args (if you accept
3415+ different kinds of arguments, be sure you modify ``args`` so it is
3416+ only ``[DEST_DIR]``).
3417+
3418+ ``after_install(options, home_dir)``:
3419+
3420+ After everything is installed, this function is called. This
3421+ is probably the function you are most likely to use. An
3422+ example would be::
3423+
3424+ def after_install(options, home_dir):
3425+ subprocess.call([join(home_dir, 'bin', 'easy_install'),
3426+ 'MyPackage'])
3427+ subprocess.call([join(home_dir, 'bin', 'my-package-script'),
3428+ 'setup', home_dir])
3429+
3430+ This example immediately installs a package, and runs a setup
3431+ script from that package.
3432+
3433+ If you provide something like ``python_version='2.4'`` then the
3434+ script will start with ``#!/usr/bin/env python2.4`` instead of
3435+ ``#!/usr/bin/env python``. You can use this when the script must
3436+ be run with a particular Python version.
3437+ """
3438+ filename = __file__
3439+ if filename.endswith('.pyc'):
3440+ filename = filename[:-1]
3441+ f = open(filename, 'rb')
3442+ content = f.read()
3443+ f.close()
3444+ py_exe = 'python%s' % python_version
3445+ content = (('#!/usr/bin/env %s\n' % py_exe)
3446+ + '## WARNING: This file is generated\n'
3447+ + content)
3448+ return content.replace('##EXT' 'END##', extra_text)
3449+
3450+##EXTEND##
3451+
3452+def convert(s):
3453+ b = base64.b64decode(s.encode('ascii'))
3454+ return zlib.decompress(b).decode('utf-8')
3455+
3456+##file site.py
3457+SITE_PY = convert("""
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
3592+AIOc2an2AKxRCP4P1A2QJQ==
3593+""")
3594+
3595+
3596+
3597+##file ez_setup.py
3598+EZ_SETUP_PY = convert("""
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
3665+BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
3666+""")
3667+
3668+
3669+
3670+##file distribute_setup.py
3671+DISTRIBUTE_SETUP_PY = convert("""
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
3751+""")
3752+
3753+
3754+
3755+##file activate.sh
3756+ACTIVATE_SH = convert("""
3757+eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9
3758+H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq
3759+DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs
3760+cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY
3761+G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T
3762+EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs
3763+wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG
3764+5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/
3765+JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR
3766+huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx
3767+Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L
3768+Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw
3769+WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX
3770+LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2
3771+""")
3772+
3773+
3774+
3775+##file activate.fish
3776+ACTIVATE_FISH = convert("""
3777+eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
3778+Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
3779+pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
3780+lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
3781+g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
3782+grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
3783+xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
3784+MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
3785+H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
3786+L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
3787+fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
3788+pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
3789+MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
3790+O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
3791+7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
3792+m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
3793+djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
3794+mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
3795+jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
3796+""")
3797+
3798+
3799+
3800+##file activate.csh
3801+ACTIVATE_CSH = convert("""
3802+eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
3803+XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
3804+kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
3805+pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
3806+sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
3807+yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
3808+E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
3809+lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
3810+r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
3811+""")
3812+
3813+
3814+
3815+##file activate.bat
3816+ACTIVATE_BAT = convert("""
3817+eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
3818+qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
3819+sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
3820+ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
3821+""")
3822+
3823+
3824+
3825+##file deactivate.bat
3826+DEACTIVATE_BAT = convert("""
3827+eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
3828+FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
3829+i2dASrm4rFz9XLgAwJNbyQ==
3830+""")
3831+
3832+
3833+
3834+##file distutils-init.py
3835+DISTUTILS_INIT = convert("""
3836+eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
3837+luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
3838+KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
3839+ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
3840+QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
3841+yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
3842+bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
3843+bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
3844+yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
3845+Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
3846+Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
3847+/n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
3848+FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
3849+AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
3850+hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
3851+UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
3852+8h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
3853+XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
3854+azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
3855+8dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
3856+gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
3857+5C4rFgwLGfMvJuAMew==
3858+""")
3859+
3860+
3861+
3862+##file distutils.cfg
3863+DISTUTILS_CFG = convert("""
3864+eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
3865+xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
3866+9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
3867+""")
3868+
3869+
3870+
3871+##file activate_this.py
3872+ACTIVATE_THIS = convert("""
3873+eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ
3874+VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a
3875+Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE
3876+qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX
3877+4lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7
3878+HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n
3879+xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96
3880+1Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI
3881+3vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU=
3882+""")
3883+
3884+
3885+
3886+if __name__ == '__main__':
3887+ main()
3888+
3889+## TODO:
3890+## Copy python.exe.manifest
3891+## Monkeypatch distutils.sysconfig
3892+>>>>>>> MERGE-SOURCE
3893
3894=== added directory '.pc/remove_syspath0_on_reinvoke.patch'
3895=== added file '.pc/remove_syspath0_on_reinvoke.patch/virtualenv.py'
3896--- .pc/remove_syspath0_on_reinvoke.patch/virtualenv.py 1970-01-01 00:00:00 +0000
3897+++ .pc/remove_syspath0_on_reinvoke.patch/virtualenv.py 2011-09-08 21:10:23 +0000
3898@@ -0,0 +1,1896 @@
3899+"""Create a "virtual" Python installation
3900+"""
3901+
3902+# If you change the version here, change it in setup.py
3903+# and docs/conf.py as well.
3904+virtualenv_version = "1.6"
3905+
3906+import base64
3907+import sys
3908+import os
3909+import optparse
3910+import re
3911+import shutil
3912+import logging
3913+import tempfile
3914+import zlib
3915+import errno
3916+import distutils.sysconfig
3917+try:
3918+ import subprocess
3919+except ImportError:
3920+ if sys.version_info <= (2, 3):
3921+ print('ERROR: %s' % sys.exc_info()[1])
3922+ print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
3923+ print('If you copy subprocess.py from a newer version of Python this script will probably work')
3924+ sys.exit(101)
3925+ else:
3926+ raise
3927+try:
3928+ set
3929+except NameError:
3930+ from sets import Set as set
3931+try:
3932+ basestring
3933+except NameError:
3934+ basestring = str
3935+
3936+join = os.path.join
3937+py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
3938+
3939+is_jython = sys.platform.startswith('java')
3940+is_pypy = hasattr(sys, 'pypy_version_info')
3941+abiflags = getattr(sys, 'abiflags', '')
3942+
3943+if is_pypy:
3944+ expected_exe = 'pypy'
3945+elif is_jython:
3946+ expected_exe = 'jython'
3947+else:
3948+ expected_exe = 'python'
3949+
3950+
3951+REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
3952+ 'fnmatch', 'locale', 'encodings', 'codecs',
3953+ 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
3954+ 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
3955+ 'zlib']
3956+
3957+REQUIRED_FILES = ['lib-dynload', 'config']
3958+
3959+majver, minver = sys.version_info[:2]
3960+if majver == 2:
3961+ if minver >= 6:
3962+ REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
3963+ if minver >= 7:
3964+ REQUIRED_MODULES.extend(['_weakrefset'])
3965+ if minver <= 3:
3966+ REQUIRED_MODULES.extend(['sets', '__future__'])
3967+elif majver == 3:
3968+ # Some extra modules are needed for Python 3, but different ones
3969+ # for different versions.
3970+ REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
3971+ '_weakrefset', 'copyreg', 'tempfile', 'random',
3972+ '__future__', 'collections', 'keyword', 'tarfile',
3973+ 'shutil', 'struct', 'copy'])
3974+ if minver >= 2:
3975+ REQUIRED_FILES[-1] = 'config-%s' % majver
3976+ if minver == 3:
3977+ # The whole list of 3.3 modules is reproduced below - the current
3978+ # uncommented ones are required for 3.3 as of now, but more may be
3979+ # added as 3.3 development continues.
3980+ REQUIRED_MODULES.extend([
3981+ #"aifc",
3982+ #"antigravity",
3983+ #"argparse",
3984+ #"ast",
3985+ #"asynchat",
3986+ #"asyncore",
3987+ "base64",
3988+ #"bdb",
3989+ #"binhex",
3990+ "bisect",
3991+ #"calendar",
3992+ #"cgi",
3993+ #"cgitb",
3994+ #"chunk",
3995+ #"cmd",
3996+ #"codeop",
3997+ #"code",
3998+ #"colorsys",
3999+ #"_compat_pickle",
4000+ #"compileall",
4001+ #"concurrent",
4002+ #"configparser",
4003+ #"contextlib",
4004+ #"cProfile",
4005+ #"crypt",
4006+ #"csv",
4007+ #"ctypes",
4008+ #"curses",
4009+ #"datetime",
4010+ #"dbm",
4011+ #"decimal",
4012+ #"difflib",
4013+ #"dis",
4014+ #"doctest",
4015+ #"dummy_threading",
4016+ #"_dummy_thread",
4017+ #"email",
4018+ #"filecmp",
4019+ #"fileinput",
4020+ #"formatter",
4021+ #"fractions",
4022+ #"ftplib",
4023+ #"functools",
4024+ #"getopt",
4025+ #"getpass",
4026+ #"gettext",
4027+ #"glob",
4028+ #"gzip",
4029+ "hashlib",
4030+ "heapq",
4031+ "hmac",
4032+ #"html",
4033+ #"http",
4034+ #"idlelib",
4035+ #"imaplib",
4036+ #"imghdr",
4037+ #"importlib",
4038+ #"inspect",
4039+ #"json",
4040+ #"lib2to3",
4041+ #"logging",
4042+ #"macpath",
4043+ #"macurl2path",
4044+ #"mailbox",
4045+ #"mailcap",
4046+ #"_markupbase",
4047+ #"mimetypes",
4048+ #"modulefinder",
4049+ #"multiprocessing",
4050+ #"netrc",
4051+ #"nntplib",
4052+ #"nturl2path",
4053+ #"numbers",
4054+ #"opcode",
4055+ #"optparse",
4056+ #"os2emxpath",
4057+ #"pdb",
4058+ #"pickle",
4059+ #"pickletools",
4060+ #"pipes",
4061+ #"pkgutil",
4062+ #"platform",
4063+ #"plat-linux2",
4064+ #"plistlib",
4065+ #"poplib",
4066+ #"pprint",
4067+ #"profile",
4068+ #"pstats",
4069+ #"pty",
4070+ #"pyclbr",
4071+ #"py_compile",
4072+ #"pydoc_data",
4073+ #"pydoc",
4074+ #"_pyio",
4075+ #"queue",
4076+ #"quopri",
4077+ "reprlib",
4078+ "rlcompleter",
4079+ #"runpy",
4080+ #"sched",
4081+ #"shelve",
4082+ #"shlex",
4083+ #"smtpd",
4084+ #"smtplib",
4085+ #"sndhdr",
4086+ #"socket",
4087+ #"socketserver",
4088+ #"sqlite3",
4089+ #"ssl",
4090+ #"stringprep",
4091+ #"string",
4092+ #"_strptime",
4093+ #"subprocess",
4094+ #"sunau",
4095+ #"symbol",
4096+ #"symtable",
4097+ #"sysconfig",
4098+ #"tabnanny",
4099+ #"telnetlib",
4100+ #"test",
4101+ #"textwrap",
4102+ #"this",
4103+ #"_threading_local",
4104+ #"threading",
4105+ #"timeit",
4106+ #"tkinter",
4107+ #"tokenize",
4108+ #"token",
4109+ #"traceback",
4110+ #"trace",
4111+ #"tty",
4112+ #"turtledemo",
4113+ #"turtle",
4114+ #"unittest",
4115+ #"urllib",
4116+ #"uuid",
4117+ #"uu",
4118+ #"wave",
4119+ "weakref",
4120+ #"webbrowser",
4121+ #"wsgiref",
4122+ #"xdrlib",
4123+ #"xml",
4124+ #"xmlrpc",
4125+ #"zipfile",
4126+ ])
4127+
4128+if is_pypy:
4129+ # these are needed to correctly display the exceptions that may happen
4130+ # during the bootstrap
4131+ REQUIRED_MODULES.extend(['traceback', 'linecache'])
4132+
4133+class Logger(object):
4134+
4135+ """
4136+ Logging object for use in command-line script. Allows ranges of
4137+ levels, to avoid some redundancy of displayed information.
4138+ """
4139+
4140+ DEBUG = logging.DEBUG
4141+ INFO = logging.INFO
4142+ NOTIFY = (logging.INFO+logging.WARN)/2
4143+ WARN = WARNING = logging.WARN
4144+ ERROR = logging.ERROR
4145+ FATAL = logging.FATAL
4146+
4147+ LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
4148+
4149+ def __init__(self, consumers):
4150+ self.consumers = consumers
4151+ self.indent = 0
4152+ self.in_progress = None
4153+ self.in_progress_hanging = False
4154+
4155+ def debug(self, msg, *args, **kw):
4156+ self.log(self.DEBUG, msg, *args, **kw)
4157+ def info(self, msg, *args, **kw):
4158+ self.log(self.INFO, msg, *args, **kw)
4159+ def notify(self, msg, *args, **kw):
4160+ self.log(self.NOTIFY, msg, *args, **kw)
4161+ def warn(self, msg, *args, **kw):
4162+ self.log(self.WARN, msg, *args, **kw)
4163+ def error(self, msg, *args, **kw):
4164+ self.log(self.WARN, msg, *args, **kw)
4165+ def fatal(self, msg, *args, **kw):
4166+ self.log(self.FATAL, msg, *args, **kw)
4167+ def log(self, level, msg, *args, **kw):
4168+ if args:
4169+ if kw:
4170+ raise TypeError(
4171+ "You may give positional or keyword arguments, not both")
4172+ args = args or kw
4173+ rendered = None
4174+ for consumer_level, consumer in self.consumers:
4175+ if self.level_matches(level, consumer_level):
4176+ if (self.in_progress_hanging
4177+ and consumer in (sys.stdout, sys.stderr)):
4178+ self.in_progress_hanging = False
4179+ sys.stdout.write('\n')
4180+ sys.stdout.flush()
4181+ if rendered is None:
4182+ if args:
4183+ rendered = msg % args
4184+ else:
4185+ rendered = msg
4186+ rendered = ' '*self.indent + rendered
4187+ if hasattr(consumer, 'write'):
4188+ consumer.write(rendered+'\n')
4189+ else:
4190+ consumer(rendered)
4191+
4192+ def start_progress(self, msg):
4193+ assert not self.in_progress, (
4194+ "Tried to start_progress(%r) while in_progress %r"
4195+ % (msg, self.in_progress))
4196+ if self.level_matches(self.NOTIFY, self._stdout_level()):
4197+ sys.stdout.write(msg)
4198+ sys.stdout.flush()
4199+ self.in_progress_hanging = True
4200+ else:
4201+ self.in_progress_hanging = False
4202+ self.in_progress = msg
4203+
4204+ def end_progress(self, msg='done.'):
4205+ assert self.in_progress, (
4206+ "Tried to end_progress without start_progress")
4207+ if self.stdout_level_matches(self.NOTIFY):
4208+ if not self.in_progress_hanging:
4209+ # Some message has been printed out since start_progress
4210+ sys.stdout.write('...' + self.in_progress + msg + '\n')
4211+ sys.stdout.flush()
4212+ else:
4213+ sys.stdout.write(msg + '\n')
4214+ sys.stdout.flush()
4215+ self.in_progress = None
4216+ self.in_progress_hanging = False
4217+
4218+ def show_progress(self):
4219+ """If we are in a progress scope, and no log messages have been
4220+ shown, write out another '.'"""
4221+ if self.in_progress_hanging:
4222+ sys.stdout.write('.')
4223+ sys.stdout.flush()
4224+
4225+ def stdout_level_matches(self, level):
4226+ """Returns true if a message at this level will go to stdout"""
4227+ return self.level_matches(level, self._stdout_level())
4228+
4229+ def _stdout_level(self):
4230+ """Returns the level that stdout runs at"""
4231+ for level, consumer in self.consumers:
4232+ if consumer is sys.stdout:
4233+ return level
4234+ return self.FATAL
4235+
4236+ def level_matches(self, level, consumer_level):
4237+ """
4238+ >>> l = Logger()
4239+ >>> l.level_matches(3, 4)
4240+ False
4241+ >>> l.level_matches(3, 2)
4242+ True
4243+ >>> l.level_matches(slice(None, 3), 3)
4244+ False
4245+ >>> l.level_matches(slice(None, 3), 2)
4246+ True
4247+ >>> l.level_matches(slice(1, 3), 1)
4248+ True
4249+ >>> l.level_matches(slice(2, 3), 1)
4250+ False
4251+ """
4252+ if isinstance(level, slice):
4253+ start, stop = level.start, level.stop
4254+ if start is not None and start > consumer_level:
4255+ return False
4256+ if stop is not None or stop <= consumer_level:
4257+ return False
4258+ return True
4259+ else:
4260+ return level >= consumer_level
4261+
4262+ #@classmethod
4263+ def level_for_integer(cls, level):
4264+ levels = cls.LEVELS
4265+ if level < 0:
4266+ return levels[0]
4267+ if level >= len(levels):
4268+ return levels[-1]
4269+ return levels[level]
4270+
4271+ level_for_integer = classmethod(level_for_integer)
4272+
4273+# create a silent logger just to prevent this from being undefined
4274+# will be overridden with requested verbosity main() is called.
4275+logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
4276+
4277+def mkdir(path):
4278+ if not os.path.exists(path):
4279+ logger.info('Creating %s', path)
4280+ os.makedirs(path)
4281+ else:
4282+ logger.info('Directory %s already exists', path)
4283+
4284+def copyfileordir(src, dest):
4285+ if os.path.isdir(src):
4286+ shutil.copytree(src, dest, True)
4287+ else:
4288+ shutil.copy2(src, dest)
4289+
4290+def copyfile(src, dest, symlink=True):
4291+ if not os.path.exists(src):
4292+ # Some bad symlink in the src
4293+ logger.warn('Cannot find file %s (bad symlink)', src)
4294+ return
4295+ if os.path.exists(dest):
4296+ logger.debug('File %s already exists', dest)
4297+ return
4298+ if not os.path.exists(os.path.dirname(dest)):
4299+ logger.info('Creating parent directories for %s' % os.path.dirname(dest))
4300+ os.makedirs(os.path.dirname(dest))
4301+ if not os.path.islink(src):
4302+ srcpath = os.path.abspath(src)
4303+ else:
4304+ srcpath = os.readlink(src)
4305+ if symlink and hasattr(os, 'symlink'):
4306+ logger.info('Symlinking %s', dest)
4307+ try:
4308+ os.symlink(srcpath, dest)
4309+ except (OSError, NotImplementedError):
4310+ logger.info('Symlinking failed, copying to %s', dest)
4311+ copyfileordir(src, dest)
4312+ else:
4313+ logger.info('Copying to %s', dest)
4314+ copyfileordir(src, dest)
4315+
4316+def writefile(dest, content, overwrite=True):
4317+ if not os.path.exists(dest):
4318+ logger.info('Writing %s', dest)
4319+ f = open(dest, 'wb')
4320+ f.write(content.encode('utf-8'))
4321+ f.close()
4322+ return
4323+ else:
4324+ f = open(dest, 'rb')
4325+ c = f.read()
4326+ f.close()
4327+ if c != content:
4328+ if not overwrite:
4329+ logger.notify('File %s exists with different content; not overwriting', dest)
4330+ return
4331+ logger.notify('Overwriting %s with new content', dest)
4332+ f = open(dest, 'wb')
4333+ f.write(content.encode('utf-8'))
4334+ f.close()
4335+ else:
4336+ logger.info('Content %s already in place', dest)
4337+
4338+def rmtree(dir):
4339+ if os.path.exists(dir):
4340+ logger.notify('Deleting tree %s', dir)
4341+ shutil.rmtree(dir)
4342+ else:
4343+ logger.info('Do not need to delete %s; already gone', dir)
4344+
4345+def make_exe(fn):
4346+ if hasattr(os, 'chmod'):
4347+ oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
4348+ newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
4349+ os.chmod(fn, newmode)
4350+ logger.info('Changed mode of %s to %s', fn, oct(newmode))
4351+
4352+def _find_file(filename, dirs):
4353+ for dir in dirs:
4354+ if os.path.exists(join(dir, filename)):
4355+ return join(dir, filename)
4356+ return filename
4357+
4358+def _install_req(py_executable, unzip=False, distribute=False):
4359+ if not distribute:
4360+ setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
4361+ project_name = 'setuptools'
4362+ bootstrap_script = EZ_SETUP_PY
4363+ source = None
4364+ else:
4365+ setup_fn = None
4366+ source = 'distribute-0.6.15.tar.gz'
4367+ project_name = 'distribute'
4368+ bootstrap_script = DISTRIBUTE_SETUP_PY
4369+ try:
4370+ # check if the global Python has distribute installed or plain
4371+ # setuptools
4372+ import pkg_resources
4373+ if not hasattr(pkg_resources, '_distribute'):
4374+ location = os.path.dirname(pkg_resources.__file__)
4375+ logger.notify("A globally installed setuptools was found (in %s)" % location)
4376+ logger.notify("Use the --no-site-packages option to use distribute in "
4377+ "the virtualenv.")
4378+ except ImportError:
4379+ pass
4380+
4381+ search_dirs = file_search_dirs()
4382+
4383+ if setup_fn is not None:
4384+ setup_fn = _find_file(setup_fn, search_dirs)
4385+
4386+ if source is not None:
4387+ source = _find_file(source, search_dirs)
4388+
4389+ if is_jython and os._name == 'nt':
4390+ # Jython's .bat sys.executable can't handle a command line
4391+ # argument with newlines
4392+ fd, ez_setup = tempfile.mkstemp('.py')
4393+ os.write(fd, bootstrap_script)
4394+ os.close(fd)
4395+ cmd = [py_executable, ez_setup]
4396+ else:
4397+ cmd = [py_executable, '-c', bootstrap_script]
4398+ if unzip:
4399+ cmd.append('--always-unzip')
4400+ env = {}
4401+ remove_from_env = []
4402+ if logger.stdout_level_matches(logger.DEBUG):
4403+ cmd.append('-v')
4404+
4405+ old_chdir = os.getcwd()
4406+ if setup_fn is not None and os.path.exists(setup_fn):
4407+ logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
4408+ cmd.append(setup_fn)
4409+ if os.environ.get('PYTHONPATH'):
4410+ env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
4411+ else:
4412+ env['PYTHONPATH'] = setup_fn
4413+ else:
4414+ # the source is found, let's chdir
4415+ if source is not None and os.path.exists(source):
4416+ os.chdir(os.path.dirname(source))
4417+ # in this case, we want to be sure that PYTHONPATH is unset (not
4418+ # just empty, really unset), else CPython tries to import the
4419+ # site.py that it's in virtualenv_support
4420+ remove_from_env.append('PYTHONPATH')
4421+ else:
4422+ logger.info('No %s egg found; downloading' % project_name)
4423+ cmd.extend(['--always-copy', '-U', project_name])
4424+ logger.start_progress('Installing %s...' % project_name)
4425+ logger.indent += 2
4426+ cwd = None
4427+ if project_name == 'distribute':
4428+ env['DONT_PATCH_SETUPTOOLS'] = 'true'
4429+
4430+ def _filter_ez_setup(line):
4431+ return filter_ez_setup(line, project_name)
4432+
4433+ if not os.access(os.getcwd(), os.W_OK):
4434+ cwd = tempfile.mkdtemp()
4435+ if source is not None and os.path.exists(source):
4436+ # the current working dir is hostile, let's copy the
4437+ # tarball to a temp dir
4438+ target = os.path.join(cwd, os.path.split(source)[-1])
4439+ shutil.copy(source, target)
4440+ try:
4441+ call_subprocess(cmd, show_stdout=False,
4442+ filter_stdout=_filter_ez_setup,
4443+ extra_env=env,
4444+ remove_from_env=remove_from_env,
4445+ cwd=cwd)
4446+ finally:
4447+ logger.indent -= 2
4448+ logger.end_progress()
4449+ if os.getcwd() != old_chdir:
4450+ os.chdir(old_chdir)
4451+ if is_jython and os._name == 'nt':
4452+ os.remove(ez_setup)
4453+
4454+def file_search_dirs():
4455+ here = os.path.dirname(os.path.abspath(__file__))
4456+ dirs = ['.', here,
4457+ #join(here, 'virtualenv_support')]
4458+ '/usr/share/python-virtualenv/']
4459+ if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
4460+ # Probably some boot script; just in case virtualenv is installed...
4461+ try:
4462+ import virtualenv
4463+ except ImportError:
4464+ pass
4465+ else:
4466+ dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
4467+ return [d for d in dirs if os.path.isdir(d)]
4468+
4469+def install_setuptools(py_executable, unzip=False):
4470+ _install_req(py_executable, unzip)
4471+
4472+def install_distribute(py_executable, unzip=False):
4473+ _install_req(py_executable, unzip, distribute=True)
4474+
4475+_pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
4476+def install_pip(py_executable):
4477+ filenames = []
4478+ for dir in file_search_dirs():
4479+ filenames.extend([join(dir, fn) for fn in os.listdir(dir)
4480+ if _pip_re.search(fn)])
4481+ filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
4482+ filenames.sort()
4483+ filenames = [filename for basename, i, filename in filenames]
4484+ if not filenames:
4485+ filename = 'pip'
4486+ else:
4487+ filename = filenames[-1]
4488+ easy_install_script = 'easy_install'
4489+ if sys.platform == 'win32':
4490+ easy_install_script = 'easy_install-script.py'
4491+ cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename]
4492+ if filename == 'pip':
4493+ logger.info('Installing pip from network...')
4494+ else:
4495+ logger.info('Installing %s' % os.path.basename(filename))
4496+ logger.indent += 2
4497+ def _filter_setup(line):
4498+ return filter_ez_setup(line, 'pip')
4499+ try:
4500+ call_subprocess(cmd, show_stdout=False,
4501+ filter_stdout=_filter_setup)
4502+ finally:
4503+ logger.indent -= 2
4504+
4505+def filter_ez_setup(line, project_name='setuptools'):
4506+ if not line.strip():
4507+ return Logger.DEBUG
4508+ if project_name == 'distribute':
4509+ for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
4510+ 'Scanning', 'Setuptools', 'Egg', 'Already',
4511+ 'running', 'writing', 'reading', 'installing',
4512+ 'creating', 'copying', 'byte-compiling', 'removing',
4513+ 'Processing'):
4514+ if line.startswith(prefix):
4515+ return Logger.DEBUG
4516+ return Logger.DEBUG
4517+ for prefix in ['Reading ', 'Best match', 'Processing setuptools',
4518+ 'Copying setuptools', 'Adding setuptools',
4519+ 'Installing ', 'Installed ']:
4520+ if line.startswith(prefix):
4521+ return Logger.DEBUG
4522+ return Logger.INFO
4523+
4524+def main():
4525+ parser = optparse.OptionParser(
4526+ version=virtualenv_version,
4527+ usage="%prog [OPTIONS] DEST_DIR")
4528+
4529+ parser.add_option(
4530+ '-v', '--verbose',
4531+ action='count',
4532+ dest='verbose',
4533+ default=0,
4534+ help="Increase verbosity")
4535+
4536+ parser.add_option(
4537+ '-q', '--quiet',
4538+ action='count',
4539+ dest='quiet',
4540+ default=0,
4541+ help='Decrease verbosity')
4542+
4543+ parser.add_option(
4544+ '-p', '--python',
4545+ dest='python',
4546+ metavar='PYTHON_EXE',
4547+ help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
4548+ 'interpreter to create the new environment. The default is the interpreter that '
4549+ 'virtualenv was installed with (%s)' % sys.executable)
4550+
4551+ parser.add_option(
4552+ '--clear',
4553+ dest='clear',
4554+ action='store_true',
4555+ help="Clear out the non-root install and start from scratch")
4556+
4557+ parser.add_option(
4558+ '--no-site-packages',
4559+ dest='no_site_packages',
4560+ action='store_true',
4561+ help="Don't give access to the global site-packages dir to the "
4562+ "virtual environment")
4563+
4564+ parser.add_option(
4565+ '--unzip-setuptools',
4566+ dest='unzip_setuptools',
4567+ action='store_true',
4568+ help="Unzip Setuptools or Distribute when installing it")
4569+
4570+ parser.add_option(
4571+ '--relocatable',
4572+ dest='relocatable',
4573+ action='store_true',
4574+ help='Make an EXISTING virtualenv environment relocatable. '
4575+ 'This fixes up scripts and makes all .pth files relative')
4576+
4577+ parser.add_option(
4578+ '--distribute',
4579+ dest='use_distribute',
4580+ action='store_true', default=True,
4581+ help='Ignored. Distribute is used by default. See --setuptools '
4582+ 'to use Setuptools instead of Distribute.')
4583+
4584+ parser.add_option(
4585+ '--setuptools',
4586+ dest='use_distribute',
4587+ action='store_false',
4588+ help='Use Setuptools instead of Distribute. Set environ variable '
4589+ 'VIRTUALENV_USE_SETUPTOOLS to make it the default.')
4590+
4591+ parser.add_option(
4592+ '--prompt=',
4593+ dest='prompt',
4594+ help='Provides an alternative prompt prefix for this environment')
4595+
4596+ if 'extend_parser' in globals():
4597+ extend_parser(parser)
4598+
4599+ options, args = parser.parse_args()
4600+
4601+ global logger
4602+
4603+ if 'adjust_options' in globals():
4604+ adjust_options(options, args)
4605+
4606+ verbosity = options.verbose - options.quiet
4607+ logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
4608+
4609+ if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
4610+ env = os.environ.copy()
4611+ interpreter = resolve_interpreter(options.python)
4612+ if interpreter == sys.executable:
4613+ logger.warn('Already using interpreter %s' % interpreter)
4614+ else:
4615+ logger.notify('Running virtualenv with interpreter %s' % interpreter)
4616+ env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
4617+ file = __file__
4618+ if file.endswith('.pyc'):
4619+ file = file[:-1]
4620+ popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
4621+ raise SystemExit(popen.wait())
4622+
4623+ if not args:
4624+ print('You must provide a DEST_DIR')
4625+ parser.print_help()
4626+ sys.exit(2)
4627+ if len(args) > 1:
4628+ print('There must be only one argument: DEST_DIR (you gave %s)' % (
4629+ ' '.join(args)))
4630+ parser.print_help()
4631+ sys.exit(2)
4632+
4633+ home_dir = args[0]
4634+
4635+ if os.environ.get('WORKING_ENV'):
4636+ logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
4637+ logger.fatal('Please deactivate your workingenv, then re-run this script')
4638+ sys.exit(3)
4639+
4640+ if 'PYTHONHOME' in os.environ:
4641+ logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
4642+ del os.environ['PYTHONHOME']
4643+
4644+ if options.relocatable:
4645+ make_environment_relocatable(home_dir)
4646+ return
4647+
4648+ create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear,
4649+ unzip_setuptools=options.unzip_setuptools,
4650+ use_distribute=options.use_distribute or majver > 2,
4651+ prompt=options.prompt)
4652+ if 'after_install' in globals():
4653+ after_install(options, home_dir)
4654+
4655+def call_subprocess(cmd, show_stdout=True,
4656+ filter_stdout=None, cwd=None,
4657+ raise_on_returncode=True, extra_env=None,
4658+ remove_from_env=None):
4659+ cmd_parts = []
4660+ for part in cmd:
4661+ if len(part) > 45:
4662+ part = part[:20]+"..."+part[-20:]
4663+ if ' ' in part or '\n' in part or '"' in part or "'" in part:
4664+ part = '"%s"' % part.replace('"', '\\"')
4665+ cmd_parts.append(part)
4666+ cmd_desc = ' '.join(cmd_parts)
4667+ if show_stdout:
4668+ stdout = None
4669+ else:
4670+ stdout = subprocess.PIPE
4671+ logger.debug("Running command %s" % cmd_desc)
4672+ if extra_env or remove_from_env:
4673+ env = os.environ.copy()
4674+ if extra_env:
4675+ env.update(extra_env)
4676+ if remove_from_env:
4677+ for varname in remove_from_env:
4678+ env.pop(varname, None)
4679+ else:
4680+ env = None
4681+ try:
4682+ proc = subprocess.Popen(
4683+ cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
4684+ cwd=cwd, env=env)
4685+ except Exception:
4686+ e = sys.exc_info()[1]
4687+ logger.fatal(
4688+ "Error %s while executing command %s" % (e, cmd_desc))
4689+ raise
4690+ all_output = []
4691+ if stdout is not None:
4692+ stdout = proc.stdout
4693+ encoding = sys.getdefaultencoding()
4694+ while 1:
4695+ line = stdout.readline().decode(encoding)
4696+ if not line:
4697+ break
4698+ line = line.rstrip()
4699+ all_output.append(line)
4700+ if filter_stdout:
4701+ level = filter_stdout(line)
4702+ if isinstance(level, tuple):
4703+ level, line = level
4704+ logger.log(level, line)
4705+ if not logger.stdout_level_matches(level):
4706+ logger.show_progress()
4707+ else:
4708+ logger.info(line)
4709+ else:
4710+ proc.communicate()
4711+ proc.wait()
4712+ if proc.returncode:
4713+ if raise_on_returncode:
4714+ if all_output:
4715+ logger.notify('Complete output from command %s:' % cmd_desc)
4716+ logger.notify('\n'.join(all_output) + '\n----------------------------------------')
4717+ raise OSError(
4718+ "Command %s failed with error code %s"
4719+ % (cmd_desc, proc.returncode))
4720+ else:
4721+ logger.warn(
4722+ "Command %s had error code %s"
4723+ % (cmd_desc, proc.returncode))
4724+
4725+
4726+def create_environment(home_dir, site_packages=True, clear=False,
4727+ unzip_setuptools=False, use_distribute=True,
4728+ prompt=None):
4729+ """
4730+ Creates a new environment in ``home_dir``.
4731+
4732+ If ``site_packages`` is true (the default) then the global
4733+ ``site-packages/`` directory will be on the path.
4734+
4735+ If ``clear`` is true (default False) then the environment will
4736+ first be cleared.
4737+ """
4738+ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
4739+
4740+ py_executable = os.path.abspath(install_python(
4741+ home_dir, lib_dir, inc_dir, bin_dir,
4742+ site_packages=site_packages, clear=clear))
4743+
4744+ install_distutils(home_dir)
4745+
4746+ if not use_distribute or os.environ.get('VIRTUALENV_USE_SETUPTOOLS'):
4747+ install_setuptools(py_executable, unzip=unzip_setuptools)
4748+ else:
4749+ install_distribute(py_executable, unzip=unzip_setuptools)
4750+
4751+ install_pip(py_executable)
4752+
4753+ install_activate(home_dir, bin_dir, prompt)
4754+
4755+def path_locations(home_dir):
4756+ """Return the path locations for the environment (where libraries are,
4757+ where scripts go, etc)"""
4758+ # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
4759+ # prefix arg is broken: http://bugs.python.org/issue3386
4760+ if sys.platform == 'win32':
4761+ # Windows has lots of problems with executables with spaces in
4762+ # the name; this function will remove them (using the ~1
4763+ # format):
4764+ mkdir(home_dir)
4765+ if ' ' in home_dir:
4766+ try:
4767+ import win32api
4768+ except ImportError:
4769+ print('Error: the path "%s" has a space in it' % home_dir)
4770+ print('To handle these kinds of paths, the win32api module must be installed:')
4771+ print(' http://sourceforge.net/projects/pywin32/')
4772+ sys.exit(3)
4773+ home_dir = win32api.GetShortPathName(home_dir)
4774+ lib_dir = join(home_dir, 'Lib')
4775+ inc_dir = join(home_dir, 'Include')
4776+ bin_dir = join(home_dir, 'Scripts')
4777+ elif is_jython:
4778+ lib_dir = join(home_dir, 'Lib')
4779+ inc_dir = join(home_dir, 'Include')
4780+ bin_dir = join(home_dir, 'bin')
4781+ elif is_pypy:
4782+ lib_dir = home_dir
4783+ inc_dir = join(home_dir, 'include')
4784+ bin_dir = join(home_dir, 'bin')
4785+ else:
4786+ lib_dir = join(home_dir, 'lib', py_version)
4787+ inc_dir = join(home_dir, 'include', py_version + abiflags)
4788+ bin_dir = join(home_dir, 'bin')
4789+ return home_dir, lib_dir, inc_dir, bin_dir
4790+
4791+
4792+def change_prefix(filename, dst_prefix):
4793+ prefixes = [sys.prefix]
4794+
4795+ if sys.platform == "darwin":
4796+ prefixes.extend((
4797+ os.path.join("/Library/Python", sys.version[:3], "site-packages"),
4798+ os.path.join(sys.prefix, "Extras", "lib", "python"),
4799+ os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
4800+
4801+ if hasattr(sys, 'real_prefix'):
4802+ prefixes.append(sys.real_prefix)
4803+ prefixes = list(map(os.path.abspath, prefixes))
4804+ filename = os.path.abspath(filename)
4805+ for src_prefix in prefixes:
4806+ if filename.startswith(src_prefix):
4807+ _, relpath = filename.split(src_prefix, 1)
4808+ assert relpath[0] == os.sep
4809+ relpath = relpath[1:]
4810+ return join(dst_prefix, relpath)
4811+ assert False, "Filename %s does not start with any of these prefixes: %s" % \
4812+ (filename, prefixes)
4813+
4814+def copy_required_modules(dst_prefix):
4815+ import imp
4816+ for modname in REQUIRED_MODULES:
4817+ if modname in sys.builtin_module_names:
4818+ logger.info("Ignoring built-in bootstrap module: %s" % modname)
4819+ continue
4820+ try:
4821+ f, filename, _ = imp.find_module(modname)
4822+ except ImportError:
4823+ logger.info("Cannot import bootstrap module: %s" % modname)
4824+ else:
4825+ if f is not None:
4826+ f.close()
4827+ dst_filename = change_prefix(filename, dst_prefix)
4828+ copyfile(filename, dst_filename)
4829+ if filename.endswith('.pyc'):
4830+ pyfile = filename[:-1]
4831+ if os.path.exists(pyfile):
4832+ copyfile(pyfile, dst_filename[:-1])
4833+
4834+
4835+def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
4836+ """Install just the base environment, no distutils patches etc"""
4837+ if sys.executable.startswith(bin_dir):
4838+ print('Please use the *system* python to run this script')
4839+ return
4840+
4841+ if clear:
4842+ rmtree(lib_dir)
4843+ ## FIXME: why not delete it?
4844+ ## Maybe it should delete everything with #!/path/to/venv/python in it
4845+ logger.notify('Not deleting %s', bin_dir)
4846+
4847+ if hasattr(sys, 'real_prefix'):
4848+ logger.notify('Using real prefix %r' % sys.real_prefix)
4849+ prefix = sys.real_prefix
4850+ else:
4851+ prefix = sys.prefix
4852+ mkdir(lib_dir)
4853+ fix_lib64(lib_dir)
4854+ stdlib_dirs = [os.path.dirname(os.__file__)]
4855+ if sys.platform == 'win32':
4856+ stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
4857+ elif sys.platform == 'darwin':
4858+ stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
4859+ if hasattr(os, 'symlink'):
4860+ logger.info('Symlinking Python bootstrap modules')
4861+ else:
4862+ logger.info('Copying Python bootstrap modules')
4863+ logger.indent += 2
4864+ try:
4865+ # copy required files...
4866+ for stdlib_dir in stdlib_dirs:
4867+ if not os.path.isdir(stdlib_dir):
4868+ continue
4869+ for fn in os.listdir(stdlib_dir):
4870+ bn = os.path.splitext(fn)[0]
4871+ if fn != 'site-packages' and bn in REQUIRED_FILES:
4872+ copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
4873+ # ...and modules
4874+ copy_required_modules(home_dir)
4875+ finally:
4876+ logger.indent -= 2
4877+ mkdir(join(lib_dir, 'site-packages'))
4878+ import site
4879+ site_filename = site.__file__
4880+ if site_filename.endswith('.pyc'):
4881+ site_filename = site_filename[:-1]
4882+ elif site_filename.endswith('$py.class'):
4883+ site_filename = site_filename.replace('$py.class', '.py')
4884+ site_filename_dst = change_prefix(site_filename, home_dir)
4885+ site_dir = os.path.dirname(site_filename_dst)
4886+ writefile(site_filename_dst, SITE_PY)
4887+ writefile(join(site_dir, 'orig-prefix.txt'), prefix)
4888+ site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
4889+ if not site_packages:
4890+ writefile(site_packages_filename, '')
4891+ else:
4892+ if os.path.exists(site_packages_filename):
4893+ logger.info('Deleting %s' % site_packages_filename)
4894+ os.unlink(site_packages_filename)
4895+
4896+ if is_pypy:
4897+ stdinc_dir = join(prefix, 'include')
4898+ else:
4899+ stdinc_dir = join(prefix, 'include', py_version + abiflags)
4900+ if os.path.exists(stdinc_dir):
4901+ copyfile(stdinc_dir, inc_dir)
4902+ else:
4903+ logger.debug('No include dir %s' % stdinc_dir)
4904+
4905+ # pypy never uses exec_prefix, just ignore it
4906+ if sys.exec_prefix != prefix and not is_pypy:
4907+ if sys.platform == 'win32':
4908+ exec_dir = join(sys.exec_prefix, 'lib')
4909+ elif is_jython:
4910+ exec_dir = join(sys.exec_prefix, 'Lib')
4911+ else:
4912+ exec_dir = join(sys.exec_prefix, 'lib', py_version)
4913+ for fn in os.listdir(exec_dir):
4914+ copyfile(join(exec_dir, fn), join(lib_dir, fn))
4915+
4916+ if is_jython:
4917+ # Jython has either jython-dev.jar and javalib/ dir, or just
4918+ # jython.jar
4919+ for name in 'jython-dev.jar', 'javalib', 'jython.jar':
4920+ src = join(prefix, name)
4921+ if os.path.exists(src):
4922+ copyfile(src, join(home_dir, name))
4923+ # XXX: registry should always exist after Jython 2.5rc1
4924+ src = join(prefix, 'registry')
4925+ if os.path.exists(src):
4926+ copyfile(src, join(home_dir, 'registry'), symlink=False)
4927+ copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
4928+ symlink=False)
4929+
4930+ mkdir(bin_dir)
4931+ py_executable = join(bin_dir, os.path.basename(sys.executable))
4932+ if 'Python.framework' in prefix:
4933+ if re.search(r'/Python(?:-32|-64)*$', py_executable):
4934+ # The name of the python executable is not quite what
4935+ # we want, rename it.
4936+ py_executable = os.path.join(
4937+ os.path.dirname(py_executable), 'python')
4938+
4939+ logger.notify('New %s executable in %s', expected_exe, py_executable)
4940+ if sys.executable != py_executable:
4941+ ## FIXME: could I just hard link?
4942+ executable = sys.executable
4943+ if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
4944+ # Cygwin misreports sys.executable sometimes
4945+ executable += '.exe'
4946+ py_executable += '.exe'
4947+ logger.info('Executable actually exists in %s' % executable)
4948+ shutil.copyfile(executable, py_executable)
4949+ make_exe(py_executable)
4950+ if sys.platform == 'win32' or sys.platform == 'cygwin':
4951+ pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
4952+ if os.path.exists(pythonw):
4953+ logger.info('Also created pythonw.exe')
4954+ shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
4955+ if is_pypy:
4956+ # make a symlink python --> pypy-c
4957+ python_executable = os.path.join(os.path.dirname(py_executable), 'python')
4958+ logger.info('Also created executable %s' % python_executable)
4959+ copyfile(py_executable, python_executable)
4960+
4961+ if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
4962+ secondary_exe = os.path.join(os.path.dirname(py_executable),
4963+ expected_exe)
4964+ py_executable_ext = os.path.splitext(py_executable)[1]
4965+ if py_executable_ext == '.exe':
4966+ # python2.4 gives an extension of '.4' :P
4967+ secondary_exe += py_executable_ext
4968+ if os.path.exists(secondary_exe):
4969+ logger.warn('Not overwriting existing %s script %s (you must use %s)'
4970+ % (expected_exe, secondary_exe, py_executable))
4971+ else:
4972+ logger.notify('Also creating executable in %s' % secondary_exe)
4973+ shutil.copyfile(sys.executable, secondary_exe)
4974+ make_exe(secondary_exe)
4975+
4976+ if 'Python.framework' in prefix:
4977+ logger.debug('MacOSX Python framework detected')
4978+
4979+ # Make sure we use the the embedded interpreter inside
4980+ # the framework, even if sys.executable points to
4981+ # the stub executable in ${sys.prefix}/bin
4982+ # See http://groups.google.com/group/python-virtualenv/
4983+ # browse_thread/thread/17cab2f85da75951
4984+ original_python = os.path.join(
4985+ prefix, 'Resources/Python.app/Contents/MacOS/Python')
4986+ shutil.copy(original_python, py_executable)
4987+
4988+ # Copy the framework's dylib into the virtual
4989+ # environment
4990+ virtual_lib = os.path.join(home_dir, '.Python')
4991+
4992+ if os.path.exists(virtual_lib):
4993+ os.unlink(virtual_lib)
4994+ copyfile(
4995+ os.path.join(prefix, 'Python'),
4996+ virtual_lib)
4997+
4998+ # And then change the install_name of the copied python executable
4999+ try:
5000+ call_subprocess(
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: