Python: Mark Homebrew Python as externally managed #3404
-
Hi there! I'm one of the maintainers of pip, and one of the co-authors of PEP 668. As a quick summary, that PEP is basically a design document describing a new feature's design, for Python's packaging tooling. The feature is providing a mechanism (a marker file) to inform installers like pip, that it should not try to modify files installed in a certain location since those are "externally managed" (i.e. managed by a non-Python-native package manager). Based on my very limited understanding of Homebrew (as a "I just need git and a few more things" user), it allows installing Python packages as dependencies of a package and they're importable by default. Based on that, IIUC, Homebrew should create the marker file in the appropriate location, as a part of the Python formula. So... To have a discussion about this and track it, I've filed this here. :) /cc @woodruffw, per https://discuss.python.org/t/pep-668-marking-python-base-environments-as-externally-managed/10302/39?u=pradyunsg PS: Not sure how Homebrew discussions work, but this seems like something that needs to be tracked, and should move into issues? |
Beta Was this translation helpful? Give feedback.
Replies: 35 comments 137 replies
-
Hi @pradyunsg, thanks for dropping by.
Potentially, but there may not be any need to do this (yet?), depending on how much work this transition requires exactly. If it's just a simple change, then we might not need a tracking issue at all. I'm not much of a Python user, but I scanned PEP 668 to see what the required changes might be. These values seem to be of particular interest:
Does that mean a
currently installs
? If so, that's setting users up for a bad time. |
Beta Was this translation helpful? Give feedback.
-
FWIW, implementing this would basically involve:
The main difference that user-facing behaviour change that this will cause is that users won't be able to install packages using pip into the Homebrew-installed Python, instead needing to create a Python virtual environment to install packages using pip. |
Beta Was this translation helpful? Give feedback.
-
This appears to have been recently implemented? And now GitHub Actions installs of Time to pass |
Beta Was this translation helpful? Give feedback.
-
@pradyunsg we have now implemented this starting with Python 3.12: Homebrew/homebrew-core#150390, and Python 3.12 has become the default Python 3 in Homebrew so more users will be made aware of the change. |
Beta Was this translation helpful? Give feedback.
-
Eli, I suggest worked through Concrete use cases would help your
communication here, and check your emotions.
Personally I just want meson to actually work with homebrew, and that
doesn’t seem a lot to ask. All conversations have ended with you ranting
about things I don’t understand and no progress being made.
If your aim is to support your users, maybe start calmly from that
perspective- again worked concrete usecases that the approach agreed on by
the python community fails in would be a helpful way forward for you.
…On Wed, 21 Feb 2024 at 22:16, Eli Schwartz ***@***.***> wrote:
Previously fixed for Debian in ***@***.***
<mesonbuild/meson@5c479d7>
Pending homebrew fix in ***@***.***
<mesonbuild/meson@a35d4d3>
—
Reply to this email directly, view it on GitHub
<#3404 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAB4O4GB5A7HEHZ2KLJR4WDYUZW5PAVCNFSM52QIMB52U5DIOJSWCZC7NNSXTOKENFZWG5LTONUW63SDN5WW2ZLOOQ5TQNJUHE2DSMI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Btw for reference, I am packaging a complex python project with large c++
dependencies: https://github.com/lip6/coriolis, so your concerns are valid
to me.
We’re currently forced into a fork of meson to support our macOS community.
…On Wed, 21 Feb 2024 at 23:20, Robert Taylor ***@***.***> wrote:
Eli, I suggest worked through Concrete use cases would help your
communication here, and check your emotions.
Personally I just want meson to actually work with homebrew, and that
doesn’t seem a lot to ask. All conversations have ended with you ranting
about things I don’t understand and no progress being made.
If your aim is to support your users, maybe start calmly from that
perspective- again worked concrete usecases that the approach agreed on by
the python community fails in would be a helpful way forward for you.
On Wed, 21 Feb 2024 at 22:16, Eli Schwartz ***@***.***>
wrote:
> Previously fixed for Debian in ***@***.***
> <mesonbuild/meson@5c479d7>
>
> Pending homebrew fix in ***@***.***
> <mesonbuild/meson@a35d4d3>
>
> —
> Reply to this email directly, view it on GitHub
> <#3404 (reply in thread)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAB4O4GB5A7HEHZ2KLJR4WDYUZW5PAVCNFSM52QIMB52U5DIOJSWCZC7NNSXTOKENFZWG5LTONUW63SDN5WW2ZLOOQ5TQNJUHE2DSMI>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
Beta Was this translation helpful? Give feedback.
-
Thank you @robtaylor; I personally appreciate your level-headed response. Nobody here wants to break users; adopting PEP 668 is (from my perspective) an important stepping stone towards reducing the number of error states that users of the Homebrewed Python frequently end up in. As the PEP and its original discussion thread note, it's necessarily a tradeoff between various stakeholders in the huge Python community; it's unfortunately impossible to simultaneously make changes and preserve every Python package deployment patterns. In terms of improving things here, I think there are two pieces we need:
|
Beta Was this translation helpful? Give feedback.
-
I ended up here post a recent update of homebrew, which installed python 3.12.2, but missed 80-90% of the packages which existed in the previous version (/usr/local/lib/python3.11/site-packages/), so almost no python programs in need for some modules work now (the dreaded "ModuleNotFoundError: No module named '...'). Attempting to fix this "the old way" (python -m pip install --upgrade ) produces the "new" × This environment is externally managed Any suggestions on how to fix missing site-packages (brew install does not find specific missing modules)? EDIT as I needed my python stuff to still work, and ASAP, I ended up with the most rudimentary solution possible: copied the content of /usr/local/lib/python3.11/site-packages/ into /usr/local/lib/python3.12/site-packages/. I know this is an unsustainable method, but short of blowing up the homebrew environment, and moving to a per individual package maintenance - with a total install of everything I need, one by one - I think this is all that can be done. I also understand and I remain very thankful for the extraordinary effort the homebrew community has put into this project, which made macos so much more useable in the past. |
Beta Was this translation helpful? Give feedback.
This comment was marked as disruptive content.
This comment was marked as disruptive content.
-
I can't install packages by |
Beta Was this translation helpful? Give feedback.
-
I would just like to make it clear that my disagreement with "externally managed" python doesn't mean I necessarily agree with any other criticisms in this thread. But in particular:
It's not obvious to me that the author of "yet another cryptobro scam" understands users at all, let alone better than homebrew. It's also not obvious to me that someone who created something 15 years ago is necessarily the best analyst of what users today need, which... may explain why the original creator of homebrew is now trying to start "homebrew but as a cryptobro scam". I also think that homebrew has drastically improved since its initial introduction in 2009, and not everyone agrees that it was any good, or any reliable, when it was first created. It is... theoretically possible... that later homebrew leads were responsible for, to put it bluntly, making homebrew popular with users. The "externally managed" python is relatively small potatoes here. I can disagree with the decision without thinking that homebrew is being destroyed by its leadership and doomed to extinction. Homebrew is doing a lot of great work! Your efforts are appreciated. ᵉᵛᵉⁿ ᶦᶠ ᴵ ʷᶦˢʰ ᶦᵗ ʷᵒᵘˡᵈ ᵈᵒ ᵇᵉᵗᵗᵉʳ ʷᵒʳᵏ ʷ.ʳ.ᵗ. ᵖʸᵗʰᵒⁿ |
Beta Was this translation helpful? Give feedback.
-
I haven't been keeping up with the discussion here (life and all) and it seems like there's a bunch of pushback and vitriol from a few vocal users who passionately disagree with this change. To these folks: Please be respectful to Homebrew maintainers here, especially please don't go down the route of name-calling, or berating their work on Homebrew where they're doing to build something extremely useful overall. Nudging them away from following broader upstream standards that are intended to protect less experienced/familiar users against subtle failure modes is something you're OK to argue for, and having a discussion about the tradeoffs involved is also fine. Berating or name-calling them is not.
Indeed. To the Homebrew maintainers: Thanks for adding this file, and adopting these protections. I've said this elsewhere and, is hopefully obvious already to some of you: I think this is a good thing in the long run, especially for anyone who is using Python for the first time since it prevents a very common "I don't know what I'm doing" mistakes by replacing a subtle "this could mess things up if you don't know what you're doing" case with a clear error message. As is hopefully also evidenced by the number of people who were either directly authors of the PEP in question or otherwise engaged in the discussions around it, this is a change for the better, even though it does break certain user workflows (in that they now need to pass an additional flag, or set an env var or run a command once to update a config file). Thanks also for dealing with the pushback here amicably -- I realise it's not my fault per se what Someone Else On The Internet™ does and, I do also recognise that I nudged y'all to do this. 😅 |
Beta Was this translation helpful? Give feedback.
-
My $0.02, with all respect due to the hard working folks maintaining
homebrew, for people like me to use: if I run an upgrade that blows up my
entire working environment, the feeling is one of microsoft déjà-vu, where
the process of upgrade doesn't offer any hints and choice for conducting it
safely, vs leaving the host in an unusable state. I know there are
workarounds, but the next thing one needs to immediately consider, post a
recovered_from_last_upgrade, is to how to get out from under homebrew.
Thanks again - sincerely!
…On Mon, Mar 4, 2024, 8:19 PM William Woodruff ***@***.***> wrote:
PEP 668 is a standards track PEP which means that, by definition, it is
normative. You can refer to PEP 1 for the distinction between standards,
process, and informational PEPs. Concretely: informational PEPs are the
least normative of the PEP categories, which PEP 668 is not.
Distributions can choose to ignore standards track PEPs if they want when
it comes to packaging standards, but we don't want to. We *want* to do
the standard thing, and our reasons have previously been extensively
explained. Language lawyering over what we "have" to do does not enter into
it.
—
Reply to this email directly, view it on GitHub
<#3404 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABS4BN4FAH6WYK7UQG5JMTYWTCMVAVCNFSM52QIMB52U5DIOJSWCZC7NNSXTOKENFZWG5LTONUW63SDN5WW2ZLOOQ5TQNRXGEYDMOI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Hi - I'd like to add my perspective here, as a very long-term Python user, and a user of Homebrew Python for about a decade. I think this change to externally-managed is a serious error - and it makes Homebrew Python useless for my (very common) case. To summarize:
So here's a humble beg from a very long-term, and committed user of Homebrew Python, and someone who has been involved in packaging for a very long time - please revert this change. In more detail: To be clear - I believe the use-case that the Python Packaging Authority often has in mind, is that of a developer of web-frameworks, deploying applications. And this change could make sense for those people. For those people, the primary concern is making sure that the application (framework) stays stable to multiple installations. For those people, However, I am willing to bet some significant sum, that those people are: a) Perfectly cabable of managing their own virtualenvs and I'll document this if it's helpful - but I am confident that a large majority of your users are science / data Python users, who are installing Numpy, Pandas and other scientific Python packages. For those people, "apps" are niche to the point of being irrelevant. In particular, the only "app" these users install often, is Jupyter, in some flavor - and they very explicitly need nearly all their other packages in the same virtualenv as Jupyter. For these users - like me - and all my students (I'm a university professor) - the externally managed model is so difficult to use that we will have to switch away from using Homebrew entirely. Indeed, I've just, very reluctantly, switched to Why? Because in practice - and I have a lot of practice, the way that I and many others work, is to have one default environment, in which we install everything, where everything is nearly always Numpy, Pandas, scikit-learn, matplotlib and other pretty stable sets of packages that rarely conflict. This is how we get students started with their installs - example : https://lisds.github.io/dsip/installation_on_mac.html. Variants on those instructions were a simple route into a working Mac installation for beginners. But now it isn't, because the beginner will be told a) they can't use pip to install packages and b) be pointed to "virtualenvs", which they do not currently need, nor understand and c) will in particular be guided to
So the "externally managed" solution, is solving a problem that I and my students don't have, at the expense of making it much harder for them to get started without learning a whole lot more about Python packaging and virtualenvs. So I think, in practice, we'll have to either downgrade to Python 3.11 and hope y'all change your minds on this one, or find another way of installing Python that doesn't cripple standard default installation. And I suspect - I say this very sadly - that the result will be that you will have a very sharp drop in the number of people using Homebrew Python, for virtually no gain in terms of real problems solved. |
Beta Was this translation helpful? Give feedback.
-
Totally agree. I think this was just historical - that they didn't want to change pip's behavior. Then they decided (I think) that there wasn't much advantage to giving a permissions error over just installing to --user if the user didn't have permission, giving the current behavior.
Yes - that seems like an excellent trade-off to me - and I'm sure @eli-schwartz would also agree that, for that case, This is a change of course, in that packages that used to go to site-packages now go to --user . But it must be rare that this will cause a problem - I'm failing to think of anything immediately. In particular, the user will now need to put the --user binary path on their
Hmm - so - as I said - even with the previous behavior - I'm pretty sure I never broke a Homebrew package with a |
Beta Was this translation helpful? Give feedback.
-
Trying to unpack the argument here - it is that, if there is one default installation location (be it
Right - and of course I'm arguing that disabling
I think I'm not following - which group is someone like me in - who uses |
Beta Was this translation helpful? Give feedback.
-
In case it's helpful - I can't imagine a popular and successful solution that forces beginners to learn and use virtual enviroments. For example, Conda and Pyenv do provide default environments, so users can happily install with default install instructions until they realize they need isolated environments, and that's when they learn about creating and switching environments. If we agree on that - I still see no strong argument against the |
Beta Was this translation helpful? Give feedback.
-
And I guess agreeing with your implicit point here - it's very difficult for me to see why the |
Beta Was this translation helpful? Give feedback.
-
We've discussed this a bit internally, and have come to the conclusion that the "system" side of PEP 668 is still a desirable property for Homebrewed Python. Given that PEP 668 doesn't currently give us a way to indicate that that some managed Python distributions aren't necessarily broken by user-site installations (i.e.
I'm curious to hear what people think of this: it's probably not the ideal solution for everyone (things are still harder than before for |
Beta Was this translation helpful? Give feedback.
-
Another summary email after some reflection: Summary: Homebrew should not use the EXTERNALLY-MANAGED system until there is a mechanism for a transparent-to-the-user default virtual environment. I have a proposed solution at the end. Detail: There are several separable problems here, and the PEP is addressing these problems at the same time, causing confusion as to the motivation and desirability of the change. The PEP assumes that it is not a major burden on the user to enforce the conscious use of virtualenvs, but I believe this assumption is seriously wrong for most users of Python. Explicit use of virtualenvs is an advanced tool, and is confusing and unnecessary for most beginners. The separable problems:
The PEP wants to solve all three problems at the same time, at the expense of forcing users to understand and manage virtualenvs. It seems the PEP authors do not believe this is a significant burden, but Eli gave a good explanation of what that burden is. Certainly, as a teacher, I cannot afford to spend multiple classes explaining Python paths, pip and package management before they can get started. Taking the three problems one by one:
Risk: Users (and teachers) will quickly abandon Python installations that try and force beginners to use virtualenvs, and prefer installations that do not. In particular, I predict a rapid switch to Conda installs, because they provide binary installers for Python and a transparent default environment. Solution: Given that it would be fairly easy to prefer This problem could be solved substantially, by having a system that, instead of preferring |
Beta Was this translation helpful? Give feedback.
-
I haven't fully caught up to the discussion here (health and family stuff) but @matthew-brett's most recent comment indicates to me that at least some of this discussion should probably be moved to https://discuss.python.org/c/packaging/feedback/37. |
Beta Was this translation helpful? Give feedback.
-
I'm happy to have that discussion there too, but for the moment I think there are two questions:
I was primarily arguing for a No, for the second, but of course I would also argue Yes for the first. I'm arguing No for the second on the basis of greater cost than benefit, particularly for beginners, compared to the less invasive switch to But I am sure that some version of this PEP, that does allow a transparent default virtualenv, could be of great benefit compared to relatively small cost. |
Beta Was this translation helpful? Give feedback.
-
This has come up a few times before: Homebrew distributes Python because millions of users install formulae that depend on it, not because the Homebrewed Python is itself intended to be the ideal distribution of Python for every potential downstream use case. If people chose to switch to Anaconda or (This doesn't meant that we want to break people who directly use the Homebrewed Python rather than transitively, but we stack their interests against (1) what PyPA standard and tooling are aligned with, and (2) the transitive use case. PEP 668 adoption breaks in favor of the transitive case, especially since virtual environments will continue to work and are encouraged.)
This is better suited for a PEP or pre-PEP discussion, I think: Homebrew would have to pretty invasively patch either (I suspect that the |
Beta Was this translation helpful? Give feedback.
-
Right - but I think it's important to concentrate on what this PEP solves, compared to
It's clear I think that the PyPA puts high value on multiple virtualenvs - and there is a small sub-population of advanced users for whom that pattern makes sense. Perhaps PyPA wishes that it would or should make sense for more users - but if that is the plan - I am confident it will fail - because it has such little utility for beginners, and such high cost. All that will happen is that you will push users off the installs that do choose to use this PEP - onto any other install that doesn't use this configuration. And likely, that will be Conda, and likely, that will cause development effort to switch from pip to conda. Which is unfortunate - but at least we see the benefit of competition - if one system makes a decision that doesn't take the broad range of users into account - the other can reap the benefit. Has any other substantial distribution adopted this PEP? I'd be surprised if they have - but also interested in what discussions looked like in making the decision. |
Beta Was this translation helpful? Give feedback.
-
Just throwing it out there - but I wonder whether the way forward would be to have a light fork of |
Beta Was this translation helpful? Give feedback.
-
I thought I'd add this vignette - because it may not be obvious what the extent of the problem is going to be for beginners. Here's an example. Let's say I install Homebrew Python 3.12. I'm a beginner, interested in Python game programming, and I found this tutorial. Very typically, for beginner tutorials, it says that I need to install
I run that, and I see this:
Remember, I'm a beginner, so I guess I try:
Maybe I do a bit of Googling, and work out that I may want:
Now I'm a bit confused, and I go back to the original message. This is the next
Presumably I would have given up on Homebrew by now, but let's say I'm brave,
But I still really need to know what this virtual environment thing is, that I will have Ok, but now I want to use
but now I have to work out that my next step is:
In short, I'll have to understand what virtualenvs are and how they work. More plausibly, the instructions on virtualenvs above look so confusing,
OK, I work out that I first need:
Then:
I get:
OK - so I'm left with this final note:
That sounds far too scary - I mean - the Homebrew people wouldn't give me that |
Beta Was this translation helpful? Give feedback.
-
It's hard to prove, but not difficult to estimate.
Yes, I understand the parameters of the discussion now, and I will stop. I was going to suggest you consider monitoring for the effect I predict - a rapid loss of "user" installs, as opposed to "system" installs, but on reflection, I think you're saying you're prepared to accept that, and, in any case, by the time you detect it, it will be too late. |
Beta Was this translation helpful? Give feedback.
-
After initially being concerned about this, the actual migration (especially after Homebrew/homebrew-core#165681 landed and clarified the guidance) was pretty straightforward. The only question for me is whether there are libraries that "should" be installed globally. Only one I've found so far is pynvim, but also I haven't actually had any issues after removing this library entirely and trusting that things that need it will install it. |
Beta Was this translation helpful? Give feedback.
-
Is there any chance that the example code Yes, it's easy when you know how, but I'm guessing a lot of the pain felt here is caused when people don't know how! Python virtual environments may well be something many users have never needed - up to now - if they were just/mainly treating Python as a source of dependencies (or other use cases such as maths/stats as mentioned above). |
Beta Was this translation helpful? Give feedback.
@pradyunsg we have now implemented this starting with Python 3.12: Homebrew/homebrew-core#150390, and Python 3.12 has become the default Python 3 in Homebrew so more users will be made aware of the change.