diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 50c27e26..ea1f586b 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -75,6 +75,8 @@ bool py_exec(const char* source, enum py_CompileMode mode, py_Ref module) PY_RAISE; +/// Compile a source string into a code object. +/// Use python's `exec()` or `eval()` to execute it. bool py_compile(const char* source, const char* filename, enum py_CompileMode mode, diff --git a/src/public/modules.c b/src/public/modules.c index 9ec76ed5..559ee09e 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -463,7 +463,11 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_ // [globals, locals, code] CodeObject* co = py_touserdata(code); - if(!co->src->is_dynamic) py_shrink(3); + if(!co->src->is_dynamic) { + if(argc != 1) + return ValueError("code object is not dynamic, so globals and locals must be None"); + py_shrink(3); + } Frame* frame = pk_current_vm->top_frame; return pk_exec(co, frame ? frame->module : NULL); } diff --git a/tests/66_eval.py b/tests/66_eval.py index 1d4ab6bd..3d1137b6 100644 --- a/tests/66_eval.py +++ b/tests/66_eval.py @@ -59,6 +59,9 @@ globals = {'a': 2} locals = {'b': 3} assert eval('a*b', globals, locals) == 6 +code = compile('a*b', '', 'eval') +assert eval(code, globals, locals) == 6 + try: exec('a*b*c', globals, locals) exit(1)