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

Use context manager to restore environment variables in resolve() #1255

Merged
merged 1 commit into from
Dec 2, 2020
Merged
Changes from all commits
Commits
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
62 changes: 30 additions & 32 deletions piptools/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from __future__ import absolute_import, division, print_function, unicode_literals

import copy
import os
from functools import partial
from itertools import chain, count, groupby

from pip._internal.req.constructors import install_req_from_line
from pip._internal.req.req_tracker import update_env_context_manager

from . import click
from .logging import log
Expand Down Expand Up @@ -156,37 +156,35 @@ def resolve(self, max_rounds=10):
self.repository.clear_caches()

# Ignore existing packages
os.environ[str("PIP_EXISTS_ACTION")] = str(
"i"
) # NOTE: str() wrapping necessary for Python 2/3 compat
for current_round in count(start=1): # pragma: no branch
if current_round > max_rounds:
raise RuntimeError(
"No stable configuration of concrete packages "
"could be found for the given constraints after "
"{max_rounds} rounds of resolving.\n"
"This is likely a bug.".format(max_rounds=max_rounds)
)

log.debug("")
log.debug(magenta("{:^60}".format("ROUND {}".format(current_round))))
# If a package version (foo==2.0) was built in a previous round,
# and in this round a different version of foo needs to be built
# (i.e. foo==1.0), the directory will exist already, which will
# cause a pip build failure. The trick is to start with a new
# build cache dir for every round, so this can never happen.
with self.repository.freshen_build_caches():
has_changed, best_matches = self._resolve_one_round()
log.debug("-" * 60)
log.debug(
"Result of round {}: {}".format(
current_round, "not stable" if has_changed else "stable, done"
)
)
if not has_changed:
break

del os.environ["PIP_EXISTS_ACTION"]
# NOTE: str() wrapping necessary for Python 2/3 compat
with update_env_context_manager(PIP_EXISTS_ACTION=str("i")):
for current_round in count(start=1): # pragma: no branch
if current_round > max_rounds:
raise RuntimeError(
"No stable configuration of concrete packages "
"could be found for the given constraints after "
"{max_rounds} rounds of resolving.\n"
"This is likely a bug.".format(max_rounds=max_rounds)
)

log.debug("")
log.debug(magenta("{:^60}".format("ROUND {}".format(current_round))))
# If a package version (foo==2.0) was built in a previous round,
# and in this round a different version of foo needs to be built
# (i.e. foo==1.0), the directory will exist already, which will
# cause a pip build failure. The trick is to start with a new
# build cache dir for every round, so this can never happen.
with self.repository.freshen_build_caches():
has_changed, best_matches = self._resolve_one_round()
log.debug("-" * 60)
log.debug(
"Result of round {}: {}".format(
current_round,
"not stable" if has_changed else "stable, done",
)
)
if not has_changed:
break

# Only include hard requirements and not pip constraints
results = {req for req in best_matches if not req.constraint}
Expand Down