Commit 45519869 authored by Xavier Thompson's avatar Xavier Thompson

[fixup] Fix leaked temporary pip $HOME on exit

Fixup "711d8710"
parent 94d51e5a
...@@ -18,7 +18,6 @@ It doesn't install scripts. It uses setuptools and requires it to be ...@@ -18,7 +18,6 @@ It doesn't install scripts. It uses setuptools and requires it to be
installed. installed.
""" """
import atexit
import copy import copy
import distutils.errors import distutils.errors
import distutils.sysconfig import distutils.sysconfig
...@@ -1843,67 +1842,73 @@ try: ...@@ -1843,67 +1842,73 @@ try:
except ImportError: except ImportError:
PIP_HAS_PYTHON_VERSION_WARNING_OPTION = False PIP_HAS_PYTHON_VERSION_WARNING_OPTION = False
# Temporary HOME with .pydistutils.cfg to disable setup_requires
pip_pydistutils_home = tempfile.mkdtemp('pip-pydistutils-home')
with open(os.path.join(pip_pydistutils_home, '.pydistutils.cfg'), 'w') as f:
f.write("[easy_install]\n"
"index-url = file:///dev/null")
atexit.register(zc.buildout.rmtree.rmtree, pip_pydistutils_home)
def call_pip_command(command, operand, options, verbosity=-10): def call_pip_command(command, operand, options, verbosity=-10):
""" """
Call `pip <command...> <operand...>` from a subprocess Call `pip <command...> <operand...>` from a subprocess
with appropriate options and environment. with appropriate options and environment.
""" """
env = os.environ.copy() cleanup = []
pythonpath = pip_path[:] try:
pythonpath.extend(env.get(k) for k in ('PYTHONPATH', 'PYTHONEXTRAPATH')) env = os.environ.copy()
env['PYTHONPATH'] = os.pathsep.join(p for p in pythonpath if p) pythonpath = pip_path[:]
pythonpath.extend(
args = [sys.executable, '-m', 'pip'] env.get(k) for k in ('PYTHONPATH', 'PYTHONEXTRAPATH'))
args.extend(command) env['PYTHONPATH'] = os.pathsep.join(p for p in pythonpath if p)
args.append('--no-deps')
args = [sys.executable, '-m', 'pip']
log_level = logger.getEffectiveLevel() args.extend(command)
pip_level = log_level - verbosity args.append('--no-deps')
if pip_level >= logging.WARNING:
args.append('-' + 'q' * (1 + (pip_level >= logging.ERROR))) # -q or -qq log_level = logger.getEffectiveLevel()
elif pip_level < logging.INFO: pip_level = log_level - verbosity
args.append('-' + 'v' * (1 + (pip_level < logging.DEBUG))) # -v or -vv if pip_level >= logging.WARNING:
# Note: more recent pip accepts even -vvv and -qqq. args.append('-' + 'q' * (1 + (pip_level >= logging.ERROR)))
elif pip_level < logging.INFO:
if not options._allow_picked_versions: args.append('-' + 'v' * (1 + (pip_level < logging.DEBUG)))
# Prevent pip from installing build dependencies on the fly # Note: more recent pip accepts even -vvv and -qqq.
# without respecting pinned versions. This only works for
# PEP 517 specifications using pyproject.toml and not for if not options._allow_picked_versions:
# dependencies in setup_requires option in legacy setup.py # Prevent pip from installing build dependencies on the fly
args.append('--no-index') # without respecting pinned versions. This only works for
args.append('--no-build-isolation') # PEP 517 specifications using pyproject.toml and not for
# dependencies in setup_requires option in legacy setup.py
# Prevent setuptools from downloading and thus installing args.append('--no-index')
# build dependencies specified in setup_requires option of args.append('--no-build-isolation')
# legacy setup.py by providing a crafted .pydistutils.cfg.
# This is used in complement to --no-build-isolation. # Prevent setuptools from downloading and thus installing
env['HOME'] = pip_pydistutils_home # build dependencies specified in setup_requires option of
# legacy setup.py by providing a crafted .pydistutils.cfg.
if PIP_HAS_PYTHON_VERSION_WARNING_OPTION: # This is used in complement to --no-build-isolation.
# Let pip display Python warnings only on first run. pip_home = tempfile.mkdtemp('pip-pydistutils-home')
if not hasattr(call_pip_command, 'displayed'): cleanup.append(lambda: zc.buildout.rmtree.rmtree(pip_home))
call_pip_command.displayed = True with open(os.path.join(pip_home, '.pydistutils.cfg'), 'w') as f:
else: f.write("[easy_install]\n"
args.append('--no-python-version-warning') "index_url = file:///dev/null")
env['HOME'] = pip_home
if PIP_HAS_PYTHON_VERSION_WARNING_OPTION:
# Let pip display Python warnings only on first run.
if not hasattr(call_pip_command, 'displayed'):
call_pip_command.displayed = True
else:
args.append('--no-python-version-warning')
args.extend(operand) args.extend(operand)
if log_level < logging.DEBUG: if log_level < logging.DEBUG:
# Log this only when buildout log level is quite low # Log this only when buildout log level is quite low
logger.debug('Running pip %s', ' '.join(command[0:1] + operand)) logger.debug('Running pip %s', ' '.join(command[0:1] + operand))
if log_level < 0: if log_level < 0:
# Log this only when buildout log level is even lower # Log this only when buildout log level is even lower
logger.debug('%s\nPYTHONPATH=%s\n', ' '.join(args), env['PYTHONPATH']) logger.debug(
'%s\nPYTHONPATH=%s\n', ' '.join(args), env['PYTHONPATH'])
sys.stdout.flush() # We want any pending output first sys.stdout.flush() # We want any pending output first
subprocess.check_call(args, env=env) subprocess.check_call(args, env=env)
finally:
for f in cleanup:
f()
def call_pip_editable(path, dest, options, verbosity=-10): def call_pip_editable(path, dest, options, verbosity=-10):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment