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

pantsbuild / pants / 24537527758

16 Apr 2026 10:35PM UTC coverage: 92.733%. First build
24537527758

Pull #23268

github

web-flow
Merge d44bec6c0 into c7f394f2f
Pull Request #23268: pref: Remove python coroutine/trampoline overhead in awaits for ~22% faster `dependencies` goal

29 of 35 new or added lines in 4 files covered. (82.86%)

91458 of 98625 relevant lines covered (92.73%)

4.04 hits per line

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

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

4
from __future__ import annotations
12✔
5

6
import itertools
12✔
7
from collections.abc import Awaitable, Coroutine, Iterable
12✔
8
from dataclasses import dataclass
12✔
9
from typing import Any, TypeVar, overload
12✔
10

11
from pants.engine.internals.native_engine import Call as Call  # noqa: F401
12✔
12
from pants.engine.internals.native_engine import _Concurrently
12✔
13
from pants.util.strutil import softwrap
12✔
14

15
_Output = TypeVar("_Output")
12✔
16

17

18
@dataclass(frozen=True)
12✔
19
class AwaitableConstraints:
12✔
20
    rule_id: str
12✔
21
    output_type: type
12✔
22
    # The number of explicit positional arguments passed to a call-by-name awaitable.
23
    explicit_args_arity: int
12✔
24
    input_types: tuple[type, ...]
12✔
25

26
    def __repr__(self) -> str:
12✔
27
        inputs = ", ".join(f"{t.__name__}" for t in self.input_types)
2✔
28
        return f"{self.rule_id}({inputs}) -> {self.output_type.__name__}"
2✔
29

30
    def __str__(self) -> str:
12✔
31
        return repr(self)
2✔
32

33

34
# These type variables are used to parametrize from 1 to 10 args when used in a tuple-style
35
# concurrently() call.
36

37
_Out0 = TypeVar("_Out0")
12✔
38
_Out1 = TypeVar("_Out1")
12✔
39
_Out2 = TypeVar("_Out2")
12✔
40
_Out3 = TypeVar("_Out3")
12✔
41
_Out4 = TypeVar("_Out4")
12✔
42
_Out5 = TypeVar("_Out5")
12✔
43
_Out6 = TypeVar("_Out6")
12✔
44
_Out7 = TypeVar("_Out7")
12✔
45
_Out8 = TypeVar("_Out8")
12✔
46
_Out9 = TypeVar("_Out9")
12✔
47

48

49
@overload
50
def Concurrently(
51
    __gets: Iterable[Coroutine[Any, Any, _Output]],
52
) -> Awaitable[tuple[_Output, ...]]: ...
53

54

55
@overload
56
def Concurrently(
57
    __get0: Coroutine[Any, Any, _Output],
58
    __get1: Coroutine[Any, Any, _Output],
59
    __get2: Coroutine[Any, Any, _Output],
60
    __get3: Coroutine[Any, Any, _Output],
61
    __get4: Coroutine[Any, Any, _Output],
62
    __get5: Coroutine[Any, Any, _Output],
63
    __get6: Coroutine[Any, Any, _Output],
64
    __get7: Coroutine[Any, Any, _Output],
65
    __get8: Coroutine[Any, Any, _Output],
66
    __get9: Coroutine[Any, Any, _Output],
67
    __get10: Coroutine[Any, Any, _Output],
68
    *__gets: Coroutine[Any, Any, _Output],
69
) -> Awaitable[tuple[_Output, ...]]: ...
70

71

72
@overload
73
def Concurrently(
74
    __get0: Coroutine[Any, Any, _Out0],
75
    __get1: Coroutine[Any, Any, _Out1],
76
    __get2: Coroutine[Any, Any, _Out2],
77
    __get3: Coroutine[Any, Any, _Out3],
78
    __get4: Coroutine[Any, Any, _Out4],
79
    __get5: Coroutine[Any, Any, _Out5],
80
    __get6: Coroutine[Any, Any, _Out6],
81
    __get7: Coroutine[Any, Any, _Out7],
82
    __get8: Coroutine[Any, Any, _Out8],
83
    __get9: Coroutine[Any, Any, _Out9],
84
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7, _Out8, _Out9]]: ...
85

86

87
@overload
88
def Concurrently(
89
    __get0: Coroutine[Any, Any, _Out0],
90
    __get1: Coroutine[Any, Any, _Out1],
91
    __get2: Coroutine[Any, Any, _Out2],
92
    __get3: Coroutine[Any, Any, _Out3],
93
    __get4: Coroutine[Any, Any, _Out4],
94
    __get5: Coroutine[Any, Any, _Out5],
95
    __get6: Coroutine[Any, Any, _Out6],
96
    __get7: Coroutine[Any, Any, _Out7],
97
    __get8: Coroutine[Any, Any, _Out8],
98
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7, _Out8]]: ...
99

