def marker_to_str(marker): from pipenv.vendor.requirementslib.models.markers import normalize_marker_str if not marker: return None from pipenv.vendor import six from pipenv.vendor.vistir.compat import Mapping marker_str = None if isinstance(marker, Mapping): marker_dict, _ = Entry.get_markers_from_dict(marker) if marker_dict: marker_str = "{0}".format(marker_dict.popitem()[1]) elif isinstance(marker, (list, set, tuple)): marker_str = " and ".join( [normalize_marker_str(m) for m in marker if m]) elif isinstance(marker, six.string_types): marker_str = "{0}".format(normalize_marker_str(marker)) if isinstance(marker_str, six.string_types): return marker_str return None
def get_markers_from_dict(cls, entry_dict): from pipenv.vendor.packaging import markers as packaging_markers from pipenv.vendor.requirementslib.models.markers import normalize_marker_str marker_keys = cls.parse_pyparsing_exprs(packaging_markers.VARIABLE) markers = set() keys_in_dict = [k for k in marker_keys if k in entry_dict] markers = { normalize_marker_str("{k} {v}".format(k=k, v=entry_dict.pop(k))) for k in keys_in_dict } if "markers" in entry_dict: markers.add(normalize_marker_str(entry_dict["markers"])) if None in markers: markers.remove(None) if markers: entry_dict["markers"] = " and ".join(list(markers)) else: markers = None return markers, entry_dict
def combine_install_requirements(ireqs): """ Return a single install requirement that reflects a combination of all the inputs. """ # We will store the source ireqs in a _source_ireqs attribute; # if any of the inputs have this, then use those sources directly. source_ireqs = [] for ireq in ireqs: source_ireqs.extend(getattr(ireq, "_source_ireqs", [ireq])) # deepcopy the accumulator so as to not modify the inputs combined_ireq = copy.deepcopy(source_ireqs[0]) for ireq in source_ireqs[1:]: # NOTE we may be losing some info on dropped reqs here if combined_ireq.req is not None and ireq.req is not None: combined_ireq.req.specifier &= ireq.req.specifier combined_ireq.constraint &= ireq.constraint if ireq.markers and not combined_ireq.markers: combined_ireq.markers = copy.deepcopy(ireq.markers) elif ireq.markers and combined_ireq.markers: _markers = [] # type: List[Marker] for marker in [ireq.markers, combined_ireq.markers]: if isinstance(marker, str): _markers.append(Marker(marker)) else: _markers.append(marker) marker_str = " and ".join( [normalize_marker_str(m) for m in _markers if m]) combined_ireq.markers = Marker(marker_str) # Return a sorted, de-duped tuple of extras combined_ireq.extras = tuple( sorted(set(tuple(combined_ireq.extras) + tuple(ireq.extras)))) # InstallRequirements objects are assumed to come from only one source, and # so they support only a single comes_from entry. This function breaks this # model. As a workaround, we deterministically choose a single source for # the comes_from entry, and add an extra _source_ireqs attribute to keep # track of multiple sources for use within pip-tools. if len(source_ireqs) > 1: if any(ireq.comes_from is None for ireq in source_ireqs): # None indicates package was directly specified. combined_ireq.comes_from = None else: # Populate the comes_from field from one of the sources. # Requirement input order is not stable, so we need to sort: # We choose the shortest entry in order to keep the printed # representation as concise as possible. combined_ireq.comes_from = min( (ireq.comes_from for ireq in source_ireqs), key=lambda x: (len(str(x)), str(x)), ) combined_ireq._source_ireqs = source_ireqs return combined_ireq
def marker_to_str(marker): from pipenv.vendor.requirementslib.models.markers import normalize_marker_str if not marker: return None from collections.abc import Mapping marker_str = None if isinstance(marker, Mapping): marker_dict, _ = Entry.get_markers_from_dict(marker) if marker_dict: marker_str = f"{marker_dict.popitem()[1]}" elif isinstance(marker, (list, set, tuple)): marker_str = " and ".join( [normalize_marker_str(m) for m in marker if m]) elif isinstance(marker, str): marker_str = f"{normalize_marker_str(marker)}" if isinstance(marker_str, str): return marker_str return None