def split_marker_element( text: str, element: str) -> Tuple[Iterable[Tuple[str, str]], Optional[Marker]]: """An element can be stripped from the marker only if all parts are connected with `and` operater. The rest part are returned as a string or `None` if all are stripped. :param text: the input marker string :param element: the element to be stripped :returns: an iterable of (op, value) pairs together with the stripped part. """ if text is None: return [], text marker = Marker(text) if "or" in marker._markers: return [], marker result = [] bare_markers = [m for m in marker._markers if m != "and"] for m in bare_markers[:]: if not isinstance(m, tuple): continue if m[0].value == element: result.append(tuple(e.value for e in m[1:])) bare_markers.remove(m) new_markers = join_list_with(bare_markers, "and") if not new_markers: return result, None marker._markers = new_markers return result, marker
def split_marker_extras( marker: PackageMarker, ) -> Tuple[Sequence[str], Optional[Marker]]: """An element can be stripped from the marker only if all parts are connected with `and` operater. The rest part are returned as a string or `None` if all are stripped. :param marker: the input marker string :returns: an iterable of (op, value) pairs together with the stripped part. """ if "or" in marker._markers: if "and" in marker._markers or any( not isinstance(p, tuple) or p[0].value != "extra" for p in marker._markers if p != "or" ): return [], marker result = [] bare_markers = [m for m in marker._markers if m not in ("and", "or")] for m in bare_markers[:]: if not isinstance(m, tuple): continue if m[0].value == "extra": if m[1].value == "==": result.append(m[2].value) elif m[1].value == "in": result.extend(v.strip() for v in m[2].value.split(",")) bare_markers.remove(m) new_markers = join_list_with(bare_markers, "and") if not new_markers: return result, None marker._markers = new_markers return result, marker
def split_marker_extras(marker: str) -> Tuple[Set[str], str]: """An element can be stripped from the marker only if all parts are connected with `and` operator. The rest part are returned as a string or `None` if all are stripped. """ def extract_extras(submarker: Union[tuple, list]) -> Set[str]: if isinstance(submarker, tuple): if submarker[0].value == "extra": if submarker[1].value == "==": return {submarker[2].value} elif submarker[1].value == "in": return {v.strip() for v in submarker[2].value.split(",")} else: return set() else: return set() else: if "and" in submarker: return set() pure_extras = [extract_extras(m) for m in submarker if m != "or"] if all(pure_extras): return set(itertools.chain.from_iterable(pure_extras)) return set() if not marker: return set(), marker new_marker = PackageMarker(marker) submarkers = PackageMarker(marker)._markers if "or" in submarkers: extras = extract_extras(submarkers) if extras: return extras, "" return set(), marker extras = set() submarkers_no_extras: List[Union[tuple, list]] = [] # Below this point the submarkers are connected with 'and' for submarker in submarkers: if submarker == "and": continue new_extras = extract_extras(submarker) if new_extras: if extras: # extras are not allowed to appear in more than one parts return set(), marker extras.update(new_extras) else: submarkers_no_extras.append(submarker) if not submarkers_no_extras: return extras, "" new_marker._markers = join_list_with(submarkers_no_extras, "and") return extras, str(new_marker)
def split_marker_extras( marker: PackageMarker, ) -> Tuple[List[str], Optional[PackageMarker]]: """An element can be stripped from the marker only if all parts are connected with `and` operater. The rest part are returned as a string or `None` if all are stripped. :param marker: the input marker string :returns: an iterable of (op, value) pairs together with the stripped part. """ def extract_extras(submarker: Union[tuple, list]) -> List[str]: if isinstance(submarker, tuple): if submarker[0].value == "extra": if submarker[1].value == "==": return [submarker[2].value] elif submarker[1].value == "in": return [v.strip() for v in submarker[2].value.split(",")] else: return [] else: return [] else: if "and" in submarker: return [] pure_extras = [extract_extras(m) for m in submarker if m != "or"] if all(pure_extras): return list(itertools.chain.from_iterable(pure_extras)) return [] submarkers = marker._markers if "or" in submarkers: extras = extract_extras(submarkers) if extras: return extras, None return [], marker extras = [] submarkers_no_extras: List[Union[tuple, list]] = [] for submarker in submarkers: if submarker == "and": continue new_extras = extract_extras(submarker) if new_extras: if extras: return [], marker extras.extend(new_extras) else: submarkers_no_extras.append(submarker) if not submarkers_no_extras: return extras, None marker._markers = join_list_with(submarkers_no_extras, "and") return extras, marker
def split_pyspec(self) -> Tuple[Optional["Marker"], PySpecSet]: """Split `python_version` and `python_full_version` from marker string""" if _only_contains_python_keys(self._markers): return None, _build_pyspec_from_marker(self._markers) if "or" in self._markers: return self.copy(), PySpecSet() py_markers = [ marker for marker in self._markers if marker != "and" and _only_contains_python_keys(marker) ] rest = [ marker for marker in self._markers if marker != "and" and marker not in py_markers ] new_markers = join_list_with(rest, "and") if not new_markers: marker = None else: marker = self.copy() marker._markers = new_markers return marker, _build_pyspec_from_marker( join_list_with(py_markers, "and"))