Skip to content

Commit 0c4aef4

Browse files
committed
feat: add multi line code formatting for has_equal_ast
1 parent c52a258 commit 0c4aef4

File tree

5 files changed

+99
-14
lines changed

5 files changed

+99
-14
lines changed

pythonwhat/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = "2.24.1"
1+
__version__ = "2.24.2"
22

33
from .test_exercise import test_exercise, allow_errors

pythonwhat/checks/has_funcs.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ def has_equal_ast(state, incorrect_msg=None, code=None, exact=True, append=None)
167167
): # if not specified, set to False if incorrect_msg was manually specified
168168
append = incorrect_msg is None
169169
if incorrect_msg is None:
170-
incorrect_msg = "Expected `{{sol_str}}`, but got `{{stu_str}}`."
170+
incorrect_msg = (
171+
"Expected \n```\n{{sol_str}}\n```\n, but got \n```\n{{stu_str}}\n```\n"
172+
if utils.is_multiline_code(state.student_code, state.solution_code)
173+
else "Expected `{{sol_str}}`, but got `{{stu_str}}`."
174+
)
171175

172176
def parse_tree(tree):
173177
# get contents of module.body if only 1 element
@@ -183,10 +187,18 @@ def parse_tree(tree):
183187
stu_rep = parse_tree(state.student_ast)
184188
sol_rep = parse_tree(state.solution_ast if not code else ast.parse(code))
185189

186-
fmt_kwargs = {
187-
"sol_str": state.solution_code if not code else code,
188-
"stu_str": state.student_code,
189-
}
190+
if utils.is_multiline_code(state.student_code, state.solution_code):
191+
fmt_kwargs = {
192+
"sol_str": utils.format_code(state.solution_code)
193+
if not code
194+
else utils.format_code(code),
195+
"stu_str": utils.format_code(state.student_code),
196+
}
197+
else:
198+
fmt_kwargs = {
199+
"sol_str": state.solution_code if not code else code,
200+
"stu_str": state.student_code,
201+
}
190202

191203
if exact and not code:
192204
state.do_test(
@@ -345,19 +357,20 @@ def has_expr(
345357
# wrap in quotes if eval_sol or eval_stu are strings
346358
if test == "value":
347359
if isinstance(eval_stu, str):
348-
fmt_kwargs["stu_eval"] = '\'{}\''.format(fmt_kwargs["stu_eval"])
360+
fmt_kwargs["stu_eval"] = "'{}'".format(fmt_kwargs["stu_eval"])
349361
if isinstance(eval_sol, str):
350-
fmt_kwargs["sol_eval"] = '\'{}\''.format(fmt_kwargs["sol_eval"])
362+
fmt_kwargs["sol_eval"] = "'{}'".format(fmt_kwargs["sol_eval"])
351363

352364
# reformat student evaluation string if it is too long
353365
fmt_kwargs["stu_eval"] = utils.shorten_string(fmt_kwargs["stu_eval"])
354366

355367
# check if student or solution evaluations are too long or contain newlines
356368
if incorrect_msg == DEFAULT_INCORRECT_MSG and (
357-
len(fmt_kwargs["sol_eval"]) > 50 or
358-
utils.has_newline(fmt_kwargs["stu_eval"]) or
359-
utils.has_newline(fmt_kwargs["sol_eval"]) or
360-
fmt_kwargs["stu_eval"] == fmt_kwargs["sol_eval"]):
369+
len(fmt_kwargs["sol_eval"]) > 50
370+
or utils.has_newline(fmt_kwargs["stu_eval"])
371+
or utils.has_newline(fmt_kwargs["sol_eval"])
372+
or fmt_kwargs["stu_eval"] == fmt_kwargs["sol_eval"]
373+
):
361374
fmt_kwargs["stu_eval"] = None
362375
fmt_kwargs["sol_eval"] = None
363376
incorrect_msg = "Expected something different."

pythonwhat/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
from types import ModuleType
22
import copy
33
import os
4+
import black
5+
6+
7+
def format_code(text):
8+
mode = black.FileMode()
9+
try:
10+
return black.format_file_contents(text, fast=True, mode=mode)
11+
except black.NothingChanged:
12+
return text
13+
14+
15+
def is_multiline_code(stu_code: str, sol_code: str) -> bool:
16+
return has_newline(stu_code) or has_newline(sol_code)
417

518

619
def include_v1():
@@ -10,11 +23,13 @@ def include_v1():
1023
def v2_only():
1124
return not include_v1()
1225

26+
1327
def shorten_string(text):
1428
if len(text) > 50:
1529
text = text[0:45] + "..."
1630
return text
1731

32+
1833
def has_newline(text):
1934
return "\n" in text
2035

requirements.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# pythonwhat deps
2-
protowhat~=2.1.0
2+
protowhat~=2.1.3
33
asttokens~=2.0.5
44
dill~=0.3.4
5-
markdown2~=2.3.10
5+
markdown2~=2.4.6
66
jinja2~=2.11.3
7+
markupsafe==2.0.1
8+
black==19.10b0
9+
Pygments==2.13.0
710

811
numpy~=1.19.5
912
pandas~=1.3.2

tests/test_spec.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,60 @@ def test_has_equal_ast_simple_pass(data):
137137
assert sct_payload["correct"]
138138

139139

140+
def test_has_equal_ast_formatting(data):
141+
data["DC_CODE"] = """
142+
def car_wash(env):
143+
car_wash_num = 0
144+
while True:
145+
car_wash_num += 2
146+
147+
# Get the current simulation time and clock-in the process time
148+
yield env.timeout(5)
149+
150+
a = 2
151+
b = 3
152+
"""
153+
data["DC_SOLUTION"] = """
154+
def car_wash(env):
155+
car_wash_num = 0
156+
while True:
157+
car_wash_num += 1
158+
159+
# Get the current simulation time and clock-in the process time
160+
yield env.timeout(5)
161+
162+
a = 2
163+
b = 3
164+
"""
165+
data["DC_SCT"] = """
166+
Ex().check_function_def("car_wash").multi(
167+
check_body().check_while().has_equal_ast()
168+
)
169+
"""
170+
sct_payload = helper.run(data)
171+
assert not sct_payload["correct"]
172+
incorrect_msg = """Did you correctly specify the body? Check the first <code>while</code> loop. Expected
173+
174+
<pre><code>while True:
175+
car_wash_num += 1
176+
177+
# Get the current simulation time and clock-in the process time
178+
yield env.timeout(5)
179+
180+
</code></pre>
181+
182+
, but got
183+
184+
<pre><code>while True:
185+
car_wash_num += 2
186+
187+
# Get the current simulation time and clock-in the process time
188+
yield env.timeout(5)
189+
190+
</code></pre>"""
191+
assert sct_payload["message"] == incorrect_msg
192+
193+
140194
def test_has_equal_ast_simple_fail(data):
141195
data["DC_SCT"] = "Ex().has_equal_ast()"
142196
failing_submission(data)

0 commit comments

Comments
 (0)