[pypy-svn] r17266 - in pypy/dist/pypy/translator: goal tool

ale at codespeak.net ale at codespeak.net
Tue Sep 6 11:53:06 CEST 2005


Author: ale
Date: Tue Sep  6 11:53:05 2005
New Revision: 17266

Added:
   pypy/dist/pypy/translator/goal/translate_pypy_new.py
      - copied, changed from r17255, pypy/dist/pypy/translator/goal/translate_pypy.py
   pypy/dist/pypy/translator/tool/pdbplus.py
   pypy/dist/pypy/translator/tool/util.py
Log:
Start of cleanup of translate_pypy.

Copied translate_pypy to translate_pypy_new inorder not to interfere with other work going on.

Moved the extensions of pdb to tool/pdbplus
Moved some helper functions to tool/util

Added: pypy/dist/pypy/translator/tool/pdbplus.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/tool/pdbplus.py	Tue Sep  6 11:53:05 2005
@@ -0,0 +1,342 @@
+import threading, pdb
+
+def run_debugger_in_thread(fn, args, cleanup=None, cleanup_args=()):
+    def _run_in_thread():
+        try:
+            try:
+                fn(*args)
+                pass # for debugger to land
+            except pdb.bdb.BdbQuit:
+                pass
+        finally:
+            if cleanup is not None:
+                cleanup(*cleanup_args)
+    return threading.Thread(target=_run_in_thread, args=())
+
+
+class PdbPlusShow(pdb.Pdb):
+
+    def post_mortem(self, t):
+        self.reset()
+        while t.tb_next is not None:
+            t = t.tb_next
+        self.interaction(t.tb_frame, t)        
+
+    show = None
+
+    def _show(self, page):
+        if not self.show:
+            print "*** No display"
+            return
+        self.show(page)
+
+    def _importobj(self, fullname):
+        obj = None
+        name = ''
+        for comp in fullname.split('.'):
+            name += comp
+            obj = getattr(obj, comp, None)
+            if obj is None:
+                try:
+                    obj = __import__(name, {}, {}, ['*'])
+                except ImportError:
+                    raise NameError
+            name += '.'
+        return obj
+
+    TRYPREFIXES = ['','pypy.','pypy.objspace.','pypy.interpreter.', 'pypy.objspace.std.' ]
+
+    def _mygetval(self, arg, errmsg):
+        try:
+            return eval(arg, self.curframe.f_globals,
+                    self.curframe.f_locals)
+        except:
+            t, v = sys.exc_info()[:2]
+            if isinstance(t, str):
+                exc_type_name = t
+            else: exc_type_name = t.__name__
+            if not isinstance(arg, str):
+                print '*** %s' % errmsg, "\t[%s: %s]" % (exc_type_name, v)
+            else:
+                print '*** %s:' % errmsg, arg, "\t[%s: %s]" % (exc_type_name, v)
+            raise
+
+    def _getobj(self, name):
+        if '.' in name:
+            for pfx in self.TRYPREFIXES:
+                try:
+                    return self._importobj(pfx+name)
+                except NameError:
+                    pass
+        try:
+            return self._mygetval(name, "Not found")
+        except (KeyboardInterrupt, SystemExit, MemoryError):
+            raise
+        except:
+            pass
+        return None
+
+    def do_find(self, arg):
+        """find obj [as var]
+find dotted named obj, possibly using prefixing with some packages 
+in pypy (see help pypyprefixes); the result is assigned to var or _."""
+        objarg, var = self._parse_modif(arg)
+        obj = self._getobj(objarg)
+        if obj is None:
+            return
+        print obj
+        self._setvar(var, obj)
+
+    def _parse_modif(self, arg, modif='as'):
+        var = '_'
+        aspos = arg.rfind(modif+' ')
+        if aspos != -1:
+            objarg = arg[:aspos].strip()
+            var = arg[aspos+(1+len(modif)):].strip()
+        else:
+            objarg = arg
+        return objarg, var
+
+    def _setvar(self, var, obj):
+        self.curframe.f_locals[var] = obj
+
+    class GiveUp(Exception):
+        pass
+
+    def _make_flt(self, expr):
+        try:
+            expr = compile(expr, '<filter>', 'eval')
+        except SyntaxError:
+            print "*** syntax: %s" % expr
+            return None
+        def flt(c):
+            marker = object()
+            try:
+                old = self.curframe.f_locals.get('cand', marker)
+                self.curframe.f_locals['cand'] = c
+                try:
+                    return self._mygetval(expr, "oops")
+                except (KeyboardInterrupt, SystemExit, MemoryError):
+                    raise
+                except:
+                    raise self.GiveUp
+            finally:
+                if old is not marker:
+                    self.curframe.f_locals['cand'] = old
+                else:
+                    del self.curframe.f_locals['cand']
+        return flt
+
+    def do_findclasses(self, arg):
+        """findclasses expr [as var]
+find annotated classes for which expr is true, cand in it referes to
+the candidate class; the result list is assigned to var or _."""
+        expr, var = self._parse_modif(arg)
+        flt = self._make_flt(expr)
+        if flt is None:
+            return
+        cls = []
+        try:
+            for c in t.annotator.getuserclasses():
+                if flt(c):
+                    cls.append(c)
+        except self.GiveUp:
+            return
+        self._setvar(var, cls)
+
+    def do_findfuncs(self, arg):
+        """findfuncs expr [as var]
+find flow-graphed functions for which expr is true, cand in it referes to
+the candidate function; the result list is assigned to var or _."""
+        expr, var = self._parse_modif(arg)
+        flt = self._make_flt(expr)
+        if flt is None:
+            return
+        funcs = []
+        try:
+            for f in t.flowgraphs:
+                if flt(f):
+                    funcs.append(f)
+        except self.GiveUp:
+            return
+        self._setvar(var, funcs)
+
+    def do_showg(self, arg):
+        """showg obj
+show graph for obj, obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes)).
+if obj is a function or method, the localized call graph is shown;
+if obj is a class or ClassDef the class definition graph is shown"""            
+        from pypy.annotation.classdef import ClassDef
+        from pypy.translator.tool import graphpage            
+        obj = self._getobj(arg)
+        if obj is None:
+            return
+        if hasattr(obj, 'im_func'):
+            obj = obj.im_func
+        if obj in t.flowgraphs:
+            page = graphpage.LocalizedCallGraphPage(t, obj)
+        elif obj in getattr(t.annotator, 'getuserclasses', lambda: {})():
+            page = graphpage.ClassDefPage(t, t.annotator.getuserclasses()[obj])
+        elif isinstance(obj, ClassDef):
+            page = graphpage.ClassDefPage(t, obj)
+        else:
+            print "*** Nothing to do"
+            return
+        self._show(page)
+
+    def _attrs(self, arg, pr):
+        arg, expr = self._parse_modif(arg, 'match')
+        if expr == '_':
+            expr = 'True'
+        obj = self._getobj(arg)
+        if obj is None:
+            return
+        import types
+        if isinstance(obj, (type, types.ClassType)):
+            obj = [obj]
+        else:
+            obj = list(obj)
+        def longname(c):
+            return "%s.%s" % (c.__module__, c.__name__) 
+        obj.sort(lambda x,y: cmp(longname(x), longname(y)))
+        cls = t.annotator.getuserclasses()
+        flt = self._make_flt(expr)
+        if flt is None:
+            return
+        for c in obj:
+            if c in cls:
+                try:
+                    attrs = [a for a in cls[c].attrs.itervalues() if flt(a)]
+                except self.GiveUp:
+                    return
+                if attrs:
+                    print "%s:" % longname(c)
+                    pr(attrs)
+
+    def do_attrs(self, arg):
+        """attrs obj [match expr]
+list annotated attrs of class obj or list of classes obj,
+obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes));
+expr is an optional filtering expression; cand in it refer to the candidate Attribute
+information object, which has a .name and .s_value."""
+        def pr(attrs):
+            print " " + ' '.join([a.name for a in attrs])
+        self._attrs(arg, pr)
+
+    def do_attrsann(self, arg):
+        """attrsann obj [match expr]
+list with their annotation annotated attrs of class obj or list of classes obj,
+obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes));
+expr is an optional filtering expression; cand in it refer to the candidate Attribute
+information object, which has a .name and .s_value."""
+        def pr(attrs):
+            for a in attrs:
+                print ' %s %s' % (a.name, a.s_value)
+        self._attrs(arg, pr)
+
+    def do_readpos(self, arg):
+        """readpos obj attrname [match expr] [as var]
+list the read positions of annotated attr with attrname of class obj,
+obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes));
+expr is an optional filtering expression; cand in it refer to the candidate read
+position information, which has a .func and .block and .i;
+the list of the read positions functions is set to var or _."""
+        class Pos:
+            def __init__(self, func, block, i):
+                self.func = func
+                self.block = block
+                self.i = i
+        arg, var = self._parse_modif(arg, 'as')
+        arg, expr = self._parse_modif(arg, 'match')
+        if expr == '_':
+            expr = 'True'
+        args = arg.split()
+        if len(args) != 2:
+            print "*** expected obj attrname:", arg
+            return
+        arg, attrname = args
+        # allow quotes around attrname
+        if (attrname.startswith("'") and attrname.endswith("'")
+            or attrname.startswith('"') and attrname.endswith('"')):
+            attrname = attrname[1:-1]
+
+        obj = self._getobj(arg)
+        if obj is None:
+            return
+        cls = t.annotator.getuserclasses()
+        if obj not in cls:
+            return
+        attrs = cls[obj].attrs
+        if attrname not in attrs:
+            print "*** bogus:", attrname
+            return
+        pos = attrs[attrname].read_locations
+        if not pos:
+            return
+        flt = self._make_flt(expr)
+        if flt is None:
+            return
+        r = {}
+        try:
+            for p in pos:
+                func, block, i = p
+                if flt(Pos(func, block, i)):
+                    print func.__module__ or '?', func.__name__, block, i
+                    r[func] = True
+        except self.GiveUp:
+            return
+        self._setvar(var, r.keys())
+            
+
+    def do_flowg(self, arg):
+        """callg obj
+show flow graph for function obj, obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes))"""            
+        import types
+        from pypy.translator.tool import graphpage                        
+        obj = self._getobj(arg)
+        if obj is None:
+            return
+        if hasattr(obj, 'im_func'):
+            obj = obj.im_func
+        if not isinstance(obj, types.FunctionType):
+            print "*** Not a function"
+            return
+        self._show(graphpage.FlowGraphPage(t, [obj]))
+
+    def do_callg(self, arg):
+        """callg obj
+show localized call-graph for function obj, obj can be an expression or a dotted name
+(in which case prefixing with some packages in pypy is tried (see help pypyprefixes))"""
+        import types
+        from pypy.translator.tool import graphpage                        
+        obj = self._getobj(arg)
+        if obj is None:
+            return
+        if hasattr(obj, 'im_func'):
+            obj = obj.im_func
+        if not isinstance(obj, types.FunctionType):
+            print "*** Not a function"
+            return
+        self._show(graphpage.LocalizedCallGraphPage(t, obj))
+
+    def do_classhier(self, arg):
+        """classhier
+show class hierarchy graph"""
+        from pypy.translator.tool import graphpage           
+        self._show(graphpage.ClassHierarchyPage(t))
+
+    def help_graphs(self):
+        print "graph commands are: showg, flowg, callg, classhier"
+
+    def help_ann_other(self):
+        print "other annotation related commands are: find, findclasses, findfuncs, attrs, attrsann, readpos"
+
+    def help_pypyprefixes(self):
+        print "these prefixes are tried for dotted names in graph commands:"
+        print self.TRYPREFIXES
+

