blob: d29a9574bf6f4d51eeadfffcdf6b48a3af508c82 [file] [log] [blame]
Vinay Sajip7ded1f02012-05-26 03:45:29 +01001:mod:`venv` --- Creation of virtual environments
2================================================
3
4.. module:: venv
5 :synopsis: Creation of virtual environments.
6.. moduleauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
7.. sectionauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
8
9
10.. index:: pair: Environments; virtual
11
12.. versionadded:: 3.3
13
Ned Deily38861202013-06-11 14:38:39 -070014**Source code:** :source:`Lib/venv`
Vinay Sajip7ded1f02012-05-26 03:45:29 +010015
16--------------
17
Georg Brandldbab58f2012-06-24 16:37:59 +020018The :mod:`venv` module provides support for creating lightweight "virtual
19environments" with their own site directories, optionally isolated from system
20site directories. Each virtual environment has its own Python binary (allowing
21creation of environments with various Python versions) and can have its own
22independent set of installed Python packages in its site directories.
23
Vinay Sajipa7045822013-09-06 09:50:43 +010024See :pep:`405` for more information about Python virtual environments.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010025
26Creating virtual environments
27-----------------------------
28
Vinay Sajipc4618e32012-07-10 08:21:07 +010029.. include:: /using/venv-create.inc
Vinay Sajip7ded1f02012-05-26 03:45:29 +010030
Vinay Sajipa945ad12012-07-09 09:24:59 +010031
Vinay Sajipcd9b7462012-07-09 10:37:01 +010032.. _venv-def:
33
Vinay Sajipa945ad12012-07-09 09:24:59 +010034.. note:: A virtual environment (also called a ``venv``) is a Python
35 environment such that the Python interpreter, libraries and scripts
36 installed into it are isolated from those installed in other virtual
37 environments, and (by default) any libraries installed in a "system" Python,
38 i.e. one which is installed as part of your operating system.
39
40 A venv is a directory tree which contains Python executable files and
41 other files which indicate that it is a venv.
42
Vinay Sajipc4618e32012-07-10 08:21:07 +010043 Common installation tools such as ``Distribute`` and ``pip`` work as
Vinay Sajipa945ad12012-07-09 09:24:59 +010044 expected with venvs - i.e. when a venv is active, they install Python
45 packages into the venv without needing to be told to do so explicitly.
Vinay Sajipc4618e32012-07-10 08:21:07 +010046 Of course, you need to install them into the venv first: this could be
47 done by running ``distribute_setup.py`` with the venv activated,
48 followed by running ``easy_install pip``. Alternatively, you could download
49 the source tarballs and run ``python setup.py install`` after unpacking,
50 with the venv activated.
Vinay Sajipa945ad12012-07-09 09:24:59 +010051
52 When a venv is active (i.e. the venv's Python interpreter is running), the
53 attributes :attr:`sys.prefix` and :attr:`sys.exec_prefix` point to the base
54 directory of the venv, whereas :attr:`sys.base_prefix` and
55 :attr:`sys.base_exec_prefix` point to the non-venv Python installation
56 which was used to create the venv. If a venv is not active, then
57 :attr:`sys.prefix` is the same as :attr:`sys.base_prefix` and
58 :attr:`sys.exec_prefix` is the same as :attr:`sys.base_exec_prefix` (they
59 all point to a non-venv Python installation).
60
Georg Brandl521ed522013-05-12 12:36:07 +020061 When a venv is active, any options that change the installation path will be
62 ignored from all distutils configuration files to prevent projects being
63 inadvertently installed outside of the virtual environment.
64
Vinay Sajipa7045822013-09-06 09:50:43 +010065 When working in a command shell, users can make a venv active by running an
66 ``activate`` script in the venv's executables directory (the precise filename
67 is shell-dependent), which prepends the venv's directory for executables to
68 the ``PATH`` environment variable for the running shell. There should be no
69 need in other circumstances to activate a venv -- scripts installed into
70 venvs have a shebang line which points to the venv's Python interpreter. This
71 means that the script will run with that interpreter regardless of the value
72 of ``PATH``. On Windows, shebang line processing is supported if you have the
73 Python Launcher for Windows installed (this was added to Python in 3.3 - see
74 :pep:`397` for more details). Thus, double-clicking an installed script in
75 a Windows Explorer window should run the script with the correct interpreter
76 without there needing to be any reference to its venv in ``PATH``.
77
Vinay Sajip7ded1f02012-05-26 03:45:29 +010078
79API
80---
81
Vinay Sajip7ded1f02012-05-26 03:45:29 +010082.. highlight:: python
83
Georg Brandldbab58f2012-06-24 16:37:59 +020084The high-level method described above makes use of a simple API which provides
85mechanisms for third-party virtual environment creators to customize environment
86creation according to their needs, the :class:`EnvBuilder` class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010087
Nick Coghlan8fbdb092013-11-23 00:30:34 +100088.. class:: EnvBuilder(system_site_packages=False, clear=False, \
89 symlinks=False, upgrade=False, with_pip=False)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010090
Georg Brandldbab58f2012-06-24 16:37:59 +020091 The :class:`EnvBuilder` class accepts the following keyword arguments on
92 instantiation:
Vinay Sajip7ded1f02012-05-26 03:45:29 +010093
Georg Brandldbab58f2012-06-24 16:37:59 +020094 * ``system_site_packages`` -- a Boolean value indicating that the system Python
95 site-packages should be available to the environment (defaults to ``False``).
Vinay Sajip7ded1f02012-05-26 03:45:29 +010096
Serhiy Storchaka0e90e992013-11-29 12:19:53 +020097 * ``clear`` -- a Boolean value which, if true, will delete the contents of
Vinay Sajipbd40d3e2012-10-11 17:22:45 +010098 any existing target directory, before creating the environment.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010099
Georg Brandldbab58f2012-06-24 16:37:59 +0200100 * ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
101 Python binary (and any necessary DLLs or other binaries,
102 e.g. ``pythonw.exe``), rather than copying. Defaults to ``True`` on Linux and
Vinay Sajip90db6612012-07-17 17:33:46 +0100103 Unix systems, but ``False`` on Windows.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100104
Serhiy Storchakafbc1c262013-11-29 12:17:13 +0200105 * ``upgrade`` -- a Boolean value which, if true, will upgrade an existing
Vinay Sajipa945ad12012-07-09 09:24:59 +0100106 environment with the running Python - for use when that Python has been
107 upgraded in-place (defaults to ``False``).
108
Serhiy Storchaka0e90e992013-11-29 12:19:53 +0200109 * ``with_pip`` -- a Boolean value which, if true, ensures pip is
Nick Coghlanaa029da2014-02-09 10:10:24 +1000110 installed in the virtual environment. This uses :mod:`ensurepip` with
111 the ``--default-pip`` option.
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000112
113 .. versionchanged:: 3.4
114 Added the ``with_pip`` parameter
115
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100116
Georg Brandldbab58f2012-06-24 16:37:59 +0200117 Creators of third-party virtual environment tools will be free to use the
118 provided ``EnvBuilder`` class as a base class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100119
Georg Brandldbab58f2012-06-24 16:37:59 +0200120 The returned env-builder is an object which has a method, ``create``:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100121
Georg Brandldbab58f2012-06-24 16:37:59 +0200122 .. method:: create(env_dir)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100123
Georg Brandldbab58f2012-06-24 16:37:59 +0200124 This method takes as required argument the path (absolute or relative to
125 the current directory) of the target directory which is to contain the
126 virtual environment. The ``create`` method will either create the
127 environment in the specified directory, or raise an appropriate
128 exception.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100129
Georg Brandldbab58f2012-06-24 16:37:59 +0200130 The ``create`` method of the ``EnvBuilder`` class illustrates the hooks
131 available for subclass customization::
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100132
Georg Brandldbab58f2012-06-24 16:37:59 +0200133 def create(self, env_dir):
134 """
135 Create a virtualized Python environment in a directory.
136 env_dir is the target directory to create an environment in.
137 """
138 env_dir = os.path.abspath(env_dir)
Georg Brandla0b79232013-10-06 12:52:49 +0200139 context = self.ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200140 self.create_configuration(context)
141 self.setup_python(context)
142 self.setup_scripts(context)
143 self.post_setup(context)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100144
Georg Brandla0b79232013-10-06 12:52:49 +0200145 Each of the methods :meth:`ensure_directories`,
Georg Brandldbab58f2012-06-24 16:37:59 +0200146 :meth:`create_configuration`, :meth:`setup_python`,
147 :meth:`setup_scripts` and :meth:`post_setup` can be overridden.
148
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100149 .. method:: ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200150
151 Creates the environment directory and all necessary directories, and
152 returns a context object. This is just a holder for attributes (such as
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100153 paths), for use by the other methods. The directories are allowed to
154 exist already, as long as either ``clear`` or ``upgrade`` were
155 specified to allow operating on an existing environment directory.
Georg Brandldbab58f2012-06-24 16:37:59 +0200156
157 .. method:: create_configuration(context)
158
159 Creates the ``pyvenv.cfg`` configuration file in the environment.
160
161 .. method:: setup_python(context)
162
163 Creates a copy of the Python executable (and, under Windows, DLLs) in
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100164 the environment. On a POSIX system, if a specific executable
165 ``python3.x`` was used, symlinks to ``python`` and ``python3`` will be
166 created pointing to that executable, unless files with those names
167 already exist.
Georg Brandldbab58f2012-06-24 16:37:59 +0200168
169 .. method:: setup_scripts(context)
170
171 Installs activation scripts appropriate to the platform into the virtual
172 environment.
173
174 .. method:: post_setup(context)
175
176 A placeholder method which can be overridden in third party
177 implementations to pre-install packages in the virtual environment or
178 perform other post-creation steps.
179
180 In addition, :class:`EnvBuilder` provides this utility method that can be
181 called from :meth:`setup_scripts` or :meth:`post_setup` in subclasses to
182 assist in installing custom scripts into the virtual environment.
183
184 .. method:: install_scripts(context, path)
185
186 *path* is the path to a directory that should contain subdirectories
187 "common", "posix", "nt", each containing scripts destined for the bin
188 directory in the environment. The contents of "common" and the
189 directory corresponding to :data:`os.name` are copied after some text
190 replacement of placeholders:
191
192 * ``__VENV_DIR__`` is replaced with the absolute path of the environment
193 directory.
194
195 * ``__VENV_NAME__`` is replaced with the environment name (final path
196 segment of environment directory).
197
Vinay Sajipdff9e252013-10-02 11:36:16 +0100198 * ``__VENV_PROMPT__`` is replaced with the prompt (the environment
199 name surrounded by parentheses and with a following space)
200
Georg Brandldbab58f2012-06-24 16:37:59 +0200201 * ``__VENV_BIN_NAME__`` is replaced with the name of the bin directory
202 (either ``bin`` or ``Scripts``).
203
204 * ``__VENV_PYTHON__`` is replaced with the absolute path of the
205 environment's executable.
206
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100207 The directories are allowed to exist (for when an existing environment
208 is being upgraded).
Georg Brandldbab58f2012-06-24 16:37:59 +0200209
210There is also a module-level convenience function:
211
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000212.. function:: create(env_dir, system_site_packages=False, clear=False, \
213 symlinks=False, with_pip=False)
Georg Brandldbab58f2012-06-24 16:37:59 +0200214
215 Create an :class:`EnvBuilder` with the given keyword arguments, and call its
216 :meth:`~EnvBuilder.create` method with the *env_dir* argument.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000217
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000218 .. versionchanged:: 3.4
219 Added the ``with_pip`` parameter
220
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000221An example of extending ``EnvBuilder``
222--------------------------------------
223
224The following script shows how to extend :class:`EnvBuilder` by implementing a
Vinay Sajip3c557f22013-07-12 20:54:25 +0100225subclass which installs setuptools and pip into a created venv::
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000226
227 import os
228 import os.path
229 from subprocess import Popen, PIPE
230 import sys
231 from threading import Thread
232 from urllib.parse import urlparse
233 from urllib.request import urlretrieve
234 import venv
235
Vinay Sajip3c557f22013-07-12 20:54:25 +0100236 class ExtendedEnvBuilder(venv.EnvBuilder):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000237 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100238 This builder installs setuptools and pip so that you can pip or
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000239 easy_install other packages into the created environment.
240
Vinay Sajip3c557f22013-07-12 20:54:25 +0100241 :param nodist: If True, setuptools and pip are not installed into the
242 created environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000243 :param nopip: If True, pip is not installed into the created
244 environment.
Vinay Sajip3c557f22013-07-12 20:54:25 +0100245 :param progress: If setuptools or pip are installed, the progress of the
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000246 installation can be monitored by passing a progress
247 callable. If specified, it is called with two
248 arguments: a string indicating some progress, and a
249 context indicating where the string is coming from.
250 The context argument can have one of three values:
251 'main', indicating that it is called from virtualize()
252 itself, and 'stdout' and 'stderr', which are obtained
253 by reading lines from the output streams of a subprocess
254 which is used to install the app.
255
256 If a callable is not specified, default progress
257 information is output to sys.stderr.
258 """
259
260 def __init__(self, *args, **kwargs):
261 self.nodist = kwargs.pop('nodist', False)
262 self.nopip = kwargs.pop('nopip', False)
263 self.progress = kwargs.pop('progress', None)
264 self.verbose = kwargs.pop('verbose', False)
265 super().__init__(*args, **kwargs)
266
267 def post_setup(self, context):
268 """
269 Set up any packages which need to be pre-installed into the
270 environment being created.
271
272 :param context: The information for the environment creation request
273 being processed.
274 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100275 os.environ['VIRTUAL_ENV'] = context.env_dir
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000276 if not self.nodist:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100277 self.install_setuptools(context)
278 # Can't install pip without setuptools
279 if not self.nopip and not self.nodist:
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000280 self.install_pip(context)
281
282 def reader(self, stream, context):
283 """
284 Read lines from a subprocess' output stream and either pass to a progress
285 callable (if specified) or write progress information to sys.stderr.
286 """
287 progress = self.progress
288 while True:
289 s = stream.readline()
290 if not s:
291 break
292 if progress is not None:
293 progress(s, context)
294 else:
295 if not self.verbose:
296 sys.stderr.write('.')
297 else:
298 sys.stderr.write(s.decode('utf-8'))
299 sys.stderr.flush()
Vinay Sajipad6bb032013-07-12 21:44:35 +0100300 stream.close()
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000301
302 def install_script(self, context, name, url):
303 _, _, path, _, _, _ = urlparse(url)
304 fn = os.path.split(path)[-1]
305 binpath = context.bin_path
306 distpath = os.path.join(binpath, fn)
307 # Download script into the env's binaries folder
308 urlretrieve(url, distpath)
309 progress = self.progress
Vinay Sajip3c557f22013-07-12 20:54:25 +0100310 if self.verbose:
311 term = '\n'
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000312 else:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100313 term = ''
314 if progress is not None:
315 progress('Installing %s ...%s' % (name, term), 'main')
316 else:
317 sys.stderr.write('Installing %s ...%s' % (name, term))
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000318 sys.stderr.flush()
319 # Install in the env
320 args = [context.env_exe, fn]
321 p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
322 t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
323 t1.start()
324 t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
325 t2.start()
326 p.wait()
327 t1.join()
328 t2.join()
329 if progress is not None:
330 progress('done.', 'main')
331 else:
332 sys.stderr.write('done.\n')
333 # Clean up - no longer needed
334 os.unlink(distpath)
335
Vinay Sajip3c557f22013-07-12 20:54:25 +0100336 def install_setuptools(self, context):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000337 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100338 Install setuptools in the environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000339
340 :param context: The information for the environment creation request
341 being processed.
342 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100343 url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
344 self.install_script(context, 'setuptools', url)
345 # clear up the setuptools archive which gets downloaded
346 pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000347 files = filter(pred, os.listdir(context.bin_path))
348 for f in files:
349 f = os.path.join(context.bin_path, f)
350 os.unlink(f)
351
352 def install_pip(self, context):
353 """
354 Install pip in the environment.
355
356 :param context: The information for the environment creation request
357 being processed.
358 """
359 url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
360 self.install_script(context, 'pip', url)
361
362 def main(args=None):
363 compatible = True
364 if sys.version_info < (3, 3):
365 compatible = False
366 elif not hasattr(sys, 'base_prefix'):
367 compatible = False
368 if not compatible:
369 raise ValueError('This script is only for use with '
370 'Python 3.3 or later')
371 else:
372 import argparse
373
374 parser = argparse.ArgumentParser(prog=__name__,
375 description='Creates virtual Python '
376 'environments in one or '
377 'more target '
378 'directories.')
379 parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
380 help='A directory to create the environment in.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100381 parser.add_argument('--no-setuptools', default=False,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000382 action='store_true', dest='nodist',
Vinay Sajip3c557f22013-07-12 20:54:25 +0100383 help="Don't install setuptools or pip in the "
384 "virtual environment.")
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000385 parser.add_argument('--no-pip', default=False,
386 action='store_true', dest='nopip',
387 help="Don't install pip in the virtual "
388 "environment.")
389 parser.add_argument('--system-site-packages', default=False,
390 action='store_true', dest='system_site',
391 help='Give the virtual environment access to the '
392 'system site-packages dir.')
393 if os.name == 'nt':
394 use_symlinks = False
395 else:
396 use_symlinks = True
397 parser.add_argument('--symlinks', default=use_symlinks,
398 action='store_true', dest='symlinks',
399 help='Try to use symlinks rather than copies, '
400 'when symlinks are not the default for '
401 'the platform.')
402 parser.add_argument('--clear', default=False, action='store_true',
403 dest='clear', help='Delete the contents of the '
404 'environment directory if it '
405 'already exists, before '
406 'environment creation.')
407 parser.add_argument('--upgrade', default=False, action='store_true',
408 dest='upgrade', help='Upgrade the environment '
409 'directory to use this version '
410 'of Python, assuming Python '
411 'has been upgraded in-place.')
412 parser.add_argument('--verbose', default=False, action='store_true',
413 dest='verbose', help='Display the output '
414 'from the scripts which '
Vinay Sajip3c557f22013-07-12 20:54:25 +0100415 'install setuptools and pip.')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000416 options = parser.parse_args(args)
417 if options.upgrade and options.clear:
418 raise ValueError('you cannot supply --upgrade and --clear together.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100419 builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000420 clear=options.clear,
421 symlinks=options.symlinks,
422 upgrade=options.upgrade,
423 nodist=options.nodist,
424 nopip=options.nopip,
425 verbose=options.verbose)
426 for d in options.dirs:
427 builder.create(d)
428
429 if __name__ == '__main__':
430 rc = 1
431 try:
432 main()
433 rc = 0
434 except Exception as e:
435 print('Error: %s' % e, file=sys.stderr)
436 sys.exit(rc)
437
Vinay Sajip3c557f22013-07-12 20:54:25 +0100438
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000439This script is also available for download `online
440<https://gist.github.com/4673395>`_.