def get_python_constraint_from_marker( marker: BaseMarker, ) -> VersionConstraint: from poetry.core.semver.empty_constraint import EmptyConstraint from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange python_marker = marker.only("python_version", "python_full_version") if python_marker.is_any(): return VersionRange() if python_marker.is_empty(): return EmptyConstraint() markers = convert_markers(marker) if contains_group_without_marker(markers, "python_version"): # groups are in disjunctive normal form (DNF), # an empty group means that python_version does not appear in this group, # which means that python_version is arbitrary for this group return VersionRange() ors = [] for or_ in markers["python_version"]: ands = [] for op, version in or_: # Expand python version if op == "==": if "*" not in version: version = "~" + version op = "" elif op == "!=": if "*" not in version: version += ".*" elif op in ("<=", ">"): parsed_version = Version.parse(version) if parsed_version.precision == 1: if op == "<=": op = "<" version = parsed_version.next_major().text elif op == ">": op = ">=" version = parsed_version.next_major().text elif parsed_version.precision == 2: if op == "<=": op = "<" version = parsed_version.next_minor().text elif op == ">": op = ">=" version = parsed_version.next_minor().text 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)) return parse_constraint(" || ".join(ors))
def is_valid_for_marker(self, marker: BaseMarker) -> bool: return marker.validate(self.marker_env)