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

pantsbuild / pants / 21378504907

26 Jan 2026 11:48PM UTC coverage: 43.218% (-37.1%) from 80.269%
21378504907

Pull #23038

github

web-flow
Merge a9ec5051e into 09b8ecaa1
Pull Request #23038: remote cache logger - new plugin to help debug the remote cache

0 of 45 new or added lines in 1 file covered. (0.0%)

17212 existing lines in 540 files now uncovered.

26144 of 60493 relevant lines covered (43.22%)

0.86 hits per line

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

68.63
/src/python/pants/build_graph/build_file_aliases.py
1
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
2✔
5

6
from collections.abc import Callable, Mapping
2✔
7
from dataclasses import dataclass
2✔
8
from typing import Any
2✔
9

10
from pants.base.parse_context import ParseContext
2✔
11
from pants.util.frozendict import FrozenDict
2✔
12

13
ContextAwareObjectFactory = Callable[[ParseContext], Callable[..., None]]
2✔
14

15

16
@dataclass(frozen=True)
2✔
17
class BuildFileAliases:
2✔
18
    """A structure containing sets of symbols to be exposed in BUILD files.
19

20
    There are three types of symbols that can be directly exposed:
21

22
    :API: public
23

24
    - targets: These are Target subclasses or TargetMacro.Factory instances.
25
    - objects: These are any python object, from constants to types.
26
    - context_aware_object_factories: These are object factories that are passed a ParseContext and
27
      produce one or more objects that use data from the context to enable some feature or utility;
28
      you might call them a BUILD file "macro" since they expand parameters to some final, "real"
29
      BUILD file object.  Common uses include creating objects that must be aware of the current
30
      BUILD file path or functions that need to be able to create targets or objects from within the
31
      BUILD file parse.
32
    """
33

34
    _objects: FrozenDict[str, Any]
2✔
35
    _context_aware_object_factories: FrozenDict[str, ContextAwareObjectFactory]
2✔
36

37
    @classmethod
2✔
38
    def _validate_alias(cls, category: str, alias: str, obj: Any) -> None:
2✔
39
        if not isinstance(alias, str):
2✔
40
            raise TypeError(
×
41
                f"Aliases must be strings, given {category} entry {alias!r} of type {type(alias).__name__} as "
42
                f"the alias of {obj}"
43
            )
44

45
    @classmethod
2✔
46
    def _validate_objects(cls, objects: dict[str, Any] | None) -> FrozenDict[str, Any]:
2✔
47
        if not objects:
2✔
48
            return FrozenDict()
2✔
49

50
        for alias, obj in objects.items():
2✔
51
            cls._validate_alias("objects", alias, obj)
2✔
52
        return FrozenDict(objects)
2✔
53

54
    @classmethod
2✔
55
    def _validate_context_aware_object_factories(
2✔
56
        cls, context_aware_object_factories: dict[str, ContextAwareObjectFactory] | None
57
    ) -> FrozenDict[str, ContextAwareObjectFactory]:
58
        if not context_aware_object_factories:
2✔
59
            return FrozenDict()
2✔
60

UNCOV
61
        for alias, obj in context_aware_object_factories.items():
×
UNCOV
62
            cls._validate_alias("context_aware_object_factories", alias, obj)
×
UNCOV
63
            if not callable(obj):
×
UNCOV
64
                raise TypeError(
×
65
                    f"The given context aware object factory {alias!r} must be a callable."
66
                )
67

UNCOV
68
        return FrozenDict(context_aware_object_factories)
×
69

70
    def __init__(
2✔
71
        self,
72
        objects: dict[str, Any] | None = None,
73
        context_aware_object_factories: dict[str, ContextAwareObjectFactory] | None = None,
74
    ) -> None:
75
        """
76
        :API: public
77
        """
78
        object.__setattr__(self, "_objects", self._validate_objects(objects))
2✔
79
        object.__setattr__(
2✔
80
            self,
81
            "_context_aware_object_factories",
82
            self._validate_context_aware_object_factories(context_aware_object_factories),
83
        )
84

85
    @property
2✔
86
    def objects(self) -> FrozenDict[str, Any]:
2✔
87
        """
88
        :API: public
89
        """
90
        return self._objects
2✔
91

92
    @property
2✔
93
    def context_aware_object_factories(self) -> FrozenDict[str, ContextAwareObjectFactory]:
2✔
94
        """
95
        :API: public
96
        """
97
        return self._context_aware_object_factories
2✔
98

99
    def merge(self, other: BuildFileAliases) -> BuildFileAliases:
2✔
100
        """Merges a set of build file aliases and returns a new set of aliases containing both.
101

102
        Any duplicate aliases from `other` will trump.
103

104
        :API: public
105
        """
UNCOV
106
        if not isinstance(other, BuildFileAliases):
×
107
            raise TypeError(f"Can only merge other BuildFileAliases, given {other}")
×
108

UNCOV
109
        def _merge(item1: Mapping[str, Any], item2: Mapping[str, Any]) -> dict[str, Any]:
×
UNCOV
110
            merged: dict[str, Any] = {}
×
UNCOV
111
            merged.update(item1)
×
UNCOV
112
            merged.update(item2)
×
UNCOV
113
            return merged
×
114

UNCOV
115
        objects = _merge(self.objects, other.objects)
×
UNCOV
116
        context_aware_object_factories = _merge(
×
117
            self.context_aware_object_factories, other.context_aware_object_factories
118
        )
UNCOV
119
        return BuildFileAliases(
×
120
            objects=objects,
121
            context_aware_object_factories=context_aware_object_factories,
122
        )
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