This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Mark.Shannon
Recipients Mark.Shannon
Date 2021-01-21.16:05:51
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1611245152.12.0.0348161555926.issue42990@roundup.psfhosted.org>
In-reply-to
Content
Currently, to make a call to Python (modules, classes, etc, not just functions) from C has to use the monster that is `_PyEval_EvalCode`.
As Python has adding features over the years, _PyEval_EvalCode has grown and grown. It is time for a refactor.

`_PyEval_EvalCode` takes 16, yes sixteen parameters!
Those 16 parameters fall into two main groups, one describing the function being called, and the other describing the arguments to the call.
Due to the jumbo size and complexity of _PyEval_EvalCode, we also have specialised forms of it, e.g. _PyFunction_Vectorcall that handle common cases and then bail to _PyEval_EvalCode in other cases.

In outline _PyEval_EvalCode performs the following actions:
1. Make a new frame.
2. Fill in that frame using the arguments and defaults provided.
3. If the code object has flags set for a generator, or coroutine, return a new generator or coroutine.
4. Otherwise call the interpreter with the newly created frame.

As _PyEval_EvalCode or its earlier equivalents have gained arguments, they have a left of list of legacy functions. It is not clear what is the "correct" function to use in C extensions. Hopefully extension code uses the `PyObject_Call` API, but `PyEval_EvalCodeEx` is part of the C-API.


To improve this situation, I propose:

A new C struct, the "frame descriptor" which contains the code object, defaults, globals, and names that describe the code to be executed. `PyFunctionObject` would wrap this, to simplify the common case of calling a Python function. 

Split the Eval functions into vector and tuple/dict forms, both forms taking a "frame descriptor", as well as the arguments.

Mark the older forms of the Eval functions as "legacy", creating a local "frame descriptor" and transforming the arguments in vector or tuple/dict forms, in the legacy functions.

Factor out the frame creation part of the Eval functions.


The above changes will be necessary for PEP 651, but I think would be a worthwhile improvement even if PEP 651 is not accepted.
History
Date User Action Args
2021-01-21 16:05:52Mark.Shannonsetrecipients: + Mark.Shannon
2021-01-21 16:05:52Mark.Shannonsetmessageid: <1611245152.12.0.0348161555926.issue42990@roundup.psfhosted.org>
2021-01-21 16:05:52Mark.Shannonlinkissue42990 messages
2021-01-21 16:05:51Mark.Shannoncreate