[pypy-svn] r17254 - pypy/dist/pypy/translator/goal

pedronis at codespeak.net pedronis at codespeak.net
Tue Sep 6 00:34:32 CEST 2005


Author: pedronis
Date: Tue Sep  6 00:34:30 2005
New Revision: 17254

Modified:
   pypy/dist/pypy/translator/goal/translate_pypy.py
Log:
some more convenience commands in translate_pypy to give fast access to the common producedures used
when tracking annotation problems:

help ann_other ->
"other annotation related commands are: find, findclasses, findfuncs, attrs, attrsann, readpos"

summarized:

find object using pypy prefixes
find(annotated)classes meeting some criteria
find(flow-graphed)func(tion)s meeting some criteria

find command store results in a variable given with "as var" modifier or _.

attrs: list annotated class(es) atttributes, possibly filtering with some criteria
attrsann: same, print annotation s_value too

readpos: read locations for a annotated class, attrname pair, possibly filtering

result as a list of functions containing read locs is stored in "as var" or _. 

examples:

# assuming we have annotated astbuilder, find the annotation for .nodes attributes for Node subclasses that have such a thing
# first retrieve Node with prefixes (just a convenience):

find astcompiler.ast.Node as N
findclasses issubclass(cand, N)
attrsann _ match cand.name == 'nodes'

# read locations for TokenObject name, just functions starting with 'build_'

readpos pyparser.astbuilder.TokenObject name match cand.func.__name__.startswith('build_')




Modified: pypy/dist/pypy/translator/goal/translate_pypy.py
==============================================================================
--- pypy/dist/pypy/translator/goal/translate_pypy.py	(original)
+++ pypy/dist/pypy/translator/goal/translate_pypy.py	Tue Sep  6 00:34:30 2005
@@ -453,6 +453,21 @@
 
         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:
@@ -461,11 +476,98 @@
                     except NameError:
                         pass
             try:
-                return self._getval(name)
-            except (NameError, AttributeError, LookupError):
-                print "*** Not found:", name
+                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
@@ -490,6 +592,108 @@
                 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
+            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
@@ -531,6 +735,9 @@
         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



More information about the Pypy-commit mailing list