Skip to content

gh-87613: AC VC add support for *args and use it for zip - #160944

Open
cmaloney wants to merge 3 commits into
python:mainfrom
cmaloney:clinic_vc_varargs_zip
Open

cmaloney wants to merge 3 commits into
python:mainfrom
cmaloney:clinic_vc_varargs_zip

Conversation

@cmaloney

@cmaloney cmaloney commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Argument Clinic @vectorcall generation accepted *args parameters but the generated code expected an argument tuple. The first commit uses the fastcall form to parse the args array making it work right.

zip previously hand coded argument parsing and had no vectorcall. Argument error messages are unchanged except for unknown keywords: zip(strict=1, x=2) now reports "got an unexpected keyword argument 'x'" instead of "takes at most 1 keyword argument (2 given)". The docstring gains a summary line; __text_signature__ is unchanged.

pyperf microbenchmark (PGO+LTO, run serially):

Benchmark base zip
zip(a, b, strict=True) 118 ns 61.5 ns: 1.92x faster
zip(a, b) 64.9 ns 53.1 ns: 1.22x faster
zip(a) 55.0 ns 47.1 ns: 1.17x faster
list(zip(a, b)) 123 ns 113 ns: 1.09x faster
zip() 27.4 ns 25.7 ns: 1.07x faster
Sub(a, b) 71.5 ns 70.6 ns: 1.01x faster

Benchmark hidden because not significant (1): zip.__new__

Benchmark code:

import pyperf

runner = pyperf.Runner()
setup = "a = (1, 2, 3); b = [4, 5, 6]"
for stmt in ["zip()", "zip(a)", "zip(a, b)", "zip(a, b, strict=True)",
             "list(zip(a, b))"]:
    runner.timeit(stmt, stmt, setup)
runner.timeit('zip.`__new__`', 'new(zip, a, b)', setup + '; new = zip.__new__')
runner.timeit('Sub(a, b)', 'S(a, b)', setup + '\nclass S(zip): pass')

cmaloney and others added 2 commits October 29, 2026 19:36
`@vectorcall` accepted `*args`, but the generated code expected an
args tuple. Use fastcall form to parse the args array.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zip had no vectorcall, so every call built an args tuple and a kwargs
dict, and strict=True also went through PyArg_ParseTupleAndKeywords with
a temporary empty tuple.  Argument error messages are unchanged except
for unknown keywords: `zip(strict=1, x=2)` now reports "got an
unexpected keyword argument 'x'" instead of "takes at most 1 keyword
argument (2 given)".  The docstring gains a summary line;
`__text_signature__` is unchanged.

pyperf microbenchmark (PGO+LTO, run serially):

| Benchmark              | base    | zip                   |
|------------------------|:-------:|:---------------------:|
| zip(a, b, strict=True) | 118 ns  | 61.5 ns: 1.92x faster |
| zip(a, b)              | 64.9 ns | 53.1 ns: 1.22x faster |
| zip(a)                 | 55.0 ns | 47.1 ns: 1.17x faster |
| list(zip(a, b))        | 123 ns  | 113 ns: 1.09x faster  |
| zip()                  | 27.4 ns | 25.7 ns: 1.07x faster |
| Sub(a, b)              | 71.5 ns | 70.6 ns: 1.01x faster |

Benchmark hidden because not significant (1): zip.`__new__`

Benchmark code:

```python
import pyperf

runner = pyperf.Runner()
setup = "a = (1, 2, 3); b = [4, 5, 6]"
for stmt in ["zip()", "zip(a)", "zip(a, b)", "zip(a, b, strict=True)",
             "list(zip(a, b))"]:
    runner.timeit(stmt, stmt, setup)
runner.timeit('zip.`__new__`', 'new(zip, a, b)', setup + '; new = zip.__new__')
runner.timeit('Sub(a, b)', 'S(a, b)', setup + '\nclass S(zip): pass')
```

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread Python/bltinmodule.c Resolved
@cmaloney cmaloney changed the title gh-87613: AC VC add support for *args and use for for zip gh-87613: AC VC add support for *args and use it for zip Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review skip news type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant