<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Posts about virtualenv</title><link>https://chriswarrick.com/</link><atom:link href="https://chriswarrick.com/blog/tags/virtualenv.xml" rel="self" type="application/rss+xml" /><description>A rarely updated blog, mostly about programming.</description><lastBuildDate>Sat, 03 Apr 2021 11:00:00 GMT</lastBuildDate><generator>https://github.com/Kwpolska/YetAnotherBlogGenerator</generator><item><title>Python Virtual Environments in Five Minutes</title><dc:creator>Chris Warrick</dc:creator><link>https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/</link><pubDate>Tue, 04 Sep 2018 18:15:00 GMT</pubDate><guid>https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/</guid><description>
In Python, virtual environments are used to isolate projects from each other
(if they require different versions of the same library, for example). They let
you install and manage packages without administrative privileges, and without
conflicting with the system package manager.  They also allow to quickly create
an environment somewhere else with the same dependencies.
Virtual environments are a crucial tool for any Python developer. And at that,
a very simple tool to work with.
</description><content:encoded><![CDATA[
<p>In Python, virtual environments are used to isolate projects from each other
(if they require different versions of the same library, for example). They let
you install and manage packages without administrative privileges, and without
conflicting with the system package manager.  They also allow to quickly create
an environment somewhere else with the same dependencies.</p>
<p>Virtual environments are a crucial tool for any Python developer. And at that,
a very simple tool to work with.</p>



<p>Let’s get started!</p>
<section id="install">
<h1>Install</h1>
<p>The best tool that can be used to create virtual environments is the
<a class="reference external" href="https://docs.python.org/3/library/venv.html">venv</a> module, which is part of
the standard library since Python 3.3.</p>
<p><code class="docutils literal">venv</code> is built into Python, and most users don’t need to install anything.
However, Debian/Ubuntu users will need to run <code class="docutils literal">sudo <span class="pre">apt-get</span> install <span class="pre">python3-venv</span></code> to make it work (due to Debian not installing some components
that <code class="docutils literal">venv</code> needs by default). <a class="brackets" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a></p>
<p>The alternative (and original, and previously standard) virtual environment tool is <a class="reference external" href="https://virtualenv.pypa.io/">virtualenv</a>. It works with Python 2.7, and has a couple
extra fetures (that you generally won’t need). virtualenv can be installed with your system package manager, or <code class="docutils literal">pip install <span class="pre">--user</span> virtualenv</code>.</p>
<p>Which one to use? Probably <code class="docutils literal">venv</code>. Both tools achieve the same goal in similar
ways. And if one of them does not work, you can try the other and it might just
work better.</p>
<p><em>(Terminology note: most of the time, the names of both tools are used
interchargeably, “venv” was often used as an abbreviation for “virtualenv”
before the stdlib tool was created)</em></p>
</section>
<section id="create">
<h1>Create</h1>
<p>To create a virtual environment named <code class="docutils literal">env</code>, you need to run the <code class="docutils literal">venv</code>
tool with the Python you want to use in that environment.</p>
<div class="code"><pre class="code text"><a id="rest_code_1fb767790a68420a97f0697df45d2e92-1" name="rest_code_1fb767790a68420a97f0697df45d2e92-1" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_1fb767790a68420a97f0697df45d2e92-1"></a>Linux:   $ python3 -m venv env
<a id="rest_code_1fb767790a68420a97f0697df45d2e92-2" name="rest_code_1fb767790a68420a97f0697df45d2e92-2" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_1fb767790a68420a97f0697df45d2e92-2"></a>Windows: &gt; py -m venv env
</pre></div>
<p>or, if you’re using <code class="docutils literal">virtualenv</code>:</p>
<div class="code"><pre class="code text"><a id="rest_code_d2d40ad9883b450e9264cf578d6f68af-1" name="rest_code_d2d40ad9883b450e9264cf578d6f68af-1" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d2d40ad9883b450e9264cf578d6f68af-1"></a>$ python3 -m virtualenv env
<a id="rest_code_d2d40ad9883b450e9264cf578d6f68af-2" name="rest_code_d2d40ad9883b450e9264cf578d6f68af-2" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d2d40ad9883b450e9264cf578d6f68af-2"></a>&gt; py -m virtualenv env
</pre></div>
<p>Afterwards, you will end up with a folder named <code class="docutils literal">env</code> that contains folders
named <code class="docutils literal">bin</code> (<code class="docutils literal">Scripts</code> on Windows — contains executables and scripts
installed by packages, including
<code class="docutils literal">python</code>), <code class="docutils literal">lib</code> (contains code), and <code class="docutils literal">include</code> (contains C headers).</p>
<p>Both tools install <code class="docutils literal">pip</code> and <code class="docutils literal">setuptools</code>, but <code class="docutils literal">venv</code> does not ship with
<code class="docutils literal">wheel</code>. In addition, the default versions tend to be more-or-less outdated.
Let’s upgrade them real quick: <a class="brackets" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-2" id="footnote-reference-2" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a></p>
<div class="code"><pre class="code text"><a id="rest_code_39b9e0a93e0746fbac8d7b7f11734578-1" name="rest_code_39b9e0a93e0746fbac8d7b7f11734578-1" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_39b9e0a93e0746fbac8d7b7f11734578-1"></a>$ env/bin/python -m pip install --upgrade pip setuptools wheel
<a id="rest_code_39b9e0a93e0746fbac8d7b7f11734578-2" name="rest_code_39b9e0a93e0746fbac8d7b7f11734578-2" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_39b9e0a93e0746fbac8d7b7f11734578-2"></a>&gt; env\Scripts\python -m pip install --upgrade pip setuptools wheel
</pre></div>
<section id="where-to-store-virtual-environments">
<h2>Where to store virtual environments?</h2>
<p>While the tools allow you to put your virtual environments anywhere in the
system, it is not a desirable thing to do. There are two options:</p>
<ol class="arabic simple">
<li><p>Have one global place for them, like <code class="docutils literal">~/virtualenvs</code>.</p></li>
<li><p>Store them in each project’s directory, like <code class="docutils literal"><span class="pre">~/git/foobar/.venv</span></code>.</p></li>
</ol>
<p>The first option can be easier to manage, there are tools that can help manage
those (eg. <code class="docutils literal">virtualenvwrapper</code>, shell auto-activation scripts, or the
<code class="docutils literal">workon</code> functions described below).  The second option is equally easy to
work with, but comes with one caveat — you must add the venv directory to your
<code class="docutils literal">.gitignore</code> file (or <code class="docutils literal">.git/info/exclude</code> if you don’t want to commit
changes to <code class="docutils literal">.gitignore</code>), since you don’t want it in your repository (it’s
binary bloat, and works only on your machine).</p>
<p>If you pick the global virtual environment store option, you can use the following short
function (put it in <code class="docutils literal">.bashrc</code> / <code class="docutils literal">.zshrc</code> / your shell configuration file)
to get a simple way to activate an environment (by running <code class="docutils literal">workon foo</code>).
<code class="docutils literal">virtualenvwrapper</code> also has a <code class="docutils literal">workon</code> feature, although I don’t think
<code class="docutils literal">virtualenvwrapper</code> is really necessary and too helpful — the <code class="docutils literal">workon</code>
feature is handy though, and so here’s a way to do it without
<code class="docutils literal">virtualenvwrapper</code>:</p>
<div class="code"><table class="codetable"><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-1"><code data-line-number="1"></code></a></td><td class="code"><code><a id="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-1" name="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-1"></a><span class="w"> </span><span class="nb">export</span><span class="w"> </span><span class="nv">WORKON_HOME</span><span class="o">=</span>~/virtualenvs
</code></td></tr><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-2"><code data-line-number="2"></code></a></td><td class="code"><code><a id="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-2" name="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-2"></a>
</code></td></tr><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-3"><code data-line-number="3"></code></a></td><td class="code"><code><a id="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-3" name="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-3"></a><span class="w"> </span><span class="k">function</span><span class="w"> </span>workon<span class="w"> </span><span class="o">{</span>
</code></td></tr><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-4"><code data-line-number="4"></code></a></td><td class="code"><code><a id="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-4" name="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-4"></a><span class="w">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nb">source</span><span class="w"> </span><span class="s2">&quot;</span><span class="nv">$WORKON_HOME</span><span class="s2">/</span><span class="nv">$1</span><span class="s2">/bin/activate&quot;</span>
</code></td></tr><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-5"><code data-line-number="5"></code></a></td><td class="code"><code><a id="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-5" name="rest_code_d4c94a5f476e4e5ab3fe0a7682a1bdb7-5"></a><span class="w"> </span><span class="o">}</span>
</code></td></tr></table></div><p>And for PowerShell fans, here’s a <code class="docutils literal">workon.ps1</code> script:</p>
<div class="code"><table class="codetable"><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_33d18c86da274b70953d97d327e4e0e7-1"><code data-line-number="1"></code></a></td><td class="code"><code><a id="rest_code_33d18c86da274b70953d97d327e4e0e7-1" name="rest_code_33d18c86da274b70953d97d327e4e0e7-1"></a> <span class="nv">$WORKON_HOME</span> <span class="p">=</span> <span class="s2">&quot;$home\virtualenvs&quot;</span>
</code></td></tr><tr><td class="linenos linenodiv"><a href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_33d18c86da274b70953d97d327e4e0e7-2"><code data-line-number="2"></code></a></td><td class="code"><code><a id="rest_code_33d18c86da274b70953d97d327e4e0e7-2" name="rest_code_33d18c86da274b70953d97d327e4e0e7-2"></a> <span class="p">&amp;</span> <span class="s2">&quot;$WORKON_HOME\</span><span class="p">$(</span><span class="nv">$args</span><span class="p">[</span><span class="n">0</span><span class="p">])</span><span class="s2">\Scripts\activate.ps1&quot;</span>
</code></td></tr></table></div><p>And for cmd.exe fans… you should switch to PowerShell, it’s a very nice and
friendly shell (though perhaps requiring some effort to learn how to be
productive with it).</p>
</section>
</section>
<section id="use">
<h1>Use</h1>
<p>There are three ways of working with virtual environments interactively (in a
shell):</p>
<ul class="simple">
<li><p>activation (run <code class="docutils literal">source env/bin/activate</code> on *nix;
<code class="docutils literal">env\Scripts\activate</code> on Windows) — it simplifies work and requires less
typing, although it can sometimes fail to work properly. (After installing
scripts, <code class="docutils literal">hash <span class="pre">-r</span></code> may be necessary on *nix to use them.)</p></li>
<li><p>executing <code class="docutils literal">env/bin/python</code> (<code class="docutils literal">env\Scripts\python</code>) and other scripts directly, as
activation only changes <code class="docutils literal">$PATH</code> and some helper variables — those variables
are not mandatory for operation, running the correct <code class="docutils literal">python</code> is, and that
method is failsafe.</p></li>
<li><p><a class="reference external" href="https://gist.github.com/datagrok/2199506">in subshells</a> (IMO, it’s bad UX)</p></li>
</ul>
<p>Whichever method you use, you must remember that without doing any of these
things, you will still be working with the system Python.</p>
<p>For non-interactive work (eg. crontab entries, system services, etc.),
activation and subshells are not viable solutions. In these cases, you must
always use the full path to Python.</p>
<p>Here are some usage examples (paths can be relative, of course):</p>
<div class="code"><pre class="code text"><a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-1" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-1" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-1"></a>## *nix, activation ##
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-2" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-2" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-2"></a>$ source /path/to/env/bin/activate
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-3" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-3" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-3"></a>(env)$ pip install Django
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-4" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-4" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-4"></a>(env)$ deactivate
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-5" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-5" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-5"></a>
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-6" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-6" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-6"></a>## *nix, manual execution ##
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-7" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-7" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-7"></a>$ /path/to/env/bin/pip install Django
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-8" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-8" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-8"></a>
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-9" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-9" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-9"></a>## Windows, activation ##
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-10" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-10" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-10"></a>&gt; C:\path\to\env\Scripts\activate
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-11" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-11" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-11"></a>(venv)&gt; pip install Django
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-12" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-12" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-12"></a>(venv)&gt; deactivate
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-13" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-13" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-13"></a>
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-14" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-14" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-14"></a>## Windows, manual execution ##
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-15" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-15" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-15"></a>&gt; C:\path\to\env\Scripts\pip install Django
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-16" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-16" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-16"></a>
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-17" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-17" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-17"></a>## Windows, updating pip/setuptools/wheel ##
<a id="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-18" name="rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-18" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_99f32ee1312e43b19d00feb1c5e6ae7f-18"></a>&gt; C:\path\to\env\Scripts\python -m pip install -U pip setuptools wheel
</pre></div>
<p>The same principle applies to running Python itself, or any other script
installed by a package. (With Django’s <code class="docutils literal">manage.py</code>, calling it as
<code class="docutils literal">./manage.py</code> requires activation, or you can run
<code class="docutils literal">venv/bin/python manage.py</code>.)</p>
<section id="moving-renaming-copying-environments">
<h2>Moving/renaming/copying environments?</h2>
<p>If you try to copy or rename a virtual environment, you will discover that the
copied environment does not work. This is because a virtual environment is
closely tied to both the Python it was created with, and the location it was
created in. (The “relocatable” option of <code class="docutils literal">virtualenv</code> does not work and is deprecated.) <a class="brackets" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-3" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>3<span class="fn-bracket">]</span></a></p>
<p>However, this is very easy to fix. Instead of moving/copying, just create a new
environment in the new location. Then, run <code class="docutils literal">pip freeze &gt; requirements.txt</code> in
the old environment to create a list of packages installed in it. With that,
you can just run <code class="docutils literal">pip install <span class="pre">-r</span> requirements.txt</code> in the new environment to
install packages from the saved list. (Of course, you can copy <code class="docutils literal">requirements.txt</code>
between machines. In many cases, it will just work; sometimes, you might need a few
modifications to <code class="docutils literal">requirements.txt</code> to remove OS-specific stuff.)</p>
<div class="code"><pre class="code text"><a id="rest_code_118b2d54954242548dd7d3e590824a4c-1" name="rest_code_118b2d54954242548dd7d3e590824a4c-1" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_118b2d54954242548dd7d3e590824a4c-1"></a>$ oldenv/bin/pip freeze &gt; requirements.txt
<a id="rest_code_118b2d54954242548dd7d3e590824a4c-2" name="rest_code_118b2d54954242548dd7d3e590824a4c-2" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_118b2d54954242548dd7d3e590824a4c-2"></a>$ python3 -m venv newenv
<a id="rest_code_118b2d54954242548dd7d3e590824a4c-3" name="rest_code_118b2d54954242548dd7d3e590824a4c-3" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_118b2d54954242548dd7d3e590824a4c-3"></a>$ newenv/bin/pip install -r requirements.txt
<a id="rest_code_118b2d54954242548dd7d3e590824a4c-4" name="rest_code_118b2d54954242548dd7d3e590824a4c-4" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#rest_code_118b2d54954242548dd7d3e590824a4c-4"></a>(You may rm -rf oldenv now if you desire)
</pre></div>
<p>Note that it might also be necessary to re-create your virtual environment
after a Python upgrade, <a class="brackets" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-4" id="footnote-reference-4" role="doc-noteref"><span class="fn-bracket">[</span>4<span class="fn-bracket">]</span></a> so it might be handy to keep an up-to-date
<code class="docutils literal">requirements.txt</code> for your virtual environments (for many projects, it makes
sense to put that in the repository).</p>
<p>To manage those <code class="docutils literal">requirements.txt</code> files in a more orgnized yet still simple
way, you might be interested in <a class="reference external" href="https://github.com/jazzband/pip-tools">pip-tools</a>.</p>
</section>
</section>
<section id="frequently-asked-questions">
<h1>Frequently Asked Questions</h1>
<section id="im-using-virtualenv-do-i-need-to-install-it-for-each-python-i-want-to-use-it-with">
<h2>I’m using virtualenv. Do I need to install it for each Python I want to use it with?</h2>
<p>In most cases, you can use <code class="docutils literal">virtualenv <span class="pre">-p</span> pythonX env</code> to specify a different
Python version, but with some Python version combinations, that approach might
be unsuccessful. (The <code class="docutils literal">venv</code> module is tied to the Python version it’s
installed in.)</p>
</section>
<section id="im-the-only-user-on-my-system-do-i-still-need-virtual-environments">
<h2>I’m the only user on my system. Do I still need virtual environments?</h2>
<p>Yes, you do. First, you will still need separation between projects, sooner or
later.  Moreover, if you were to install packages system-wide with pip, you
might end up causing conflicts between packages installed by the system package
manager and by pip. Running <code class="docutils literal">sudo pip</code> is never a good idea because of this.</p>
</section>
<section id="im-using-docker-do-i-still-need-virtual-environments">
<h2>I’m using Docker. Do I still need virtual environments?</h2>
<p>They are still a good idea in that case. They protect you against any bad
system-wide Python packages your OS image might have (and one popular base OS
is famous for those). They don’t introduce any extra overhead, while allowing
to have a clean environment and the ability to re-create it outside of Docker
(eg. for local development without Docker)</p>
</section>
<section id="what-about-pipenv">
<h2>What about Pipenv?</h2>
<p>Pipenv is a dependency management tool. It isn’t compatible with most workflows, and comes with many issues. In my opinion, it’s not worth using (Also, that thing about it being an officially recommended tool? Turns out it’s not true.)</p>
<p>I also wrote a blog post detailing concerns with that tool, titled <a class="reference external" href="https://chriswarrick.com/blog/2018/07/17/pipenv-promises-a-lot-delivers-very-little/">Pipenv: promises a lot, delivers very little</a>.</p>
<p>Consider using <a class="reference external" href="https://github.com/jazzband/pip-tools">pip-tools</a> instead.</p>
</section>
</section>
<section id="footnotes">
<h1>Footnotes</h1>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="footnote-1" role="doc-footnote">
<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-reference-1">1</a><span class="fn-bracket">]</span></span>
<p>The thing you’re actually installing is <code class="docutils literal">ensurepip</code>. In general, Debian isn’t exactly friendly with Python packaging.</p>
</aside>
<aside class="footnote brackets" id="footnote-2" role="doc-footnote">
<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-reference-2">2</a><span class="fn-bracket">]</span></span>
<p>On Windows, you <em>must</em> run <code class="docutils literal">python <span class="pre">-m</span> pip</code> instead of <code class="docutils literal">pip</code> if you want to upgrade the package manager itself.</p>
</aside>
<aside class="footnote brackets" id="footnote-3" role="doc-footnote">
<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-reference-3">3</a><span class="fn-bracket">]</span></span>
<p>All script shebangs contain the direct path to the environment’s Python executable.  Many things in the virtual environment are symlinks that point to the original Python.</p>
</aside>
<aside class="footnote brackets" id="footnote-4" role="doc-footnote">
<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="https://chriswarrick.com/blog/2018/09/04/python-virtual-environments/#footnote-reference-4">4</a><span class="fn-bracket">]</span></span>
<p>Definitely after a minor version (3.x → 3.y) upgrade, sometimes (I’m looking at you Homebrew) after a patch version upgrade (3.x.y → 3.x.z) as well.</p>
</aside>
</aside>
</section>
]]></content:encoded><category>Python</category><category>best practices</category><category>devel</category><category>guide</category><category>Python</category><category>venv</category><category>virtual environments</category><category>virtualenv</category></item></channel></rss>