New GitHub issue #119127 from dgrigonis:<br>
<hr>
<pre>
# Feature or enhancement
### Proposal:
I know that this has been brought up in the past, but I would appreciate if this was reconsidered. I would be happy to bring this up to a nice level.
```python
from functools import partial
from partial2 import partial as partial2, Placeholder
_ = VOID = Placeholder()
%timeit partial(opr.sub, 1, 2) # 130 ns
%timeit partial2(opr.sub, 1, 2) # 155 ns
p1 = partial(opr.sub, 1)
p2 = partial2(opr.sub, 1)
p3 = partial2(opr.sub, _, 1)
p4 = partial2(opr.sub, VOID, 1)
print(p1(2)) # -1
print(p2(2)) # -1
print(p3(2)) # 1
print(p4(2)) # 1
%timeit p1(2) # 48 ns
%timeit p2(2) # 52 ns
%timeit p3(2) # 54 ns
%timeit p4(2) # 54 ns
```
The logic is as follows:
```python
def partial(func, *p_args, **p_kwds):
p_args = list(p_args)
nvoid = sum(a is VOID for a in p_args)
arng = range(len(p_args))
def wrapper(*args, **kwds):
if len(args) < nvoid:
raise ValueError('Not all VOIDs are filled')
t_args = p_args.copy()
j = 0
for i in arng:
if p_args[i] is VOID:
t_args[i] = args[j]
j += 1
t_args.extend(args[j:])
return func(*t_args, **{**p_kwds, **kwds})
return wrapper
```
`vectorcall` change looks like:
```C
if (np) {
nargs_new = pto_nargs + nargs - np;
Py_ssize_t ip = 0;
for (Py_ssize_t i=0; i < pto_nargs; i++) {
if (PyObject_TypeCheck(pto_args[i], &placeholderType)){
memcpy(stack + i, args + ip, 1 * sizeof(PyObject*));
ip += 1;
} else {
memcpy(stack + i, pto_args + i, 1 * sizeof(PyObject*));
}
}
if (nargs_total > np){
memcpy(stack + pto_nargs, args + np, (nargs_total - np) * sizeof(PyObject*));
}
// EO Placeholders ------
} else {
```
### Has this already been discussed elsewhere?
I have already discussed this feature proposal on Discourse
### Links to previous discussion of this feature:
https://discuss.python.org/t/functools-partial-placeholder-arguments/53487
</pre>
<hr>
<a href="https://github.com/python/cpython/issues/119127">View on GitHub</a>
<p>Labels: type-feature</p>
<p>Assignee: </p>