Author bup
Recipients bup
Date 2019-03-13.23:31:43
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1552519903.9.0.270264105873.issue36283@roundup.psfhosted.org>
In-reply-to
Content
The footnote about why eval/exec cannot be used for arbitrary code has been (for the most part) incorrect for quite some time as the signature for PyEval_EvalCodeEx demonstrates:

PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject *const *args, int argcount, PyObject *const *kws, int kwcount, PyObject *const *defs, int defcount, PyObject *kwdefs, PyObject *closure)

Making eval a wrapper for PyEval_EvalCodeEx instead of PyEval_EvalCode would be a backwards compatible change since new parameters come after the current 3. A hypothetical signature for the new signature would be something like:
    eval(src, globals: abc.Mapping, locals: abc.Mapping, args: tuple, kwargs: dict, defaults: tuple, kwdefaults: dict, closure: tuple). 

In that case, `src` could be unicode, bytes, frames, tracebacks, code objects, and even updated to support stuff like parser.STType or ast.Module/ast.Interactive/ast.Expresion objects. 

The only objection I can think of is the same as the reason it's currently documented that globals must be a dictionary and that is that the LOAD_NAME opcode (seemingly) arbitrarily requires frame.f_globals be a dict subtype (even though LOAD_GLOBAL doesn't).

On that point, I still don't understand why PyObject_GetItem doesn't have a PyDict_CheckExact test for a dictionary fast-path when tp_as_mapping is found non-null. That operation - a pointer comparison - takes a fraction of a nanosecond on a modern CPU making it essentially free compared to the rest of the logic in there... Furthermore, this addition would greatly simplify both core and abstract apis and enable the possibility of fixing several longstanding bugs caused by using PyDict_GetItem/PyDict_SetItem on a dict subtype. Actually, the better solution may be to add PyDict_Check in PyObject_Getitem and PyDict_CheckExact in PyDict_GetItem.

After writing all that out this seems more like an issue with  PyObject_GetItem and how there is zero consistency throughout the entirety the abstract/core api as to whether some arbitrary procedure will try to use the core dictionary api as a fast path or head straight for the abstract api.
History
Date User Action Args
2019-03-13 23:31:43bupsetrecipients: + bup
2019-03-13 23:31:43bupsetmessageid: <1552519903.9.0.270264105873.issue36283@roundup.psfhosted.org>
2019-03-13 23:31:43buplinkissue36283 messages
2019-03-13 23:31:43bupcreate