def set_context(node, ctx, p):
    # XXX passing the yacc production object to raise the error
    # message is a bit flakey and gets things wrong occasionally
    # when there are blank lines around the error. We can do better.
    items = None
    err_msg = ''
    node_type = type(node)
    if node_type in context_allowed:
        node.ctx = ctx
        if ctx == Store:
            if node_type == ast.Tuple:
                if len(node.elts) == 0:
                    err_msg = '()'
                else:
                    items = node.elts
            elif node_type == ast.List:
                items = node.elts
    elif node_type in context_disallowed:
        err_msg = context_disallowed[node_type]
    else:
        msg = 'unexpected expression in assignment %d (line %d)'
        raise SystemError(msg % (node_type.__name__, node.lineno))

    if err_msg:
        m = 'assign to' if ctx == Store else 'delete'
        msg = "can't %s %s" % (m, err_msg)
        tok = FakeToken(p.lexer.lexer, p.lexer.lexer.lineno - 1)
        syntax_error(msg, tok)

    if items is not None:
        for item in items:
            set_context(item, ctx, p)
Returns the row of the end of the next diffscuss thread, and the current
dataset/ETHPy150Open nucleic/enaml/enaml/core/parser.py/set_context--crossover with--dataset/ETHPy150Open hut8labs/diffscuss/diffscuss/support/editor.py/find_next_thread_end