blob: 461c9e170e472ba9665b791673085b092454d239 [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 Coghlan8fbdb092013-11-23 00:30:34 +1000110 installed in the virtual environment
111
112 .. versionchanged:: 3.4
113 Added the ``with_pip`` parameter
114
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100115
Georg Brandldbab58f2012-06-24 16:37:59 +0200116 Creators of third-party virtual environment tools will be free to use the
117 provided ``EnvBuilder`` class as a base class.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100118
Georg Brandldbab58f2012-06-24 16:37:59 +0200119 The returned env-builder is an object which has a method, ``create``:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100120
Georg Brandldbab58f2012-06-24 16:37:59 +0200121 .. method:: create(env_dir)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100122
Georg Brandldbab58f2012-06-24 16:37:59 +0200123 This method takes as required argument the path (absolute or relative to
124 the current directory) of the target directory which is to contain the
125 virtual environment. The ``create`` method will either create the
126 environment in the specified directory, or raise an appropriate
127 exception.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100128
Georg Brandldbab58f2012-06-24 16:37:59 +0200129 The ``create`` method of the ``EnvBuilder`` class illustrates the hooks
130 available for subclass customization::
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100131
Georg Brandldbab58f2012-06-24 16:37:59 +0200132 def create(self, env_dir):
133 """
134 Create a virtualized Python environment in a directory.
135 env_dir is the target directory to create an environment in.
136 """
137 env_dir = os.path.abspath(env_dir)
Georg Brandla0b79232013-10-06 12:52:49 +0200138 context = self.ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200139 self.create_configuration(context)
140 self.setup_python(context)
141 self.setup_scripts(context)
142 self.post_setup(context)
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100143
Georg Brandla0b79232013-10-06 12:52:49 +0200144 Each of the methods :meth:`ensure_directories`,
Georg Brandldbab58f2012-06-24 16:37:59 +0200145 :meth:`create_configuration`, :meth:`setup_python`,
146 :meth:`setup_scripts` and :meth:`post_setup` can be overridden.
147
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100148 .. method:: ensure_directories(env_dir)
Georg Brandldbab58f2012-06-24 16:37:59 +0200149
150 Creates the environment directory and all necessary directories, and
151 returns a context object. This is just a holder for attributes (such as
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100152 paths), for use by the other methods. The directories are allowed to
153 exist already, as long as either ``clear`` or ``upgrade`` were
154 specified to allow operating on an existing environment directory.
Georg Brandldbab58f2012-06-24 16:37:59 +0200155
156 .. method:: create_configuration(context)
157
158 Creates the ``pyvenv.cfg`` configuration file in the environment.
159
160 .. method:: setup_python(context)
161
162 Creates a copy of the Python executable (and, under Windows, DLLs) in
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100163 the environment. On a POSIX system, if a specific executable
164 ``python3.x`` was used, symlinks to ``python`` and ``python3`` will be
165 created pointing to that executable, unless files with those names
166 already exist.
Georg Brandldbab58f2012-06-24 16:37:59 +0200167
168 .. method:: setup_scripts(context)
169
170 Installs activation scripts appropriate to the platform into the virtual
171 environment.
172
173 .. method:: post_setup(context)
174
175 A placeholder method which can be overridden in third party
176 implementations to pre-install packages in the virtual environment or
177 perform other post-creation steps.
178
179 In addition, :class:`EnvBuilder` provides this utility method that can be
180 called from :meth:`setup_scripts` or :meth:`post_setup` in subclasses to
181 assist in installing custom scripts into the virtual environment.
182
183 .. method:: install_scripts(context, path)
184
185 *path* is the path to a directory that should contain subdirectories
186 "common", "posix", "nt", each containing scripts destined for the bin
187 directory in the environment. The contents of "common" and the
188 directory corresponding to :data:`os.name` are copied after some text
189 replacement of placeholders:
190
191 * ``__VENV_DIR__`` is replaced with the absolute path of the environment
192 directory.
193
194 * ``__VENV_NAME__`` is replaced with the environment name (final path
195 segment of environment directory).
196
Vinay Sajipdff9e252013-10-02 11:36:16 +0100197 * ``__VENV_PROMPT__`` is replaced with the prompt (the environment
198 name surrounded by parentheses and with a following space)
199
Georg Brandldbab58f2012-06-24 16:37:59 +0200200 * ``__VENV_BIN_NAME__`` is replaced with the name of the bin directory
201 (either ``bin`` or ``Scripts``).
202
203 * ``__VENV_PYTHON__`` is replaced with the absolute path of the
204 environment's executable.
205
Vinay Sajip577d4ff2013-07-12 21:52:51 +0100206 The directories are allowed to exist (for when an existing environment
207 is being upgraded).
Georg Brandldbab58f2012-06-24 16:37:59 +0200208
209There is also a module-level convenience function:
210
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000211.. function:: create(env_dir, system_site_packages=False, clear=False, \
212 symlinks=False, with_pip=False)
Georg Brandldbab58f2012-06-24 16:37:59 +0200213
214 Create an :class:`EnvBuilder` with the given keyword arguments, and call its
215 :meth:`~EnvBuilder.create` method with the *env_dir* argument.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000216
Nick Coghlan8fbdb092013-11-23 00:30:34 +1000217 .. versionchanged:: 3.4
218 Added the ``with_pip`` parameter
219
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000220An example of extending ``EnvBuilder``
221--------------------------------------
222
223The following script shows how to extend :class:`EnvBuilder` by implementing a
Vinay Sajip3c557f22013-07-12 20:54:25 +0100224subclass which installs setuptools and pip into a created venv::
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000225
226 import os
227 import os.path
228 from subprocess import Popen, PIPE
229 import sys
230 from threading import Thread
231 from urllib.parse import urlparse
232 from urllib.request import urlretrieve
233 import venv
234
Vinay Sajip3c557f22013-07-12 20:54:25 +0100235 class ExtendedEnvBuilder(venv.EnvBuilder):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000236 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100237 This builder installs setuptools and pip so that you can pip or
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000238 easy_install other packages into the created environment.
239
Vinay Sajip3c557f22013-07-12 20:54:25 +0100240 :param nodist: If True, setuptools and pip are not installed into the
241 created environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000242 :param nopip: If True, pip is not installed into the created
243 environment.
Vinay Sajip3c557f22013-07-12 20:54:25 +0100244 :param progress: If setuptools or pip are installed, the progress of the
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000245 installation can be monitored by passing a progress
246 callable. If specified, it is called with two
247 arguments: a string indicating some progress, and a
248 context indicating where the string is coming from.
249 The context argument can have one of three values:
250 'main', indicating that it is called from virtualize()
251 itself, and 'stdout' and 'stderr', which are obtained
252 by reading lines from the output streams of a subprocess
253 which is used to install the app.
254
255 If a callable is not specified, default progress
256 information is output to sys.stderr.
257 """
258
259 def __init__(self, *args, **kwargs):
260 self.nodist = kwargs.pop('nodist', False)
261 self.nopip = kwargs.pop('nopip', False)
262 self.progress = kwargs.pop('progress', None)
263 self.verbose = kwargs.pop('verbose', False)
264 super().__init__(*args, **kwargs)
265
266 def post_setup(self, context):
267 """
268 Set up any packages which need to be pre-installed into the
269 environment being created.
270
271 :param context: The information for the environment creation request
272 being processed.
273 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100274 os.environ['VIRTUAL_ENV'] = context.env_dir
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000275 if not self.nodist:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100276 self.install_setuptools(context)
277 # Can't install pip without setuptools
278 if not self.nopip and not self.nodist:
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000279 self.install_pip(context)
280
281 def reader(self, stream, context):
282 """
283 Read lines from a subprocess' output stream and either pass to a progress
284 callable (if specified) or write progress information to sys.stderr.
285 """
286 progress = self.progress
287 while True:
288 s = stream.readline()
289 if not s:
290 break
291 if progress is not None:
292 progress(s, context)
293 else:
294 if not self.verbose:
295 sys.stderr.write('.')
296 else:
297 sys.stderr.write(s.decode('utf-8'))
298 sys.stderr.flush()
Vinay Sajipad6bb032013-07-12 21:44:35 +0100299 stream.close()
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000300
301 def install_script(self, context, name, url):
302 _, _, path, _, _, _ = urlparse(url)
303 fn = os.path.split(path)[-1]
304 binpath = context.bin_path
305 distpath = os.path.join(binpath, fn)
306 # Download script into the env's binaries folder
307 urlretrieve(url, distpath)
308 progress = self.progress
Vinay Sajip3c557f22013-07-12 20:54:25 +0100309 if self.verbose:
310 term = '\n'
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000311 else:
Vinay Sajip3c557f22013-07-12 20:54:25 +0100312 term = ''
313 if progress is not None:
314 progress('Installing %s ...%s' % (name, term), 'main')
315 else:
316 sys.stderr.write('Installing %s ...%s' % (name, term))
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000317 sys.stderr.flush()
318 # Install in the env
319 args = [context.env_exe, fn]
320 p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
321 t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
322 t1.start()
323 t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
324 t2.start()
325 p.wait()
326 t1.join()
327 t2.join()
328 if progress is not None:
329 progress('done.', 'main')
330 else:
331 sys.stderr.write('done.\n')
332 # Clean up - no longer needed
333 os.unlink(distpath)
334
Vinay Sajip3c557f22013-07-12 20:54:25 +0100335 def install_setuptools(self, context):
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000336 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100337 Install setuptools in the environment.
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000338
339 :param context: The information for the environment creation request
340 being processed.
341 """
Vinay Sajip3c557f22013-07-12 20:54:25 +0100342 url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
343 self.install_script(context, 'setuptools', url)
344 # clear up the setuptools archive which gets downloaded
345 pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000346 files = filter(pred, os.listdir(context.bin_path))
347 for f in files:
348 f = os.path.join(context.bin_path, f)
349 os.unlink(f)
350
351 def install_pip(self, context):
352 """
353 Install pip in the environment.
354
355 :param context: The information for the environment creation request
356 being processed.
357 """
358 url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
359 self.install_script(context, 'pip', url)
360
361 def main(args=None):
362 compatible = True
363 if sys.version_info < (3, 3):
364 compatible = False
365 elif not hasattr(sys, 'base_prefix'):
366 compatible = False
367 if not compatible:
368 raise ValueError('This script is only for use with '
369 'Python 3.3 or later')
370 else:
371 import argparse
372
373 parser = argparse.ArgumentParser(prog=__name__,
374 description='Creates virtual Python '
375 'environments in one or '
376 'more target '
377 'directories.')
378 parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
379 help='A directory to create the environment in.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100380 parser.add_argument('--no-setuptools', default=False,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000381 action='store_true', dest='nodist',
Vinay Sajip3c557f22013-07-12 20:54:25 +0100382 help="Don't install setuptools or pip in the "
383 "virtual environment.")
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000384 parser.add_argument('--no-pip', default=False,
385 action='store_true', dest='nopip',
386 help="Don't install pip in the virtual "
387 "environment.")
388 parser.add_argument('--system-site-packages', default=False,
389 action='store_true', dest='system_site',
390 help='Give the virtual environment access to the '
391 'system site-packages dir.')
392 if os.name == 'nt':
393 use_symlinks = False
394 else:
395 use_symlinks = True
396 parser.add_argument('--symlinks', default=use_symlinks,
397 action='store_true', dest='symlinks',
398 help='Try to use symlinks rather than copies, '
399 'when symlinks are not the default for '
400 'the platform.')
401 parser.add_argument('--clear', default=False, action='store_true',
402 dest='clear', help='Delete the contents of the '
403 'environment directory if it '
404 'already exists, before '
405 'environment creation.')
406 parser.add_argument('--upgrade', default=False, action='store_true',
407 dest='upgrade', help='Upgrade the environment '
408 'directory to use this version '
409 'of Python, assuming Python '
410 'has been upgraded in-place.')
411 parser.add_argument('--verbose', default=False, action='store_true',
412 dest='verbose', help='Display the output '
413 'from the scripts which '
Vinay Sajip3c557f22013-07-12 20:54:25 +0100414 'install setuptools and pip.')
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000415 options = parser.parse_args(args)
416 if options.upgrade and options.clear:
417 raise ValueError('you cannot supply --upgrade and --clear together.')
Vinay Sajip3c557f22013-07-12 20:54:25 +0100418 builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000419 clear=options.clear,
420 symlinks=options.symlinks,
421 upgrade=options.upgrade,
422 nodist=options.nodist,
423 nopip=options.nopip,
424 verbose=options.verbose)
425 for d in options.dirs:
426 builder.create(d)
427
428 if __name__ == '__main__':
429 rc = 1
430 try:
431 main()
432 rc = 0
433 except Exception as e:
434 print('Error: %s' % e, file=sys.stderr)
435 sys.exit(rc)
436
Vinay Sajip3c557f22013-07-12 20:54:25 +0100437
Vinay Sajip2b4fcfb2013-01-30 13:44:00 +0000438This script is also available for download `online
439<https://gist.github.com/4673395>`_.