Beispiel #1
0
def unboxable(gx, types):
    if not isinstance(types, set):
        types = infer.inode(gx, types).types()
    classes = set(t[0] for t in types)

    if [cl for cl in classes if cl.ident not in ['int_', 'float_', 'bool_', 'complex']]:
        return None
    else:
        if classes:
            return classes.pop().ident
        return None
Beispiel #2
0
def analyze_virtuals(gx):
    for node in gx.merged_inh:
        # --- for every message
        if isinstance(node, CallFunc) and not infer.inode(gx, node).mv.module.builtin:  # ident == 'builtin':
            objexpr, ident, direct_call, method_call, constructor, parent_constr, anon_func = infer.analyze_callfunc(gx, node, merge=gx.merged_inh)
            if not method_call or objexpr not in gx.merged_inh:
                continue  # XXX

            # --- determine abstract receiver class
            classes = polymorphic_t(gx, gx.merged_inh[objexpr])
            classes = [cl for cl in classes if isinstance(cl, Class)]
            if not classes:
                continue

            if isinstance(objexpr, Name) and objexpr.name == 'self' and infer.inode(gx, objexpr).parent:
                abstract_cl = infer.inode(gx, objexpr).parent.parent
                upgrade_cl(gx, abstract_cl, node, ident, classes)

            lcp = lowest_common_parents(classes)
            if lcp:
                upgrade_cl(gx, lcp[0], node, ident, classes)
Beispiel #3
0
def error(msg, gx, node=None, warning=False, mv=None):
    if warning:
        kind = '*WARNING*'
    else:
        kind = '*ERROR*'
    if not mv and node and (node, 0, 0) in gx.cnode:
        mv = infer.inode(gx, node).mv
    filename = lineno = None
    if mv:
        filename = mv.module.relative_filename
        if node and hasattr(node, 'lineno'):
            lineno = node.lineno
    result = (kind, filename, lineno, msg)
    if result not in ERRORS:
        ERRORS.add(result)
    if not warning:
        print format_error(result)
        sys.exit(1)
Beispiel #4
0
def singletype(gx, node, type):
    types = [t[0] for t in infer.inode(gx, node).types()]
    if len(types) == 1 and isinstance(types[0], type):
        return types[0]
Beispiel #5
0
def annotate(gx):
    if not gx.annotation:
        return

    for module in gx.modules.values():
        if module.builtin:
            continue
        mv = module.mv
        merge = dict((k, v) for k, v in gx.merged_inh.items()
                     if (k, 0, 0) in gx.cnode and inode(gx, k).mv == mv)
        source = open(module.filename).readlines()

        # --- constants/names/attributes
        for expr in merge:
            if isinstance(expr, (Const, Name)):
                paste(
                    gx, source, expr,
                    nodetypestr(gx, expr, inode(gx, expr).parent, False,
                                mv=mv), mv)

        for expr in merge:
            if isinstance(expr, Getattr):
                paste(
                    gx, source, expr,
                    nodetypestr(gx, expr, inode(gx, expr).parent, False,
                                mv=mv), mv)

        for expr in merge:
            if isinstance(expr, (Tuple, List, Dict)):
                paste(
                    gx, source, expr,
                    nodetypestr(gx, expr, inode(gx, expr).parent, False,
                                mv=mv), mv)

        # --- instance variables
        funcs = mv.funcs.values()
        for cl in mv.classes.values():
            labels = [
                var.name + ': ' + nodetypestr(gx, var, cl, False, mv=mv)
                for var in cl.vars.values() if var in merge and merge[var]
                and not var.name.startswith('__')
            ]
            if labels:
                paste(gx, source, cl.node, ', '.join(labels), mv)
            funcs += cl.funcs.values()

        # --- function variables
        for func in funcs:
            if not func.node or func.node in gx.inherited:
                continue
            vars = [func.vars[f] for f in func.formals]
            labels = [
                var.name + ': ' + nodetypestr(gx, var, func, False, mv=mv)
                for var in vars if not var.name.startswith('__')
            ]
            paste(gx, source, func.node, ', '.join(labels), mv)

        # --- callfuncs
        for callfunc, _ in mv.callfuncs:
            if isinstance(callfunc.node, Getattr):
                if not callfunc.node.__class__.__name__.startswith(
                        'FakeGetattr'):  # XXX
                    paste(
                        gx, source, callfunc.node.expr,
                        nodetypestr(gx,
                                    callfunc,
                                    inode(gx, callfunc).parent,
                                    False,
                                    mv=mv), mv)
            else:
                paste(
                    gx, source, callfunc.node,
                    nodetypestr(gx,
                                callfunc,
                                inode(gx, callfunc).parent,
                                False,
                                mv=mv), mv)

        # --- higher-level crap (listcomps, returns, assignments, prints)
        for expr in merge:
            if isinstance(expr, ListComp):
                paste(
                    gx, source, expr,
                    nodetypestr(gx, expr, inode(gx, expr).parent, False,
                                mv=mv), mv)
            elif isinstance(expr, Return):
                paste(
                    gx, source, expr,
                    nodetypestr(gx,
                                expr.value,
                                inode(gx, expr).parent,
                                False,
                                mv=mv), mv)
            elif isinstance(expr, (AssTuple, AssList)):
                paste(
                    gx, source, expr,
                    nodetypestr(gx, expr, inode(gx, expr).parent, False,
                                mv=mv), mv)
            elif isinstance(expr, (Print, Printnl)):
                paste(
                    gx, source, expr, ', '.join(
                        nodetypestr(
                            gx, child, inode(gx, child).parent, False, mv=mv)
                        for child in expr.nodes), mv)

        # --- assignments
        for expr in merge:
            if isinstance(expr, Assign):
                pairs = assign_rec(expr.nodes[0], expr.expr)
                paste(
                    gx, source, expr, ', '.join(
                        nodetypestr(gx, r, inode(gx, r).parent, False, mv=mv)
                        for (l, r) in pairs), mv)
            elif isinstance(expr, AugAssign):
                paste(
                    gx, source, expr,
                    nodetypestr(gx,
                                expr.expr,
                                inode(gx, expr).parent,
                                False,
                                mv=mv), mv)

        # --- output annotated file (skip if no write permission)
        try:
            out = open(module.filename[:-3] + '.ss.py', 'w')
            out.write(''.join(source))
            out.close()
        except IOError:
            pass
