docs/changes.rst | 3 ++ virtualenv.py | 92 +++++++++++++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 80c3dc1..1d9c1fe 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,6 +1,9 @@ Release History =============== +* Remove virtualenv file's path from directory when executing with a new + python. Fixes issue #779, #763 (PR #805) + 13.1.2 (2015-08-23) ~~~~~~~~~~~~~~~~~~~ diff --git a/virtualenv.py b/virtualenv.py index da25205..64e70d4 100755 --- a/virtualenv.py +++ b/virtualenv.py @@ -5,9 +5,22 @@ __version__ = "13.1.2" virtualenv_version = __version__ # legacy -import base64 -import sys import os +import sys + +# If we are running in a new interpreter to create a virtualenv, +# we do NOT want paths from our existing location interfering with anything, +# So we remove this file's directory from sys.path - most likely to be +# the previous interpreter's site-packages. Solves #705, #763, #779 +if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): + del_paths = [] + for path in sys.path: + if os.path.realpath(os.path.dirname(__file__)) == os.path.realpath(path): + del_paths.append(path) + for path in del_paths: + sys.path.remove(path) + +import base64 import codecs import optparse import re @@ -23,6 +36,11 @@ import struct import subprocess import tarfile +try: + import ConfigParser +except ImportError: + import configparser as ConfigParser + if sys.version_info < (2, 6): print('ERROR: %s' % sys.exc_info()[1]) print('ERROR: this script requires Python 2.6 or greater.') @@ -33,11 +51,6 @@ try: except NameError: basestring = str -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser - join = os.path.join py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) @@ -1096,45 +1109,34 @@ def change_prefix(filename, dst_prefix): def copy_required_modules(dst_prefix, symlink): import imp - # If we are running under -p, we need to remove the current - # directory from sys.path temporarily here, so that we - # definitely get the modules from the site directory of - # the interpreter we are running under, not the one - # virtualenv.py is installed under (which might lead to py2/py3 - # incompatibility issues) - _prev_sys_path = sys.path - if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): - sys.path = sys.path[1:] - try: - for modname in REQUIRED_MODULES: - if modname in sys.builtin_module_names: - logger.info("Ignoring built-in bootstrap module: %s" % modname) - continue - try: - f, filename, _ = imp.find_module(modname) - except ImportError: - logger.info("Cannot import bootstrap module: %s" % modname) + + for modname in REQUIRED_MODULES: + if modname in sys.builtin_module_names: + logger.info("Ignoring built-in bootstrap module: %s" % modname) + continue + try: + f, filename, _ = imp.find_module(modname) + except ImportError: + logger.info("Cannot import bootstrap module: %s" % modname) + else: + if f is not None: + f.close() + # special-case custom readline.so on OS X, but not for pypy: + if modname == 'readline' and sys.platform == 'darwin' and not ( + is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))): + dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so') + elif modname == 'readline' and sys.platform == 'win32': + # special-case for Windows, where readline is not a + # standard module, though it may have been installed in + # site-packages by a third-party package + pass else: - if f is not None: - f.close() - # special-case custom readline.so on OS X, but not for pypy: - if modname == 'readline' and sys.platform == 'darwin' and not ( - is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))): - dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so') - elif modname == 'readline' and sys.platform == 'win32': - # special-case for Windows, where readline is not a - # standard module, though it may have been installed in - # site-packages by a third-party package - pass - else: - dst_filename = change_prefix(filename, dst_prefix) - copyfile(filename, dst_filename, symlink) - if filename.endswith('.pyc'): - pyfile = filename[:-1] - if os.path.exists(pyfile): - copyfile(pyfile, dst_filename[:-1], symlink) - finally: - sys.path = _prev_sys_path + dst_filename = change_prefix(filename, dst_prefix) + copyfile(filename, dst_filename, symlink) + if filename.endswith('.pyc'): + pyfile = filename[:-1] + if os.path.exists(pyfile): + copyfile(pyfile, dst_filename[:-1], symlink) def subst_path(prefix_path, prefix, home_dir):