Skip to content

Commit

Permalink
fix and make common python version normalization
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby committed Jun 1, 2022
1 parent b026aab commit a571fa5
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 51 deletions.
38 changes: 5 additions & 33 deletions src/poetry/core/packages/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from poetry.core.packages.dependency_group import MAIN_GROUP
from poetry.core.packages.specification import PackageSpecification
from poetry.core.packages.utils.utils import contains_group_without_marker
from poetry.core.packages.utils.utils import normalize_python_version_markers
from poetry.core.semver.helpers import parse_constraint
from poetry.core.semver.version_range_constraint import VersionRangeConstraint
from poetry.core.version.markers import parse_marker
Expand Down Expand Up @@ -192,39 +193,10 @@ def marker(self, marker: str | BaseMarker) -> None:
# 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)
python_version_markers = markers["python_version"]
self._python_versions = normalize_python_version_markers(
python_version_markers
)

self._python_constraint = parse_constraint(self._python_versions)

Expand Down
26 changes: 12 additions & 14 deletions src/poetry/core/packages/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
from urllib.request import url2pathname

from poetry.core.pyproject.toml import PyProjectTOML
from poetry.core.semver.helpers import parse_constraint
from poetry.core.semver.version import Version
from poetry.core.semver.version_range import VersionRange
from poetry.core.version.markers import dnf


if TYPE_CHECKING:
from poetry.core.packages.constraints import BaseConstraint
from poetry.core.semver.version import Version
from poetry.core.semver.version_constraint import VersionConstraint
from poetry.core.semver.version_union import VersionUnion
from poetry.core.version.markers import BaseMarker
Expand Down Expand Up @@ -206,7 +207,6 @@ def create_nested_marker(
from poetry.core.packages.constraints.constraint import Constraint
from poetry.core.packages.constraints.multi_constraint import MultiConstraint
from poetry.core.packages.constraints.union_constraint import UnionConstraint
from poetry.core.semver.version import Version
from poetry.core.semver.version_union import VersionUnion

if constraint.is_any():
Expand Down Expand Up @@ -286,8 +286,6 @@ 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")
Expand All @@ -304,8 +302,15 @@ def get_python_constraint_from_marker(
# which means that python_version is arbitrary for this group
return VersionRange()

python_version_markers = markers["python_version"]
normalized = normalize_python_version_markers(python_version_markers)
constraint = parse_constraint(normalized)
return constraint


def normalize_python_version_markers(disjunction: list[list[tuple[str, str]]]) -> str:
ors = []
for or_ in markers["python_version"]:
for or_ in disjunction:
ands = []
for op, version in or_:
# Expand python version
Expand All @@ -318,14 +323,7 @@ def get_python_constraint_from_marker(
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 parsed_version.precision == 2:
if op == "<=":
op = "<"
version = parsed_version.next_minor().text
Expand Down Expand Up @@ -354,4 +352,4 @@ def get_python_constraint_from_marker(

ors.append(" ".join(ands))

return parse_constraint(" || ".join(ors))
return " || ".join(ors)
4 changes: 2 additions & 2 deletions tests/packages/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ def test_dependency_from_pep_508_should_not_produce_empty_constraints_for_correc

assert dep.name == "pytest-mypy"
assert str(dep.constraint) == "*"
assert dep.python_versions == "<=3.10 >3"
assert dep.python_versions == "<3.11 >3"
assert dep.python_constraint.allows(Version.parse("3.6"))
assert dep.python_constraint.allows(Version.parse("3.10"))
assert dep.python_constraint.allows(Version.parse("3.10.4"))
assert not dep.python_constraint.allows(Version.parse("3"))
assert dep.python_constraint.allows(Version.parse("3.0.1"))
assert (
Expand Down
4 changes: 2 additions & 2 deletions tests/packages/utils/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ def test_convert_markers(
('python_version != "3.6.* "', "!=3.6.*"),
# <, <=, >, >= precision 1
('python_version < "3"', "<3"),
('python_version <= "3"', "<4"),
('python_version > "3"', ">=4"),
('python_version <= "3"', "<=3"),
('python_version > "3"', ">3"),
('python_version >= "3"', ">=3"),
# <, <=, >, >= precision 2
('python_version < "3.6"', "<3.6"),
Expand Down

0 comments on commit a571fa5

Please sign in to comment.