8000 00251: Change user install location · fedora-python/cpython@a27528f · GitHub
[go: up one dir, main page]

Skip to content

Comm 8000 it a27528f

Browse files
hroncokencukoumcyprianfrenzymadness
authored andcommitted
00251: Change user install location
Set values of base and platbase in sysconfig from /usr to /usr/local when RPM build is not detected to make pip and similar tools install into separate location. Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe Downstream only. We've tried to rework in Fedora 36/Python 3.10 to follow https://bugs.python.org/issue43976 but we have identified serious problems with that approach, see https://bugzilla.redhat.com/2026979 or https://bugzilla.redhat.com/2097183 pypa/distutils integration: pypa/distutils#70 Co-authored-by: Petr Viktorin <encukou@gmail.com> Co-authored-by: Miro Hrončok <miro@hroncok.cz> Co-authored-by: Michal Cyprian <m.cyprian@gmail.com> Co-authored-by: Lumír Balhar <frenzy.madness@gmail.com>
1 parent 6280bb5 commit a27528f

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

Lib/site.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,15 @@ def getsitepackages(prefixes=None):
414414
return sitepackages
415415

416416
def addsitepackages(known_paths, prefixes=None):
417-
"""Add site-packages to sys.path"""
417+
"""Add site-packages to sys.path
418+
419+
'/usr/local' is included in PREFIXES if RPM build is not detected
420+
to make packages installed into this location visible.
421+
422+
"""
418423
_trace("Processing global site-packages")
424+
if ENABLE_USER_SITE and 'RPM_BUILD_ROOT' not in os.environ:
425+
PREFIXES.insert(0, "/usr/local")
419426
for sitedir in getsitepackages(prefixes):
420427
if os.path.isdir(sitedir):
421428
addsitedir(sitedir, known_paths)

Lib/sysconfig/__init__.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@
106106
else:
107107
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
108108

109+
# For a brief period of time in the Fedora 36 life cycle,
110+
# this installation scheme existed and was documented in the release notes.
111+
# For backwards compatibility, we keep it here (at least on 3.10 and 3.11).
112+
_INSTALL_SCHEMES['rpm_prefix'] = _INSTALL_SCHEMES['posix_prefix']
113+
114+
109115
def _get_implementation():
110116
return 'Python'
111117

@@ -167,6 +173,19 @@ def joinuser(*args):
167173
},
168174
}
169175

176+
# This is used by distutils.command.install in the stdlib
177+
# as well as pypa/distutils (e.g. bundled in setuptools).
178+
# The self.prefix value is set to sys.prefix + /local/
179+
# if neither RPM build nor virtual environment is
180+
# detected to make distutils install packages
181+
# into the separate location.
182+
# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
183+
if (not (hasattr(sys, 'real_prefix') or
184+
sys.prefix != sys.base_prefix) and
185+
'RPM_BUILD_ROOT' not in os.environ):
186+
_prefix_addition = '/local'
187+
188+
170189
_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
171190
'scripts', 'data')
172191

@@ -266,11 +285,40 @@ def _extend_dict(target_dict, other_dict):
266285
target_dict[key] = value
267286

268287

288+
_CONFIG_VARS_LOCAL = None
289+
290+
291+
def _config_vars_local():
292+
# This function returns the config vars with prefixes amended to /usr/local
293+
# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
294+
global _CONFIG_VARS_LOCAL
295+
if _CONFIG_VARS_LOCAL is None:
296+
_CONFIG_VARS_LOCAL = dict(get_config_vars())
297+
_CONFIG_VARS_LOCAL['base'] = '/usr/local'
298+
_CONFIG_VARS_LOCAL['platbase'] = '/usr/local'
299+
return _CONFIG_VARS_LOCAL
300+
301+
269302
def _expand_vars(scheme, vars):
270303
res = {}
271304
if vars is None:
272305
vars = {}
273-
_extend_dict(vars, get_config_vars())
306+
307+
# when we are not in a virtual environment or an RPM build
308+
# we change '/usr' to '/usr/local'
309+
# to avoid surprises, we explicitly check for the /usr/ prefix
310+
# Python virtual environments have different prefixes
311+
# we only do this for posix_prefix, not to mangle the venv scheme
312+
# posix_prefix is used by sudo pip install
313+
# we only change the defaults here, so explicit --prefix will take precedence
314+
# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
315+
if (scheme == 'posix_prefix' and
316+
sys.prefix == '/usr' and
317+
'RPM_BUILD_ROOT' not in os.environ):
318+
_extend_dict(vars, _config_vars_local())
319+
else:
320+
_extend_dict(vars, get_config_vars())
321+
274322
if os.name == 'nt':
275323
# On Windows we want to substitute 'lib' for schemes rather
276324
# than the native value (without modifying vars, in case it

Lib/test/test_sysconfig.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,19 @@ def test_get_path(self):
130130
for scheme in _INSTALL_SCHEMES:
131131
for name in _INSTALL_SCHEMES[scheme]:
132132
expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
133+
tested = get_path(name, scheme)
134+
# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
135+
if tested.startswith('/usr/local'):
136+
# /usr/local should only be used in posix_prefix
137+
self.assertEqual(scheme, 'posix_prefix')
138+
# Fedora CI runs tests for venv and virtualenv that check for other prefixes
139+
self.assertEqual(sys.prefix, '/usr')
140+
# When building the RPM of Python, %check runs this with RPM_BUILD_ROOT set
141+
# Fedora CI runs this with RPM_BUILD_ROOT unset
142+
self.assertNotIn('RPM_BUILD_ROOT', os.environ)
143+
tested = tested.replace('/usr/local', '/usr')
133144
self.assertEqual(
134-
os.path.normpath(get_path(name, scheme)),
145+
os.path.normpath(tested),
135146
os.path.normpath(expected),
136147
)
137148

@@ -386,7 +397,7 @@ def test_get_config_h_filename(self):
386397
self.assertTrue(os.path.isfile(config_h), config_h)
387398

388399
def test_get_scheme_names(self):
389-
wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv']
400+
wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv', 'rpm_prefix']
390401
if HAS_USER_BASE:
391402
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
392403
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
@@ -398,6 +409,8 @@ def test_symlink(self): # Issue 7880
398409
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
399410
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
400411

412+
@unittest.skipIf('RPM_BUILD_ROOT' not in os.environ,
413+
"Test doesn't expect Fedora's paths")
401414
def test_user_similar(self):
402415
# Issue #8759: make sure the posix scheme for the users
403416
# is similar to the global posix_prefix one

0 commit comments

Comments
 (0)
0