blob: e9ede8b415f993820fdcdfb0c6b7f1b7d2504abb [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
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.
Vinay Sajipc4618e32012-07-10 08:21:07 +010046 Of course, you need to install them into the venv first: this could be
Jason R. Coombs13266fb2014-05-12 22:40:49 -040047 done by running ``ez_setup.py`` with the venv activated,
Vinay Sajipc4618e32012-07-10 08:21:07 +010048 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
Larry Hastings3732ed22014-03-15 21:13:56 -070079.. _venv-api:
80
Vinay Sajip7ded1f02012-05-26 03:45:29 +010081API
82---
83
Vinay Sajip7ded1f02012-05-26 03:45:29 +010084.. highlight:: python
85
Georg Brandldbab58f2012-06-24 16:37:59 +020086The high-level method described above makes use of a simple API which provides
87mechanisms for third-party virtual environment creators to customize environment
88creation according to their needs, the :class:`EnvBuilder` class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010089
Nick Coghlan8fbdb092013-11-23 00:30:34 +100090.. class:: EnvBuilder(system_site_packages=False, clear=False, \
91 symlinks=False, upgrade=False, with_pip=False)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010092
Georg Brandldbab58f2012-06-24 16:37:59 +020093 The :class:`EnvBuilder` class accepts the following keyword arguments on
94 instantiation:
Vinay Sajip7ded1f02012-05-26 03:45:29 +010095
Georg Brandldbab58f2012-06-24 16:37:59 +020096 * ``system_site_packages`` -- a Boolean value indicating that the system Python
97 site-packages should be available to the environment (defaults to ``False``).
Vinay Sajip7ded1f02012-05-26 03:45:29 +010098
Serhiy Storchaka0e90e992013-11-29 12:19:53 +020099 * ``clear`` -- a Boolean value which, if true, will delete the contents of
Vinay Sajipbd40d3e2012-10-11 17:22:45 +0100100 any existing target directory, before creating the environment.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100101
Georg Brandldbab58f2012-06-24 16:37:59 +0200102 * ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
103 Python binary (and any necessary DLLs or other binaries,
104 e.g. ``pythonw.exe``), rather than copying. Defaults to ``True`` on Linux and
Vinay Sajip90db6612012-07-17 17:33:46 +0100105 Unix systems, but ``False`` on Windows.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100106
Serhiy Storchakafbc1c262013-11-29 12:17:13 +0200107 * ``upgrade`` -- a Boolean value which, if true, will upgrade an existing
Vinay Sajipa945ad12012-07-09 09:24:59 +0100108 environment with the running Python - for use when that Python has been
109 upgraded in-place (defaults to ``False``).
110
Serhiy Storchaka0e90e992013-11-29 12:19:53 +0200111 * ``with_pip`` -- a Boolean value which, if true, ensures pip is
Nick Coghlanaa029da2014-02-09 10:10:24 +1000112 installed in the virtual environment. This uses :mod:`ensurepip` with
113 the ``--default-pip`` option.
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000114
115 .. versionchanged:: 3.4
116 Added the ``with_pip`` parameter
117
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100118
Georg Brandldbab58f2012-06-24 16:37:59 +0200119 Creators of third-party virtual environment tools will be free to use the
120 provided ``EnvBuilder`` class as a base class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100121
Georg Brandldbab58f2012-06-24 16:37:59 +0200122 The returned env-builder is an object which has a method, ``create``:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100123
Georg Brandldbab58f2012-06-24 16:37:59 +0200124 .. method:: create(env_dir)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100125
Georg Brandldbab58f2012-06-24 16:37:59 +0200126 This method takes as required argument the path (absolute or relative to
127 the current directory) of the target directory which is to contain the
128 virtual environment. The ``create`` method will either create the
129 environment in the specified directory, or raise an appropriate
130 exception.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100131
Georg Brandldbab58f2012-06-24 16:37:59 +0200132 The ``create`` method of the ``EnvBuilder`` class illustrates the hooks
133 available for subclass customization::
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100134
Georg Brandldbab58f2012-06-24 16:37:59 +0200135 def create(self, env_dir):
136 """
137 Create a virtualized Python environment in a directory.
138 env_dir is the target directory to create an environment in.
139 """
140 env_dir = os.path.abspath(env_dir)
Georg Brandla0b79232013-10-06 12:52:49 +0200141 context = self.ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200142 self.create_configuration(context)
143 self.setup_python(context)
144 self.setup_scripts(context)
145 self.post_setup(context)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100146
Georg Brandla0b79232013-10-06 12:52:49 +0200147 Each of the methods :meth:`ensure_directories`,
Georg Brandldbab58f2012-06-24 16:37:59 +0200148 :meth:`create_configuration`, :meth:`setup_python`,
149 :meth:`setup_scripts` and :meth:`post_setup` can be overridden.
150
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100151 .. method:: ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200152
153 Creates the environment directory and all necessary directories, and
154 returns a context object. This is just a holder for attributes (such as
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100155 paths), for use by the other methods. The directories are allowed to
156 exist already, as long as either ``clear`` or ``upgrade`` were
157 specified to allow operating on an existing environment directory.
Georg Brandldbab58f2012-06-24 16:37:59 +0200158
159 .. method:: create_configuration(context)
160
161 Creates the ``pyvenv.cfg`` configuration file in the environment.
162
163 .. method:: setup_python(context)
164
165 Creates a copy of the Python executable (and, under Windows, DLLs) in
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100166 the environment. On a POSIX system, if a specific executable
167 ``python3.x`` was used, symlinks to ``python`` and ``python3`` will be
168 created pointing to that executable, unless files with those names
169 already exist.
Georg Brandldbab58f2012-06-24 16:37:59 +0200170
171 .. method:: setup_scripts(context)
172
173 Installs activation scripts appropriate to the platform into the virtual
174 environment.
175
176 .. method:: post_setup(context)
177
178 A placeholder method which can be overridden in third party
179 implementations to pre-install packages in the virtual environment or
180 perform other post-creation steps.
181
182 In addition, :class:`EnvBuilder` provides this utility method that can be
183 called from :meth:`setup_scripts` or :meth:`post_setup` in subclasses to
184 assist in installing custom scripts into the virtual environment.
185
186 .. method:: install_scripts(context, path)
187
188 *path* is the path to a directory that should contain subdirectories
189 "common", "posix", "nt", each containing scripts destined for the bin
190 directory in the environment. The contents of "common" and the
191 directory corresponding to :data:`os.name` are copied after some text
192 replacement of placeholders:
193
194 * ``__VENV_DIR__`` is replaced with the absolute path of the environment
195 directory.
196
197 * ``__VENV_NAME__`` is replaced with the environment name (final path
198 segment of environment directory).
199
Vinay Sajipdff9e252013-10-02 11:36:16 +0100200 * ``__VENV_PROMPT__`` is replaced with the prompt (the environment
201 name surrounded by parentheses and with a following space)
202
Georg Brandldbab58f2012-06-24 16:37:59 +0200203 * ``__VENV_BIN_NAME__`` is replaced with the name of the bin directory
204 (either ``bin`` or ``Scripts``).
205
206 * ``__VENV_PYTHON__`` is replaced with the absolute path of the
207 environment's executable.
208
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100209 The directories are allowed to exist (for when an existing environment
210 is being upgraded).
Georg Brandldbab58f2012-06-24 16:37:59 +0200211
212There is also a module-level convenience function:
213
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000214.. function:: create(env_dir, system_site_packages=False, clear=False, \
215 symlinks=False, with_pip=False)
Georg Brandldbab58f2012-06-24 16:37:59 +0200216
217 Create an :class:`EnvBuilder` with the given keyword arguments, and call its
218 :meth:`~EnvBuilder.create` method with the *env_dir* argument.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000219
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000220 .. versionchanged:: 3.4
221 Added the ``with_pip`` parameter
222
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000223An example of extending ``EnvBuilder``
224--------------------------------------
225
226The following script shows how to extend :class:`EnvBuilder` by implementing a
Vinay Sajip3c557f22013-07-12 20:54:25 +0100227subclass which installs setuptools and pip into a created venv::
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000228
229 import os
230 import os.path
231 from subprocess import Popen, PIPE
232 import sys
233 from threading import Thread
234 from urllib.parse import urlparse
235 from urllib.request import urlretrieve
236 import venv
237
Vinay Sajip3c557f22013-07-12 20:54:25 +0100238 class ExtendedEnvBuilder(venv.EnvBuilder):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000239 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100240 This builder installs setuptools and pip so that you can pip or
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000241 easy_install other packages into the created environment.
242
Vinay Sajip3c557f22013-07-12 20:54:25 +0100243 :param nodist: If True, setuptools and pip are not installed into the
244 created environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000245 :param nopip: If True, pip is not installed into the created
246 environment.
Vinay Sajip3c557f22013-07-12 20:54:25 +0100247 :param progress: If setuptools or pip are installed, the progress of the
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000248 installation can be monitored by passing a progress
249 callable. If specified, it is called with two
250 arguments: a string indicating some progress, and a
251 context indicating where the string is coming from.
252 The context argument can have one of three values:
253 'main', indicating that it is called from virtualize()
254 itself, and 'stdout' and 'stderr', which are obtained
255 by reading lines from the output streams of a subprocess
256 which is used to install the app.
257
258 If a callable is not specified, default progress
259 information is output to sys.stderr.
260 """
261
262 def __init__(self, *args, **kwargs):
263 self.nodist = kwargs.pop('nodist', False)
264 self.nopip = kwargs.pop('nopip', False)
265 self.progress = kwargs.pop('progress', None)
266 self.verbose = kwargs.pop('verbose', False)
267 super().__init__(*args, **kwargs)
268
269 def post_setup(self, context):
270 """
271 Set up any packages which need to be pre-installed into the
272 environment being created.
273
274 :param context: The information for the environment creation request
275 being processed.
276 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100277 os.environ['VIRTUAL_ENV'] = context.env_dir
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000278 if not self.nodist:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100279 self.install_setuptools(context)
280 # Can't install pip without setuptools
281 if not self.nopip and not self.nodist:
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000282 self.install_pip(context)
283
284 def reader(self, stream, context):
285 """
286 Read lines from a subprocess' output stream and either pass to a progress
287 callable (if specified) or write progress information to sys.stderr.
288 """
289 progress = self.progress
290 while True:
291 s = stream.readline()
292 if not s:
293 break
294 if progress is not None:
295 progress(s, context)
296 else:
297 if not self.verbose:
298 sys.stderr.write('.')
299 else:
300 sys.stderr.write(s.decode('utf-8'))
301 sys.stderr.flush()
Vinay Sajipad6bb032013-07-12 21:44:35 +0100302 stream.close()
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000303
304 def install_script(self, context, name, url):
305 _, _, path, _, _, _ = urlparse(url)
306 fn = os.path.split(path)[-1]
307 binpath = context.bin_path
308 distpath = os.path.join(binpath, fn)
309 # Download script into the env's binaries folder
310 urlretrieve(url, distpath)
311 progress = self.progress
Vinay Sajip3c557f22013-07-12 20:54:25 +0100312 if self.verbose:
313 term = '\n'
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000314 else:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100315 term = ''
316 if progress is not None:
317 progress('Installing %s ...%s' % (name, term), 'main')
318 else:
319 sys.stderr.write('Installing %s ...%s' % (name, term))
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000320 sys.stderr.flush()
321 # Install in the env
322 args = [context.env_exe, fn]
323 p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
324 t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
325 t1.start()
326 t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
327 t2.start()
328 p.wait()
329 t1.join()
330 t2.join()
331 if progress is not None:
332 progress('done.', 'main')
333 else:
334 sys.stderr.write('done.\n')
335 # Clean up - no longer needed
336 os.unlink(distpath)
337
Vinay Sajip3c557f22013-07-12 20:54:25 +0100338 def install_setuptools(self, context):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000339 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100340 Install setuptools in the environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000341
342 :param context: The information for the environment creation request
343 being processed.
344 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100345 url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
346 self.install_script(context, 'setuptools', url)
347 # clear up the setuptools archive which gets downloaded
348 pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000349 files = filter(pred, os.listdir(context.bin_path))
350 for f in files:
351 f = os.path.join(context.bin_path, f)
352 os.unlink(f)
353
354 def install_pip(self, context):
355 """
356 Install pip in the environment.
357
358 :param context: The information for the environment creation request
359 being processed.
360 """
361 url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
362 self.install_script(context, 'pip', url)
363
364 def main(args=None):
365 compatible = True
366 if sys.version_info < (3, 3):
367 compatible = False
368 elif not hasattr(sys, 'base_prefix'):
369 compatible = False
370 if not compatible:
371 raise ValueError('This script is only for use with '
372 'Python 3.3 or later')
373 else:
374 import argparse
375
376 parser = argparse.ArgumentParser(prog=__name__,
377 description='Creates virtual Python '
378 'environments in one or '
379 'more target '
380 'directories.')
381 parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
382 help='A directory to create the environment in.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100383 parser.add_argument('--no-setuptools', default=False,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000384 action='store_true', dest='nodist',
Vinay Sajip3c557f22013-07-12 20:54:25 +0100385 help="Don't install setuptools or pip in the "
386 "virtual environment.")
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000387 parser.add_argument('--no-pip', default=False,
388 action='store_true', dest='nopip',
389 help="Don't install pip in the virtual "
390 "environment.")
391 parser.add_argument('--system-site-packages', default=False,
392 action='store_true', dest='system_site',
393 help='Give the virtual environment access to the '
394 'system site-packages dir.')
395 if os.name == 'nt':
396 use_symlinks = False
397 else:
398 use_symlinks = True
399 parser.add_argument('--symlinks', default=use_symlinks,
400 action='store_true', dest='symlinks',
401 help='Try to use symlinks rather than copies, '
402 'when symlinks are not the default for '
403 'the platform.')
404 parser.add_argument('--clear', default=False, action='store_true',
405 dest='clear', help='Delete the contents of the '
406 'environment directory if it '
407 'already exists, before '
408 'environment creation.')
409 parser.add_argument('--upgrade', default=False, action='store_true',
410 dest='upgrade', help='Upgrade the environment '
411 'directory to use this version '
412 'of Python, assuming Python '
413 'has been upgraded in-place.')
414 parser.add_argument('--verbose', default=False, action='store_true',
415 dest='verbose', help='Display the output '
416 'from the scripts which '
Vinay Sajip3c557f22013-07-12 20:54:25 +0100417 'install setuptools and pip.')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000418 options = parser.parse_args(args)
419 if options.upgrade and options.clear:
420 raise ValueError('you cannot supply --upgrade and --clear together.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100421 builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000422 clear=options.clear,
423 symlinks=options.symlinks,
424 upgrade=options.upgrade,
425 nodist=options.nodist,
426 nopip=options.nopip,
427 verbose=options.verbose)
428 for d in options.dirs:
429 builder.create(d)
430
431 if __name__ == '__main__':
432 rc = 1
433 try:
434 main()
435 rc = 0
436 except Exception as e:
437 print('Error: %s' % e, file=sys.stderr)
438 sys.exit(rc)
439
Vinay Sajip3c557f22013-07-12 20:54:25 +0100440
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000441This script is also available for download `online
442<https://gist.github.com/4673395>`_.