def marker(self, marker: str | BaseMarker) -> None: from poetry.core.packages.utils.utils import convert_markers from poetry.core.semver.helpers import parse_constraint from poetry.core.version.markers import BaseMarker from poetry.core.version.markers import parse_marker if not isinstance(marker, BaseMarker): marker = parse_marker(marker) self._marker = marker markers = convert_markers(marker) if "extra" in markers: # If we have extras, the dependency is optional self.deactivate() for or_ in markers["extra"]: for _, extra in or_: self.in_extras.append(extra) # Recalculate python versions. self._python_versions = "*" if not contains_group_without_marker(markers, "python_version"): ors = [] for or_ in markers["python_version"]: ands = [] for op, version in or_: # Expand python version if op == "==" and "*" not in version: version = "~" + version op = "" elif op == "!=": version += ".*" elif op in ("in", "not in"): versions = [] for v in re.split("[ ,]+", version): split = v.split(".") if len(split) in [1, 2]: split.append("*") op_ = "" if op == "in" else "!=" else: op_ = "==" if op == "in" else "!=" versions.append(op_ + ".".join(split)) glue = " || " if op == "in" else ", " if versions: ands.append(glue.join(versions)) continue ands.append(f"{op}{version}") ors.append(" ".join(ands)) self._python_versions = " || ".join(ors) self._python_constraint = parse_constraint(self._python_versions)
def test_convert_markers(): marker = parse_marker( 'sys_platform == "win32" and python_version < "3.6" ' 'or sys_platform == "win32" and python_version < "3.6" and python_version >= "3.3" ' 'or sys_platform == "win32" and python_version < "3.3"') converted = convert_markers(marker) assert converted["python_version"] == [ [("<", "3.6")], [("<", "3.6"), (">=", "3.3")], [("<", "3.3")], ] marker = parse_marker('python_version == "2.7" or python_version == "2.6"') converted = convert_markers(marker) assert converted["python_version"] == [[("==", "2.7")], [("==", "2.6")]]
def to_pep_508(self, with_extras: bool = True) -> str: from poetry.core.packages.utils.utils import convert_markers requirement = self.base_pep_508_name markers = [] has_extras = False if not self.marker.is_any(): marker = self.marker if not with_extras: marker = marker.without_extras() # we re-check for any marker here since the without extra marker might # return an any marker again if not marker.is_empty() and not marker.is_any(): markers.append(str(marker)) has_extras = "extra" in convert_markers(marker) else: # Python marker if self.python_versions != "*": python_constraint = self.python_constraint markers.append( self._create_nested_marker("python_version", python_constraint)) in_extras = " || ".join(self._in_extras) if in_extras and with_extras and not has_extras: markers.append( self._create_nested_marker( "extra", parse_generic_constraint(in_extras))) if markers: if self.is_vcs() or self.is_url() or self.is_file(): requirement += " " if len(markers) > 1: marker_str = " and ".join(f"({m})" for m in markers) requirement += f"; {marker_str}" else: requirement += f"; {markers[0]}" return requirement
def test_convert_markers( marker: str, expected: dict[str, list[list[tuple[str, str]]]]) -> None: parsed_marker = parse_marker(marker) converted = convert_markers(parsed_marker) assert converted == expected