I’m not sure why you’re answering about UX, because the really important point in my answer was that these tools and the conda-forge distribution have been designed precisely for these problems, with a dedicated community around it.
Yes, and I wonder whether the time has come now that some tool is being actively promoted for doing just this.
Because, unless those tools have options I’m not aware of, uvx someapp (which is what’s now being promoted) is a very different experience than installing someapp via conda-forge, activating the environment, and then running it. So offering those other tools as an alternative won’t be a very compelling alternative.
There’s also condax, which is similar to pipx (not sure how much maintenance it gets, but it works), and gives you access to all packages from conda-forge and Anaconda (such as clang, gcc, gdb, cmake, etc.).
This is very offtopic, but it appears that uvx pixi runs a completely different command line tool than the one being discussed here This is obviously my error for not reading the docs, but it was still a bit of an unexpected surprise.
PyPI admin here sharing from my experience facilitating the service for a while, only.
The PSF has historically been the entity that ensures the sustainability of the de-facto index, and I feel certain it is equipped to do so.
The PSF has a mission. That mission is committed to by the trust of the community and by US tax law.
PyPI must always act in accordance of that mission, and everything else is a liability.
My perspective on this is solely based on that concern.
There is a compounding concern with the extent of sponsors support for the python package index becoming “a free CDN”.
It is best for the PSF and for its sponsors that PyPI always fulfills its mission as a matter of course and defends against abuse and misuse as a matter of sustainability.
Hosting arbitrary software is not aligned. Hosting software that is open source and of practical value to Python developers and users is always aligned.
How users, lawyers, and accountants interpret that alignment is beyond me , I have often encouraged a conservative approach to this and would do so in this context as well.
About the ripgrep case, and purely from a UX perspective: I’d view it differently if it was Python software depending on it via `subprocess.run()` or just a convenient way for someone to install or run it in an unrelated context. It seems to me like the major question is whether a Python package can somehow express a dependency on ripgrep (perhaps a specific version of it). In that sense, it sounds more similar to your CMake example to me: Your Python code depends on it, and because PyPI is really an island that can only express dependencies inside the island, people have figured it’s convenient to put everything their Python code depends on inside that island. I think nowhere this is as clear as with all the different CUDA libraries that data science folks use; but, really, is `subprocess.run`ing ripgrep so different from using cDLL on a cuda library?
I also do not intend to express an opinion on what the policy should be; and, yes, pypi becoming a free-for-all data storage warehouse sounds concerning. I just think there’s a UX justification, if we take things to a ridiculous extreme, for a Python-based emulator depending on a “Python package” that provides a Linux distribution’s installation media image: That’s the only kind of dependency your package can express.
Does this mean, to you, that packages on PyPI should have unexpressed dependencies? That they should not be at all on PyPI if they have dependencies they cannot express (except if they’re put on PyPI)? That there should be a dummy package on PyPI telling to use another distribution mechanism (would suck if someone else grabbed the name of the package)? Or that it’s reasonable to expect packages on PyPI to just subtly break without warning if you have the wrong version of CMake or ripgrep?
I find this suggestion interesting, because I actually somehow imagined CPython developers are not big fans of approaches like conda. (Maybe this was historically the case?) I am a data scientist and used to fight a lot with cuda version dependencies etc. Still, to me at least conda, long time ago when I looked into it, seemed like “a terrible hack” to be avoided. I wish I remembered why exactly, but I suspect it was around the idea that they would choose one set of versions that they support, and somehow that set never matched what you—or typically Python code you got from elsewhere—needed; then you’d have to go to pypi anyway to augment it, and things would break and you would have been better off using uv or whatnot alone to manage the whole mess anyway. I admit my insight is very dated and reality may be much more rosy today (I have switched to nix+uv instead of conda or pixi).
On the other hand, it feels to me like you are saying that conda and pixi solve Python dependency problems that could be solved using PyPI in some cases, as people are doing, but you’d prefer people not to and go use conda or pixi instead. Do I read this correctly? (Not meant as a criticism; I think putting the whole world on PyPI is opens very interesting cans of worms.)
They have already. Any package [1] that requires a C or C++ compiler for building has an unexpressed build dependency. Python packaging (of which PyPI is a logical consequence) was never designed to deal with non-Python dependencies.
I don’t think there’s a uniform opinion among CPython developers about conda vs. pip etc.
For now, I am simply pointing out that PyPI was not designed for this. Any attempt to use it for non-Python dependencies may run against limitations or inefficiencies (such as the lack of cross-package dynamic linking). I am also pointing out that those additional packages may also constitute an additional burden for the small team that maintains the infrastructure.
My personal opinion is that on the surface that feels like it’s falling into the grey area, but it’s hard to know specifically how I’d feel without looking into how it’s being used, and it’s relatively small and self contained so it’s unlikely to rise to the top of the list of things to spend time on.
I’d probably personally be inclined to allow it both because the cost is relatively low and I think there’s probably a reasonable justification for using it in Python development workflow… but that’s just my personal off the cuff opinion.
Python fills a notable combination of gaps for installing and running binaries:
Python provides platform independent installation. Without a Python package manager, you either need to use OS or even distro-specific tooling, or different shells. Staying with the ripgrep example, you can see a dozen examples in the GitHub search and on grep.app, either OS specific or GitHub Actions specific (taiki-e/install-action). For uv itself as another example, we have a Unix curl | sh installer, a Windows PowerShell installer and an astral-sh/setup-uv (and a dozen official or inofficial alternatives), but nothing that works universally [1]. On most Python CI or development environments, Python is available, or your already using Python for some script.
Python packaging handles platform detection: It selects archives based on glibc versions and musl, it handles the minimum macOS version and all those tier 2 and tier 3 that custom installers usually don’t extend to, and there’s a built-in build-from-source fallback with arbitrary build systems across programming languages [2]. As a side-product of manylinux, we’ve accidentally developed a leading binary distribution system.
Packaging tools can backtrack to a version old enough to support your platform (e.g., where x86_64 mac was dropped), they can pin versions (old versions remain available) and there’s integration with updating (dependabot, renovate) and auditing tools. There is no installer script involved that wants to change PATH or edit your dotfiles. Packaging tools have hash checking and get a lot of security scrutiny, you can declare and manage tool versions in (standardized) files, there’s isolation with precedence for an active environment (venvs).
Installing a tool with Python is standardized: You don’t need to figure out how the archive is structured (and if the structure was changed in the last major version), it’s always the same command. That is not to say that curl | tar or apt install ripgrep is wrong, but there’s a lot of convenience you can get from the standardization on a single install commands (uvx ...), a lot of (complex) features you can get from the extensive ecosystem.
I’ve intentionally avoided talking about whether it’s appropriate to use PyPI as host for those binaries; that’s not my expertise. This is just about why Python is appealing as a binary distribution mechanism.
There just doesn’t seem to be a winner for cross-platform from all the binary installation tools ↩︎
If you’re using maturin, we even install the compiler for you, on all platforms rustup supports ↩︎
It does not, really, since conda and pixi readily do that. Much of what you’re saying [1] in favor of Python package managers applies to pretty much all other package managers too.
There’s one major difference. PiP is much more likely to be present on machine already than conda. Having to install conda goes back to the problem of needing to likely follow platform specific instructions.
Actual technical side of pip/conda is not really as relevant. The main thing is which command is most likely to work on random machine with as few steps as possible.
But pip does not provide a good experience for distributing binaries. You need to create a virtual environment, activate it and install the binaries there. Or install into the system environment, which is often protected and/or needs scary flags like --break-system-packages to do the install.
For distributing binaries, you need pipx or uv, which are not that likely to be installed on your machine. Yes, it’s easy to install uv[1], but isn’t that sort of the point? It’s easy to install uv as a standalone binary, so why not install all those other standalone binaries the same way?
Less so to install pipx, because it’s written in Python, but that’s a whole different problem… ↩︎
curl -fsSL https://pixi.sh/install.sh | sh # unix
# or
powershell -ExecutionPolicy Bypass -c "irm -useb https://pixi.sh/install.ps1 | iex" # win
Of course, all the caveats about not running scripts from untrusted sources apply[1], but my point is pixi is dead easy to install, and then gives you immediate access to a very wide range of “system” tools/libraries/etc. It’s also nowhere near as heavy-weight as conda[2], which is why I’m specifically talking about pixi here.
you can check out the sources of those scripts, which are linked from the installation page↩︎
This is rapidly getting off-topic. To bring it back to the original question, isn’t the point of the argument that it’s easy for publishers to publish their binaries to PyPI, and then users can run them easily using uvx the_app? So there’s two real objections here:
The point of this thread, which is that publshing binaries on PyPI is an abuse of the intended purpose of PyPI. I think there’s a reasonable consensus here that it is an abuse, and while it might be OK on a case-by-case basis (such as CMake, used by build backends) it’s not OK as a general distribution mechanism.
The idea that it’s “easier”. For users, it’s no easier than many other mechanisms[1]. For publishers, it’s not actually that easy - the original article suggests using a tool to do the publishing, and it would be just as easy to write a tool to generate other types of install (shell scripts, the way uv and pixi are installed, for example).
IMO, publishing single-file binary executables is an example of something that’s “nearly easy”. It’s straightforward to publish your tool to (for example) github releases, and that’s good enough for many users. But the last step of finding a cross-platform solution that is simple enough for any user is difficult. Publishing via PyPI only works by pushing the problem back onto other tools, by assuming the user has uv and/or pipx installed.
So ultimately, I think the original article is both misguided in the way it suggests that this “solves” the distribution question, and harmful in encouraging a misuse of a public resource, PyPI.
Not least because it requires uv or pipx to make it easy, and you can’t assume an average user will have one of those already installed. ↩︎
The point was that the case of “it’s hard to do X without pushing stuff to PyPI” is not actually all that strong, which coincides with the broader argument you’re making (basically, I agree with your comment 100%).
Just because PyPI is “there” and (after a lot of work by many people) pretty easily accessible, doesn’t mean it should be misused for distributing things that are completely unrelated to the python community.
And in complementary fashion once more, the point (by @pitrou and myself) is that there are other distribution channels that explicitly consider “distribution of generic binaries” as in-scope, so saying “no” here isn’t even leaving people out in the cold with zero options.
One side benefit of this thread is that it’s made me aware of pixi. I’m not a user of conda, so knowing that there’s a lightweight entry point into that ecosystem without having to buy into the “full conda experience” is very interesting to me.
To keep things somewhat on topic, one argument that could be made in favour of publishing on PyPI is that there’s no approval process - you just do it. Is it possible for a tool developer to just publish to a conda channel in the same way? Having to submit your new utility to conda-forge, and wait for it to get approved and added, is additional friction that I could see being used as an argument against that option.