Example #1
0
    def visitTryExcept(self, node):

        # If we are code after a 'try' block, then it either succeeded or
        # handled its own exception. So either the 'try' and 'else' blocks ran,
        # or some of the 'try' and one of the handlers ran. If we treat the
        # 'try' and 'else' blocks as one, then we can say that
        # 'try'/'except'/'else' produces unconditional locals when the same
        # name is local to 'try'/'else' and every handler. All other bindings
        # are conditional.

        # Visit children
        body_v = walk([node.body, node.else_], NameFinder())
        # (A handler is (type, name, body) where 'type' and 'name' can be None)
        handler_vs = [ walk(h, NameFinder()) for h in node.handlers ]
        assert all(not v.conditional_locals for v in handler_vs)

        # Free names come from 'try', 'else', and names in 'except' that aren't
        # bound by the exception name. Since 'handlers' bundles each 'except'
        # body with its exception name, the bindings are already computed.
        self._see_unbound(body_v.free | union(v.free for v in handler_vs))

        # Unconditional locals only come from locals in both the 'try'/'else'
        # body and every 'except' body. All other locals are conditional.
        locals = body_v.locals & intersect(v.locals for v in handler_vs)
        conditional_locals = \
            (body_v.all_locals() | union(v.all_locals() for v in handler_vs)) \
                - locals

        self._bind(locals)
        self._bind_conditional(conditional_locals)
Example #2
0
    def visitTryExcept(self, node):

        # If we are code after a 'try' block, then it either succeeded or
        # handled its own exception. So either the 'try' and 'else' blocks ran,
        # or some of the 'try' and one of the handlers ran. If we treat the
        # 'try' and 'else' blocks as one, then we can say that
        # 'try'/'except'/'else' produces unconditional locals when the same
        # name is local to 'try'/'else' and every handler. All other bindings
        # are conditional.

        # Visit children
        body_v = walk([node.body, node.else_], NameFinder())
        # (A handler is (type, name, body) where 'type' and 'name' can be None)
        handler_vs = [walk(h, NameFinder()) for h in node.handlers]
        assert all(not v.conditional_locals for v in handler_vs)

        # Free names come from 'try', 'else', and names in 'except' that aren't
        # bound by the exception name. Since 'handlers' bundles each 'except'
        # body with its exception name, the bindings are already computed.
        self._see_unbound(body_v.free | union(v.free for v in handler_vs))

        # Unconditional locals only come from locals in both the 'try'/'else'
        # body and every 'except' body. All other locals are conditional.
        locals = body_v.locals & intersect(v.locals for v in handler_vs)
        conditional_locals = \
            (body_v.all_locals() | union(v.all_locals() for v in handler_vs)) \
                - locals

        self._bind(locals)
        self._bind_conditional(conditional_locals)
Example #3
0
def is_const(ast):
    ''' Whether an AST represents a constant expression.

        I'm not sure what "constant" means yet, but here are some examples:

            >>> all(is_const(parse(s, mode='eval')) for s in (
            ...     '0',
            ...     'True',
            ...     'None',
            ...     '"foo"',
            ...     '[1,2]',
            ...     '(False, [])',
            ...     '{"a": 1}',
            ...     '{"a": 0, (True, False): [None, 3, "fish", ()]}',
            ... ))
            True

        And some non-examples, some of which maybe should be reclassified:

            >>> any(is_const(parse(s, mode='eval')) for s in (
            ...     '0+1',
            ...     '~8',
            ...     '0 < 1',
            ...     'not True',
            ...     '"fo%s" % "o"',
            ...     'len([1,2])',
            ...     '[1,2][0]',
            ...     '[1,a]',
            ...     '[a for a in [1,2]]',
            ...     '{"a": 0}.keys()',
            ...     'set()',
            ...     'list()',
            ...     'dict()',
            ...     'dict',
            ...     'lambda: 3',
            ...     'lambda a: a',
            ... ))
            False
    '''
    return (
        isinstance(ast, Const) or
        isinstance(ast, Name) and ast.name in ['None', 'True', 'False'] or
        isinstance(ast, (List, Tuple, Dict)) and all(map(is_const, ast)) or
        isinstance(ast, Expression) and is_const(ast.node)
    )
Example #4
0
def is_const(ast):
    ''' Whether an AST represents a constant expression.

        I'm not sure what "constant" means yet, but here are some examples:

            >>> all(is_const(parse(s, mode='eval')) for s in (
            ...     '0',
            ...     'True',
            ...     'None',
            ...     '"foo"',
            ...     '[1,2]',
            ...     '(False, [])',
            ...     '{"a": 1}',
            ...     '{"a": 0, (True, False): [None, 3, "fish", ()]}',
            ... ))
            True

        And some non-examples, some of which maybe should be reclassified:

            >>> any(is_const(parse(s, mode='eval')) for s in (
            ...     '0+1',
            ...     '~8',
            ...     '0 < 1',
            ...     'not True',
            ...     '"fo%s" % "o"',
            ...     'len([1,2])',
            ...     '[1,2][0]',
            ...     '[1,a]',
            ...     '[a for a in [1,2]]',
            ...     '{"a": 0}.keys()',
            ...     'set()',
            ...     'list()',
            ...     'dict()',
            ...     'dict',
            ...     'lambda: 3',
            ...     'lambda a: a',
            ... ))
            False
    '''
    return (isinstance(ast, Const)
            or isinstance(ast, Name) and ast.name in ['None', 'True', 'False']
            or isinstance(ast, (List, Tuple, Dict)) and all(map(is_const, ast))
            or isinstance(ast, Expression) and is_const(ast.node))