Added: pypy/dist/pypy/translator/tool/util.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/tool/util.py	Tue Sep  6 11:53:05 2005
@@ -0,0 +1,96 @@
+from pypy.annotation.model import SomeObject
+
+def sanity_check_exceptblocks(translator):
+    annotator = translator.annotator
+    irreg = 0
+    for graph in translator.flowgraphs.itervalues():
+        et, ev = graph.exceptblock.inputargs
+        s_et = annotator.binding(et, extquery=True)
+        s_ev = annotator.binding(ev, extquery=True)
+        if s_et:
+            if s_et.knowntype == type:
+                if s_et.__class__ == SomeObject:
+                    if hasattr(s_et, 'is_type_of') and  s_et.is_type_of == [ev]:
+                        continue
+                else:
+                    if s_et.__class__ == annmodel.SomePBC:
+                        continue
+            print "*****", graph.name, "exceptblock is not completely sane"
+            irreg += 1
+    if irreg == 0:
+        print "*** All exceptblocks seem sane."
+
+def find_someobjects(translator, quiet=False):
+    """Find all functions in that have SomeObject in their signature."""
+    annotator = translator.annotator
+    if not annotator:
+        return # no annotations available
+
+    translator.highlight_functions = {}
+
+    def is_someobject(var):
+        try:
+            return annotator.binding(var).__class__ == SomeObject
+        except KeyError:
+            return False
+
+    def short_binding(var):
+        try:
+            binding = annotator.binding(var)
+        except KeyError:
+            return "?"
+        if binding.is_constant():
+            return 'const %s' % binding.__class__.__name__
+        else:
+            return binding.__class__.__name__
+
+    header = True
+    items = [(graph.name, func, graph)
+             for func, graph in translator.flowgraphs.items()]
+    items.sort()
+    num = someobjnum = 0
+    for graphname, func, graph in items:
+        unknown_input_args = len(filter(is_someobject, graph.getargs()))
+        unknown_return_value = is_someobject(graph.getreturnvar())
+        if unknown_input_args or unknown_return_value:
+            someobjnum += 1
+            translator.highlight_functions[func] = True
+            if not quiet:
+                if header:
+                    header = False
+                    print "=" * 70
+                    print "Functions that have SomeObject in their signature"
+                    print "=" * 70
+                print ("%(name)s(%(args)s) -> %(result)s\n"
+                       "%(filename)s:%(lineno)s\n"
+                       % {'name': graph.name,
+                          'filename': func.func_globals.get('__name__', '?'),
+                          'lineno': func.func_code.co_firstlineno,
+                          'args': ', '.join(map(short_binding,
+                                                graph.getargs())),
+                          'result': short_binding(graph.getreturnvar())})
+        num += 1
+    if not quiet:
+        print "=" * 70
+        percent = int(num and (100.0*someobjnum / num) or 0)
+        print "someobjectness: %2d percent" % (percent)
+        print "(%d out of %d functions get or return SomeObjects" % (
+            someobjnum, num) 
+        print "=" * 70
+
+def worstblocks_topten(ann, n=10):
+    h = [(count, block) for block, count in ann.reflowcounter.iteritems()]
+    h.sort()
+    if not h:
+        return
+    print
+    ansi_print(',-----------------------  Top %d Most Reflown Blocks  -----------------------.' % n, 36)
+    for i in range(n):
+        if not h:
+            break
+        count, block = h.pop()
+        ansi_print('                                                      #%3d: reflown %d times  |' % (i+1, count), 36)
+        about(block)
+    ansi_print("`----------------------------------------------------------------------------'", 36)
+    print
+



More information about the Pypy-commit mailing list