# Combining the argument-conversion loops in \_PyEval\_Vector

**URL:** <https://discuss.python.org/t/combining-the-argument-conversion-loops-in-pyeval-vector/109635>\
**Category:** Core Development\
**Created:** [October 23, 2026, 11:34pm UTC](https://discuss.python.org/t/combining-the-argument-conversion-loops-in-pyeval-vector/109635 "2026-10-23T23:34:26Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ashm-dev](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ashm-dev/32/38301_2.png) [@ashm-dev](https://discuss.python.org/u/ashm-dev)\
**Post date:** [October 23, 2026, 11:34pm UTC](https://discuss.python.org/t/combining-the-argument-conversion-loops-in-pyeval-vector/109635/1 "2026-10-23T23:34:26Z")

</div>

In [`_PyEval_Vector`](https://github.com/python/cpython/blob/3a440b65695615e9fd9912342b79cdd54fced0d2/Python/ceval.c#L2222-L2265), positional and keyword argument values are converted to `_PyStackRef` in separate loops. Both loops call `PyStackRef_FromPyObjectNew`.

The values are consecutive in `args`, and `total_args` already includes both groups. I replaced the two loops locally with:

```c
for (size_t i = 0; i < total_args; i++) {
    arguments[i] = PyStackRef_FromPyObjectNew(args[i]);
}

```

This removes the duplicated conversion code and the second `kwnames` check. Conversion order and reference ownership stay the same. `_PyEvalFramePushAndInit` still receives the positional count, `argcount`, and `kwnames` separately.

The test suite passes with the change.

Is there a reason to keep the positional and keyword conversions separate?

P.S. Even with `-O3 -march=native`, the compiler (gcc-16 and clang-23) leaves these as two separate loops in the optimized `IR` (LLVM IR | GCC GIMPLE), including the second kwnames check and keyword-count load. This suggests a small performance optimization opportunity, rather than just a source-code cleanup.