Beispiel #6
0
def annotate(gx):
    if not gx.annotation:
        return

    for module in gx.modules.values():
        if module.builtin:
            continue
        mv = module.mv
        merge = dict((k, v) for k, v in gx.merged_inh.items() if (k, 0, 0) in gx.cnode and inode(gx, k).mv == mv)
        source = open(module.filename).readlines()

        # --- constants/names/attributes
        for expr in merge:
            if isinstance(expr, (Const, Name)):
                paste(gx, source, expr, nodetypestr(gx, expr, inode(gx, expr).parent, False, mv=mv), mv)

        for expr in merge:
            if isinstance(expr, Getattr):
                paste(gx, source, expr, nodetypestr(gx, expr, inode(gx, expr).parent, False, mv=mv), mv)

        for expr in merge:
            if isinstance(expr, (Tuple, List, Dict)):
                paste(gx, source, expr, nodetypestr(gx, expr, inode(gx, expr).parent, False, mv=mv), mv)

        # --- instance variables
        funcs = mv.funcs.values()
        for cl in mv.classes.values():
            labels = [var.name + ': ' + nodetypestr(gx, var, cl, False, mv=mv) for var in cl.vars.values() if var in merge and merge[var] and not var.name.startswith('__')]
            if labels:
                paste(gx, source, cl.node, ', '.join(labels), mv)
            funcs += cl.funcs.values()

        # --- function variables
        for func in funcs:
            if not func.node or func.node in gx.inherited:
                continue
            vars = [func.vars[f] for f in func.formals]
            labels = [var.name + ': ' + nodetypestr(gx, var, func, False, mv=mv) for var in vars if not var.name.startswith('__')]
            paste(gx, source, func.node, ', '.join(labels), mv)

        # --- callfuncs
        for callfunc, _ in mv.callfuncs:
            if isinstance(callfunc.node, Getattr):
                if not callfunc.node.__class__.__name__.startswith('FakeGetattr'):  # XXX
                    paste(gx, source, callfunc.node.expr, nodetypestr(gx, callfunc, inode(gx, callfunc).parent, False, mv=mv), mv)
            else:
                paste(gx, source, callfunc.node, nodetypestr(gx, callfunc, inode(gx, callfunc).parent, False, mv=mv), mv)

        # --- higher-level crap (listcomps, returns, assignments, prints)
        for expr in merge:
            if isinstance(expr, ListComp):
                paste(gx, source, expr, nodetypestr(gx, expr, inode(gx, expr).parent, False, mv=mv), mv)
            elif isinstance(expr, Return):
                paste(gx, source, expr, nodetypestr(gx, expr.value, inode(gx, expr).parent, False, mv=mv), mv)
            elif isinstance(expr, (AssTuple, AssList)):
                paste(gx, source, expr, nodetypestr(gx, expr, inode(gx, expr).parent, False, mv=mv), mv)
            elif isinstance(expr, (Print, Printnl)):
                paste(gx, source, expr, ', '.join(nodetypestr(gx, child, inode(gx, child).parent, False, mv=mv) for child in expr.nodes), mv)

        # --- assignments
        for expr in merge:
            if isinstance(expr, Assign):
                pairs = assign_rec(expr.nodes[0], expr.expr)
                paste(gx, source, expr, ', '.join(nodetypestr(gx, r, inode(gx, r).parent, False, mv=mv) for (l, r) in pairs), mv)
            elif isinstance(expr, AugAssign):
                paste(gx, source, expr, nodetypestr(gx, expr.expr, inode(gx, expr).parent, False, mv=mv), mv)

        # --- output annotated file (skip if no write permission)
        try:
            out = open(module.filename[:-3] + '.ss.py', 'w')
            out.write(''.join(source))
            out.close()
        except IOError:
            pass
Beispiel #7
0
def singletype(gx, node, type):
    types = [t[0] for t in infer.inode(gx, node).types()]
    if len(types) == 1 and isinstance(types[0], type):
        return types[0]