Example #1
0
def test_comp(
    state,
    typestr,
    comptype,
    index,
    iter_vars_names,
    not_called_msg,
    insufficient_ifs_msg,
    incorrect_iter_vars_msg,
    comp_iter,
    ifs,
    key=None,
    body=None,
    value=None,
    rep=None,
):

    MSG_INCORRECT_ITER_VARS = "您是否使用了正确的迭代器(iterator)变量?"
    MSG_INCORRECT_NUM_ITER_VARS = "你是否使用了{{num_vars}}迭代器变量(iterator variables)?"
    MSG_INSUFFICIENT_IFS = "Have you used {{sol_len}} ifs?"

    # make sure other messages are set to default if None
    if insufficient_ifs_msg is None:
        insufficient_ifs_msg = MSG_INSUFFICIENT_IFS

    # get comprehension
    child = check_node(state,
                       comptype,
                       index - 1,
                       typestr,
                       missing_msg=not_called_msg)

    # test comprehension iter and its variable names (or number of variables)
    if comp_iter:
        multi(check_part(child, "iter", "iterable part"), comp_iter)

    # test iterator variables
    default_msg = (MSG_INCORRECT_ITER_VARS
                   if iter_vars_names else MSG_INCORRECT_NUM_ITER_VARS)
    has_context(child, incorrect_iter_vars_msg or default_msg, iter_vars_names)

    # test the main expressions.
    if body:
        multi(check_part(child, "body", "body"), body)  # list and gen comp
    if key:
        multi(check_part(child, "key", "key part"), key)  # dict comp
    if value:
        multi(check_part(child, "value", "value part"), value)  # ""

    # test a list of ifs. each entry corresponds to a filter in the comprehension.
    for i, if_test in enumerate(ifs or []):
        # test that ifs are same length
        has_equal_part_len(child, "ifs", insufficient_ifs_msg)
        # test individual ifs
        multi(
            check_part_index(child, "ifs", i,
                             utils.get_ord(i + 1) + " if"),
            if_test,
        )
Example #2
0
def test_with(
    state,
    index,
    context_vals=False,  # whether to check number of context vals
    context_tests=None,  # check on context expressions
    body=None,
    undefined_msg=None,
    context_vals_len_msg=None,
    context_vals_msg=None,
):
    """Test a with statement.
with open_file('...') as bla:

    [ open_file('...').__enter__() ]


with open_file('...') as file:
    [ ]

    """

    MSG_NUM_CTXT = "Make sure to use the correct number of context variables. It seems you defined too many."
    MSG_NUM_CTXT2 = "Make sure to use the correct number of context variables. It seems you defined too little."
    MSG_CTXT_NAMES = "Make sure to use the correct context variable names. Was expecting `{{sol_vars}}` but got `{{stu_vars}}`."

    check_with = partial(check_node, state, "withs", index - 1,
                         "{{ordinal}} `with` statement")

    child = check_with()
    child2 = check_with()

    if context_vals:
        # test context var names ----
        has_context(
            child,
            incorrect_msg=context_vals_msg or MSG_CTXT_NAMES,
            exact_names=True,
        )

        # test num context vars ----
        has_equal_part_len(child, "context", MSG_NUM_CTXT)

    # Context sub tests ----
    if context_tests and not isinstance(context_tests, list):
        context_tests = [context_tests]

    for i, context_test in enumerate(context_tests or []):
        # partial the substate check, because the function uses two prepended messages
        def check_context(state):
            return check_part_index(
                state,
                "context",
                i,
                "%s context" % utils.get_ord(i + 1),
                missing_msg=MSG_NUM_CTXT2,
            )

        check_context(child)  # test exist

        ctxt_state = check_context(child2)  # sub tests
        multi(ctxt_state, context_test)

    # Body sub tests ----
    if body is not None:
        body_state = check_part(child2, "body", "body")

        with_context(body_state, body, child=child)