[Dep Downloader] Added support for PEP668 compliant Debian pip

This commit is contained in:
Salvador E. Tropea 2023-08-10 09:20:02 -03:00
parent 2beb0c4ecb
commit 7bc3f11a2b
2 changed files with 27 additions and 17 deletions

View File

@ -294,7 +294,7 @@ def check_pip():
def pip_install(pip_command, dest=None, name='.'): def pip_install(pip_command, dest=None, name='.'):
cmd = [pip_command, 'install', '-U', '--no-warn-script-location'] cmd = [pip_command, 'install', '-U', '--user', '--no-warn-script-location']
if name == '.': if name == '.':
# Applied only when installing a downloaded tarball # Applied only when installing a downloaded tarball
# This is what --user means, but Debian's pip installs to /usr/local when used by root # This is what --user means, but Debian's pip installs to /usr/local when used by root
@ -302,20 +302,28 @@ def pip_install(pip_command, dest=None, name='.'):
# If we have an older version installed don't remove it # If we have an older version installed don't remove it
'--ignore-installed']) '--ignore-installed'])
cmd.append(name) cmd.append(name)
logger.debug('- Running: {}'.format(cmd)) retry = True
try: while retry:
res_run = subprocess.run(cmd, check=True, capture_output=True, cwd=dest) logger.debug('- Running: {}'.format(cmd))
logger.debugl(3, '- Output from pip:\n'+res_run.stdout.decode()) retry = False
except subprocess.CalledProcessError as e: try:
logger.debug('- Failed to install `{}` using pip (cmd: {} code: {})'.format(name, e.cmd, e.returncode)) res_run = subprocess.run(cmd, check=True, capture_output=True, cwd=dest)
if e.output: logger.debugl(3, '- Output from pip:\n'+res_run.stdout.decode())
logger.debug('- Output from command: '+e.output.decode()) except subprocess.CalledProcessError as e:
if e.stderr: logger.debug('- Failed to install `{}` using pip (cmd: {} code: {})'.format(name, e.cmd, e.returncode))
logger.debug('- StdErr from command: '+e.stderr.decode()) if e.output:
return False logger.debug('- Output from command: '+e.output.decode())
except Exception as e: if e.stderr:
logger.debug('- Failed to install `{}` using pip ({})'.format(name, e)) logger.debug('- StdErr from command: '+e.stderr.decode())
return False if not retry and b'externally-managed-environment' in e.stderr:
# PEP 668 ... and the broken Python packaging concept
retry = True
cmd.insert(-1, '--break-system-packages')
else:
return False
except Exception as e:
logger.debug('- Failed to install `{}` using pip ({})'.format(name, e))
return False
return True return True
@ -365,6 +373,7 @@ def python_downloader(dep):
# Check if we have pip and wheel # Check if we have pip and wheel
pip_command = check_pip() pip_command = check_pip()
if pip_command is None: if pip_command is None:
logger.error('No pip command available!')
return False return False
# Try to pip install it # Try to pip install it
if not pip_install(pip_command, name=dep.pypi_name.lower()): if not pip_install(pip_command, name=dep.pypi_name.lower()):
@ -788,7 +797,7 @@ def check_tool_python(dep, reload=False):
res = importlib.reload(reload) res = importlib.reload(reload)
return res, ver return res, ver
except ModuleNotFoundError: except ModuleNotFoundError:
pass logger.error(f'Pip failed for {dep.module_name}')
return None, None return None, None

View File

@ -60,13 +60,14 @@ def try_dependency(ctx, caplog, monkeypatch, docstring, name_dep, downloader_nam
def try_dependency_module(ctx, caplog, monkeypatch, docstring, name_dep, downloader_name): def try_dependency_module(ctx, caplog, monkeypatch, docstring, name_dep, downloader_name):
# Note: every attempt to install in a chosen dir failed, even when the module was there and in the sys.path the # Note: every attempt to install in a chosen dir failed, even when the module was there and in the sys.path the
# importlib call miserably failed. # importlib call miserably failed.
caplog.set_level(logging.INFO) caplog.set_level(logging.DEBUG)
with monkeypatch.context(): with monkeypatch.context():
# Refresh the module with actual dependencies # Refresh the module with actual dependencies
mod = importlib.reload(downloader) mod = importlib.reload(downloader)
mod.register_deps('test', yaml.safe_load(docstring)) mod.register_deps('test', yaml.safe_load(docstring))
# Get the dependency # Get the dependency
dep = mod.used_deps['test:'+name_dep] dep = mod.used_deps['test:'+name_dep]
logging.info(f"downloader_name: {downloader_name}")
# Download it # Download it
cov.load() cov.load()
cov.start() cov.start()