Skip to content

functools.partial placeholders#119127

@dg-pb

Description

@dg-pb

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.

fromfunctoolsimportpartialfrompartial2importpartialaspartial2, Placeholder_=VOID=Placeholder() %timeitpartial(opr.sub, 1, 2) # 130 ns%timeitpartial2(opr.sub, 1, 2) # 155 nsp1=partial(opr.sub, 1) p2=partial2(opr.sub, 1) p3=partial2(opr.sub, _, 1) p4=partial2(opr.sub, VOID, 1) print(p1(2)) # -1print(p2(2)) # -1print(p3(2)) # 1print(p4(2)) # 1%timeitp1(2) # 48 ns%timeitp2(2) # 52 ns%timeitp3(2) # 54 ns%timeitp4(2) # 54 ns

The logic is as follows:

defpartial(func, *p_args, **p_kwds): p_args=list(p_args) nvoid=sum(aisVOIDforainp_args) arng=range(len(p_args)) defwrapper(*args, **kwds): iflen(args) <nvoid: raiseValueError('Not all VOIDs are filled') t_args=p_args.copy() j=0foriinarng: ifp_args[i] isVOID: t_args[i] =args[j] j+=1t_args.extend(args[j:]) returnfunc(*t_args, **{**p_kwds, **kwds}) returnwrapper

vectorcall change looks like:

if (np){nargs_new=pto_nargs+nargs-np; Py_ssize_tip=0; for (Py_ssize_ti=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

Linked PRs

Metadata

Metadata

Assignees

Labels

extension-modulesC modules in the Modules dirtype-featureA feature request or enhancement

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions