Typecheck eval arguments during execution instead of compilation

When checking types during compilation, things like

    (eval '(print 1) (. foo mod))

fail, even if `(. foo mod)` is a dictionary.
This commit is contained in:
Gregor Best 2015-08-12 19:00:03 +02:00
parent 6d19128c3c
commit 44416fc276
2 changed files with 12 additions and 4 deletions

View File

@ -729,15 +729,11 @@ class HyASTCompiler(object):
elist = [HySymbol("hy_eval")] + [expr[0]]
if len(expr) >= 2:
if not isinstance(expr[1], (HyDict, HySymbol)):
raise HyTypeError(expr, "Globals must be a dictionary")
elist.append(expr[1])
else:
elist.append(HyExpression([HySymbol("locals")]))
if len(expr) == 3:
if not isinstance(expr[2], HyString):
raise HyTypeError(expr, "Module name must be a string")
elist.append(expr[2])
else:
elist.append(HyString(self.module_name))

View File

@ -108,6 +108,15 @@ def hy_eval(hytree, namespace, module_name):
foo.start_column = 0
foo.end_column = 0
replace_hy_obj(hytree, foo)
try:
checktype = basestring
except NameError:
checktype = str
if not isinstance(module_name, checktype):
raise HyTypeError(foo, "Module name must be a string")
_ast, expr = hy_compile(hytree, module_name, get_expr=True)
# Spoof the positions in the generated ast...
@ -119,6 +128,9 @@ def hy_eval(hytree, namespace, module_name):
node.lineno = 1
node.col_offset = 1
if not isinstance(namespace, dict):
raise HyTypeError(foo, "Globals must be a dictionary")
# Two-step eval: eval() the body of the exec call
eval(ast_compile(_ast, "<eval_body>", "exec"), namespace)