Skip to content
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

Check for pip configuration when an externally managed environment is detected. #979

Merged
merged 24 commits into from
Aug 15, 2024
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
696be7b
Raise an error when an externally managed environment is detected.
nuclearsandwich Aug 8, 2024
c121579
Fix typos and punctuation.
nuclearsandwich Aug 8, 2024
e9ad440
Use tuple rather than list literal.
nuclearsandwich Aug 8, 2024
8ce4a75
Consolidate version check.
nuclearsandwich Aug 9, 2024
2c76686
Pass necessary environment variable via sudo.
nuclearsandwich Aug 9, 2024
29ec176
Update test to expect sudo --preserve-env for pip.
nuclearsandwich Aug 9, 2024
48b9da2
flake8 cleanup
nuclearsandwich Aug 9, 2024
a5e10e7
Run pip tests with PIP_BREAK_SYSTEM_PACKAGES=1.
nuclearsandwich Aug 9, 2024
f042758
Add documentation for pip configuration.
nuclearsandwich Aug 9, 2024
a2adfe8
Add doc link to error output.
nuclearsandwich Aug 9, 2024
5b2cc64
Use inline monospace font to refer to rosdep the cli tool.
nuclearsandwich Aug 9, 2024
73ed28a
Briefly note that sudo configuration could prevent this from working.
nuclearsandwich Aug 9, 2024
f1dffc6
Recommend a specific config file to use and format user config as a w…
nuclearsandwich Aug 9, 2024
f685769
Fix errors in config checker.
nuclearsandwich Aug 9, 2024
65c7152
Change formatting of rosdep.
nuclearsandwich Aug 9, 2024
f8472d2
Complete a sentence I stopped writing.
nuclearsandwich Aug 9, 2024
70775f4
Add period to end of sentence.
nuclearsandwich Aug 9, 2024
25ac0e0
Add period to end of sentence.
nuclearsandwich Aug 9, 2024
8c57dba
Invert conditional for an earlier return.
nuclearsandwich Aug 9, 2024
56a745a
Edit text for clarity and typos.
nuclearsandwich Aug 9, 2024
a2e9a1e
Reflow conditional for easier reading.
nuclearsandwich Aug 10, 2024
f14c6de
Fix control flow after inverting the conditional.
nuclearsandwich Aug 10, 2024
8b48f13
Add test to confirm that get_install_command handles externally manag…
nuclearsandwich Aug 10, 2024
8e94ef1
Use ConfigParser.getboolean to check config value.
nuclearsandwich Aug 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/rosdep2/platforms/pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
import subprocess
import sys

from configparser import ConfigParser
from pathlib import Path

try:
import importlib.metadata as importlib_metadata
except ImportError:
Expand All @@ -43,6 +46,15 @@
# pip package manager key
PIP_INSTALLER = 'pip'

EXTERNALLY_MANAGED_EXPLAINER = """
rosdep installation of pip packages requires installing packages packages globally as root
nuclearsandwich marked this conversation as resolved.
Show resolved Hide resolved
When using Python >= 3.11, PEP 668 compliance requires you to allow pip to install alongside
externally managed packages using the 'break-system-packages' option.
The recommeded way to set this option when using rosdep is to set the environment variable
PIP_BREAK_SYSTEM_PACKAGES=1
in your environment.
"""


def register_installers(context):
context.set_installer(PIP_INSTALLER, PipInstaller())
Expand Down Expand Up @@ -70,6 +82,35 @@ def get_pip_command():
return None


def externally_managed_installable():
"""
PEP 668 enacted in Python 3.11 blocks pip from working in "externally
managed" envrionments such operating systems with included package
nuclearsandwich marked this conversation as resolved.
Show resolved Hide resolved
managers. If we're on Python 3.11 or greater, we need to check that pip
is configured to allow installing system-wide packages with the
flagrantly named "break system packages" config option or environment
variable.
"""
if sys.version_info[0] == 3 and sys.version_info[1] >= 11:
if "PIP_BREAK_SYSTEM_PACKAGES" in os.environ and os.environ[
"PIP_BREAK_SYSTEM_PACKAGES"
].lower() in ["yes", "1", "true"]:
nuclearsandwich marked this conversation as resolved.
Show resolved Hide resolved
return True
if 'XDG_CONFIG_DIRS' in os.environ:
global_config = ConfigParser()
for dir in os.environ['XDG_CONFIG_DIRS'].split(":"):
global_config_file = Path(dir) / "pip" / "pip.conf"
global_config.read(global_config_file)
if global_config['install']['break-system-packages']:
return True
fallback_config = Path('/etc/pip.conf')
global_config.read(fallback_config)
if global_config['install']['break-system-packages']:
return True
return False
return True


def is_cmd_available(cmd):
try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Expand Down Expand Up @@ -145,6 +186,8 @@ def get_install_command(self, resolved, interactive=True, reinstall=False, quiet
pip_cmd = get_pip_command()
if not pip_cmd:
raise InstallFailed((PIP_INSTALLER, 'pip is not installed'))
if not externally_managed_installable():
raise InstallFailed((PIP_INSTALLER, EXTERNALLY_MANAGED_EXPLAINER))
packages = self.get_packages_to_install(resolved, reinstall=reinstall)
if not packages:
return []
Expand Down
Loading