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

pantsbuild / pants / 25441711719

06 May 2026 02:31PM UTC coverage: 92.915%. Remained the same
25441711719

push

github

web-flow
use sha pin (with comment) format for generated actions (#23312)

Per the GitHub Action best practices we recently enabled at #23249, we
should pin each action to a SHA so that the reference is actually
immutable.

This will -- I hope -- knock out a large chunk of the 421 alerts we
currently get from zizmor. The next followup would then be upgrades and
harmonizing the generated and none-generated pins.

Notice: This idea was suggested by Claude while going over pinact output
and I was surprised to see that post processing the yaml wasn't too
gross.

92206 of 99237 relevant lines covered (92.91%)

4.04 hits per line

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

100.0
/src/python/pants/backend/codegen/protobuf/python/python_protobuf_module_mapper.py
1
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
4✔
5

6
from collections import defaultdict
4✔
7
from typing import DefaultDict
4✔
8

9
from pants.backend.codegen.protobuf.python.python_protobuf_subsystem import PythonProtobufSubsystem
4✔
10
from pants.backend.codegen.protobuf.target_types import (
4✔
11
    AllProtobufTargets,
12
    ProtobufGrpcToggleField,
13
    ProtobufSourceField,
14
)
15
from pants.backend.python.dependency_inference.module_mapper import (
4✔
16
    FirstPartyPythonMappingImpl,
17
    FirstPartyPythonMappingImplMarker,
18
    ModuleProvider,
19
    ModuleProviderType,
20
    ResolveName,
21
)
22
from pants.backend.python.subsystems.setup import PythonSetup
4✔
23
from pants.backend.python.target_types import PythonResolveField
4✔
24
from pants.core.util_rules.stripped_source_files import StrippedFileNameRequest, strip_file_name
4✔
25
from pants.engine.rules import collect_rules, concurrently, rule
4✔
26
from pants.engine.unions import UnionRule
4✔
27
from pants.util.logging import LogLevel
4✔
28

29

30
def proto_path_to_py_module(stripped_path: str, *, suffix: str) -> str:
4✔
31
    return stripped_path.replace(".proto", suffix).replace("/", ".")
2✔
32

33

34
# This is only used to register our implementation with the plugin hook via unions.
35
class PythonProtobufMappingMarker(FirstPartyPythonMappingImplMarker):
4✔
36
    pass
4✔
37

38

39
@rule(desc="Creating map of Protobuf targets to generated Python modules", level=LogLevel.DEBUG)
4✔
40
async def map_protobuf_to_python_modules(
4✔
41
    protobuf_targets: AllProtobufTargets,
42
    python_setup: PythonSetup,
43
    python_protobuf_subsystem: PythonProtobufSubsystem,
44
    _: PythonProtobufMappingMarker,
45
) -> FirstPartyPythonMappingImpl:
46
    grpc_suffixes = []
2✔
47
    if python_protobuf_subsystem.grpcio_plugin:
2✔
48
        grpc_suffixes.append("_pb2_grpc")
2✔
49
    if python_protobuf_subsystem.grpclib_plugin:
2✔
50
        grpc_suffixes.append("_grpc")
1✔
51

52
    stripped_file_per_target = await concurrently(
2✔
53
        strip_file_name(StrippedFileNameRequest(tgt[ProtobufSourceField].file_path))
54
        for tgt in protobuf_targets
55
    )
56

57
    resolves_to_modules_to_providers: DefaultDict[
2✔
58
        ResolveName, DefaultDict[str, list[ModuleProvider]]
59
    ] = defaultdict(lambda: defaultdict(list))
60
    for tgt, stripped_file in zip(protobuf_targets, stripped_file_per_target):
2✔
61
        resolve = tgt[PythonResolveField].normalized_value(python_setup)
2✔
62

63
        # NB: We don't consider the MyPy plugin, which generates `_pb2.pyi`. The stubs end up
64
        # sharing the same module as the implementation `_pb2.py`. Because both generated files
65
        # come from the same original Protobuf target, we're covered.
66
        module = proto_path_to_py_module(stripped_file.value, suffix="_pb2")
2✔
67
        resolves_to_modules_to_providers[resolve][module].append(
2✔
68
            ModuleProvider(tgt.address, ModuleProviderType.IMPL)
69
        )
70
        if tgt.get(ProtobufGrpcToggleField).value:
2✔
71
            for suffix in grpc_suffixes:
1✔
72
                module = proto_path_to_py_module(stripped_file.value, suffix=suffix)
1✔
73
                resolves_to_modules_to_providers[resolve][module].append(
1✔
74
                    ModuleProvider(tgt.address, ModuleProviderType.IMPL)
75
                )
76

77
    return FirstPartyPythonMappingImpl.create(resolves_to_modules_to_providers)
2✔
78

79

80
def rules():
4✔
81
    return (
4✔
82
        *collect_rules(),
83
        UnionRule(FirstPartyPythonMappingImplMarker, PythonProtobufMappingMarker),
84
    )
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