def _resolve(self, working_set, reqs): reqs_by_key = OrderedDict((req.key, req) for req in reqs) unresolved_reqs = OrderedDict() resolveds = OrderedSet() 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_by_key.values(): 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): try: resolveds.update(working_set.resolve([req], env=self)) except DistributionNotFound as e: TRACER.log('Failed to resolve a requirement: %s' % e) requirers = unresolved_reqs.setdefault(e.req, OrderedSet()) if e.requirers: requirers.update(reqs_by_key[requirer] for requirer in e.requirers) if unresolved_reqs: TRACER.log('Unresolved requirements:') for req in unresolved_reqs: TRACER.log(' - %s' % req) TRACER.log('Distributions contained within this pex:') distributions_by_key = defaultdict(list) if not self._pex_info.distributions: TRACER.log(' None') else: for dist_name, dist_digest in self._pex_info.distributions.items( ): TRACER.log(' - %s' % dist_name) distribution = DistributionHelper.distribution_from_path( path=os.path.join(self._pex_info.install_cache, dist_digest, dist_name)) distributions_by_key[ distribution.as_requirement().key].append(distribution) if not self._pex_info.ignore_errors: items = [] for index, (requirement, requirers) in enumerate(unresolved_reqs.items()): rendered_requirers = '' if requirers: rendered_requirers = ( '\n Required by:' '\n {requirers}').format( requirers='\n '.join(map(str, requirers))) items.append('{index: 2d}: {requirement}' '{rendered_requirers}' '\n But this pex only contains:' '\n {distributions}'.format( index=index + 1, requirement=requirement, rendered_requirers=rendered_requirers, distributions='\n '.join( os.path.basename(d.location) for d in distributions_by_key[ requirement.key]))) die('Failed to execute PEX file. Needed {platform} compatible dependencies for:\n{items}' .format(platform=Platform.of_interpreter( self._interpreter), items='\n'.join(items))) return resolveds
def is_foreign(self): if self._platform is None: return False return self._platform != Platform.of_interpreter(self._interpreter)
def _resolve(self, working_set, reqs): environment = self._target_interpreter_env.copy() environment['extra'] = list( set(itertools.chain(*(req.extras for req in reqs)))) reqs_by_key = OrderedDict() for req in reqs: if req.marker and not req.marker.evaluate(environment=environment): TRACER.log( 'Skipping activation of `%s` due to environment marker de-selection' % req) continue reqs_by_key.setdefault(req.key, []).append(req) unresolved_reqs = OrderedDict() resolveds = OrderedSet() # 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 key, reqs in reqs_by_key.items(): with TRACER.timed('Resolving {} from {}'.format(key, reqs), V=2): # N.B.: We resolve the bare requirement with no version specifiers since the resolve process # used to build this pex already did so. There may be multiple distributions satisfying any # particular key (e.g.: a Python 2 specific version and a Python 3 specific version for a # multi-python PEX) and we want the working set to pick the most appropriate one. req = Requirement.parse(key) try: resolveds.update(working_set.resolve([req], env=self)) except DistributionNotFound as e: TRACER.log('Failed to resolve a requirement: %s' % e) requirers = unresolved_reqs.setdefault(e.req, OrderedSet()) if e.requirers: requirers.update(reqs_by_key[requirer] for requirer in e.requirers) if unresolved_reqs: TRACER.log('Unresolved requirements:') for req in unresolved_reqs: TRACER.log(' - %s' % req) TRACER.log('Distributions contained within this pex:') distributions_by_key = defaultdict(list) if not self._pex_info.distributions: TRACER.log(' None') else: for dist_name, dist_digest in self._pex_info.distributions.items( ): TRACER.log(' - %s' % dist_name) distribution = DistributionHelper.distribution_from_path( path=os.path.join(self._pex_info.install_cache, dist_digest, dist_name)) distributions_by_key[ distribution.as_requirement().key].append(distribution) if not self._pex_info.ignore_errors: items = [] for index, (requirement, requirers) in enumerate(unresolved_reqs.items()): rendered_requirers = '' if requirers: rendered_requirers = ( '\n Required by:' '\n {requirers}').format( requirers='\n '.join(map(str, requirers))) items.append('{index: 2d}: {requirement}' '{rendered_requirers}' '\n But this pex only contains:' '\n {distributions}'.format( index=index + 1, requirement=requirement, rendered_requirers=rendered_requirers, distributions='\n '.join( os.path.basename(d.location) for d in distributions_by_key[ requirement.key]))) die('Failed to execute PEX file. Needed {platform} compatible dependencies for:\n{items}' .format(platform=Platform.of_interpreter( self._interpreter), items='\n'.join(items))) return resolveds