* Helper to convert from vectorcall convention, since the protocol requires * args and kwargs to be passed as tuple and dict explicitly. * We always pass a dict, so always returns it. */
| 211 | * We always pass a dict, so always returns it. |
| 212 | */ |
| 213 | static int |
| 214 | get_args_and_kwargs( |
| 215 | PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames, |
| 216 | PyObject **out_args, PyObject **out_kwargs) |
| 217 | { |
| 218 | len_args = PyVectorcall_NARGS(len_args); |
| 219 | PyObject *args = PyTuple_New(len_args); |
| 220 | PyObject *kwargs = NULL; |
| 221 | |
| 222 | if (args == NULL) { |
| 223 | return -1; |
| 224 | } |
| 225 | for (Py_ssize_t i = 0; i < len_args; i++) { |
| 226 | Py_INCREF(fast_args[i]); |
| 227 | PyTuple_SET_ITEM(args, i, fast_args[i]); |
| 228 | } |
| 229 | kwargs = PyDict_New(); |
| 230 | if (kwargs == NULL) { |
| 231 | Py_DECREF(args); |
| 232 | return -1; |
| 233 | } |
| 234 | if (kwnames != NULL) { |
| 235 | Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); |
| 236 | for (Py_ssize_t i = 0; i < nkwargs; i++) { |
| 237 | PyObject *key = PyTuple_GET_ITEM(kwnames, i); |
| 238 | PyObject *value = fast_args[i+len_args]; |
| 239 | if (PyDict_SetItem(kwargs, key, value) < 0) { |
| 240 | Py_DECREF(args); |
| 241 | Py_DECREF(kwargs); |
| 242 | return -1; |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | *out_args = args; |
| 247 | *out_kwargs = kwargs; |
| 248 | return 0; |
| 249 | } |
| 250 | |
| 251 | |
| 252 | static void |
no outgoing calls
no test coverage detected