100

101
@overload
102
def Concurrently(
103
    __get0: Coroutine[Any, Any, _Out0],
104
    __get1: Coroutine[Any, Any, _Out1],
105
    __get2: Coroutine[Any, Any, _Out2],
106
    __get3: Coroutine[Any, Any, _Out3],
107
    __get4: Coroutine[Any, Any, _Out4],
108
    __get5: Coroutine[Any, Any, _Out5],
109
    __get6: Coroutine[Any, Any, _Out6],
110
    __get7: Coroutine[Any, Any, _Out7],
111
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7]]: ...
112

113

114
@overload
115
def Concurrently(
116
    __get0: Coroutine[Any, Any, _Out0],
117
    __get1: Coroutine[Any, Any, _Out1],
118
    __get2: Coroutine[Any, Any, _Out2],
119
    __get3: Coroutine[Any, Any, _Out3],
120
    __get4: Coroutine[Any, Any, _Out4],
121
    __get5: Coroutine[Any, Any, _Out5],
122
    __get6: Coroutine[Any, Any, _Out6],
123
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6]]: ...
124

125

126
@overload
127
def Concurrently(
128
    __get0: Coroutine[Any, Any, _Out0],
129
    __get1: Coroutine[Any, Any, _Out1],
130
    __get2: Coroutine[Any, Any, _Out2],
131
    __get3: Coroutine[Any, Any, _Out3],
132
    __get4: Coroutine[Any, Any, _Out4],
133
    __get5: Coroutine[Any, Any, _Out5],
134
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5]]: ...
135

136

137
@overload
138
def Concurrently(
139
    __get0: Coroutine[Any, Any, _Out0],
140
    __get1: Coroutine[Any, Any, _Out1],
141
    __get2: Coroutine[Any, Any, _Out2],
142
    __get3: Coroutine[Any, Any, _Out3],
143
    __get4: Coroutine[Any, Any, _Out4],
144
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3, _Out4]]: ...
145

146

147
@overload
148
def Concurrently(
149
    __get0: Coroutine[Any, Any, _Out0],
150
    __get1: Coroutine[Any, Any, _Out1],
151
    __get2: Coroutine[Any, Any, _Out2],
152
    __get3: Coroutine[Any, Any, _Out3],
153
) -> Awaitable[tuple[_Out0, _Out1, _Out2, _Out3]]: ...
154

155

156
@overload
157
def Concurrently(
158
    __get0: Coroutine[Any, Any, _Out0],
159
    __get1: Coroutine[Any, Any, _Out1],
160
    __get2: Coroutine[Any, Any, _Out2],
161
) -> Awaitable[tuple[_Out0, _Out1, _Out2]]: ...
162

163

164
@overload
165
def Concurrently(
166
    __get0: Coroutine[Any, Any, _Out0],
167
    __get1: Coroutine[Any, Any, _Out1],
168
) -> Awaitable[tuple[_Out0, _Out1]]: ...
169

170

171
def Concurrently(
12✔
172
    __arg0: (Iterable[Coroutine[Any, Any, _Output]] | Coroutine[Any, Any, _Out0]),
173
    __arg1: Coroutine[Any, Any, _Out1] | None = None,
174
    __arg2: Coroutine[Any, Any, _Out2] | None = None,
175
    __arg3: Coroutine[Any, Any, _Out3] | None = None,
176
    __arg4: Coroutine[Any, Any, _Out4] | None = None,
177
    __arg5: Coroutine[Any, Any, _Out5] | None = None,
178
    __arg6: Coroutine[Any, Any, _Out6] | None = None,
179
    __arg7: Coroutine[Any, Any, _Out7] | None = None,
180
    __arg8: Coroutine[Any, Any, _Out8] | None = None,
181
    __arg9: Coroutine[Any, Any, _Out9] | None = None,
182
    *__args: Coroutine[Any, Any, _Output],
183
) -> Awaitable[
184
    tuple[_Output, ...]
185
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7, _Out8, _Out9]
186
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7, _Out8]
187
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6, _Out7]
188
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5, _Out6]
189
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4, _Out5]
190
    | tuple[_Out0, _Out1, _Out2, _Out3, _Out4]
191
    | tuple[_Out0, _Out1, _Out2, _Out3]
192
    | tuple[_Out0, _Out1, _Out2]
193
    | tuple[_Out0, _Out1]
194
    | tuple[_Out0]
195
]:
196
    """Yield a tuple of Coroutine instances all at once.
197

198
    The `yield`ed value `self.calls` is interpreted by the engine within
199
    `generator_send()`. This class will yield a tuple of Coroutine instances,
200
    which is converted into `PyGeneratorResponse::GetMulti`.
201

202
    The engine will fulfill these coroutines in parallel, and return a tuple of _Output
203
    instances to this method, which then returns this tuple to the `@rule` which called
204
    `await concurrently(...) for ... in ...)`.
205
    """
206
    if (
12✔
207
        isinstance(__arg0, Iterable)
208
        and __arg1 is None
209
        and __arg2 is None
210
        and __arg3 is None
211
        and __arg4 is None
212
        and __arg5 is None
213
        and __arg6 is None
214
        and __arg7 is None
215
        and __arg8 is None
216
        and __arg9 is None
217
        and not __args
218
    ):
219
        return _Concurrently(tuple(__arg0))
12✔
220

221
    if (
12✔
222
        isinstance(__arg0, (Coroutine, Call))
223
        and __arg1 is None
224
        and __arg2 is None
225
        and __arg3 is None
226
        and __arg4 is None
227
        and __arg5 is None
228
        and __arg6 is None
229
        and __arg7 is None
230
        and __arg8 is None
231
        and __arg9 is None
232
        and not __args
233
    ):
NEW
234
        return _Concurrently((__arg0,))
×
235

236
    if (
12✔
237
        isinstance(__arg0, (Coroutine, Call))
238
        and isinstance(__arg1, (Coroutine, Call))
239
        and __arg2 is None
240
        and __arg3 is None
241
        and __arg4 is None
242
        and __arg5 is None
243
        and __arg6 is None
244
        and __arg7 is None
245
        and __arg8 is None
246
        and __arg9 is None
247
        and not __args
248
    ):
249
        return _Concurrently((__arg0, __arg1))
12✔
250

251
    if (
12✔
252
        isinstance(__arg0, (Coroutine, Call))
253
        and isinstance(__arg1, (Coroutine, Call))
254
        and isinstance(__arg2, (Coroutine, Call))
255
        and __arg3 is None
256
        and __arg4 is None
257
        and __arg5 is None
258
        and __arg6 is None
259
        and __arg7 is None
260
        and __arg8 is None
261
        and __arg9 is None
262
        and not __args
263
    ):
264
        return _Concurrently((__arg0, __arg1, __arg2))
12✔
265

266
    if (
12✔
267
        isinstance(__arg0, (Coroutine, Call))
268
        and isinstance(__arg1, (Coroutine, Call))
269
        and isinstance(__arg2, (Coroutine, Call))
270
        and isinstance(__arg3, (Coroutine, Call))
271
        and __arg4 is None
272
        and __arg5 is None
273
        and __arg6 is None
274
        and __arg7 is None
275
        and __arg8 is None
276
        and __arg9 is None
277
        and not __args
278
    ):
279
        return _Concurrently((__arg0, __arg1, __arg2, __arg3))
12✔
280

281
    if (
7✔
282
        isinstance(__arg0, (Coroutine, Call))
283
        and isinstance(__arg1, (Coroutine, Call))
284
        and isinstance(__arg2, (Coroutine, Call))
285
        and isinstance(__arg3, (Coroutine, Call))
286
        and isinstance(__arg4, (Coroutine, Call))
287
        and __arg5 is None
288
        and __arg6 is None
289
        and __arg7 is None
290
        and __arg8 is None
291
        and __arg9 is None
292
        and not __args
293
    ):
294
        return _Concurrently((__arg0, __arg1, __arg2, __arg3, __arg4))
5✔
295

296
    if (
5✔
297
        isinstance(__arg0, (Coroutine, Call))
298
        and isinstance(__arg1, (Coroutine, Call))
299
        and isinstance(__arg2, (Coroutine, Call))
300
        and isinstance(__arg3, (Coroutine, Call))
301
        and isinstance(__arg4, (Coroutine, Call))
302
        and isinstance(__arg5, (Coroutine, Call))
303
        and __arg6 is None
304
        and __arg7 is None
305
        and __arg8 is None
306
        and __arg9 is None
307
        and not __args
308
    ):
309
        return _Concurrently((__arg0, __arg1, __arg2, __arg3, __arg4, __arg5))
4✔
310

311
    if (
1✔
312
        isinstance(__arg0, (Coroutine, Call))
313
        and isinstance(__arg1, (Coroutine, Call))
314
        and isinstance(__arg2, (Coroutine, Call))
315
        and isinstance(__arg3, (Coroutine, Call))
316
        and isinstance(__arg4, (Coroutine, Call))
317
        and isinstance(__arg5, (Coroutine, Call))
318
        and isinstance(__arg6, (Coroutine, Call))
319
        and __arg7 is None
320
        and __arg8 is None
321
        and __arg9 is None
322
        and not __args
323
    ):
NEW
324
        return _Concurrently((__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6))
×
325

