-
Notifications
You must be signed in to change notification settings - Fork 298
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.