Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3622)

Unified Diff: Lib/venv/__init__.py

Issue 14843: support define_macros / undef_macros in setup.cfg
Patch Set: Created 11 months, 2 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Lib/urllib/parse.py ('k') | Lib/venv/__main__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Lib/venv/__init__.py Sat Jun 09 17:31:59 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +0,0 @@
-"""
-Virtual environment (venv) package for Python. Based on PEP 405.
-
-Copyright (C) 20011-2012 Vinay Sajip. All Rights Reserved.
-
-usage: python -m venv [-h] [--system-site-packages] [--symlinks] [--clear]
- [--upgrade]
- ENV_DIR [ENV_DIR ...]
-
-Creates virtual Python environments in one or more target directories.
-
-positional arguments:
- ENV_DIR A directory to create the environment in.
-
-optional arguments:
- -h, --help show this help message and exit
- --system-site-packages
- Give the virtual environment access to the system
- site-packages dir.
- --symlinks Attempt to symlink rather than copy.
- --clear Delete the environment directory if it already exists.
- If not specified and the directory exists, an error is
- raised.
- --upgrade Upgrade the environment directory to use this version
- of Python, assuming Python has been upgraded in-place.
-"""
-import base64
-import io
-import logging
-import os
-import os.path
-import shutil
-import sys
-import sysconfig
-try:
- import threading
-except ImportError:
- threading = None
-import zipfile
-
-logger = logging.getLogger(__name__)
-
-class Context:
- """
- Holds information about a current venv creation/upgrade request.
- """
- pass
-
-
-class EnvBuilder:
- """
- This class exists to allow virtual environment creation to be
- customised. The constructor parameters determine the builder's
- behaviour when called upon to create a virtual environment.
-
- By default, the builder makes the system (global) site-packages dir
- available to the created environment.
-
- By default, the creation process uses symlinks wherever possible.
-
- :param system_site_packages: If True, the system (global) site-packages
- dir is available to created environments.
- :param clear: If True and the target directory exists, it is deleted.
- Otherwise, if the target directory exists, an error is
- raised.
- :param symlinks: If True, attempt to symlink rather than copy files into
- virtual environment.
- :param upgrade: If True, upgrade an existing virtual environment.
- """
-
- def __init__(self, system_site_packages=False, clear=False,
- symlinks=False, upgrade=False):
- self.system_site_packages = system_site_packages
- self.clear = clear
- self.symlinks = symlinks
- self.upgrade = upgrade
-
- def create(self, env_dir):
- """
- Create a virtual environment in a directory.
-
- :param env_dir: The target directory to create an environment in.
-
- """
- if (self.symlinks and
- sys.platform == 'darwin' and
- sysconfig.get_config_var('PYTHONFRAMEWORK')):
- # Symlinking the stub executable in an OSX framework build will
- # result in a broken virtual environment.
- raise ValueError(
- 'Symlinking is not supported on OSX framework Python.')
- env_dir = os.path.abspath(env_dir)
- context = self.ensure_directories(env_dir)
- self.create_configuration(context)
- self.setup_python(context)
- if not self.upgrade:
- self.setup_scripts(context)
- self.post_setup(context)
-
- def ensure_directories(self, env_dir):
- """
- Create the directories for the environment.
-
- Returns a context object which holds paths in the environment,
- for use by subsequent logic.
- """
-
- def create_if_needed(d):
- if not os.path.exists(d):
- os.makedirs(d)
-
- if os.path.exists(env_dir) and not (self.clear or self.upgrade):
- raise ValueError('Directory exists: %s' % env_dir)
- if os.path.exists(env_dir) and self.clear:
- shutil.rmtree(env_dir)
- context = Context()
- context.env_dir = env_dir
- context.env_name = os.path.split(env_dir)[1]
- context.prompt = '(%s) ' % context.env_name
- create_if_needed(env_dir)
- env = os.environ
- if sys.platform == 'darwin' and '__PYTHONV_LAUNCHER__' in env:
- executable = os.environ['__PYTHONV_LAUNCHER__']
- else:
- executable = sys.executable
- dirname, exename = os.path.split(os.path.abspath(executable))
- context.executable = executable
- context.python_dir = dirname
- context.python_exe = exename
- if sys.platform == 'win32':
- binname = 'Scripts'
- incpath = 'Include'
- libpath = os.path.join(env_dir, 'Lib', 'site-packages')
- else:
- binname = 'bin'
- incpath = 'include'
- libpath = os.path.join(env_dir, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages')
- context.inc_path = path = os.path.join(env_dir, incpath)
- create_if_needed(path)
- create_if_needed(libpath)
- context.bin_path = binpath = os.path.join(env_dir, binname)
- context.bin_name = binname
- context.env_exe = os.path.join(binpath, exename)
- create_if_needed(binpath)
- return context
-
- def create_configuration(self, context):
- """
- Create a configuration file indicating where the environment's Python
- was copied from, and whether the system site-packages should be made
- available in the environment.
-
- :param context: The information for the environment creation request
- being processed.
- """
- context.cfg_path = path = os.path.join(context.env_dir, 'pyvenv.cfg')
- with open(path, 'w', encoding='utf-8') as f:
- f.write('home = %s\n' % context.python_dir)
- if self.system_site_packages:
- incl = 'true'
- else:
- incl = 'false'
- f.write('include-system-site-packages = %s\n' % incl)
- f.write('version = %d.%d.%d\n' % sys.version_info[:3])
-
- if os.name == 'nt':
- def include_binary(self, f):
- if f.endswith(('.pyd', '.dll')):
- result = True
- else:
- result = f.startswith('python') and f.endswith('.exe')
- return result
-
- def symlink_or_copy(self, src, dst):
- """
- Try symlinking a file, and if that fails, fall back to copying.
- """
- force_copy = not self.symlinks
- if not force_copy:
- try:
- if not os.path.islink(dst): # can't link to itself!
- os.symlink(src, dst)
- except Exception: # may need to use a more specific exception
- logger.warning('Unable to symlink %r to %r', src, dst)
- force_copy = True
- if force_copy:
- shutil.copyfile(src, dst)
-
- def setup_python(self, context):
- """
- Set up a Python executable in the environment.
-
- :param context: The information for the environment creation request
- being processed.
- """
- binpath = context.bin_path
- exename = context.python_exe
- path = context.env_exe
- copier = self.symlink_or_copy
- copier(context.executable, path)
- dirname = context.python_dir
- if os.name != 'nt':
- if not os.path.islink(path):
- os.chmod(path, 0o755)
- for suffix in ('python', 'python3'):
- path = os.path.join(binpath, suffix)
- if not os.path.exists(path):
- os.symlink(exename, path)
- else:
- subdir = 'DLLs'
- include = self.include_binary
- files = [f for f in os.listdir(dirname) if include(f)]
- for f in files:
- src = os.path.join(dirname, f)
- dst = os.path.join(binpath, f)
- if dst != context.env_exe: # already done, above
- copier(src, dst)
- dirname = os.path.join(dirname, subdir)
- if os.path.isdir(dirname):
- files = [f for f in os.listdir(dirname) if include(f)]
- for f in files:
- src = os.path.join(dirname, f)
- dst = os.path.join(binpath, f)
- copier(src, dst)
- # copy init.tcl over
- for root, dirs, files in os.walk(context.python_dir):
- if 'init.tcl' in files:
- tcldir = os.path.basename(root)
- tcldir = os.path.join(context.env_dir, 'Lib', tcldir)
- os.makedirs(tcldir)
- src = os.path.join(root, 'init.tcl')
- dst = os.path.join(tcldir, 'init.tcl')
- shutil.copyfile(src, dst)
- break
-
- def setup_scripts(self, context):
- """
- Set up scripts into the created environment from a directory.
-
- This method installs the default scripts into the environment
- being created. You can prevent the default installation by overriding
- this method if you really need to, or if you need to specify
- a different location for the scripts to install. By default, the
- 'scripts' directory in the venv package is used as the source of
- scripts to install.
- """
- path = os.path.abspath(os.path.dirname(__file__))
- path = os.path.join(path, 'scripts')
- self.install_scripts(context, path)
-
- def post_setup(self, context):
- """
- Hook for post-setup modification of the venv. Subclasses may install
- additional packages or scripts here, add activation shell scripts, etc.
-
- :param context: The information for the environment creation request
- being processed.
- """
- pass
-
- def replace_variables(self, text, context):
- """
- Replace variable placeholders in script text with context-specific
- variables.
-
- Return the text passed in , but with variables replaced.
-
- :param text: The text in which to replace placeholder variables.
- :param context: The information for the environment creation request
- being processed.
- """
- text = text.replace('__VENV_DIR__', context.env_dir)
- text = text.replace('__VENV_NAME__', context.prompt)
- text = text.replace('__VENV_BIN_NAME__', context.bin_name)
- text = text.replace('__VENV_PYTHON__', context.env_exe)
- return text
-
- def install_scripts(self, context, path):
- """
- Install scripts into the created environment from a directory.
-
- :param context: The information for the environment creation request
- being processed.
- :param path: Absolute pathname of a directory containing script.
- Scripts in the 'common' subdirectory of this directory,
- and those in the directory named for the platform
- being run on, are installed in the created environment.
- Placeholder variables are replaced with environment-
- specific values.
- """
- binpath = context.bin_path
- plen = len(path)
- for root, dirs, files in os.walk(path):
- if root == path: # at top-level, remove irrelevant dirs
- for d in dirs[:]:
- if d not in ('common', os.name):
- dirs.remove(d)
- continue # ignore files in top level
- for f in files:
- srcfile = os.path.join(root, f)
- suffix = root[plen:].split(os.sep)[2:]
- if not suffix:
- dstdir = binpath
- else:
- dstdir = os.path.join(binpath, *suffix)
- if not os.path.exists(dstdir):
- os.makedirs(dstdir)
- dstfile = os.path.join(dstdir, f)
- with open(srcfile, 'rb') as f:
- data = f.read()
- if srcfile.endswith('.exe'):
- mode = 'wb'
- else:
- mode = 'w'
- data = data.decode('utf-8')
- data = self.replace_variables(data, context)
- with open(dstfile, mode) as f:
- f.write(data)
- os.chmod(dstfile, 0o755)
-
-
-def create(env_dir, system_site_packages=False, clear=False, symlinks=False):
- """
- Create a virtual environment in a directory.
-
- By default, makes the system (global) site-packages dir available to
- the created environment.
-
- :param env_dir: The target directory to create an environment in.
- :param system_site_packages: If True, the system (global) site-packages
- dir is available to the environment.
- :param clear: If True and the target directory exists, it is deleted.
- Otherwise, if the target directory exists, an error is
- raised.
- :param symlinks: If True, attempt to symlink rather than copy files into
- virtual environment.
- """
- builder = EnvBuilder(system_site_packages=system_site_packages,
- clear=clear, symlinks=symlinks)
- builder.create(env_dir)
-
-def main(args=None):
- compatible = True
- if sys.version_info < (3, 3):
- compatible = False
- elif not hasattr(sys, 'base_prefix'):
- compatible = False
- if not compatible:
- raise ValueError('This script is only for use with '
- 'Python 3.3 (pythonv variant)')
- else:
- import argparse
-
- parser = argparse.ArgumentParser(prog=__name__,
- description='Creates virtual Python '
- 'environments in one or '
- 'more target '
- 'directories.')
- parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
- help='A directory to create the environment in.')
- parser.add_argument('--system-site-packages', default=False,
- action='store_true', dest='system_site',
- help='Give the virtual environment access to the '
- 'system site-packages dir.')
- if os.name == 'nt' or (sys.platform == 'darwin' and
- sysconfig.get_config_var('PYTHONFRAMEWORK')):
- use_symlinks = False
- else:
- use_symlinks = True
- parser.add_argument('--symlinks', default=use_symlinks,
- action='store_true', dest='symlinks',
- help="Attempt to symlink rather than copy.")
- parser.add_argument('--clear', default=False, action='store_true',
- dest='clear', help='Delete the environment '
- 'directory if it already '
- 'exists. If not specified and '
- 'the directory exists, an error'
- ' is raised.')
- parser.add_argument('--upgrade', default=False, action='store_true',
- dest='upgrade', help='Upgrade the environment '
- 'directory to use this version '
- 'of Python, assuming Python '
- 'has been upgraded in-place.')
- options = parser.parse_args(args)
- if options.upgrade and options.clear:
- raise ValueError('you cannot supply --upgrade and --clear together.')
- builder = EnvBuilder(system_site_packages=options.system_site,
- clear=options.clear, symlinks=options.symlinks,
- upgrade=options.upgrade)
- for d in options.dirs:
- builder.create(d)
-
-if __name__ == '__main__':
- rc = 1
- try:
- main()
- rc = 0
- except Exception as e:
- print('Error: %s' % e, file=sys.stderr)
- sys.exit(rc)
« no previous file with comments | « Lib/urllib/parse.py ('k') | Lib/venv/__main__.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7