blob: af4a6d1ab409400026207252d41acab808fc8fdf [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.
Terry Jan Reedyfa089b92016-06-11 15:02:54 -04006
Vinay Sajip7ded1f02012-05-26 03:45:29 +01007.. moduleauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
8.. sectionauthor:: Vinay Sajip <vinay_sajip@yahoo.co.uk>
9
Vinay Sajip7ded1f02012-05-26 03:45:29 +010010.. versionadded:: 3.3
11
Terry Jan Reedyfa089b92016-06-11 15:02:54 -040012**Source code:** :source:`Lib/venv/`
13
14.. index:: pair: Environments; virtual
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
Jason R. Coombs13266fb2014-05-12 22:40:49 -040043 Common installation tools such as ``Setuptools`` 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.
46
47 When a venv is active (i.e. the venv's Python interpreter is running), the
48 attributes :attr:`sys.prefix` and :attr:`sys.exec_prefix` point to the base
49 directory of the venv, whereas :attr:`sys.base_prefix` and
50 :attr:`sys.base_exec_prefix` point to the non-venv Python installation
51 which was used to create the venv. If a venv is not active, then
52 :attr:`sys.prefix` is the same as :attr:`sys.base_prefix` and
53 :attr:`sys.exec_prefix` is the same as :attr:`sys.base_exec_prefix` (they
54 all point to a non-venv Python installation).
55
Georg Brandl521ed522013-05-12 12:36:07 +020056 When a venv is active, any options that change the installation path will be
57 ignored from all distutils configuration files to prevent projects being
58 inadvertently installed outside of the virtual environment.
59
Vinay Sajipa7045822013-09-06 09:50:43 +010060 When working in a command shell, users can make a venv active by running an
61 ``activate`` script in the venv's executables directory (the precise filename
62 is shell-dependent), which prepends the venv's directory for executables to
63 the ``PATH`` environment variable for the running shell. There should be no
64 need in other circumstances to activate a venv -- scripts installed into
65 venvs have a shebang line which points to the venv's Python interpreter. This
66 means that the script will run with that interpreter regardless of the value
67 of ``PATH``. On Windows, shebang line processing is supported if you have the
68 Python Launcher for Windows installed (this was added to Python in 3.3 - see
69 :pep:`397` for more details). Thus, double-clicking an installed script in
70 a Windows Explorer window should run the script with the correct interpreter
71 without there needing to be any reference to its venv in ``PATH``.
72
Vinay Sajip7ded1f02012-05-26 03:45:29 +010073
Larry Hastings3732ed22014-03-15 21:13:56 -070074.. _venv-api:
75
Vinay Sajip7ded1f02012-05-26 03:45:29 +010076API
77---
78
Vinay Sajip7ded1f02012-05-26 03:45:29 +010079.. highlight:: python
80
Georg Brandldbab58f2012-06-24 16:37:59 +020081The high-level method described above makes use of a simple API which provides
82mechanisms for third-party virtual environment creators to customize environment
83creation according to their needs, the :class:`EnvBuilder` class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010084
Nick Coghlan8fbdb092013-11-23 00:30:34 +100085.. class:: EnvBuilder(system_site_packages=False, clear=False, \
86 symlinks=False, upgrade=False, with_pip=False)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010087
Georg Brandldbab58f2012-06-24 16:37:59 +020088 The :class:`EnvBuilder` class accepts the following keyword arguments on
89 instantiation:
Vinay Sajip7ded1f02012-05-26 03:45:29 +010090
Georg Brandldbab58f2012-06-24 16:37:59 +020091 * ``system_site_packages`` -- a Boolean value indicating that the system Python
92 site-packages should be available to the environment (defaults to ``False``).
Vinay Sajip7ded1f02012-05-26 03:45:29 +010093
Serhiy Storchaka0e90e992013-11-29 12:19:53 +020094 * ``clear`` -- a Boolean value which, if true, will delete the contents of
Vinay Sajipbd40d3e2012-10-11 17:22:45 +010095 any existing target directory, before creating the environment.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010096
Georg Brandldbab58f2012-06-24 16:37:59 +020097 * ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
98 Python binary (and any necessary DLLs or other binaries,
99 e.g. ``pythonw.exe``), rather than copying. Defaults to ``True`` on Linux and
Vinay Sajip90db6612012-07-17 17:33:46 +0100100 Unix systems, but ``False`` on Windows.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100101
Serhiy Storchakafbc1c262013-11-29 12:17:13 +0200102 * ``upgrade`` -- a Boolean value which, if true, will upgrade an existing
Vinay Sajipa945ad12012-07-09 09:24:59 +0100103 environment with the running Python - for use when that Python has been
104 upgraded in-place (defaults to ``False``).
105
Serhiy Storchaka0e90e992013-11-29 12:19:53 +0200106 * ``with_pip`` -- a Boolean value which, if true, ensures pip is
Nick Coghlanaa029da2014-02-09 10:10:24 +1000107 installed in the virtual environment. This uses :mod:`ensurepip` with
108 the ``--default-pip`` option.
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000109
110 .. versionchanged:: 3.4
111 Added the ``with_pip`` parameter
112
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100113
Georg Brandldbab58f2012-06-24 16:37:59 +0200114 Creators of third-party virtual environment tools will be free to use the
115 provided ``EnvBuilder`` class as a base class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100116
Georg Brandldbab58f2012-06-24 16:37:59 +0200117 The returned env-builder is an object which has a method, ``create``:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100118
Georg Brandldbab58f2012-06-24 16:37:59 +0200119 .. method:: create(env_dir)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100120
Georg Brandldbab58f2012-06-24 16:37:59 +0200121 This method takes as required argument the path (absolute or relative to
122 the current directory) of the target directory which is to contain the
123 virtual environment. The ``create`` method will either create the
124 environment in the specified directory, or raise an appropriate
125 exception.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100126
Georg Brandldbab58f2012-06-24 16:37:59 +0200127 The ``create`` method of the ``EnvBuilder`` class illustrates the hooks
128 available for subclass customization::
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100129
Georg Brandldbab58f2012-06-24 16:37:59 +0200130 def create(self, env_dir):
131 """
132 Create a virtualized Python environment in a directory.
133 env_dir is the target directory to create an environment in.
134 """
135 env_dir = os.path.abspath(env_dir)
Georg Brandla0b79232013-10-06 12:52:49 +0200136 context = self.ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200137 self.create_configuration(context)
138 self.setup_python(context)
139 self.setup_scripts(context)
140 self.post_setup(context)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100141
Georg Brandla0b79232013-10-06 12:52:49 +0200142 Each of the methods :meth:`ensure_directories`,
Georg Brandldbab58f2012-06-24 16:37:59 +0200143 :meth:`create_configuration`, :meth:`setup_python`,
144 :meth:`setup_scripts` and :meth:`post_setup` can be overridden.
145
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100146 .. method:: ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200147
148 Creates the environment directory and all necessary directories, and
149 returns a context object. This is just a holder for attributes (such as
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100150 paths), for use by the other methods. The directories are allowed to
151 exist already, as long as either ``clear`` or ``upgrade`` were
152 specified to allow operating on an existing environment directory.
Georg Brandldbab58f2012-06-24 16:37:59 +0200153
154 .. method:: create_configuration(context)
155
156 Creates the ``pyvenv.cfg`` configuration file in the environment.
157
158 .. method:: setup_python(context)
159
160 Creates a copy of the Python executable (and, under Windows, DLLs) in
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100161 the environment. On a POSIX system, if a specific executable
162 ``python3.x`` was used, symlinks to ``python`` and ``python3`` will be
163 created pointing to that executable, unless files with those names
164 already exist.
Georg Brandldbab58f2012-06-24 16:37:59 +0200165
166 .. method:: setup_scripts(context)
167
168 Installs activation scripts appropriate to the platform into the virtual
169 environment.
170
171 .. method:: post_setup(context)
172
173 A placeholder method which can be overridden in third party
174 implementations to pre-install packages in the virtual environment or
175 perform other post-creation steps.
176
177 In addition, :class:`EnvBuilder` provides this utility method that can be
178 called from :meth:`setup_scripts` or :meth:`post_setup` in subclasses to
179 assist in installing custom scripts into the virtual environment.
180
181 .. method:: install_scripts(context, path)
182
183 *path* is the path to a directory that should contain subdirectories
184 "common", "posix", "nt", each containing scripts destined for the bin
185 directory in the environment. The contents of "common" and the
186 directory corresponding to :data:`os.name` are copied after some text
187 replacement of placeholders:
188
189 * ``__VENV_DIR__`` is replaced with the absolute path of the environment
190 directory.
191
192 * ``__VENV_NAME__`` is replaced with the environment name (final path
193 segment of environment directory).
194
Vinay Sajipdff9e252013-10-02 11:36:16 +0100195 * ``__VENV_PROMPT__`` is replaced with the prompt (the environment
196 name surrounded by parentheses and with a following space)
197
Georg Brandldbab58f2012-06-24 16:37:59 +0200198 * ``__VENV_BIN_NAME__`` is replaced with the name of the bin directory
199 (either ``bin`` or ``Scripts``).
200
201 * ``__VENV_PYTHON__`` is replaced with the absolute path of the
202 environment's executable.
203
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100204 The directories are allowed to exist (for when an existing environment
205 is being upgraded).
Georg Brandldbab58f2012-06-24 16:37:59 +0200206
207There is also a module-level convenience function:
208
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000209.. function:: create(env_dir, system_site_packages=False, clear=False, \
210 symlinks=False, with_pip=False)
Georg Brandldbab58f2012-06-24 16:37:59 +0200211
212 Create an :class:`EnvBuilder` with the given keyword arguments, and call its
213 :meth:`~EnvBuilder.create` method with the *env_dir* argument.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000214
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000215 .. versionchanged:: 3.4
216 Added the ``with_pip`` parameter
217
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000218An example of extending ``EnvBuilder``
219--------------------------------------
220
221The following script shows how to extend :class:`EnvBuilder` by implementing a
Vinay Sajip3c557f22013-07-12 20:54:25 +0100222subclass which installs setuptools and pip into a created venv::
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000223
224 import os
225 import os.path
226 from subprocess import Popen, PIPE
227 import sys
228 from threading import Thread
229 from urllib.parse import urlparse
230 from urllib.request import urlretrieve
231 import venv
232
Vinay Sajip3c557f22013-07-12 20:54:25 +0100233 class ExtendedEnvBuilder(venv.EnvBuilder):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000234 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100235 This builder installs setuptools and pip so that you can pip or
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000236 easy_install other packages into the created environment.
237
Vinay Sajip3c557f22013-07-12 20:54:25 +0100238 :param nodist: If True, setuptools and pip are not installed into the
239 created environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000240 :param nopip: If True, pip is not installed into the created
241 environment.
Vinay Sajip3c557f22013-07-12 20:54:25 +0100242 :param progress: If setuptools or pip are installed, the progress of the
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000243 installation can be monitored by passing a progress
244 callable. If specified, it is called with two
245 arguments: a string indicating some progress, and a
246 context indicating where the string is coming from.
247 The context argument can have one of three values:
248 'main', indicating that it is called from virtualize()
249 itself, and 'stdout' and 'stderr', which are obtained
250 by reading lines from the output streams of a subprocess
251 which is used to install the app.
252
253 If a callable is not specified, default progress
254 information is output to sys.stderr.
255 """
256
257 def __init__(self, *args, **kwargs):
258 self.nodist = kwargs.pop('nodist', False)
259 self.nopip = kwargs.pop('nopip', False)
260 self.progress = kwargs.pop('progress', None)
261 self.verbose = kwargs.pop('verbose', False)
262 super().__init__(*args, **kwargs)
263
264 def post_setup(self, context):
265 """
266 Set up any packages which need to be pre-installed into the
267 environment being created.
268
269 :param context: The information for the environment creation request
270 being processed.
271 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100272 os.environ['VIRTUAL_ENV'] = context.env_dir
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000273 if not self.nodist:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100274 self.install_setuptools(context)
275 # Can't install pip without setuptools
276 if not self.nopip and not self.nodist:
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000277 self.install_pip(context)
278
279 def reader(self, stream, context):
280 """
281 Read lines from a subprocess' output stream and either pass to a progress
282 callable (if specified) or write progress information to sys.stderr.
283 """
284 progress = self.progress
285 while True:
286 s = stream.readline()
287 if not s:
288 break
289 if progress is not None:
290 progress(s, context)
291 else:
292 if not self.verbose:
293 sys.stderr.write('.')
294 else:
295 sys.stderr.write(s.decode('utf-8'))
296 sys.stderr.flush()
Vinay Sajipad6bb032013-07-12 21:44:35 +0100297 stream.close()
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000298
299 def install_script(self, context, name, url):
300 _, _, path, _, _, _ = urlparse(url)
301 fn = os.path.split(path)[-1]
302 binpath = context.bin_path
303 distpath = os.path.join(binpath, fn)
304 # Download script into the env's binaries folder
305 urlretrieve(url, distpath)
306 progress = self.progress
Vinay Sajip3c557f22013-07-12 20:54:25 +0100307 if self.verbose:
308 term = '\n'
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000309 else:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100310 term = ''
311 if progress is not None:
312 progress('Installing %s ...%s' % (name, term), 'main')
313 else:
314 sys.stderr.write('Installing %s ...%s' % (name, term))
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000315 sys.stderr.flush()
316 # Install in the env
317 args = [context.env_exe, fn]
318 p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
319 t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
320 t1.start()
321 t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
322 t2.start()
323 p.wait()
324 t1.join()
325 t2.join()
326 if progress is not None:
327 progress('done.', 'main')
328 else:
329 sys.stderr.write('done.\n')
330 # Clean up - no longer needed
331 os.unlink(distpath)
332
Vinay Sajip3c557f22013-07-12 20:54:25 +0100333 def install_setuptools(self, context):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000334 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100335 Install setuptools in the environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000336
337 :param context: The information for the environment creation request
338 being processed.
339 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100340 url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
341 self.install_script(context, 'setuptools', url)
342 # clear up the setuptools archive which gets downloaded
343 pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000344 files = filter(pred, os.listdir(context.bin_path))
345 for f in files:
346 f = os.path.join(context.bin_path, f)
347 os.unlink(f)
348
349 def install_pip(self, context):
350 """
351 Install pip in the environment.
352
353 :param context: The information for the environment creation request
354 being processed.
355 """
356 url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
357 self.install_script(context, 'pip', url)
358
359 def main(args=None):
360 compatible = True
361 if sys.version_info < (3, 3):
362 compatible = False
363 elif not hasattr(sys, 'base_prefix'):
364 compatible = False
365 if not compatible:
366 raise ValueError('This script is only for use with '
367 'Python 3.3 or later')
368 else:
369 import argparse
370
371 parser = argparse.ArgumentParser(prog=__name__,
372 description='Creates virtual Python '
373 'environments in one or '
374 'more target '
375 'directories.')
376 parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
377 help='A directory to create the environment in.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100378 parser.add_argument('--no-setuptools', default=False,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000379 action='store_true', dest='nodist',
Vinay Sajip3c557f22013-07-12 20:54:25 +0100380 help="Don't install setuptools or pip in the "
381 "virtual environment.")
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000382 parser.add_argument('--no-pip', default=False,
383 action='store_true', dest='nopip',
384 help="Don't install pip in the virtual "
385 "environment.")
386 parser.add_argument('--system-site-packages', default=False,
387 action='store_true', dest='system_site',
388 help='Give the virtual environment access to the '
389 'system site-packages dir.')
390 if os.name == 'nt':
391 use_symlinks = False
392 else:
393 use_symlinks = True
394 parser.add_argument('--symlinks', default=use_symlinks,
395 action='store_true', dest='symlinks',
396 help='Try to use symlinks rather than copies, '
397 'when symlinks are not the default for '
398 'the platform.')
399 parser.add_argument('--clear', default=False, action='store_true',
400 dest='clear', help='Delete the contents of the '
401 'environment directory if it '
402 'already exists, before '
403 'environment creation.')
404 parser.add_argument('--upgrade', default=False, action='store_true',
405 dest='upgrade', help='Upgrade the environment '
406 'directory to use this version '
407 'of Python, assuming Python '
408 'has been upgraded in-place.')
409 parser.add_argument('--verbose', default=False, action='store_true',
410 dest='verbose', help='Display the output '
411 'from the scripts which '
Vinay Sajip3c557f22013-07-12 20:54:25 +0100412 'install setuptools and pip.')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000413 options = parser.parse_args(args)
414 if options.upgrade and options.clear:
415 raise ValueError('you cannot supply --upgrade and --clear together.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100416 builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000417 clear=options.clear,
418 symlinks=options.symlinks,
419 upgrade=options.upgrade,
420 nodist=options.nodist,
421 nopip=options.nopip,
422 verbose=options.verbose)
423 for d in options.dirs:
424 builder.create(d)
425
426 if __name__ == '__main__':
427 rc = 1
428 try:
429 main()
430 rc = 0
431 except Exception as e:
432 print('Error: %s' % e, file=sys.stderr)
433 sys.exit(rc)
434
Vinay Sajip3c557f22013-07-12 20:54:25 +0100435
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000436This script is also available for download `online
437<https://gist.github.com/4673395>`_.