• 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/jvm/resolve/lockfile_metadata.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

UNCOV
4
from __future__ import annotations
×
5

UNCOV
6
from collections.abc import Iterable
×
UNCOV
7
from dataclasses import dataclass
×
UNCOV
8
from enum import Enum
×
UNCOV
9
from typing import Any, cast
×
10

UNCOV
11
from pants.core.util_rules.lockfile_metadata import (
×
12
    LockfileMetadata,
13
    LockfileMetadataValidation,
14
    LockfileScope,
15
    _get_metadata,
16
    lockfile_metadata_registrar,
17
)
UNCOV
18
from pants.jvm.resolve.common import ArtifactRequirement
×
UNCOV
19
from pants.util.ordered_set import FrozenOrderedSet
×
20

UNCOV
21
_jvm_lockfile_metadata = lockfile_metadata_registrar(LockfileScope.JVM)
×
22

23

UNCOV
24
class InvalidJVMLockfileReason(Enum):
×
UNCOV
25
    REQUIREMENTS_MISMATCH = "requirements_mismatch"
×
26

27

UNCOV
28
class LockfileContext(Enum):
×
UNCOV
29
    USER = "user"
×
UNCOV
30
    TOOL = "tool"
×
31

32

UNCOV
33
@dataclass(frozen=True)
×
UNCOV
34
class JVMLockfileMetadata(LockfileMetadata):
×
UNCOV
35
    scope = LockfileScope.JVM
×
36

UNCOV
37
    @staticmethod
×
UNCOV
38
    def new(
×
39
        requirements: Iterable[ArtifactRequirement],
40
    ) -> JVMLockfileMetadata:
41
        """Call the most recent version of the `LockfileMetadata` class to construct a concrete
42
        instance.
43

44
        This static method should be used in place of the `LockfileMetadata` constructor. This gives
45
        calling sites a predictable method to call to construct a new `LockfileMetadata` for
46
        writing, while still allowing us to support _reading_ older, deprecated metadata versions.
47
        """
48

UNCOV
49
        return JVMLockfileMetadataV1.from_artifact_requirements(requirements)
×
50

UNCOV
51
    def is_valid_for(
×
52
        self,
53
        requirements: Iterable[ArtifactRequirement] | None,
54
        context: LockfileContext,
55
    ) -> LockfileMetadataValidation:
56
        """Returns Truthy if this `JVMLockfileMetadata` can be used in the current execution
57
        context."""
58

59
        raise NotImplementedError("call `is_valid_for` on subclasses only")
×
60

61

UNCOV
62
@_jvm_lockfile_metadata(1)
×
UNCOV
63
@dataclass(frozen=True)
×
UNCOV
64
class JVMLockfileMetadataV1(JVMLockfileMetadata):
×
65
    """Initial metadata version for JVM user lockfiles.
66

67
    User validity is tested by the set of user requirements strings appearing as a subset of those
68
    in the metadata requirements.
69

70
    Tool validity is tested by the set of user requirements strings being an exact match of those
71
    in the metadata requirements.
72
    """
73

UNCOV
74
    requirements: FrozenOrderedSet[str]
×
75

UNCOV
76
    @classmethod
×
UNCOV
77
    def from_artifact_requirements(
×
78
        cls, requirements: Iterable[ArtifactRequirement]
79
    ) -> JVMLockfileMetadataV1:
UNCOV
80
        return cls(FrozenOrderedSet(sorted(i.to_metadata_str() for i in requirements)))
×
81

UNCOV
82
    @classmethod
×
UNCOV
83
    def _from_json_dict(
×
84
        cls: type[JVMLockfileMetadataV1],
85
        json_dict: dict[Any, Any],
86
        lockfile_description: str,
87
        error_suffix: str,
88
    ) -> JVMLockfileMetadataV1:
UNCOV
89
        metadata = _get_metadata(json_dict, lockfile_description, error_suffix)
×
90

UNCOV
91
        requirements = metadata(
×
92
            "generated_with_requirements",
93
            FrozenOrderedSet[str],
94
            FrozenOrderedSet,
95
        )
96

UNCOV
97
        return JVMLockfileMetadataV1(requirements)
×
98

UNCOV
99
    @classmethod
×
UNCOV
100
    def additional_header_attrs(cls, instance: LockfileMetadata) -> dict[Any, Any]:
×
UNCOV
101
        instance = cast(JVMLockfileMetadataV1, instance)
×
UNCOV
102
        return {
×
103
            "generated_with_requirements": (
104
                sorted(instance.requirements) if instance.requirements is not None else None
105
            )
106
        }
107

UNCOV
108
    def is_valid_for(
×
109
        self,
110
        requirements: Iterable[ArtifactRequirement] | None,
111
        context: LockfileContext,
112
    ) -> LockfileMetadataValidation:
113
        """Returns a truthy object if the request requirements match the metadata requirements."""
114

UNCOV
115
        failure_reasons: set[InvalidJVMLockfileReason] = set()
×
UNCOV
116
        req_strings = FrozenOrderedSet(sorted(i.to_metadata_str() for i in requirements or []))
×
117

UNCOV
118
        if (context == LockfileContext.USER and not self.requirements.issuperset(req_strings)) or (
×
119
            context == LockfileContext.TOOL and self.requirements != req_strings
120
        ):
121
            failure_reasons.add(InvalidJVMLockfileReason.REQUIREMENTS_MISMATCH)
×
122

UNCOV
123
        return LockfileMetadataValidation(failure_reasons)
×
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

© 2026 Coveralls, Inc