Skip to content

functools.partial does not re-set vector call. #119109

Open
@dg-pb

Description

@dg-pb

Bug report

Bug description:

The comment here

/* pto->kw is mutable, so need to check every time */

Indicates that it needs to be checked every time. However, once it removes vectorcall in partial_vectorcall_fallback there is no mechanism to set it back.

def func(a, b, c=0):
    return a - b - c

p2 = partial(func, 1, c=1)
In [13]: print(p2(2))    # -1
vectorcall
call
-2

In [14]:

In [14]: print(p2(2))    # -1
call
-2

In [15]: del p2.keywords['c']

In [16]: print(p2(2))    # -1
call
-1

I see 3 possibilities:

  1. Set additional flag in partial_setvectorcall(pto->hasvcall) storing state whether vectorcall is supported. Then implement fallback in partial_call in the same manner as it looks now in partial_vectorcall
  2. Re-setting vectorcall after _PyObject_MakeTpCall in partial_vectorcall_fallback. So that partial_vectorcall will stay as a primary entry in all cases. This adds 4ns overhead compared to 1.
  3. Leave it as it is, but remove confusion that this needs to be checked more than 1 time.

CPython versions tested on:

3.11

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions