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
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)
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)
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]
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
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