[New-bugs-announce] [issue36283] eval is needlessly limited

Dan Snider report at bugs.python.org
Wed Mar 13 19:31:43 EDT 2019


New submission from Dan Snider <mr.assume.away at gmail.com>:

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.

----------
components: Interpreter Core
messages: 337885
nosy: bup
priority: normal
severity: normal
status: open
title: eval is needlessly limited
type: enhancement
versions: Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue36283>
_______________________________________


More information about the New-bugs-announce mailing list