<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>The Wombelix Post - pip</title><link href="https://dominik.wombacher.cc/" rel="alternate"/><link href="/feeds/tag_pip.atom.xml" rel="self"/><id>https://dominik.wombacher.cc/</id><updated>2021-09-23T00:00:00+02:00</updated><entry><title>pipx behave different than pip if package already exists</title><link href="https://dominik.wombacher.cc/posts/pipx-behave-different-than-pip-if-package-already-exists.html" rel="alternate"/><published>2021-09-23T00:00:00+02:00</published><updated>2021-09-23T00:00:00+02:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2021-09-23:/posts/pipx-behave-different-than-pip-if-package-already-exists.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;I decided to put as much as possible of my local config into an Ansible Playbook.
Makes it easier to track what I install and change, also to setup from  ... &lt;a class="read-more" href="/posts/pipx-behave-different-than-pip-if-package-already-exists.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;I decided to put as much as possible of my local config into an Ansible Playbook.
Makes it easier to track what I install and change, also to setup from scratch should it necessary.&lt;/p&gt;
&lt;p&gt;In the past I mainly used &lt;cite&gt;pip&lt;/cite&gt; in combination with &lt;cite&gt;venv&lt;/cite&gt; to install Python stuff.
Changing for most of it to &lt;cite&gt;pipx&lt;/cite&gt; seems logical, it will take care about the necessary &lt;em&gt;venvs&lt;/em&gt; on it's own.&lt;/p&gt;
&lt;p&gt;Just had to learn that the return code of &lt;cite&gt;pip&lt;/cite&gt; is &lt;strong&gt;0&lt;/strong&gt; but from &lt;cite&gt;pipx&lt;/cite&gt; it's &lt;strong&gt;1&lt;/strong&gt; in case a package already exists.&lt;/p&gt;
&lt;p&gt;Why does it matter? Not the most elegant solution but I decided to just use &lt;cite&gt;command&lt;/cite&gt; to trigger &lt;em&gt;pip&lt;/em&gt; / &lt;em&gt;pipx&lt;/em&gt; from my Playbook:&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nt"&gt;name&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;Python Package Installation (pip)&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;command&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;&amp;quot;python3&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;-m&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;pip&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;install&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;--user&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;{{&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;item&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;}}&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;changed_when&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;false&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;loop&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;pipx&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;nox&lt;/span&gt;&lt;span class="pygments-w"&gt;

&lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nt"&gt;name&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;Python Package Installation (pipx)&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;command&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;&amp;quot;pipx&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;install&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;{{&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;item&lt;/span&gt;&lt;span class="pygments-nv"&gt; &lt;/span&gt;&lt;span class="pygments-s"&gt;}}&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;changed_when&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;false&lt;/span&gt;&lt;span class="pygments-w"&gt;
  &lt;/span&gt;&lt;span class="pygments-nt"&gt;loop&lt;/span&gt;&lt;span class="pygments-p"&gt;:&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;poetry&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;duplicity&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p-Indicator"&gt;-&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-l-Scalar-Plain"&gt;pre-commit&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;No problem with &lt;cite&gt;pip&lt;/cite&gt;, but &lt;cite&gt;pipx&lt;/cite&gt; failed after the first run.&lt;/p&gt;
&lt;p&gt;There was an older &lt;a class="reference external" href="https://github.com/pypa/pipx/issues/125"&gt;GitHub Issue&lt;/a&gt;, based on the comments,
&lt;cite&gt;pipx&lt;/cite&gt; was supposed to behave smilar as &lt;cite&gt;pip&lt;/cite&gt; and also use return code 0 since v0.13 already.
After some research I found the &lt;a class="reference external" href="https://github.com/pypa/pipx/pull/560"&gt;Pull Request&lt;/a&gt;
that reverted the earlier change during some re-factoring.&lt;/p&gt;
&lt;p&gt;Thanks to the great improvements in that PR, it was just a very small change necessary to restore the
functionality introduced in &lt;a class="reference external" href="https://github.com/pypa/pipx/commit/11b853e9c6926b32133b27822516b2a5b4f35411"&gt;Commit 11b853e&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="pygments-gh"&gt;diff --git a/docs/changelog.md b/docs/changelog.md&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gh"&gt;index 0a95ce15..67d14929 100644&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;--- a/docs/changelog.md&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+++ b/docs/changelog.md&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -1,6 +1,7 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;dev&lt;span class="pygments-w"&gt;

 &lt;/span&gt;- Fixed `pipx list` output phrasing to convey that python version displayed is the one with which package was installed.&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+- Fixed `pipx install` to provide return code 0 if venv already exists, similar to pip’s behavior. (#736)&lt;/span&gt;&lt;span class="pygments-w"&gt;

 &lt;/span&gt;0.16.4&lt;span class="pygments-w"&gt;

&lt;/span&gt;&lt;span class="pygments-gh"&gt;diff --git a/src/pipx/constants.py b/src/pipx/constants.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gh"&gt;index 4fe2d58b..11fc013f 100644&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;--- a/src/pipx/constants.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+++ b/src/pipx/constants.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -21,7 +21,7 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;# pipx shell exit codes&lt;span class="pygments-w"&gt;
 &lt;/span&gt;EXIT_CODE_OK = ExitCode(0)&lt;span class="pygments-w"&gt;
 &lt;/span&gt;EXIT_CODE_INJECT_ERROR = ExitCode(1)&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-EXIT_CODE_INSTALL_VENV_EXISTS = ExitCode(1)&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+EXIT_CODE_INSTALL_VENV_EXISTS = ExitCode(0)&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;EXIT_CODE_LIST_PROBLEM = ExitCode(1)&lt;span class="pygments-w"&gt;
 &lt;/span&gt;EXIT_CODE_UNINSTALL_VENV_NONEXISTENT = ExitCode(1)&lt;span class="pygments-w"&gt;
 &lt;/span&gt;EXIT_CODE_UNINSTALL_ERROR = ExitCode(1)&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gh"&gt;diff --git a/tests/test_install.py b/tests/test_install.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gh"&gt;index 941f4c01..0eb2d9cc 100644&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;--- a/tests/test_install.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+++ b/tests/test_install.py&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -109,7 +109,7 &amp;#64;&amp;#64; def test_install_no_packages_found(pipx_temp_env, capsys):&lt;/span&gt;&lt;span class="pygments-w"&gt;

 &lt;/span&gt;def test_install_same_package_twice_no_force(pipx_temp_env, capsys):&lt;span class="pygments-w"&gt;
 &lt;/span&gt;    assert not run_pipx_cli([&amp;quot;install&amp;quot;, &amp;quot;pycowsay&amp;quot;])&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-    assert run_pipx_cli([&amp;quot;install&amp;quot;, &amp;quot;pycowsay&amp;quot;])&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+    assert not run_pipx_cli([&amp;quot;install&amp;quot;, &amp;quot;pycowsay&amp;quot;])&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;    captured = capsys.readouterr()&lt;span class="pygments-w"&gt;
 &lt;/span&gt;    assert (&lt;span class="pygments-w"&gt;
 &lt;/span&gt;        &amp;quot;'pycowsay' already seems to be installed. Not modifying existing installation&amp;quot;&lt;span class="pygments-w"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Related Pull Request: &lt;a class="reference external" href="https://github.com/pypa/pipx/pull/736"&gt;https://github.com/pypa/pipx/pull/736&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Merged into &lt;cite&gt;pipx/main&lt;/cite&gt; on 25th September 2021&lt;/p&gt;
&lt;p&gt;That's a good example why I love and prefer Open Source, I could fix the Problem on my own and share the improvement with the community, within a few days it was already merged and will be part of the next Release.&lt;/p&gt;
</content><category term="Code"/><category term="Python"/><category term="Code"/><category term="pipx"/><category term="pip"/></entry></feed>