11import ast
22import inspect
3+ import string
34from copy import copy
45from pythonwhat .parsing import TargetVars , FunctionParser , ObjectAccessParser , parser_dict
56from pythonwhat .Reporter import Reporter
@@ -31,6 +32,17 @@ def __len__(self):
3132 return len (self ._items )
3233
3334
35+ class MsgFormatter (string .Formatter ):
36+ def __init__ (self , default = '{{{0}}}' ):
37+ self .default = default
38+
39+ def get_value (self , key , args , kwds ):
40+ if isinstance (key , str ):
41+ return kwds .get (key , self .default .format (key ))
42+ else :
43+ Formatter .get_value (key , args , kwds )
44+
45+
3446class State (object ):
3547 """State of the SCT environment.
3648
@@ -43,6 +55,7 @@ def __init__(self,
4355 student_context = None , solution_context = None ,
4456 student_parts = None , solution_parts = None ,
4557 highlight = None , messages = None ,
58+ msg_formatter = None ,
4659 ** kwargs ):
4760
4861 # Set basic fields from kwargs
@@ -70,6 +83,8 @@ def __init__(self,
7083
7184 self .highlight = self .student_tree if highlight is None else highlight
7285
86+ self .msg_formatter = MsgFormatter () if msg_formatter is None else msg_formatter
87+
7388 self .converters = get_manual_converters () # accessed only from root state
7489
7590 self .fun_usage = {}
@@ -108,10 +123,11 @@ def build_message(self, tail="", fmt_kwargs=None):
108123 msgs = self .messages [:] + [{'msg' : tail or "" , 'kwargs' :fmt_kwargs }]
109124 # format messages in list, by iterating over previous, current, and next message
110125 for prev_d , d , next_d in zip ([{}, * msgs [:- 1 ]], msgs , [* msgs [1 :], {}]):
111- out = d ['msg' ].format (parent = prev_d .get ('kwargs' ),
112- child = next_d .get ('kwargs' ),
113- this = d ['kwargs' ],
114- ** d ['kwargs' ])
126+ out = self .msg_formatter .format (d ['msg' ],
127+ parent = prev_d .get ('kwargs' ),
128+ child = next_d .get ('kwargs' ),
129+ this = d ['kwargs' ],
130+ ** d ['kwargs' ])
115131 out_list .append (out )
116132
117133 return "" .join (out_list )
@@ -163,6 +179,7 @@ def to_child_state(self, student_subtree, solution_subtree,
163179 solution_process = self .solution_process ,
164180 raw_student_output = self .raw_student_output ,
165181 pre_exercise_tree = self .pre_exercise_tree ,
182+ msg_formatter = self .msg_formatter ,
166183 student_tree = student_subtree ,
167184 solution_tree = solution_subtree ,
168185 student_parts = student_parts ,
0 commit comments