• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 19015773527

02 Nov 2025 05:33PM UTC coverage: 17.872% (-62.4%) from 80.3%
19015773527

Pull #22816

github

web-flow
Merge a12d75757 into 6c024e162
Pull Request #22816: Update Pants internal Python to 3.14

4 of 5 new or added lines in 3 files covered. (80.0%)

28452 existing lines in 683 files now uncovered.

9831 of 55007 relevant lines covered (17.87%)

0.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/python/pants/backend/python/providers/python_build_standalone/constraints.py
1
# Copyright 2024 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
UNCOV
3
from __future__ import annotations
×
4

UNCOV
5
import operator
×
UNCOV
6
from collections.abc import Callable, Iterable
×
UNCOV
7
from typing import Protocol, cast
×
8

UNCOV
9
from packaging.version import Version
×
10

UNCOV
11
_OPERATORS = (
×
12
    (">=", operator.ge),
13
    ("<=", operator.le),
14
    ("==", operator.eq),
15
    ("!=", operator.ne),
16
    # `>` and `<` must come last since these strings are shorter!
17
    (">", operator.gt),
18
    ("<", operator.lt),
19
)
20

21

UNCOV
22
class ConstraintParseError(Exception):
×
UNCOV
23
    pass
×
24

25

UNCOV
26
class ConstraintSatisfied(Protocol):
×
27
    def is_satisified(self, version: Version) -> bool: ...
28

29

UNCOV
30
class Constraint(ConstraintSatisfied):
×
31
    """A single version constraint with operator."""
32

UNCOV
33
    def __init__(
×
34
        self, cmp_callback: Callable[[Version, Version], bool], cmp_version: Version
35
    ) -> None:
UNCOV
36
        self.cmp_callback: Callable[[Version, Version], bool] = cmp_callback
×
UNCOV
37
        self.cmp_version: Version = cmp_version
×
38

UNCOV
39
    def is_satisified(self, version: Version) -> bool:
×
UNCOV
40
        return self.cmp_callback(version, self.cmp_version)
×
41

UNCOV
42
    @classmethod
×
UNCOV
43
    def parse(cls, constraint: str) -> Constraint:
×
UNCOV
44
        constraint = constraint.strip()
×
45

UNCOV
46
        for op, callback in _OPERATORS:
×
UNCOV
47
            constraint_without_op = constraint.removeprefix(op)
×
UNCOV
48
            if constraint_without_op != constraint:
×
UNCOV
49
                cmp_callback = cast("Callable[[Version, Version], bool]", callback)
×
UNCOV
50
                cmp_version = Version(constraint_without_op.strip())
×
UNCOV
51
                return cls(cmp_callback, cmp_version)
×
52

53
        raise ConstraintParseError(
×
54
            f"A constraint must start with a comparison operator, i.e. {', '.join(x[0] for x in _OPERATORS)}, found {constraint!r}."
55
        )
56

57

UNCOV
58
class ConstraintsList(ConstraintSatisfied):
×
59
    """A list of constraints which must all match (i.e., they are AND'ed together)."""
60

UNCOV
61
    def __init__(self, constraints: Iterable[ConstraintSatisfied]) -> None:
×
UNCOV
62
        self.constraints: tuple[ConstraintSatisfied, ...] = tuple(constraints)
×
63

UNCOV
64
    def is_satisified(self, version: Version) -> bool:
×
UNCOV
65
        for constraint in self.constraints:
×
UNCOV
66
            if not constraint.is_satisified(version):
×
UNCOV
67
                return False
×
UNCOV
68
        return True
×
69

UNCOV
70
    @classmethod
×
UNCOV
71
    def parse(cls, constraints_str: str) -> ConstraintsList:
×
UNCOV
72
        parts = constraints_str.split(",")
×
UNCOV
73
        constraints = [Constraint.parse(part.strip()) for part in parts]
×
UNCOV
74
        return cls(constraints)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc