logoalt Hacker News

zahlman06/24/20251 replyview on HN

> An example:

None of this example has anything to do with performance or reliance on C dependencies, but ok.

> even now it makes 0 sense to me why virtual envs are not designed and supposed to be portable between machines with the same architecture (!).

They aren't designed to be relocatable at all - and that's the only actual stumbling block to it. (They may even contain activation scripts for other platforms!)

That's because a bunch of stuff in there specifies absolute paths. In particular, installers (Pip, at least) will generate wrapper scripts that specify absolute paths. This is so that you can copy them out of the environment and have them work. Yes, people really do use that workflow (especially on Windows, where symlinking isn't straightforward).

It absolutely could be made to work - probably fairly easily, and there have been calls to sacrifice that workflow to make it work. It's also entirely possible to do a bit of surgery on a relocated venv and make it work again. I've done it a few times.

The third-party `virtualenv` also offers some support for this. Their documentation says there are some issues with this. I'm pretty sure they're mainly talking about that wrapper-script-copying use case.

> Or why venvs need to be activated with shell-variety specific code.

The activation sets environment variables for the current shell. That isn't possible (at least in a cross-platform way) from Python since the Python process would be a child of that shell. (This is also why you have to e.g. use `source` explicitly to run the Linux versions.)

But venvs generally don't need to be activated at all. The only things the activation script effectively does:

* Set the path environment variable so that the virtual environment's Python (or symlink thereto) will be found first.

* Put some fancy stuff in the prompt so that you can feel like you're "in" the virtual environment (a luxury, not at all required).

* Set `VIRTUAL_ENV`, which some Python code might care about (but they could equally well check things like `sys.executable`)

* Unset (and remember) `PYTHONHOME` (which is a hack that hardly anyone has a good use case for anyway)

* (on some systems that don't have a separate explicit deactivate script) set up the means to undo all those changes

The actually important thing is the path variable change, and even then you don't need that unless the code is going to e.g. start a Python subprocess and ask the system to find Python. (Or, much more commonly, because you have a `#!/usr/bin/env python` shebang somewhere.) You can just run the virtual environment's Python directly.

In particular, you don't have to activate the virtual environment in order to use its wrapper scripts, as long as you can find them. And, in fact, Pipx depends on this.


Replies

oblio06/25/2025

> None of this example has anything to do with performance or reliance on C dependencies, but ok.

<C dependencies>

You'd realize why I wrote that if you used Java/Maven. Java is by and large self-contained. Stuff like Python, Ruby, PHP, Javascript[1] etc, are not, they depend on system libraries.

So when you install something on Solaris, FreeBSD, MacOS, Windows, well, then you have to deal with the whole mess.

1. Is the C dependency installed on the system? 2. Is it the correct major version or minor version? 3. Has it been compiled with the correct flags or whatnot? 4. If it's not on the system, can the programming language specific package manager pull a binary from a repo for my OS-arch combo? 5. If there's no binary, can the programming language specific package manager pull the sources and compile them for my OS-arch combo?

All of those steps can and do fail, take time, and sometimes you have to handle them yourself because of bugs.

Java is fast enough that almost everything can be written in Java, so 99% of the libraries you use only have 1 artifact: the universal jar, and that's available in Maven repos. No faffing around with wheels or whatnot, or worse, with actual system dependencies that are implicitly (or explicitly) required by dependencies written in the higher level programming language.

<Virtual envs>

I won't even bother to address in detail the insanity that you described about virtual envs, it's just Stockholm syndrome. Almost every other programming language does just fine without venvs. Also I don't really buy that issue with the lack of portability, it's just a bunch of bad design decision early on in Python's design. Even for Windows there are better possibilities (symlinks are feasible, you just need admin access).

I say this as someone who's used basically all mainstream programming language over the years.

The sane way to do virtual envs is to have them be just... folders. No absolute paths, no activation, just have a folder and a configuration file. The launcher automatically detects a configuration file with the default name and the configuration file in turn points the launcher and Python to use the stuff in the folder.

Deployment then becomes... drumroll just copying the folder to another machine (usually zipping/unzipping it first).

* * *

[1] Javascript is a bit of a special case but it's still slower than Java, on average.

show 1 reply