Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Virtual environments are an incomplete solution at best. In particular, they really don't help much with the use case of wanting to install a tool: if you're installing a tool and not just setting up a development environment for working on a specific project with its dependencies, then you probably want to make that tool usable without activating its venv. The virtual environment capabilities shipped with Python itself don't really have any affordances for that.


> then you probably want to make that tool usable without activating its venv. The virtual environment capabilities shipped with Python itself don't really have any affordances for that.

The only reason it isn't "usable" is because the wrapper script isn't on your system's path. Unless your tools actually depend on venv-related environment variables being set (for example, because they make subprocess calls and assume that `'python'` will use the currently running Python when they should correctly be using `sys.executable`), which IMX is very rare, you don't ever actually have to activate a venv to do anything with it. In particular, you don't need to activate it to use its REPL; you can instead directly specify the path to its Python executable.

The missing affordance basically looks like `ln -s path/to/venv/bin/tool ~/.local/bin`. Which is a big part of what Pipx does for you. (And once I realized that, I started using Pipx's vendored shared copy of pip: https://zahlman.github.io/posts/2025/01/07/python-packaging-...)


uvx / uv tool works great for that.

You can `uv tool install your_package`, add a dir to your PATH, and then you can launch the tool appropriately, with it installed in its own venv


  $ virtualenv ~/venv/yt-dlp
  $ . ~/venv/yt-dlp/bin/activate
  $ pip install yt-dlp
  $ ln -s ~/venv/yt-dlp/bin/yt-dlp ~/bin/yt-dlp
  $ deactivate
  $ yt-dlp ...


Isn't that really obviously about five steps too many to be considered a reasonable way of installing a package?

(And you didn't handle getting an appropriate version of python installed.)


> Isn't that really obviously about five steps too many to be considered a reasonable way of installing a package?

That's why I use pipx. But the activation and deactivation in that example are completely unnecessary, and the last line is just using the installed package. Installation actually looks like:

  $ python -m venv ~/venv/yt-dlp
  $ ~/venv/yt-dlp/bin/pip install yt-dlp
  $ ln -s ~/venv/yt-dlp/bin/yt-dlp ~/bin/yt-dlp
which is only two steps too many if we acknowledge that there has to be at least one step. This all of course can also just be put in a shell script, or a function in your ~/.bashrc.

Pip just happens to be laser focused on the actual installation of packages, so it doesn't provide that wrapper. (With PAPER I'm aiming for slightly broader scope, but still something intended specifically for users that's only one piece of a developer toolchain.)

> (And you didn't handle getting an appropriate version of python installed.)

When was the last time you tried to obtain an application that could be installed as a PyPI package and your system Python wasn't compatible? Everyone knows the CPython release cadence now and is strongly pressured to advance their own support in lock-step with that. Similarly for libraries. There's already a full set of wheels for the latest version of NumPy for 3.14, 22 of them. Even musl-based distributions are provided for. Even 32-bit Windows is provided for, for those few holdouts.

If your target audience doesn't have Python and understand on a basic level what that is, why will they be able to understand using the uv command line and accept using that to install a program?


I don't get it. Then you just install the tool outside of venv? then it's installed for your user account.


But then all the tool's dependencies have to play nice with the dependencies of all your other unrelated Python-based tools.

One thing you can do (I'm not saying it's user friendly) is set up the tool in a virtualenv and then set up an alias like

    alias foo-tool=/home/blah blah/tools/something/env/bin/python -m foo-tool


Or you can make a symlink from your PATH, which is how Pipx does it.


But this is true for anything that isn't statically linked?


Why would static linking be necessary? The virtual environment contains all the needed dependencies, and isolates them from everything else.


ah, right!


That requires you to be running the right version of python at the system level, and for all your installed tools to have compatible package versions. It doesn't work very often for me


What sorts of things are you installing that you "often" need to care about having the "right" version of Python? It's normal in the Python ecosystem that packages explicitly support every non-EOL Python version. Numpy already has wheels out for 3.14. And even if you use an older Python, the older compatible Numpy versions don't go away.

Can you give a concrete example of an installation you attempted that failed?


It's rarely the python version itself that is the problem (provided everything supports 3.9+ or similarly recent versions).

The package versions are however fraught - our machine learning codebase at work only was stuck on the 1.x versions of numpy for more than a year, as scipy and ultralytics both took forever to upgrade, and that prevented us adopting packages that depend on the 2.x numpy.


The entire point of the virtual environments is that you can have both on your system, as needed, for separate projects.

But the language isn't designed to support multiple versions of the same library in the same runtime environment. If you get them both to load (and there are a lot of ways), they are different libraries (actual different module objects) with different names (or the same name in different namespaces). Packaging tools can't do anything meaningful about this. I write about this on HN more often than I'd like; see e.g. https://news.ycombinator.com/item?id=45467514 . It's also covered in https://zahlman.github.io/posts/2024/12/24/python-packaging-... .




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: