From 5c3de4c0222143615d14dc7bfab855f6804e45c0 Mon Sep 17 00:00:00 2001 From: John Sirois Date: Fri, 2 Nov 2018 22:21:31 -0600 Subject: [PATCH] Fixup PEXEnvironment extras resolution. In #582 and #592 support for environment markers was added to the pex runtime. In so doing, the resolver was fixed to record full requirement strings into PEX-INFO. Since part of those full requirement strings could now include environment markers that selected for active extras, a bug was introduced since we did not also add the active extras to the environment marker evaluation environment. This change adds a failing test that is fixed by properly setting up the environment marker environment to include active extras. Fixes #615. --- pex/environment.py | 5 ++++- tests/test_environment.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pex/environment.py b/pex/environment.py index d40ea1765..fbe72d1db 100644 --- a/pex/environment.py +++ b/pex/environment.py @@ -159,10 +159,13 @@ def _resolve(self, working_set, reqs): unresolved_reqs = set() resolveds = set() + environment = self._target_interpreter_env.copy() + environment['extra'] = list(set(itertools.chain(*(req.extras for req in reqs)))) + # Resolve them one at a time so that we can figure out which ones we need to elide should # there be an interpreter incompatibility. for req in reqs: - if req.marker and not req.marker.evaluate(environment=self._target_interpreter_env): + if req.marker and not req.marker.evaluate(environment=environment): TRACER.log('Skipping activation of `%s` due to environment marker de-selection' % req) continue with TRACER.timed('Resolving %s' % req, V=2): diff --git a/tests/test_environment.py b/tests/test_environment.py index 4cdefa3bc..a4c19a5b3 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -163,3 +163,24 @@ def bad_interpreter(include_site_extras=True): release, _, _ = platform.mac_ver() major_minor = '.'.join(release.split('.')[:2]) assert to_bytes('macosx-{}-intel'.format(major_minor)) == stdout.strip() + + +def test_activate_extras_issue_615(): + with yield_pex_builder() as pb: + for resolved_dist in resolver.resolve(['pex[requests]==1.5.1']): + pb.add_requirement(resolved_dist.requirement) + pb.add_dist_location(resolved_dist.distribution.location) + pb.set_script('pex') + pb.freeze() + env = os.environ.copy() + env['PEX_VERBOSE'] = '9' + process = PEX(pb.path()).run(args=['--version'], + env=env, + blocking=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + assert 0 == process.returncode, ( + 'Process failed with exit code {} and stderr:\n{}'.format(process.returncode, stderr) + ) + assert to_bytes('{} 1.5.1'.format(os.path.basename(pb.path()))) == stdout.strip()