pythonwhat/State.py
def to_child(self, append_message="", node_name="", **kwargs):
        """Dive into nested tree.

        Set the current state as a state with a subtree of this syntax tree as
        student tree and solution tree. This is necessary when testing if statements or
        for loops for example.
        """
        base_kwargs = {
            attr: getattr(self, attr)
            for attr in self.params
            if attr not in ["highlight"]
        }

        if not isinstance(append_message, dict):
            append_message = {"msg": append_message, "kwargs": {}}

        kwargs["messages"] = [*self.messages, append_message]
        kwargs["parent_state"] = self

        for kwarg in ["solution_context", "student_context"]:
            if kwarg in kwargs and not kwargs[kwarg]:
                kwargs.pop(kwarg, None)

        def update_kwarg(name, func):
            kwargs[name] = func(kwargs[name])

        def update_context(name):
            update_kwarg(name, getattr(self, name).update_ctx)

        if isinstance(kwargs.get("student_ast", None), list):
            update_kwarg("student_ast", wrap_in_module)
        if isinstance(kwargs.get("solution_ast", None), list):
            update_kwarg("solution_ast", wrap_in_module)

        if "student_ast" in kwargs:
            kwargs["student_code"] = self.student_ast_tokens.get_text(
                kwargs["student_ast"]
            )
        if "solution_ast" in kwargs:
            kwargs["solution_code"] = self.solution_ast_tokens.get_text(
                kwargs["solution_ast"]
            )

        # get new contexts
        if "solution_context" in kwargs:
            update_context("solution_context")
        if "student_context" in kwargs:
            update_context("student_context")

        # get new envs
        if "solution_env" in kwargs:
            update_context("solution_env")
        if "student_env" in kwargs:
            update_context("student_env")

        klass = self.SUBCLASSES[node_name] if node_name else State
        child = klass(**{**base_kwargs, **kwargs})
        return child
def to_child(self, append_message="", node_name="", **kwargs):
        """Dive into nested tree.

        Set the current state as a state with a subtree of this syntax tree as
        student tree and solution tree. This is necessary when testing if statements or
        for loops for example.
        """
        base_kwargs = {
            attr: getattr(self, attr)
            for attr in self.params
            if attr not in ["highlight"]
        }

        if not isinstance(append_message, dict):
            append_message = {"msg": append_message, "kwargs": {}}

        kwargs["messages"] = [*self.messages, append_message]
        kwargs["parent_state"] = self

        for kwarg in ["solution_context", "student_context"]:
            if kwarg in kwargs and not kwargs[kwarg]:
                kwargs.pop(kwarg, None)

        def update_kwarg(name, func):
            kwargs[name] = func(kwargs[name])

        def update_context(name):
            update_kwarg(name, getattr(self, name).update_ctx)

        if isinstance(kwargs.get("student_ast", None), list):
            update_kwarg("student_ast", wrap_in_module)
        if isinstance(kwargs.get("solution_ast", None), list):
            update_kwarg("solution_ast", wrap_in_module)

        if "student_ast" in kwargs:
            kwargs["student_code"] = self.student_ast_tokens.get_text(
                kwargs["student_ast"]
            )
        if "solution_ast" in kwargs:
            kwargs["solution_code"] = self.solution_ast_tokens.get_text(
                kwargs["solution_ast"]
            )

        # get new contexts
        if "solution_context" in kwargs:
            update_context("solution_context")
        if "student_context" in kwargs:
            update_context("student_context")

        # get new envs
        if "solution_env" in kwargs:
            update_context("solution_env")
        if "student_env" in kwargs:
            update_context("student_env")

        klass = self.SUBCLASSES[node_name] if node_name else State
        child = klass(**{**base_kwargs, **kwargs})
        return child
Dive into nested tree.

        Set the current state as a state with a subtree of this syntax tree as
        student tree and solution tree. This is necessary when testing if statements or
        for loops for example.