forked from datacamp/pythonwhat
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsct_syntax.py
More file actions
65 lines (47 loc) · 2.14 KB
/
sct_syntax.py
File metadata and controls
65 lines (47 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from protowhat.sct_syntax import Chain as ProtoChain, F as ProtoF, state_dec_gen
from pythonwhat.checks.check_wrappers import scts
from pythonwhat.State import State
from pythonwhat.probe import Node, Probe, TEST_NAMES
from pythonwhat.utils import include_v1
from pythonwhat import test_funcs
from functools import wraps
# TODO: could define scts for check_wrappers at the module level
sct_dict = scts.copy()
def multi_dec(f):
"""Decorator for multi to remove nodes for original test functions from root node"""
@wraps(f)
def wrapper(*args, **kwargs):
args = (
args[0] if len(args) == 1 and isinstance(args[0], (list, tuple)) else args
)
for arg in args:
if isinstance(arg, Node) and arg.parent.name is "root":
arg.parent.remove_child(arg)
arg.update_child_calls()
return f(*args, **kwargs)
return wrapper
state_dec = state_dec_gen(State, sct_dict)
class Chain(ProtoChain):
def __init__(self, state, attr_scts=sct_dict):
super().__init__(state, attr_scts)
class F(ProtoF):
def __init__(self, stack=None, attr_scts=sct_dict):
super().__init__(stack, attr_scts)
def Ex(state=None):
return Chain(state or State.root_state)
if include_v1():
# Prepare SCTs that may be chained attributes ----------------------
# decorate functions that may try to run test_* function nodes as subtests
# so they remove those nodes from the tree
for k in ["multi", "with_context"]:
sct_dict[k] = multi_dec(sct_dict[k])
# allow test_* functions as chained attributes
for k in TEST_NAMES:
sct_dict[k] = Probe(tree=None, f=getattr(test_funcs, k), eval_on_call=True)
# original logical test_* functions behave like multi
# this is necessary to allow them to take check_* funcs as args
# since probe behavior will try to call all SCTs passed (assuming they're also probes)
for k in ["test_or", "test_correct"]:
sct_dict[k] = multi_dec(getattr(test_funcs, k))
# Prepare check_funcs to be used alone (e.g. test = check_with().check_body())
v2_check_functions = {k: state_dec(v) for k, v in scts.items()}