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

pantsbuild / pants / 25259185675

02 May 2026 06:47PM UTC coverage: 92.141% (-0.8%) from 92.955%
25259185675

push

github

web-flow
Fix the dynamic UI. (#23306)

In #23114 we upgraded to indicatif 0.18.4,
which included a fix to respect TERM, and 
display nothing if it's unset.

Since we did not pass TERM through pantsd, the
dynamic ui is now not shown. 

This change fixes that, and also pass NO_COLOR
through, since indicatif inspects it too.

88773 of 96345 relevant lines covered (92.14%)

3.83 hits per line

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

86.84
/src/python/pants/util/meta.py
1
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from abc import ABC, abstractmethod
11✔
5
from collections.abc import Callable
11✔
6
from typing import Any, TypeVar
11✔
7

8
T = TypeVar("T")
11✔
9
C = TypeVar("C", bound=type[Any])
11✔
10

11

12
class SingletonMetaclass(type):
11✔
13
    """When using this metaclass in your class definition, your class becomes a singleton. That is,
14
    every construction returns the same instance.
15

16
    Example class definition:
17

18
      class Unicorn(metaclass=SingletonMetaclass):
19
        pass
20
    """
21

22
    def __call__(cls, *args: Any, **kwargs: Any) -> Any:
11✔
23
        # TODO: convert this into an `@memoized_classproperty`!
24
        if not hasattr(cls, "instance"):
11✔
25
            cls.instance = super().__call__(*args, **kwargs)
11✔
26
        return cls.instance
11✔
27

28

29
class _ClassPropertyDescriptor:
11✔
30
    """Define a readable attribute on a class, given a function."""
31

32
    # The current solution is preferred as it doesn't require any modifications to the class
33
    # definition beyond declaring a @classproperty.  It seems overriding __set__ and __delete__ would
34
    # require defining a metaclass or overriding __setattr__/__delattr__ (see
35
    # https://stackoverflow.com/questions/5189699/how-to-make-a-class-property).
36
    def __init__(self, fget: classmethod | staticmethod, doc: str | None) -> None:
11✔
37
        self.fget = fget
11✔
38
        self.__doc__ = doc
11✔
39

40
    # See https://docs.python.org/3/howto/descriptor.html for more details.
41
    def __get__(self, obj: T, objtype: type[T] | None = None) -> Any:
11✔
42
        if objtype is None:
11✔
43
            objtype = type(obj)
×
44
            # Get the callable field for this object, which may be a property.
45
        callable_field = self.fget.__get__(obj, objtype)
11✔
46
        if getattr(self.fget.__func__, "__isabstractmethod__", False):
11✔
47
            field_name = self.fget.__func__.fget.__name__  # type: ignore[union-attr]
×
48
            raise TypeError(
×
49
                f"""\
50
The classproperty '{field_name}' in type '{objtype.__name__}' was an abstractproperty, meaning that type \
51
{objtype.__name__} must override it by setting it as a variable in the class body or defining a method \
52
with an @classproperty decorator."""
53
            )
54
        return callable_field()
11✔
55

56

57
def runtime_ignore_subscripts(cls: C) -> C:
11✔
58
    """Use as a decorator on a class to make it subscriptable at runtime, returning the class.
59

60
    Generally, this is used inside the `else` of a `TYPE_CHECKING` check.
61

62
    Usage:
63
    >>> if TYPE_CHECKING:
64
    ...     class MyClass(Generic[...]):
65
    ...         ...
66
    ... else:
67
    ...     @runtime_ignore_subscripts
68
    ...     class MyClass:
69
    ...         ...
70
    ...
71
    >>> MyClass[int] is MyClass
72
    True
73
    """
74

75
    @classmethod  # type: ignore[misc]
11✔
76
    def __class_getitem__(cls, item):
11✔
77
        return cls
11✔
78

79
    cls.__class_getitem__ = __class_getitem__
11✔
80

81
    return cls
11✔
82

83

84
def classproperty(func: Callable[..., T]) -> T:
11✔
85
    """Use as a decorator on a method definition to make it a class-level attribute.
86

87
    This decorator can be applied to a method, a classmethod, or a staticmethod. This decorator will
88
    bind the first argument to the class object.
89

90
    Usage:
91
    >>> class Foo:
92
    ...   @classproperty
93
    ...   def name(cls):
94
    ...     return cls.__name__
95
    ...
96
    >>> Foo.name
97
    'Foo'
98

99
    Setting or deleting the attribute of this name will overwrite this property.
100

101
    The docstring of the classproperty `x` for a class `C` can be obtained by
102
    `C.__dict__['x'].__doc__`.
103
    """
104
    doc = func.__doc__
11✔
105

106
    if not isinstance(func, (classmethod, staticmethod)):
11✔
107
        # MyPy complains about converting a Callable -> classmethod. We use a Callable in the first
108
        # place because there is no typing.classmethod, i.e. a type that takes generic arguments, and
109
        # we need to use TypeVars for the call sites of this decorator to work properly.
110
        func = classmethod(func)  # type: ignore[assignment]
11✔
111

112
    # If we properly annotated this function as returning a _ClassPropertyDescriptor, then MyPy would
113
    # no longer work correctly at call sites for this decorator.
114
    return _ClassPropertyDescriptor(func, doc)  # type: ignore[arg-type, return-value]
11✔
115

116

117
class _ClassDecoratorWithSentinelAttribute(ABC):
11✔
118
    """Base class to wrap a class decorator which sets a "sentinel attribute".
119

120
    This functionality is exposed via the `@decorated_type_checkable` decorator.
121
    """
122

123
    @abstractmethod
124
    def __call__(self, cls: type[Any]) -> type[Any]: ...
125

126
    def define_instance_of(self, obj: type[Any], **kwargs) -> type[Any]:
11✔
127
        return type(obj.__name__, (obj,), {"_decorated_type_checkable_type": type(self), **kwargs})
×
128

129
    def is_instance(self, obj: type[Any]) -> bool:
11✔
130
        return getattr(obj, "_decorated_type_checkable_type", None) is type(self)
×
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