classification
Title: PyObject_Call not behaving as documented
Type: behavior Stage:
Components: C API Versions: Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: josh.r, maxbachmann
Priority: normal Keywords:

Created on 2020-12-13 00:21 by maxbachmann, last changed 2020-12-16 14:42 by josh.r.

Messages (2)
msg382927 - (view) Author: Max Bachmann (maxbachmann) * Date: 2020-12-13 00:21
The documentation of PyObject_Call here: https://docs.python.org/3/c-api/call.html#c.PyObject_Call
states, that it is the equivalent of the Python expression: callable(*args, **kwargs).

so I would expect:
PyObject* args = PyTuple_New(0);
PyObject* kwargs = PyDict_New();
PyObject_Call(funcObj, args, kwargs)

to behave similar to
args = []
kwargs = {}
func(*args, **kwargs)

however this is not the case since in this case when I edit kwargs inside
PyObject* func(PyObject* /*self*/, PyObject* /*args*/, PyObject* keywds)
{
  PyObject* str = PyUnicode_FromString("test_str");
  PyDict_SetItemString(keywds, "test", str);
}

it changes the original dictionary passed into PyObject_Call. I was wondering, whether this means, that:
a) it is not allowed to modify the keywds argument passed to a PyCFunctionWithKeywords
b) when calling PyObject_Call it is required to copy the kwargs for the call using PyDict_Copy

Neither the documentation of PyObject_Call nor the documentation of PyCFunctionWithKeywords (https://docs.python.org/3/c-api/structures.html#c.PyCFunctionWithKeywords) made this clear to me.
msg383173 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2020-12-16 14:42
Pingback from #42033. Proper fix for that issue likely involves moving the work for copying kwargs into PyObject_Call, which would fix this bug by side-effect.
History
Date User Action Args
2020-12-16 14:42:35josh.rsetnosy: + josh.r
messages: + msg383173
2020-12-13 00:21:25maxbachmanncreate