-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom distutils/sysconfig INSTALL_SCHEME leads to different paths in virtualenv, how to avoid this? #2208
Comments
I'll have to have a think about this and come back to you 🤔 how does venv solve this or are you patching venv too? |
The main problem here is that you overwrite the existing The second problem is that virtualenv does not pick a specific scheme, but instead uses the default one, which may change at runtime. This is now expected by the upstream as of Python 3.10, with the addition of https://docs.python.org/3/library/sysconfig.html#sysconfig._get_preferred_schemes. My proposed solution: Fedora should add a new scheme, instead of overwriting virtualenv should ask for a specific scheme, as the default one can change. I would recommend selecting |
No idea how it solves this, but it naturally works. We don't patch it. Maybe it sets real_prefix before asking for the paths?
The problem with this approach is that not everything respects _get_preferred_schemes. IIRC even distutils doesn't. That's why we cannot do that (just yet).
If it does, we can patch our virtualenv for now to use the scheme we want... I've tried that, but the problem is, virtualenv prefers distutils results when it is available.
Having a specific scheme for this would make this easier indeed. |
venv's https://github.com/python/cpython/blob/v3.10.0/Lib/venv/__init__.py#L122-L131 |
Hi, sadly we cannot prefer sysconfig over distutils as that wouldn't be backwards compatible. I'd be open for a proposal that allows upstream patching what scheme virtualenv is using, but this must be a new API. |
A hacky workaround is to hotpatch virtualenv/discovery/py_info.py PythonInfo.install_path(): # A hack for https://github.com/pypa/virtualenv/issues/2208
if result.startswith(u"local/"):
return result[6:]
return result |
Ack. You can add a similar patch to distutils tough.
Shouldn't distutils produce the same paths on non-patched Python installations? |
The entire point of this endeavor is that we cannot longer patch distutils, as setuptools wants to bundle their own and users tend to update setuptools from pip, which would erase our patches :/ |
And it is in the process of being updated to honor sysconfig :) |
I wonder whether we could somehow detect that it is virtualenv who's asking for the scheme. Or if virtualenv could explicitly say that (e.g. by first checking for a specially named prefix and falling back to the present behavior). Was that what you had in mind with:
? |
The later 👍 |
This is my totally untested draft of that: diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py
index 0de6128..027507a 100644
--- a/src/virtualenv/discovery/py_info.py
+++ b/src/virtualenv/discovery/py_info.py
@@ -73,7 +73,16 @@ class PythonInfo(object):
self.file_system_encoding = u(sys.getfilesystemencoding())
self.stdout_encoding = u(getattr(sys.stdout, "encoding", None))
- self.sysconfig_paths = {u(i): u(sysconfig.get_path(i, expand=False)) for i in sysconfig.get_path_names()}
+ # https://github.com/pypa/virtualenv/issues/2208
+ if "posix_venv" in sysconfig.get_scheme_names():
+ self.sysconfig_scheme = "posix_venv"
+ self.sysconfig_paths = {u(i): u(sysconfig.get_path(i, expand=False, scheme="posix_venv")) for i in sysconfig.get_path_names()}
+ self.distutils_install = {} # we cannot use distutils at all if "posix_venv" exists, distutils don't know it
+ else:
+ self.sysconfig_scheme = None
+ self.sysconfig_paths = {u(i): u(sysconfig.get_path(i, expand=False)) for i in sysconfig.get_path_names()}
+ self.distutils_install = {u(k): u(v) for k, v in self._distutils_install().items()}
+
# https://bugs.python.org/issue22199
makefile = getattr(sysconfig, "get_makefile_filename", getattr(sysconfig, "_get_makefile_filename", None))
self.sysconfig = {
@@ -95,7 +104,6 @@ class PythonInfo(object):
if self.implementation == "PyPy" and sys.version_info.major == 2:
self.sysconfig_vars[u"implementation_lower"] = u"python"
- self.distutils_install = {u(k): u(v) for k, v in self._distutils_install().items()}
confs = {k: (self.system_prefix if v.startswith(self.prefix) else v) for k, v in self.sysconfig_vars.items()}
self.system_stdlib = self.sysconfig_path("stdlib", confs)
self.system_stdlib_platform = self.sysconfig_path("platstdlib", confs)
@@ -119,7 +127,7 @@ class PythonInfo(object):
def install_path(self, key):
result = self.distutils_install.get(key)
- if result is None: # use sysconfig if distutils is unavailable
+ if result is None: # use sysconfig if sysconfig_scheme is set or distutils is unavailable
# set prefixes to empty => result is relative from cwd
prefixes = self.prefix, self.exec_prefix, self.base_prefix, self.base_exec_prefix
config_var = {k: "" if v in prefixes else v for k, v in self.sysconfig_vars.items()} Does that seem reasonable? Open-ended question: Should I check for |
If the proposal from above is platform agnostic this should be too. |
I've tested this approach and it works. For platform agnostic, I guess the scheme should just be called |
Name it venv if the venv module will also use it, otherwise virtualenv 😊 |
the venv module might use it in the future. the name shall say "this is an installation scheme for virtual environments regardless of the tool that creates them" |
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. Fixes pypa#2208
A draft PR in #2209 |
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
…ils scheme Python is preparing to allow re-distributors to set custom sysconfig install schemes in 3.11+: https://bugs.python.org/issue43976 Fedora is already adapting the default installation scheme to their needs: https://lists.fedoraproject.org/archives/list/[email protected]/thread/AAGUFQZ4RZDU7KUN4HA43KQJCMSFR3GW/ With either of the above, the distributors need to signalize the paths used in virtual environments somehow. When they set the "venv" install scheme in sysconfig, it is now favored over the default sysconfig scheme as well as over distutils. A similar technique was proposed to Python, for the venv module: https://bugs.python.org/issue45413 Fixes pypa#2208
The virutalenv hack is in the fedora-distributed version of virtualenv... Presumably eventually will become unnecessary once they provide a proper "venv" distutils? This patch applies both before and after the bump in comment 5, so your call. Differential Revision: https://phabricator.services.mozilla.com/D130410
The virutalenv hack is in the fedora-distributed version of virtualenv... Presumably eventually will become unnecessary once they provide a proper "venv" distutils? This patch applies both before and after the bump in comment 5, so your call. Differential Revision: https://phabricator.services.mozilla.com/D130410
…me if it exists Python distributors with custom default installation scheme can set a scheme that can't be used to expand the paths in a venv. This can happen if build itself is not installed in a venv. The distributors are encouraged to set a "venv" scheme to be used for this. See https://bugs.python.org/issue45413 and pypa/virtualenv#2208 Since Python that ships with the macOS developer tools does not have the "venv" scheme yet, we keep the special case below. Once it gains the "venv" scheme, it will be preferred. Fixes pypa#433
…me if it exists Python distributors with custom default installation scheme can set a scheme that can't be used to expand the paths in a venv. This can happen if build itself is not installed in a venv. The distributors are encouraged to set a "venv" scheme to be used for this. See https://bugs.python.org/issue45413 and pypa/virtualenv#2208 Since Python that ships with the macOS developer tools does not have the "venv" scheme yet, we keep the special case below. Once it gains the "venv" scheme, it will be preferred. Fixes pypa#433
…me if it exists Python distributors with custom default installation scheme can set a scheme that can't be used to expand the paths in a venv. This can happen if build itself is not installed in a venv. The distributors are encouraged to set a "venv" scheme to be used for this. See https://bugs.python.org/issue45413 and pypa/virtualenv#2208 Since Python that ships with the macOS developer tools does not have the "venv" scheme yet, we keep the special case below. Once it gains the "venv" scheme, it will be preferred. Fixes #433
Issue
With the proposal in https://bugs.python.org/issue43976 we are testing an approach in Fedora, that changes the default install scheme to use
/usr/local
paths. Essentially, we set:However, we have realized this breaks standard assumptions about virtual environments created by virtualenv.
The activation scripts and
python
s are in<venv_name>/local/bin
, not<venv_name>/bin
.This is a bummer for us and I've been trying to wrap my head around this, but I don't know how to properly solve this on our end or on virtualenv's end.
Is there something I can add to the conditional to recognize this is virtualenv asking for the paths?
I realize this is not a virtualenv issue, but rather our own, but I opened it here anyway because you are best equipped to help me out with this 🙏
Environment
python3 >= 3.10.0-2
cc @FFY00 @encukou @frenzymadness
The text was updated successfully, but these errors were encountered: