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

pantsbuild / pants / 22507851448

27 Feb 2026 11:28PM UTC coverage: 92.928% (-0.007%) from 92.935%
22507851448

push

github

web-flow
silence new HdrHistogram induced deprecation warning on Python 3.14 (#23144)

No more:
```
/usr/lib/python3.14/ctypes/_endian.py:33: DeprecationWarning: Due to '_pack_', the
'ExternalHeader' Structure will use memory layout compatible with MSVC (Windows). If this is intended, set _layout_ to 'ms'. The
 implicit default is deprecated and slated to become an error in Python 3.19.
  super().__setattr__(attrname, value)
/usr/lib/python3.14/ctypes/_endian.py:33: DeprecationWarning: Due to '_pack_', the 'PayloadHeader' Structure will use memory
layout compatible with MSVC (Windows). If this is intended, set _layout_ to 'ms'. The implicit default is deprecated and slated
to become an error in Python 3.19.
  super().__setattr__(attrname, value)
```

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

71 existing lines in 12 files now uncovered.

90912 of 97831 relevant lines covered (92.93%)

4.06 hits per line

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

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

5
import json
×
UNCOV
6
import logging
×
7
from typing import Any
×
8

9
from pants.engine.internals.scheduler import Workunit
×
UNCOV
10
from pants.engine.rules import collect_rules, rule
×
UNCOV
11
from pants.engine.streaming_workunit_handler import (
×
12
    StreamingWorkunitContext,
13
    WorkunitsCallback,
14
    WorkunitsCallbackFactory,
15
    WorkunitsCallbackFactoryRequest,
16
)
17
from pants.engine.unions import UnionRule
×
18
from pants.option.option_types import BoolOption, StrOption
×
UNCOV
19
from pants.option.subsystem import Subsystem
×
20
from pants.util.dirutil import safe_open
×
21

UNCOV
22
logger = logging.getLogger(__name__)
×
23

24

UNCOV
25
def just_dump_map(workunits_map):
×
UNCOV
26
    return [
×
27
        {
28
            k: v
29
            for k, v in wu.items()
30
            if k
31
            in (
32
                "name",
33
                "span_id",
34
                "level",
35
                "parent_id",
36
                "start_secs",
37
                "start_nanos",
38
                "description",
39
                "duration_secs",
40
                "duration_nanos",
41
                "metadata",
42
            )
43
        }
44
        for wu in workunits_map.values()
45
    ]
46

47

UNCOV
48
def pass_through_unserializable_metadata(obj):
×
49
    """Most of the metadata in workunit objects is json serializable, but it is not guaranteed that
50
    all of it is.
51

52
    This function is intended to be used as a `default` encoder to json.dumps to drop a minimal stub
53
    encoding with the name instead of throwing a TypeError and halting the entire workunit logging.
54
    """
UNCOV
55
    return {"name": obj.__class__.__name__, "json_serializable": False, "str": str(obj)}
×
56

57

UNCOV
58
class WorkunitLoggerCallback(WorkunitsCallback):
×
59
    """Configuration for WorkunitLogger."""
60

61
    def __init__(self, wulogger: WorkunitLogger):
×
UNCOV
62
        self.wulogger = wulogger
×
63
        self._completed_workunits: dict[str, object] = {}
×
64

65
    @property
×
UNCOV
66
    def can_finish_async(self) -> bool:
×
67
        return False
×
68

UNCOV
69
    def __call__(
×
70
        self,
71
        *,
72
        completed_workunits: tuple[Workunit, ...],
73
        started_workunits: tuple[Workunit, ...],
74
        context: StreamingWorkunitContext,
75
        finished: bool = False,
76
        **kwargs: Any,
77
    ) -> None:
78
        for wu in completed_workunits:
×
79
            self._completed_workunits[wu["span_id"]] = wu
×
80
        if finished:
×
81
            filepath = f"{self.wulogger.logdir}/{context.run_tracker.run_id}.json"
×
UNCOV
82
            with safe_open(filepath, "w") as f:
×
UNCOV
83
                json.dump(
×
84
                    just_dump_map(self._completed_workunits),
85
                    f,
86
                    default=pass_through_unserializable_metadata,
87
                )
UNCOV
88
                logger.info(f"Wrote log to {filepath}")
×
89

90

UNCOV
91
class WorkunitLoggerCallbackFactoryRequest:
×
92
    """A unique request type that is installed to trigger construction of our WorkunitsCallback."""
93

94

95
class WorkunitLogger(Subsystem):
×
UNCOV
96
    options_scope = "workunit-logger"
×
97
    help = "Workunit Logger subsystem. Useful for debugging pants itself."
×
98

UNCOV
99
    enabled = BoolOption("--enabled", default=False, help="Whether to enable workunit logging.")
×
UNCOV
100
    logdir = StrOption("--logdir", default=".pants.d", help="Where to write the log to.")
×
101

102

UNCOV
103
@rule
×
UNCOV
104
async def construct_callback(
×
105
    _: WorkunitLoggerCallbackFactoryRequest,
106
    wulogger: WorkunitLogger,
107
) -> WorkunitsCallbackFactory:
UNCOV
108
    return WorkunitsCallbackFactory(
×
109
        lambda: WorkunitLoggerCallback(wulogger) if wulogger.enabled else None
110
    )
111

112

UNCOV
113
def rules():
×
UNCOV
114
    return [
×
115
        UnionRule(WorkunitsCallbackFactoryRequest, WorkunitLoggerCallbackFactoryRequest),
116
        *collect_rules(),
117
    ]
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