Ejemplo n.º 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,
        )
Ejemplo n.º 2
0
def test_args(state, arg_names, arg_defaults, nb_args_msg, arg_names_msg,
              arg_defaults_msg):

    MSG_NUM_ARGS = "You should define {{parent[typestr]}} with {{sol_len}} arguments, instead got {{stu_len}}."
    MSG_BAD_ARG_NAME = "The {{parent[ordinal]}} {{parent[part]}} should be called `{{sol_part[name]}}`, instead got `{{stu_part[name]}}`."
    MSG_BAD_DEFAULT = (
        "The {{parent[part]}} `{{stu_part[name]}}` should have no default.")
    MSG_INC_DEFAULT = (
        "The {{parent[part]}} `{{stu_part[name]}}` does not have the correct default."
    )

    MSG_NO_VARARG = "Have you specified an argument to take a `*` argument and named it `{{sol_part['*args'][name]}}`?"
    MSG_NO_KWARGS = "Have you specified an argument to take a `**` argument and named it `{{sol_part['**kwargs'][name]}}`?"
    MSG_VARARG_NAME = "Have you specified an argument to take a `*` argument and named it `{{sol_part[name]}}`?"
    MSG_KWARG_NAME = "Have you specified an argument to take a `**` argument and named it `{{sol_part[name]}}`?"

    if arg_names or arg_defaults:
        # test number of args
        has_equal_part_len(state, "_spec1_args", nb_args_msg or MSG_NUM_ARGS)

        # iterate over each arg, testing name and default
        for ii in range(len(state.solution_parts["_spec1_args"])):
            # get argument state
            arg_state = check_part_index(state, "_spec1_args", ii, "argument",
                                         "NO MISSING MSG")
            # test exact name
            has_equal_part(arg_state, "name", arg_names_msg
                           or MSG_BAD_ARG_NAME)

            if arg_defaults:
                # test whether is default
                has_equal_part(arg_state, "is_default", arg_defaults_msg
                               or MSG_BAD_DEFAULT)
                # test default value, use if to prevent running a process no default
                if arg_state.solution_parts["is_default"]:
                    has_equal_value(
                        arg_state,
                        incorrect_msg=arg_defaults_msg or MSG_INC_DEFAULT,
                        append=True,
                    )

        # test *args and **kwargs
        if state.solution_parts["*args"]:
            vararg = check_part(state, "*args", "", missing_msg=MSG_NO_VARARG)
            has_equal_part(vararg, "name", MSG_VARARG_NAME)

        if state.solution_parts["**kwargs"]:
            kwarg = check_part(state,
                               "**kwargs",
                               "",
                               missing_msg=MSG_NO_KWARGS)
            has_equal_part(kwarg, "name", MSG_KWARG_NAME)
Ejemplo n.º 3
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)