Exemple #1
0
def test_parse_constraint_multi_wilcard(input):
    assert parse_constraint(input) == VersionUnion(
        VersionRange(
            Version.from_parts(2, 7, 0), Version.from_parts(3, 0, 0), True, False
        ),
        VersionRange(Version.from_parts(3, 2, 0), None, True, False),
    )
def test_allows_any():
    v = Version.parse("1.2.3")

    assert v.allows_any(v)
    assert not v.allows_any(Version.parse("0.0.3"))
    assert v.allows_any(VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4")))
    assert v.allows_any(VersionRange())
    assert not v.allows_any(EmptyConstraint())
def test_intersect() -> None:
    v = Version.parse("1.2.3")

    assert v.intersect(v) == v
    assert v.intersect(Version.parse("1.1.4")).is_empty()
    assert (v.intersect(
        VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4"))) == v)
    assert (Version.parse("1.1.4").intersect(
        VersionRange(v, Version.parse("1.2.4"))).is_empty())
def test_difference() -> None:
    v = Version.parse("1.2.3")

    assert v.difference(v).is_empty()
    assert v.difference(Version.parse("0.8.0")) == v
    assert v.difference(
        VersionRange(Version.parse("1.1.4"),
                     Version.parse("1.2.4"))).is_empty()
    assert (v.difference(
        VersionRange(Version.parse("1.4.0"), Version.parse("3.0.0"))) == v)
Exemple #5
0
def test_allows_post_releases_explicit_with_min(base, one, two):
    range = VersionRange(min=one, include_min=True)
    assert not range.allows(base)
    assert range.allows(two)

    range = VersionRange(min=two, include_min=True)
    assert not range.allows(base)
    assert not range.allows(one)
def test_parse_constraint_multi(input: str) -> None:
    assert parse_constraint(input) == VersionRange(
        Version.from_parts(2, 0, 0),
        Version.from_parts(3, 0, 0),
        include_min=False,
        include_max=True,
    )
    def __str__(self) -> str:
        from .version_range import VersionRange

        if self.excludes_single_version():
            return "!={}".format(VersionRange().difference(self))

        return " || ".join([str(r) for r in self._ranges])
Exemple #8
0
def parse_constraint(constraints: str) -> VersionConstraint:
    if constraints == "*":
        from poetry.core.semver.version_range import VersionRange

        return VersionRange()

    or_constraints = re.split(r"\s*\|\|?\s*", constraints.strip())
    or_groups = []
    for constraints in or_constraints:
        and_constraints = re.split(
            "(?<!^)(?<![~=>< ,]) *(?<!-)[, ](?!-) *(?!,|$)", constraints)
        constraint_objects = []

        if len(and_constraints) > 1:
            for constraint in and_constraints:
                constraint_objects.append(parse_single_constraint(constraint))
        else:
            constraint_objects.append(
                parse_single_constraint(and_constraints[0]))

        if len(constraint_objects) == 1:
            constraint = constraint_objects[0]
        else:
            constraint = constraint_objects[0]
            for next_constraint in constraint_objects[1:]:
                constraint = constraint.intersect(next_constraint)

        or_groups.append(constraint)

    if len(or_groups) == 1:
        return or_groups[0]
    else:
        from poetry.core.semver.version_union import VersionUnion

        return VersionUnion.of(*or_groups)
def test_allows_post_releases_explicit_with_max(
    base: Version, one: Version, two: Version
) -> None:
    range = VersionRange(max=one, include_max=True)
    assert range.allows(base)
    assert not range.allows(two)

    range = VersionRange(max=two, include_max=True)
    assert range.allows(base)
    assert range.allows(one)
Exemple #10
0
def test_allows_all_bordering_range_not_more_inclusive(v010, v250):
    # Allows bordering range that is not more inclusive
    exclusive = VersionRange(v010, v250)
    inclusive = VersionRange(v010, v250, True, True)
    assert inclusive.allows_all(exclusive)
    assert inclusive.allows_all(inclusive)
    assert not exclusive.allows_all(inclusive)
    assert exclusive.allows_all(exclusive)
    def python_versions(self, value: Union[str, "VersionTypes"]) -> None:
        from poetry.core.semver.version_range import VersionRange

        self._python_versions = value

        if value == "*" or value == VersionRange():
            value = "~2.7 || >=3.4"

        self._python_constraint = parse_constraint(value)
        self._python_marker = parse_marker(
            create_nested_marker("python_version", self._python_constraint))
Exemple #12
0
def test_allows_all(v123, v124, v140, v250, v300):
    assert VersionRange(v123, v250).allows_all(EmptyConstraint())

    range = VersionRange(v123, v250, include_max=True)
    assert not range.allows_all(v123)
    assert range.allows_all(v124)
    assert range.allows_all(v250)
    assert not range.allows_all(v300)
def test_union() -> None:
    v = Version.parse("1.2.3")

    assert v.union(v) == v

    result = v.union(Version.parse("0.8.0"))
    assert result.allows(v)
    assert result.allows(Version.parse("0.8.0"))
    assert not result.allows(Version.parse("1.1.4"))

    range = VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4"))
    assert v.union(range) == range

    union = Version.parse("1.1.4").union(
        VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4")))
    assert union == VersionRange(Version.parse("1.1.4"),
                                 Version.parse("1.2.4"),
                                 include_min=True)

    result = v.union(
        VersionRange(Version.parse("0.0.3"), Version.parse("1.1.4")))
    assert result.allows(v)
    assert result.allows(Version.parse("0.1.0"))
Exemple #14
0
    def union(self, other: VersionConstraint) -> VersionConstraint:
        from poetry.core.semver.version_range import VersionRange

        if other.allows(self):
            return other

        if isinstance(other, VersionRangeConstraint):
            if self.allows(other.min):
                return VersionRange(
                    other.min,
                    other.max,
                    include_min=True,
                    include_max=other.include_max,
                )

            if self.allows(other.max):
                return VersionRange(
                    other.min,
                    other.max,
                    include_min=other.include_min,
                    include_max=True,
                )

        return VersionUnion.of(self, other)
def test_allows_all_contained_unions(
    v010: Version,
    v114: Version,
    v123: Version,
    v124: Version,
    v140: Version,
    v200: Version,
    v234: Version,
) -> None:
    # Allows unions that are completely contained
    range = VersionRange(v114, v200)
    assert range.allows_all(VersionRange(v123, v124).union(v140))
    assert not range.allows_all(VersionRange(v010, v124).union(v140))
    assert not range.allows_all(VersionRange(v123, v234).union(v140))
    def of(cls, *ranges: VersionConstraint) -> VersionConstraint:
        from poetry.core.semver.version_range import VersionRange

        flattened: list[VersionRangeConstraint] = []
        for constraint in ranges:
            if constraint.is_empty():
                continue

            if isinstance(constraint, VersionUnion):
                flattened += constraint.ranges
                continue

            assert isinstance(constraint, VersionRangeConstraint)
            flattened.append(constraint)

        if not flattened:
            return EmptyConstraint()

        if any([constraint.is_any() for constraint in flattened]):
            return VersionRange()

        # Only allow Versions and VersionRanges here so we can more easily reason
        # about everything in flattened. _EmptyVersions and VersionUnions are
        # filtered out above.
        for constraint in flattened:
            if not isinstance(constraint, VersionRangeConstraint):
                raise ValueError(f"Unknown VersionConstraint type {constraint}.")

        flattened.sort()

        merged: list[VersionRangeConstraint] = []
        for constraint in flattened:
            # Merge this constraint with the previous one, but only if they touch.
            if not merged or (
                not merged[-1].allows_any(constraint)
                and not merged[-1].is_adjacent_to(constraint)
            ):
                merged.append(constraint)
            else:
                new_constraint = merged[-1].union(constraint)
                assert isinstance(new_constraint, VersionRangeConstraint)
                merged[-1] = new_constraint

        if len(merged) == 1:
            return merged[0]

        return VersionUnion(*merged)
    def excludes_single_wildcard_range(self) -> bool:
        from poetry.core.semver.version_range import VersionRange

        if len(self._ranges) != 2:
            return False

        idx_order = (0, 1) if self._ranges[0].max else (1, 0)
        one = self._ranges[idx_order[0]]
        two = self._ranges[idx_order[1]]

        is_range_exclusion = (
            one.max and not one.include_max and two.min and two.include_min
        )

        if not is_range_exclusion:
            return False

        if not self._excludes_single_wildcard_range_check_is_valid_range(one, two):
            return False

        return isinstance(VersionRange().difference(self), VersionRange)
Exemple #18
0
def get_python_constraint_from_marker(
    marker: "BaseMarker",
) -> "VersionTypes":
    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  # noqa

    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)

    ors = []
    for or_ in markers["python_version"]:
        ands = []
        for op, version in or_:
            # Expand python version
            if op == "==":
                version = "~" + version
                op = ""
            elif op == "!=":
                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("{}{}".format(op, version))

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

    return parse_constraint(" || ".join(ors))
import pytest

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.semver.version_union import VersionUnion


@pytest.mark.parametrize(
    "constraint,version",
    [
        (
            "~=3.8",
            VersionRange(
                min=Version.from_parts(3, 8),
                max=Version.from_parts(4, 0),
                include_min=True,
            ),
        ),
        (
            "== 3.8.*",
            VersionRange(
                min=Version.from_parts(3, 8),
                max=Version.from_parts(3, 9, 0),
                include_min=True,
            ),
        ),
        (
            "~= 3.8",
            VersionRange(
                min=Version.from_parts(3, 8),
Exemple #20
0
def parse_single_constraint(constraint: str) -> VersionConstraint:
    from poetry.core.semver.patterns import BASIC_CONSTRAINT
    from poetry.core.semver.patterns import CARET_CONSTRAINT
    from poetry.core.semver.patterns import TILDE_CONSTRAINT
    from poetry.core.semver.patterns import TILDE_PEP440_CONSTRAINT
    from poetry.core.semver.patterns import X_CONSTRAINT
    from poetry.core.semver.version import Version
    from poetry.core.semver.version_range import VersionRange
    from poetry.core.semver.version_union import VersionUnion

    m = re.match(r"(?i)^v?[xX*](\.[xX*])*$", constraint)
    if m:
        return VersionRange()

    # Tilde range
    m = TILDE_CONSTRAINT.match(constraint)
    if m:
        version = Version.parse(m.group("version"))
        high = version.stable.next_minor()
        if version.release.precision == 1:
            high = version.stable.next_major()

        return VersionRange(version, high, include_min=True)

    # PEP 440 Tilde range (~=)
    m = TILDE_PEP440_CONSTRAINT.match(constraint)
    if m:
        version = Version.parse(m.group("version"))
        if version.release.precision == 2:
            high = version.stable.next_major()
        else:
            high = version.stable.next_minor()

        return VersionRange(version, high, include_min=True)

    # Caret range
    m = CARET_CONSTRAINT.match(constraint)
    if m:
        version = Version.parse(m.group("version"))

        return VersionRange(version, version.next_breaking(), include_min=True)

    # X Range
    m = X_CONSTRAINT.match(constraint)
    if m:
        op = m.group("op")
        major = int(m.group(2))
        minor = m.group(3)

        if minor is not None:
            version = Version.from_parts(major, int(minor), 0)
            result: VersionConstraint = VersionRange(version,
                                                     version.next_minor(),
                                                     include_min=True)
        else:
            if major == 0:
                result = VersionRange(max=Version.from_parts(1, 0, 0))
            else:
                version = Version.from_parts(major, 0, 0)

                result = VersionRange(version,
                                      version.next_major(),
                                      include_min=True)

        if op == "!=":
            result = VersionRange().difference(result)

        return result

    # Basic comparator
    m = BASIC_CONSTRAINT.match(constraint)
    if m:
        op = m.group("op")
        version_string = m.group("version")

        if version_string == "dev":
            version_string = "0.0-dev"

        try:
            version = Version.parse(version_string)
        except ValueError:
            raise ValueError(
                f"Could not parse version constraint: {constraint}")

        if op == "<":
            return VersionRange(max=version)
        if op == "<=":
            return VersionRange(max=version, include_max=True)
        if op == ">":
            return VersionRange(min=version)
        if op == ">=":
            return VersionRange(min=version, include_min=True)
        if op == "!=":
            return VersionUnion(VersionRange(max=version),
                                VersionRange(min=version))
        return version

    from poetry.core.semver.exceptions import ParseConstraintError

    raise ParseConstraintError(
        f"Could not parse version constraint: {constraint}")
Exemple #21
0
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.semver.version_union import VersionUnion
from poetry.core.version.pep440 import ReleaseTag


@pytest.mark.parametrize(
    "constraint,version",
    [
        (
            "~=3.8",
            VersionRange(
                min=Version.from_parts(3, 8),
                max=Version.from_parts(4, 0),
                include_min=True,
            ),
        ),
        (
            "== 3.8.*",
            VersionRange(
                min=Version.from_parts(3, 8),
                max=Version.from_parts(3, 9, 0),
                include_min=True,
            ),
        ),
        (
            "~= 3.8",
            VersionRange(
                min=Version.from_parts(3, 8),
from typing import cast

import pytest

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.semver.version_union import VersionUnion
from poetry.core.version.pep440 import ReleaseTag


@pytest.mark.parametrize(
    "input,constraint",
    [
        ("*", VersionRange()),
        ("*.*", VersionRange()),
        ("v*.*", VersionRange()),
        ("*.x.*", VersionRange()),
        ("x.X.x.*", VersionRange()),
        (">1.0.0", VersionRange(min=Version.from_parts(1, 0, 0))),
        ("<1.2.3", VersionRange(max=Version.from_parts(1, 2, 3))),
        ("<=1.2.3",
         VersionRange(max=Version.from_parts(1, 2, 3), include_max=True)),
        (">=1.2.3",
         VersionRange(min=Version.from_parts(1, 2, 3), include_min=True)),
        ("=1.2.3", Version.from_parts(1, 2, 3)),
        ("1.2.3", Version.from_parts(1, 2, 3)),
        ("1!2.3.4", Version.from_parts(2, 3, 4, epoch=1)),
        ("=1.0", Version.from_parts(1, 0, 0)),
        ("1.2.3b5", Version.from_parts(1, 2, 3, pre=ReleaseTag("beta", 5))),
Exemple #23
0
def test_parse_constraint_multi(input):
    assert parse_constraint(input) == VersionRange(
        Version(2, 0, 0), Version(3, 0, 0), include_min=False, include_max=True
    )
Exemple #24
0
def test_intersect(v114, v123, v124, v200, v250, v300):
    # two overlapping ranges
    assert VersionRange(v123, v250).intersect(VersionRange(
        v200, v300)) == VersionRange(v200, v250)

    # a non-overlapping range allows no versions
    a = VersionRange(v114, v124)
    b = VersionRange(v200, v250)
    assert a.intersect(b).is_empty()

    # adjacent ranges allow no versions if exclusive
    a = VersionRange(v114, v124)
    b = VersionRange(v124, v200)
    assert a.intersect(b).is_empty()

    # adjacent ranges allow version if inclusive
    a = VersionRange(v114, v124, include_max=True)
    b = VersionRange(v124, v200, include_min=True)
    assert a.intersect(b) == v124

    # with an open range
    open = VersionRange()
    a = VersionRange(v114, v124)
    assert open.intersect(open) == open
    assert open.intersect(a) == a

    # returns the version if the range allows it
    assert VersionRange(v114, v124).intersect(v123) == v123
    assert VersionRange(v123, v124).intersect(v114).is_empty()
Exemple #25
0
def test_union(v003, v010, v072, v080, v114, v123, v124, v130, v140, v200,
               v234, v250, v300):
    # with a version returns the range if it contains the version
    range = VersionRange(v114, v124)
    assert range.union(v123) == range

    # with a version on the edge of the range, expands the range
    range = VersionRange(v114, v124)
    assert range.union(v124) == VersionRange(v114, v124, include_max=True)
    assert range.union(v114) == VersionRange(v114, v124, include_min=True)

    # with a version allows both the range and the version if the range
    # doesn't contain the version
    result = VersionRange(v003, v114).union(v124)
    assert result.allows(v010)
    assert not result.allows(v123)
    assert result.allows(v124)

    # returns a VersionUnion for a disjoint range
    result = VersionRange(v003, v114).union(VersionRange(v130, v200))
    assert result.allows(v080)
    assert not result.allows(v123)
    assert result.allows(v140)

    # considers open ranges disjoint
    result = VersionRange(v003, v114).union(VersionRange(v114, v200))
    assert result.allows(v080)
    assert not result.allows(v114)
    assert result.allows(v140)
    result = VersionRange(v114, v200).union(VersionRange(v003, v114))
    assert result.allows(v080)
    assert not result.allows(v114)
    assert result.allows(v140)

    # returns a merged range for an overlapping range
    result = VersionRange(v003, v114).union(VersionRange(v080, v200))
    assert result == VersionRange(v003, v200)

    # considers closed ranges overlapping
    result = VersionRange(v003, v114,
                          include_max=True).union(VersionRange(v114, v200))
    assert result == VersionRange(v003, v200)
    result = VersionRange(v003, v114).union(
        VersionRange(v114, v200, include_min=True))
    assert result == VersionRange(v003, v200)
    def excludes_single_version(self) -> bool:
        from .version import Version
        from .version_range import VersionRange

        return isinstance(VersionRange().difference(self), Version)
Exemple #27
0
def test_include_max_prerelease(v200, v300, v300b1):
    result = VersionRange(v200, v300)

    assert not result.allows(v300b1)
    assert not result.allows_any(VersionRange(v300b1))
    assert not result.allows_all(VersionRange(v200, v300b1))

    result = VersionRange(v200, v300, always_include_max_prerelease=True)

    assert result.allows(v300b1)
    assert result.allows_any(VersionRange(v300b1))
    assert result.allows_all(VersionRange(v200, v300b1))
Exemple #28
0
def test_allows_all(v003, v010, v080, v114, v123, v124, v140, v200, v234, v250,
                    v300):
    assert VersionRange(v123, v250).allows_all(EmptyConstraint())

    range = VersionRange(v123, v250, include_max=True)
    assert not range.allows_all(v123)
    assert range.allows_all(v124)
    assert range.allows_all(v250)
    assert not range.allows_all(v300)

    # with no min
    range = VersionRange(max=v250)
    assert range.allows_all(VersionRange(v080, v140))
    assert not range.allows_all(VersionRange(v080, v300))
    assert range.allows_all(VersionRange(max=v140))
    assert not range.allows_all(VersionRange(max=v300))
    assert range.allows_all(range)
    assert not range.allows_all(VersionRange())

    # with no max
    range = VersionRange(min=v010)
    assert range.allows_all(VersionRange(v080, v140))
    assert not range.allows_all(VersionRange(v003, v140))
    assert range.allows_all(VersionRange(v080))
    assert not range.allows_all(VersionRange(v003))
    assert range.allows_all(range)
    assert not range.allows_all(VersionRange())

    # Allows bordering range that is not more inclusive
    exclusive = VersionRange(v010, v250)
    inclusive = VersionRange(v010, v250, True, True)
    assert inclusive.allows_all(exclusive)
    assert inclusive.allows_all(inclusive)
    assert not exclusive.allows_all(inclusive)
    assert exclusive.allows_all(exclusive)

    # Allows unions that are completely contained
    range = VersionRange(v114, v200)
    assert range.allows_all(VersionRange(v123, v124).union(v140))
    assert not range.allows_all(VersionRange(v010, v124).union(v140))
    assert not range.allows_all(VersionRange(v123, v234).union(v140))
Exemple #29
0
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))
Exemple #30
0
def test_allows_any(v003, v010, v072, v080, v114, v123, v124, v140, v200, v234,
                    v250, v300):
    # disallows an empty constraint
    assert not VersionRange(v123, v250).allows_any(EmptyConstraint())

    # allows allowed versions
    range = VersionRange(v123, v250, include_max=True)
    assert not range.allows_any(v123)
    assert range.allows_any(v124)
    assert range.allows_any(v250)
    assert not range.allows_any(v300)

    # with no min
    range = VersionRange(max=v200)
    assert range.allows_any(VersionRange(v140, v300))
    assert not range.allows_any(VersionRange(v234, v300))
    assert range.allows_any(VersionRange(v140))
    assert not range.allows_any(VersionRange(v234))
    assert range.allows_any(range)

    # with no max
    range = VersionRange(min=v072)
    assert range.allows_any(VersionRange(v003, v140))
    assert not range.allows_any(VersionRange(v003, v010))
    assert range.allows_any(VersionRange(max=v080))
    assert not range.allows_any(VersionRange(max=v003))
    assert range.allows_any(range)

    # with min and max
    range = VersionRange(v072, v200)
    assert range.allows_any(VersionRange(v003, v140))
    assert range.allows_any(VersionRange(v140, v300))
    assert not range.allows_any(VersionRange(v003, v010))
    assert not range.allows_any(VersionRange(v234, v300))
    assert not range.allows_any(VersionRange(max=v010))
    assert not range.allows_any(VersionRange(v234))
    assert range.allows_any(range)

    # allows a bordering range when both are inclusive
    assert not VersionRange(max=v250).allows_any(VersionRange(min=v250))
    assert not VersionRange(max=v250, include_max=True).allows_any(
        VersionRange(min=v250))
    assert not VersionRange(max=v250).allows_any(
        VersionRange(min=v250, include_min=True))
    assert not VersionRange(min=v250).allows_any(VersionRange(max=v250))
    assert VersionRange(max=v250, include_max=True).allows_any(
        VersionRange(min=v250, include_min=True))

    # allows unions that are partially contained'
    range = VersionRange(v114, v200)
    assert range.allows_any(VersionRange(v010, v080).union(v140))
    assert range.allows_any(VersionRange(v123, v234).union(v300))
    assert not range.allows_any(VersionRange(v234, v300).union(v010))

    # pre-release min does not allow lesser than itself
    range = VersionRange(Version.parse("1.9b1"), include_min=True)
    assert not range.allows_any(
        VersionRange(
            Version.parse("1.8.0"), Version.parse("1.9.0"), include_min=True))