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

pantsbuild / pants / 19250292619

11 Nov 2025 12:09AM UTC coverage: 77.865% (-2.4%) from 80.298%
19250292619

push

github

web-flow
flag non-runnable targets used with `code_quality_tool` (#22875)

2 of 5 new or added lines in 2 files covered. (40.0%)

1487 existing lines in 72 files now uncovered.

71448 of 91759 relevant lines covered (77.86%)

3.22 hits per line

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

64.2
/src/python/pants/engine/internals/defaults.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3
"""The `BuildFileDefaultsParserState.set_defaults` is used by the pants.engine.internals.Parser,
4
exposed as the `__defaults__` BUILD file symbol.
5

6
When parsing a BUILD (from the rule `pants.engine.internals.build_files.parse_address_family`) the
7
defaults from the closest parent BUILD file is passed as input to the parser, and the new defaults
8
resulting after the BUILD file have been parsed is returned in the `AddressFamily`.
9

10
These defaults are then applied when creating the `TargetAdaptor` targets by the `Registrar` in the
11
parser.
12
"""
13

14
from __future__ import annotations
11✔
15

16
from collections.abc import Callable, Iterable, Mapping
11✔
17
from dataclasses import dataclass
11✔
18
from typing import Any, Union
11✔
19

20
from pants.engine.addresses import Address
11✔
21
from pants.engine.internals.parametrize import Parametrize
11✔
22
from pants.engine.target import (
11✔
23
    Field,
24
    ImmutableValue,
25
    InvalidFieldException,
26
    RegisteredTargetTypes,
27
    Target,
28
    TargetGenerator,
29
)
30
from pants.engine.unions import UnionMembership
11✔
31
from pants.util.frozendict import FrozenDict
11✔
32

33
SetDefaultsValueT = Mapping[str, Any]
11✔
34
SetDefaultsKeyT = Union[str, tuple[str, ...]]
11✔
35
SetDefaultsT = Mapping[SetDefaultsKeyT, SetDefaultsValueT]
11✔
36

37

38
class BuildFileDefaults(FrozenDict[str, FrozenDict[str, ImmutableValue]]):
11✔
39
    """Map target types to default field values."""
40

41

42
class ParametrizeDefault(Parametrize):
11✔
43
    """Parametrize for default field values.
44

45
    This is to have eager validation on the field values rather than erroring first when applied on
46
    an actual target.
47
    """
48

49
    @classmethod
11✔
50
    def create(
11✔
51
        cls, freeze: Callable[[Any], ImmutableValue], parametrize: Parametrize
52
    ) -> ParametrizeDefault:
UNCOV
53
        return cls(
×
54
            *map(freeze, parametrize.args),
55
            **{kw: freeze(arg) for kw, arg in parametrize.kwargs.items()},
56
        ).to_weak()
57

58

59
@dataclass
11✔
60
class BuildFileDefaultsParserState:
11✔
61
    address: Address
11✔
62
    defaults: dict[str, Mapping[str, Any]]
11✔
63
    registered_target_types: RegisteredTargetTypes
11✔
64
    union_membership: UnionMembership
11✔
65

66
    @classmethod
11✔
67
    def create(
11✔
68
        cls,
69
        path: str,
70
        defaults: BuildFileDefaults,
71
        registered_target_types: RegisteredTargetTypes,
72
        union_membership: UnionMembership,
73
    ) -> BuildFileDefaultsParserState:
74
        return cls(
2✔
75
            address=Address(path, generated_name="__defaults__"),
76
            defaults=dict(defaults),
77
            registered_target_types=registered_target_types,
78
            union_membership=union_membership,
79
        )
80

81
    def _freeze_field_value(self, field_type: type[Field], value: Any) -> ImmutableValue:
11✔
82
        if isinstance(value, ParametrizeDefault):
1✔
83
            return value
×
84
        elif isinstance(value, Parametrize):
1✔
85

UNCOV
86
            def freeze(v: Any) -> ImmutableValue:
×
UNCOV
87
                return self._freeze_field_value(field_type, v)
×
88

UNCOV
89
            return ParametrizeDefault.create(freeze, value)
×
90
        else:
91
            return field_type.compute_value(raw_value=value, address=self.address)
1✔
92

93
    def get_frozen_defaults(self) -> BuildFileDefaults:
11✔
94
        types = self.registered_target_types.aliases_to_types
1✔
95
        return BuildFileDefaults(
1✔
96
            {
97
                target_alias: FrozenDict(
98
                    {
99
                        **{
100
                            field_type.alias: self._freeze_field_value(field_type, default)
101
                            for field_alias, default in fields.items()
102
                            for field_type in self._target_type_field_types(types[target_alias])
103
                            if field_alias in (field_type.alias, field_type.deprecated_alias)
104
                        },
105
                        **{
106
                            key: ParametrizeDefault(
107
                                parametrize.group_name,
108
                                **{
109
                                    field_type.alias: self._freeze_field_value(field_type, default)
110
                                    for field_alias, default in parametrize.kwargs.items()
111
                                    for field_type in self._target_type_field_types(
112
                                        types[target_alias]
113
                                    )
114
                                    if field_alias
115
                                    in (field_type.alias, field_type.deprecated_alias)
116
                                },
117
                            )
118
                            .to_weak()
119
                            .to_group()
120
                            for key, parametrize in fields.items()
121
                            if isinstance(parametrize, Parametrize) and parametrize.is_group
122
                        },
123
                    }
124
                )
125
                for target_alias, fields in self.defaults.items()
126
            }
127
        )
128

129
    def get(self, target_alias: str) -> Mapping[str, Any]:
11✔
130
        # Used by `pants.engine.internals.parser.Parser._generate_symbols.Registrar.__call__`
131
        return self.defaults.get(target_alias, {})
2✔
132

133
    def set_defaults(
11✔
134
        self,
135
        *args: SetDefaultsT,
136
        all: SetDefaultsValueT | None = None,
137
        extend: bool = False,
138
        ignore_unknown_fields: bool = False,
139
        ignore_unknown_targets: bool = False,
140
    ) -> None:
141
        defaults: dict[str, dict[str, Any]] = (
1✔
142
            {} if not extend else {k: dict(v) for k, v in self.defaults.items()}
143
        )
144

145
        if all is not None:
1✔
UNCOV
146
            self._process_defaults(
×
147
                defaults,
148
                {tuple(self.registered_target_types.aliases): all},
149
                ignore_unknown_fields=True,
150
                ignore_unknown_targets=ignore_unknown_targets,
151
            )
152

153
        for arg in args:
1✔
154
            self._process_defaults(
1✔
155
                defaults,
156
                arg,
157
                ignore_unknown_fields=ignore_unknown_fields,
158
                ignore_unknown_targets=ignore_unknown_targets,
159
            )
160

161
        # Update with new defaults, dropping targets without any default values.
162
        for tgt, default in defaults.items():
1✔
UNCOV
163
            if not default:
×
UNCOV
164
                self.defaults.pop(tgt, None)
×
165
            else:
UNCOV
166
                self.defaults[tgt] = default
×
167

168
    def _target_type_field_types(self, target_type: type[Target]) -> tuple[type[Field], ...]:
11✔
169
        return (
1✔
170
            *target_type.class_field_types(self.union_membership),
171
            *(target_type.moved_fields if issubclass(target_type, TargetGenerator) else ()),
172
        )
173

174
    def _process_defaults(
11✔
175
        self,
176
        defaults: dict[str, dict[str, Any]],
177
        targets_defaults: SetDefaultsT,
178
        ignore_unknown_fields: bool = False,
179
        ignore_unknown_targets: bool = False,
180
    ):
181
        if not isinstance(targets_defaults, dict):
1✔
UNCOV
182
            raise ValueError(
×
183
                f"Expected dictionary mapping targets to default field values for {self.address} "
184
                f"but got: {type(targets_defaults).__name__}."
185
            )
186

187
        types = self.registered_target_types.aliases_to_types
1✔
188
        for target, default in targets_defaults.items():
1✔
189
            if not isinstance(default, dict):
1✔
UNCOV
190
                raise ValueError(
×
191
                    f"Invalid default field values in {self.address} for target type {target}, "
192
                    f"must be an `dict` but was {default!r} with type `{type(default).__name__}`."
193
                )
194

195
            targets: Iterable[str]
196
            targets = target if isinstance(target, tuple) else (target,)
1✔
197
            for target_alias in map(str, targets):
1✔
198
                if target_alias in types:
1✔
UNCOV
199
                    target_type = types[target_alias]
×
200
                elif ignore_unknown_targets:
1✔
201
                    continue
1✔
202
                else:
UNCOV
203
                    raise ValueError(f"Unrecognized target type {target_alias} in {self.address}.")
×
204

205
                # Copy default dict if we may mutate it.
UNCOV
206
                raw_values = dict(default) if ignore_unknown_fields else default
×
207

208
                # Validate that field exists on target
UNCOV
209
                valid_field_aliases = set(
×
210
                    target_type._get_field_aliases_to_field_types(
211
                        self._target_type_field_types(target_type)
212
                    ).keys()
213
                )
214

UNCOV
215
                def _check_field_alias(field_alias: str) -> None:
×
UNCOV
216
                    if field_alias in valid_field_aliases:
×
UNCOV
217
                        return
×
UNCOV
218
                    if not ignore_unknown_fields:
×
UNCOV
219
                        raise InvalidFieldException(
×
220
                            f"Unrecognized field `{field_alias}` for target {target_type.alias}. "
221
                            f"Valid fields are: {', '.join(sorted(valid_field_aliases))}.",
222
                        )
UNCOV
223
                    elif field_alias in raw_values:
×
UNCOV
224
                        del raw_values[field_alias]
×
225

UNCOV
226
                for field_alias, field_value in default.items():
×
UNCOV
227
                    if isinstance(field_value, Parametrize) and field_value.is_group:
×
UNCOV
228
                        field_value.to_weak()
×
UNCOV
229
                        for parametrize_field_alias in field_value.kwargs.keys():
×
UNCOV
230
                            _check_field_alias(parametrize_field_alias)
×
231
                    else:
UNCOV
232
                        _check_field_alias(field_alias)
×
233

234
                # Merge all provided defaults for this call.
UNCOV
235
                defaults.setdefault(target_type.alias, {}).update(raw_values)
×
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