On 27 April 2017 at 11:47, Nico Kadel-Garcia nkadel@gmail.com wrote:
On Wed, Apr 26, 2017 at 7:13 AM, Charalampos Stratakis
At the present time, running sudo pip3 in Fedora is not safe. Pip shares its installation directory with dnf, can remove dnf-managed files and generally break the Python 3 interpreter.
This is true of every version of pip, not merely pip3. It was also true of CPAN, and of many gradle, maven, and ant working environments that semi-randomly collate the very latest versions of indeterminate components and spray them on top of your system workspace with their own quite distinct ideas about packaging and versioning.
There is no solution to this problem, except to use tools like "pyvenv" to set aside secluded workspaces for Python modules and their dependencies assembly. So, for most developers, they *should not* use "sudo pip". They should remain in user space, or possibly in shared workspaces, to avoid overwriting system components.
Nothing is changing in terms of *recommended* practices. This change proposal is entirely about harm mitigation for the cases where users *do* run "sudo pip ...", either because that's their instinctive reaction to a permissions error, or because some misguided installation instructions for a 3rd party package advised them to do it.
Debian and derivatives already mitigate the potential harm for these cases by requiring the "--install-layout=deb" option to be passed to get distutils to install into the system directories rather than doing it by default: https://wiki.debian.org/Python#Deviations_from_upstream
Their approach means that any harm caused by "sudo pip install X" can subsequently be fully reversed by doing "sudo pip uninstall X".
At this moment, this is NOT true for Fedora and derivatives. Instead, the remediation step here is "sudo pip uninstall X && sudo dnf reinstall <something>" where you have to:
1. Figure out what "<something>" needs to be 2. Hope that whatever you broke didn't affect your ability to run "sudo dnf reinstall"
Our first attempt to make sudo pip safe on Fedora [0] was based on using a different binary (/usr/libexec/system-python) for RPM packaging purposes and changing the behavior of /usr/bin/python3 (and pip that uses its settings) to install under /usr/local by default. Switching all the Python 3 packages
Oh, Oh my. The extent to which this unworkable is... fascinating.
Nico, the contemptuous tone you have adopted in this post is entirely inappropriate. Please give other list participants the courtesy of assuming expertise at least equivalent to your own, rather than engaging in attempted displays of assumed superiority.
You will inevitably install incompatible future versions of critical packages which are incompatible with the Fedora system packages. And as soon as you install one that breaks RPM, if /usr/local/ if ahead of /usr in your search path for modules, you are *screwed*.
This isn't true, as long as the fix is as simple as using pip to uninstall whatever problematic package you just installed.
At the moment, that isn't the case on Fedora and derivatives, since "sudo pip install ..." can actually *corrupt* a system package installation, rather than merely shadowing it at import time the way it does on Debian et al.
And if /usr/local is first, well, an RPM update may introduce a component that is incompatible with the pip installed modules at arbitrary times.
The goal of this change isn't to allow co-existence of arbitrary upstream and downstream versions as supported combinations - it's to make sure that forced installation of an incompatible upstream version is an easily reversible error, rather than a potentially system-breaking mistake.
We decided to try a different approach. The main idea is to detect an ongoing RPM build and modify the behavior of the Python 3 executable only when in normal user environment so that RPM builds won't be affected at all.
See https://xkcd.com/1172/ . You're inventing a workflow that isn't supported by *anyone*.
The problem is that the default behaviour needs to change (to mitigate the potential harm caused by a relatively common end user error), but unlike Debian package builds (which know they need to set "--install-layout=deb"), most RPM builds for Python packages currently rely on that default behaviour as part of the build process. Changing the default indiscriminately would thus be a breaking change that not only affects Fedora RPM builds, but also COPR and other third party RPM builds.
So we need a solution that retains the existing behaviour for RPM builds, but changes the behaviour to be less potentially destructive when run interactively at a shell prompt, or as part of a configuration management script.
The adjustment of the behavior can be done on different levels. The first option is to set the sys.prefix variable to /usr/local when the interpreter is initialized. This will affect all the install methods, but the solution can cause some problems in applications that rely on the value of sys.prefix. A prototype of this implementation can be seen here [1].
I'm sorry, but.... ouch. Please stop trying to implement "pip install" as a system installation tool.
That is not the goal of the change.
The effort would be better spent upgrading and enhancing "py2pack".
Improving the level of commonality and collaboration between Fedora & Mageia's pyp2rpm and openSUSE's py2pack would indeed be desirable, but it's entirely orthogonal to the harm mitigation exercise being discussed here.
The other possibility is to limit the pip install location change to distutils and pip [2]. This is the "safer" option, but does not cover all corner cases. For example, Python software built locally using cmake or similar tools will be installed into /usr/lib and can conflict with system tools. Debian chose to implement similar solution.
It's local environment specific, unstable software sensitive to arbitrary and unmanaged upstream dependency updates, and extremely sensitive to local system pip modules. It *does not belong* in /usr/lib. Because the components are modular and bundled in a non-RPM compatible fashion, it behooves developers to use a tool to segregate the tools as much as feasible from the Fedora underlying infrastructure. i.e., use pyvenv to build them in a contained environment segregated from the system files.
Helping users that are already doing the right thing isn't the problem at hand - this is about making it easier for users to recover from doing the *wrong* thing.
Cheers, Nick.
On Apr 27, 2017, at 2:32 AM, Nick Coghlan ncoghlan@gmail.com wrote:
Debian and derivatives already mitigate the potential harm for these cases by requiring the "--install-layout=deb" option to be passed to get distutils to install into the system directories rather than doing it by default: https://wiki.debian.org/Python#Deviations_from_upstream https://wiki.debian.org/Python#Deviations_from_upstream
Their approach means that any harm caused by "sudo pip install X" can subsequently be fully reversed by doing "sudo pip uninstall X".
For whatever it’s worth, at some point in time I plan on attempting to formalize the Debian solution (or something akin to it) within a PEP and try to get baked in support for it in Python.
I also feel required to point out that ``sudo pip uninstall`` isn’t always enough, because while the two systems install to different locations, pip currently will uninstall the files in /usr when installing to /usr/local. They’ve patched their copy of pip to refuse to uninstall files from /usr, but upstream pip will still do it. Again, something I hope to get sorted at some point (and of course, an upgrade totally restores the files in /usr).
— Donald Stufft
On Apr 27, 2017, at 06:21 AM, Donald Stufft wrote:
For whatever it’s worth, at some point in time I plan on attempting to formalize the Debian solution (or something akin to it) within a PEP and try to get baked in support for it in Python.
I also feel required to point out that ``sudo pip uninstall`` isn’t always enough, because while the two systems install to different locations, pip currently will uninstall the files in /usr when installing to /usr/local. They’ve patched their copy of pip to refuse to uninstall files from /usr, but upstream pip will still do it. Again, something I hope to get sorted at some point (and of course, an upgrade totally restores the files in /usr).
Also note that `pip install` defaults to --user in Debian, and that alleviates a lot of the "well that didn't work, let me add sudo" urges. Upstream, this bug tracks that, although it's long standing without much recent progress:
https://github.com/pypa/pip/issues/1668
IMHO, that's the right direction to go, and I think Donald is philosophically aligned (apologies if I'm misreading that, DS!). There are of course plenty of knock-on issues to work out, which is probably why that issue is still open.
Defaulting to --user won't solve all the problems but I think it's very much a step in the right direction.
Even with this, over in Debuntu-land we sometimes still see bug reports from people who were confused by importing an unexpected version of a package, and not remembering (or knowing) that some third party version outside of the archive had been installed, and /usr/local/lib does come before /usr/lib in sys.path. This lead to https://bugs.python.org/issue29546 which will be in 3.7 and should at least help in debugging such situations.
Cheers, -Barry
On Apr 27, 2017, at 11:08 AM, Barry Warsaw barry@python.org wrote:
Also note that `pip install` defaults to --user in Debian, and that alleviates a lot of the "well that didn't work, let me add sudo" urges. Upstream, this bug tracks that, although it's long standing without much recent progress:
https://github.com/pypa/pip/issues/1668 https://github.com/pypa/pip/issues/1668
IMHO, that's the right direction to go, and I think Donald is philosophically aligned (apologies if I'm misreading that, DS!). There are of course plenty of knock-on issues to work out, which is probably why that issue is still open.
I think solving this problem (to the degree it can be solved) relies on a multifaceted solution.
One part is certainly defaulting to —user in upstream where it makes sense to do so, so that people are not incentivized by a permission error by default to just throw a sudo in front of their command to make it work.
I think the other part is recognizing that there are valid use cases for ``sudo pip install`` (just like there are for doing ``sudo make install``) and striving to make that function as best we can. The two things I think need done for that are to standardize the “vendor” vs “local” split for site-packages that Debian has, so that the two different sources of a package are not fighting over dropping files into the same directory. The other thing I think that needs to get done is for pip to get better at the concept of overlaying installs on sys.path. We shouldn’t need to uninstall something in the “Vendor site-packages” in order to install it into the “local site-packages” (And similarly for user site-packages).
— Donald Stufft
python-devel@lists.fedoraproject.org