add check_class_def
machow opened this issue · 3 comments
machow commented
cc @hugobowne
To test cases like...
class A(object):
def __init__(self): pass
Here is the AST. Note that the body of the class is just python expressions, so we would only need to add an SCT to select the ClassDef node (and maybe to grab the bases).
machow commented
@gvwilson I'll walk through this on Friday morning, to illustrate pythonwhat. Below are details for how to implement a check_class_def
SCT.
Useful lines of code
- while parser - fairly similar to what's needed here.
- check_node SCT - used behind the scenes to grab while AST nodes
- wrapping check_node to create check_while
Experimenting with AST
from pythonwhat.State import State
def create_state(sol_code, stu_code="", pe_code=""):
s = State(
student_code = stu_code,
solution_code = sol_code,
full_student_code = stu_code,
full_solution_code = sol_code,
pre_exercise_code = pe_code,
student_process = None,
solution_process = None,
raw_student_output = ""
)
return s
code = """
class C:
def a(self): print('hey')
"""
state = create_state(code, code, "")
state.student_ast # this is what the ast-viewer graphs
# we can dump the AST to text for inspection
import ast
from pythonwhat import utils_ast
ast.dump(state.student_ast)
utils_ast.pdp(state.student_ast)
Steps to implement
Add a parsing class to pythonwhat.parsing.py
, that looks something like...
class ClassDefParser(Parser):
"""Find class def structures.
A parser which inherits from the basic parser to find class def structures.
Only 'top-level' class def structures will be found!
"""
def __init__(self):
self.out = []
def visit_ClassDef(self, node):
self.out.append({
'node': node,
'name': "name": getattr(node, 'name', None),
'bases': [{'node': base} for base in node.bases],
'body': node.body,
})
Update pythonwhat/check_wrappers.py
here with something like
'class_def': 'class definition of `{index}`'
Update pythonwhat/check_wrappers.py
here with
'bases': '{ordinal} base class'
Update the parses dict in pythonwhat/parsing.py
. This is used by pythonwhat/state.py
here to put property methods on the State
class for each parser.