[py-svn] r32907 - in py/branch/apigen/py/test/tracer: . testing

fijal at codespeak.net fijal at codespeak.net
Thu Oct 5 13:57:03 CEST 2006


Author: fijal
Date: Thu Oct  5 13:56:38 2006
New Revision: 32907

Added:
   py/branch/apigen/py/test/tracer/docstorage.py   (contents, props changed)
Modified:
   py/branch/apigen/py/test/tracer/description.py
   py/branch/apigen/py/test/tracer/testing/test_docgen.py
   py/branch/apigen/py/test/tracer/tracer.py
Log:
A little bit refactoring, added (untested) accessor, added call_site


Modified: py/branch/apigen/py/test/tracer/description.py
==============================================================================
--- py/branch/apigen/py/test/tracer/description.py	(original)
+++ py/branch/apigen/py/test/tracer/description.py	Thu Oct  5 13:56:38 2006
@@ -2,6 +2,12 @@
 from pypy.annotation.description import FunctionDesc
 from pypy.annotation.model import unionof
 
+class CallSite(object):
+    def __init__(self, filename, lineno, source):
+        self.filename = filename
+        self.lineno = lineno
+        self.source = source
+
 #class __extend__(FunctionDesc):
 def consider_call(self, inputcells):
     if not hasattr(self, 'inputcells'):
@@ -10,4 +16,10 @@
     for cell_num, cell in enumerate(inputcells):
         self.inputcells[cell_num] = unionof(cell, self.inputcells[cell_num])
 
+def consider_call_site(self, frame):
+    if not hasattr(self, 'call_sites'):
+        self.call_sites = []
+    self.call_sites.append(CallSite(frame.code.raw.co_filename, frame.lineno+1, str(frame.statement)))
+
 FunctionDesc.consider_call = consider_call
+FunctionDesc.consider_call_site = consider_call_site

Added: py/branch/apigen/py/test/tracer/docstorage.py
==============================================================================
--- (empty file)
+++ py/branch/apigen/py/test/tracer/docstorage.py	Thu Oct  5 13:56:38 2006
@@ -0,0 +1,77 @@
+
+""" This module is keeping track about API informations as well as
+providing some interface to easily access stored data
+"""
+
+import py
+import sys
+
+from pypy.annotation.bookkeeper import Bookkeeper
+from pypy.annotation.policy import AnnotatorPolicy
+
+class DummyAnnotator(object):
+    policy = AnnotatorPolicy()
+
+class DocStorage(object):
+    """ Class storing info about API
+    """
+    def __init__(self):
+        self.bookkeeper = Bookkeeper(DummyAnnotator())
+        #self.call_stack = []
+    
+    def consider_call(self, frame, caller_frame):
+        assert isinstance(frame, py.code.Frame)
+        desc = self.find_desc(frame)
+        if desc:
+            self.generalize_args(desc, frame)
+            desc.consider_call_site(caller_frame)
+    
+    def generalize_args(self, desc, frame):
+        args = [arg for key, arg in frame.getargs()]
+        #self.call_stack.append((desc, args))
+        desc.consider_call([self.bookkeeper.immutablevalue(arg) for arg in args])
+
+    def consider_return(self, frame, arg):
+        pass
+
+    def find_desc(self, frame):
+        for desc in self.descs.values():
+            if desc.pyobj.func_code is frame.code.raw:
+                return desc
+        return None
+    
+    def from_dict(self, _dict):
+        self.descs = dict([self.make_desc(key, val) for key, val in _dict.iteritems()])
+        return self
+    
+    def make_desc(self, key, value):
+        desc = self.bookkeeper.getdesc(value)
+        return (key, desc)
+    
+    def from_pkg(self, module):
+        self.from_dict(module.__package__.__dict__)
+        return self
+
+class DocStorageAccessor(object):
+    """ Set of helper functions to access DocStorage, separated in different
+    class to keep abstraction
+    """
+    def __init__(self, ds):
+        self.ds = ds
+
+    def get_names(self):
+        # get iterator over all API exposed names
+        return self.ds.descs.iterkeys()
+    
+    def get_function(self, name):
+        return self.ds.descs[name].pyobj
+    
+    def get_function_doc(self, name):
+        return self.ds.descs[name].pyobj.__doc__ or "*Not documented*"
+    
+    def get_function_args(self, name):
+        return self.ds.descs[name].inputcells
+
+    def get_function_callpoints(self, name):
+        # return list of tuple (filename, fileline, line)
+        return self.ds.descs[name].call_sites

