The irony is that poster was trying to install a solution to this very problem (virtualenv).
The broader problem is that, at this point, python is effectively its own OS. Coupled with macOS being schizophrenic between "We want to provide a posix environment for users" and "No user should ever look under the hood, so no need to tell them about all the duct taped bits."
Which brew attempts to bridge. Admirably, but never perfectly.
No, the problem is that Python's packaging system (like Homebrew's!) was created without adequate reference to prior art, has undergone much more evolution than design, and has suffered in every attempt to improve it from the fact of its adoption by a large userbase which democratically manages it so that changes must be conservative.
As a result, Python packaging has an utterly insane design that it can't evolve its way out of.
Problems that have proven more or less intractable for resolution by evolutionary change:
- total lack of static metadata— you must download a source package and attempt to build it in order to determine what its actual dependencies are
- relatedly, package setup scripts are way too powerful and can do literally anything, which makes automating Python packaging a nightmare
- any possible vendorization is deeply limited by the fact that Python processes can't include multiple versions of a single library
- the behavior of all Python packaging tools relies on the implicit state of PyPI, forcing a high degree of non-determinism unless you go to great lengths to take snapshots of PyPI
- native dependencies (i.e., dependencies on C libraries) are either just totally undeclared, or packaged abuse setup.py in order to manually compile them in an ad-hoc, unmanaged fashion
There's no way out of this that doesn't involve breaking things for Python developers who are, whether out of shortsightedness or resigned pragmatism, relying on or working around the many, various bad practices that the Python packaging 'system' currently allows.
This is why programmatically generating Python packages for general-purpose package managers like Homebrew ranges (depending on the resources made available by the package manager's design) ranges from impossible to stupidly complex and computationally expensive to kinda works but has no hope of reliability/correctness/completeness.
> No, the problem is that Python's packaging system (like Homebrew's!) was created without adequate reference to prior art
What's a good example of prior art that Python might have considered in its design? This whole discussion is super interesting to me and I'd like to read more on better examples of dependency management.
> I'd like to read more on better examples of dependency management.
I'll answer this before we do some Python history. Since there are a range of paradigms, if you really want a good sense of the main ways things are done and the tradeoffs involved in mature systems, take a look at: dnf/RPM as it's done on current Fedora, Gentoo Portage, Guix, Cargo from Rust, Flatpak, macOS' .apps, and Distri. Each of those represents a different approach.
(You could get away with just looking at dnf and Portage, which also represent modern iterations of the paradigms Python could have looked to in the early days of its own software distribution tooling, if not the earliest days of the language itself.)
SOME PYTHON HISTORY
That's a great question, in part because Python has been around so long! It's easy to collapse the past in a way that's uncharitable to projects like Python, so let me expand on this a little and cross-reference some dates to get it into perspective for both of us.
The best examples to consider today for dependency management are probably Linux distro package managers, *BSD ports systems, and Rust's `cargo`. But Python is older than Linux or any of the major surviving free Unices! So one legitimate difficulty Python has faced here is its age— what Python folks could have looked to for inspiration in 1991 was, compared to today, extremely limited and much less publicly available. They were not positioned, as the designers of Rust were, to really think through how code in the language would be distributed on day zero, before the language would see any real adoption.
There have, however, been opportunities for the Python community to rethink things in light of the work and experience of projects (like Linux distros or ports systems) where dependency management is a very central problem. There have also been occasions on which some breakage was already expected or permitted, and such a change might have been feasible. But I think the focus has been elsewhere, and the Python community and its leadership have had to face the very real risk that too many breaking changes in their language's tooling could result in shrinking or dividing the community in a way that Rust hasn't yet. So the issue isn't some unkind nonsense like ‘Pythonistas are idiots’ or whatever.
That said, by the time distutils rolled out as part of Python's standard library in 2000, apt, Debian's second-gen high-level package management tool was out and had undergone a couple years of battle testing. The *BSD ports systems had also been around for years by then, and Gentoo would hit the scene leveraging a similar approach to build a whole Linux distro that same year. I'm not sure what Linux package management tools were like, but that would certainly have been enough to tell already that static metadata for source packages was a must (and so something like setup.py is not appropriate).
Similarly with the creation of setuptools in 2004— by then there were lots of examples of mature package managers in two major paradigms: source-based (like Homebrew), and binary (like most Linux distro package managers). Similarly again with the rollout of Python 3.0 in 2008. When pipenv came out in 2018, the answer to questions like ‘why does pipenv take so long to freeze dependencies into a lock file’ (‘it has to download every package and pretend to try to build them’) revealed that the Python packaging world had failed to meaningfully incorporate lessons on package management from the outside world in the intervening 10 years.
Homebrew was a much later arrival, so its case is a little more baffling. But some of its choices that now seem naive or questionable should also be credited with its widespread adoption. For example, the choice to depend thoroughly on the underlying macOS system instead of isolating dependencies makes Homebrew pretty brittle in the face of upgrades between macOS releases, but it also made it much more convenient for getting things installed quickly from a blank slate state than other source-based package managers (i.e., MacPorts) for macOS at the time, since it meant less compiling from source. Similarly, while the simplicity of Homebrew's build recipe DSL is a current source of problems, that same simplicity (paired with embedding it in a popular, interpreted language) has made Homebrew feel approachable and helped to draw in the huge number of contributors that have worked on Homebrew's formulae.
I think of those sorts of things as paradoxical people requirements.
To wit, only people interested in new languages spend lots of effort building new languages (and their associated ecosystems).
People who have been using an existing language for years, long enough to internalize the design decisions and flaws, have little incentive to stop using something they're an expert at, to build something new.
Ergo, the person you really want designing a language and ecosystem is someone who's used existing art enough to be an expert, then decides to give it all up, start from scratch, and do something harder.
The irony is that poster was trying to install a solution to this very problem (virtualenv).
The broader problem is that, at this point, python is effectively its own OS. Coupled with macOS being schizophrenic between "We want to provide a posix environment for users" and "No user should ever look under the hood, so no need to tell them about all the duct taped bits."
Which brew attempts to bridge. Admirably, but never perfectly.
Obligatory: https://xkcd.com/1987/