-
Notifications
You must be signed in to change notification settings - Fork 302
Open
Labels
Description
#ENABLE_CHECK50_ASSERT=true
import check50
import check50.c
@check50.check()
def exists():
"""test.c exists"""
check50.exists('test.c')
@check50.check(exists)
def compiles():
"""test.c compiles"""
check50.c.compile('test.c', lcs50=True)
@check50.check()
def foo():
"""abc"""
assert check50.run("pwd").stdout() == "foo"Testing on this file returns this output:
Results for . generated by check50 v4.0.0.dev0
:) test.c exists
checking that test.c exists...
:) test.c compiles
running clang test.c -o test -std=c11 -ggdb -lm -lcs50...
:( abc
expected: "'foo'"
actual: "/tmp/tmpu97pc8q4/foo\n"
checked: check50.run('pwd').stdout() == 'foo'
where check50.run('pwd').stdout() = '/tmp/tmpu97pc8q4/foo\n'
running pwd...
running pwd...
pwd should only ever run once. What happens in this case is caused by this pair of lines in runtime.py:
context[expr_str] = eval(expr_str, caller_globals, caller_locals)cond = eval(eval_src, eval_globals, eval_locals)The first of the two lines is supposed to evaluate the expression and store its value within context. After we've replaced the evaluated statements in our src conditional and stored that in eval_src, we evaluate eval_src in the second of the of the two lines.
If we end up running a command twice, that is because we've improperly replaced the evaluated statements in src (see the line below), causing eval(eval_src, ...) to evaluate again.
eval_src, eval_context = substitute_expressions(src, filtered_context)So substitute_expressions must have an issue with its tokenizing logic.