Modified: py/branch/apigen/py/test/tracer/testing/test_docgen.py
==============================================================================
--- py/branch/apigen/py/test/tracer/testing/test_docgen.py	(original)
+++ py/branch/apigen/py/test/tracer/testing/test_docgen.py	Thu Oct  5 13:56:38 2006
@@ -13,6 +13,7 @@
 #    sys.path.insert(0, str(data_path))
 
 def fun(a, b, c):
+    "Some docstring"
     return "d"
 
 def test_basic():
@@ -23,8 +24,15 @@
     fun(1, ("g", 3), 8)
     fun(2., ("a", 1.), "a")
     t.end_tracing()
-    inputcells = ds.descs['fun'].inputcells
+    desc = ds.descs['fun']
+    inputcells = desc.inputcells
     assert len(inputcells) == 3
     assert isinstance(inputcells[0], model.SomeFloat)
     assert isinstance(inputcells[1], model.SomeTuple)
     assert isinstance(inputcells[2], model.SomeObject)
+    cs = desc.call_sites
+    assert len(cs) == 2
+    assert cs[0].filename == __file__
+    assert cs[0].lineno == test_basic.func_code.co_firstlineno + 5
+    assert cs[1].filename == __file__
+    assert cs[1].lineno == test_basic.func_code.co_firstlineno + 6

Modified: py/branch/apigen/py/test/tracer/tracer.py
==============================================================================
--- py/branch/apigen/py/test/tracer/tracer.py	(original)
+++ py/branch/apigen/py/test/tracer/tracer.py	Thu Oct  5 13:56:38 2006
@@ -10,55 +10,12 @@
 # from pypy's code.
 # BLAH BLAH BLAH
 
-from pypy.annotation.bookkeeper import Bookkeeper
-from pypy.annotation.policy import AnnotatorPolicy
 from py.__.test.tracer.description import FunctionDesc
-
-class DummyAnnotator(object):
-    policy = AnnotatorPolicy()
+from py.__.test.tracer.docstorage import DocStorage
 
 class UnionError(Exception):
     pass
 
-class DocStorage(object):
-    """ Class storing info about API
-    """
-    def __init__(self):
-        self.bookkeeper = Bookkeeper(DummyAnnotator())
-        #self.call_stack = []
-    
-    def consider_call(self, frame):
-        assert isinstance(frame, py.code.Frame)
-        desc = self.find_desc(frame)
-        if desc:
-            self.generalize_args(desc, frame)
-    
-    def generalize_args(self, desc, frame):
-        args = [arg for key, arg in frame.getargs()]
-        #self.call_stack.append((desc, args))
-        desc.consider_call([self.bookkeeper.immutablevalue(arg) for arg in args])
-
-    def consider_return(self, frame, arg):
-        pass
-
-    def find_desc(self, frame):
-        for desc in self.descs.values():
-            if desc.pyobj.func_code is frame.code.raw:
-                return desc
-        return None
-    
-    def from_dict(self, _dict):
-        self.descs = dict([self.make_desc(key, val) for key, val in _dict.iteritems()])
-        return self
-    
-    def make_desc(self, key, value):
-        desc = self.bookkeeper.getdesc(value)
-        return (key, desc)
-    
-    def from_pkg(self, module):
-        self.from_dict(module.__package__.__dict__)
-        return self
-
 class Tracer(object):
     """ Basic tracer object, used for gathering additional info
     about API functions
@@ -72,7 +29,7 @@
         frame = py.code.Frame(frame)
         if event == 'call':
             assert arg is None
-            self.docstorage.consider_call(frame)
+            self.docstorage.consider_call(frame, py.code.Frame(sys._getframe(2)))
         elif event == 'return':
             self.docstorage.consider_return(frame, arg)
         


More information about the py-svn mailing list