326
    if (
1✔
327
        isinstance(__arg0, (Coroutine, Call))
328
        and isinstance(__arg1, (Coroutine, Call))
329
        and isinstance(__arg2, (Coroutine, Call))
330
        and isinstance(__arg3, (Coroutine, Call))
331
        and isinstance(__arg4, (Coroutine, Call))
332
        and isinstance(__arg5, (Coroutine, Call))
333
        and isinstance(__arg6, (Coroutine, Call))
334
        and isinstance(__arg7, (Coroutine, Call))
335
        and __arg8 is None
336
        and __arg9 is None
337
        and not __args
338
    ):
NEW
339
        return _Concurrently((__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7))
×
340

341
    if (
1✔
342
        isinstance(__arg0, (Coroutine, Call))
343
        and isinstance(__arg1, (Coroutine, Call))
344
        and isinstance(__arg2, (Coroutine, Call))
345
        and isinstance(__arg3, (Coroutine, Call))
346
        and isinstance(__arg4, (Coroutine, Call))
347
        and isinstance(__arg5, (Coroutine, Call))
348
        and isinstance(__arg6, (Coroutine, Call))
349
        and isinstance(__arg7, (Coroutine, Call))
350
        and isinstance(__arg8, (Coroutine, Call))
351
        and __arg9 is None
352
        and not __args
353
    ):
NEW
354
        return _Concurrently(
×
355
            (__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8)
356
        )
357

358
    if (
1✔
359
        isinstance(__arg0, (Coroutine, Call))
360
        and isinstance(__arg1, (Coroutine, Call))
361
        and isinstance(__arg2, (Coroutine, Call))
362
        and isinstance(__arg3, (Coroutine, Call))
363
        and isinstance(__arg4, (Coroutine, Call))
364
        and isinstance(__arg5, (Coroutine, Call))
365
        and isinstance(__arg6, (Coroutine, Call))
366
        and isinstance(__arg7, (Coroutine, Call))
367
        and isinstance(__arg8, (Coroutine, Call))
368
        and isinstance(__arg9, (Coroutine, Call))
369
        and all(isinstance(arg, (Coroutine, Call)) for arg in __args)
370
    ):
NEW
371
        return _Concurrently(
×
372
            (
373
                __arg0,
374
                __arg1,
375
                __arg2,
376
                __arg3,
377
                __arg4,
378
                __arg5,
379
                __arg6,
380
                __arg7,
381
                __arg8,
382
                __arg9,
383
                *__args,
384
            )
385
        )
386

387
    args = __arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8, __arg9, *__args
1✔
388

389
    def render_arg(arg: Any) -> str | None:
1✔
390
        if arg is None:
1✔
391
            return None
×
392
        return repr(arg)
1✔
393

394
    likely_args_explicitly_passed = tuple(
1✔
395
        reversed(
396
            [
397
                render_arg(arg)
398
                for arg in itertools.dropwhile(lambda arg: arg is None, reversed(args))
399
            ]
400
        )
401
    )
402
    if any(arg is None for arg in likely_args_explicitly_passed):
1✔
403
        raise ValueError(
×
404
            softwrap(
405
                f"""
406
                Unexpected concurrently() None arguments: {
407
                    ", ".join(map(str, likely_args_explicitly_passed))
408
                }
409

410
                When calling concurrently() on individual rule calls, all leading arguments must be
411
                awaitables.
412
                """
413
            )
414
        )
415

416
    raise TypeError(
1✔
417
        softwrap(
418
            f"""
419
            Unexpected concurrently() argument types: {", ".join(map(str, likely_args_explicitly_passed))}
420

421
            `concurrently` can be used in two ways:
422
              1. concurrently(Iterable[awaitable[T]]) -> Tuple[T]
423
              2. concurrently(awaitable[T1]], ...) -> Tuple[T1, T2, ...]
424

425
            The 1st form is intended for homogenous collections of rule calls and emulates an
426
            async `for ...` comprehension used to iterate over the collection in parallel and
427
            collect the results in a homogenous tuple when all are complete.
428

429
            The 2nd form supports executing heterogeneous rule calls in parallel and collecting
430
            them in a heterogeneous tuple when all are complete. Currently up to 10 heterogeneous
431
            rule calls can be passed while still tracking their output types for type-checking by
432
            MyPy and similar type checkers. If more than 10 rule calls are passed, type checking
433
            will enforce that they are homogeneous.
434
            """
435
        )
436
    )
437

438

439
concurrently = Concurrently
12✔
440

441

442
@dataclass(frozen=True)
12✔
443
class Params:
12✔
444
    """A set of values with distinct types.
445

446
    Distinct types are enforced at consumption time by the rust type of the same name.
447
    """
448

449
    params: tuple[Any, ...]
12✔
450

451
    def __init__(self, *args: Any) -> None:
12✔
452
        object.__setattr__(self, "params", tuple(args))
12✔
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