[py-svn] r34659 - in py/dist/py/apigen/rest: . testing

guido at codespeak.net guido at codespeak.net
Thu Nov 16 12:30:16 CET 2006


Author: guido
Date: Thu Nov 16 12:30:12 2006
New Revision: 34659

Modified:
   py/dist/py/apigen/rest/genrest.py
   py/dist/py/apigen/rest/testing/test_rest.py
Log:
Displaying method origin (class where a method is defined) and base classes
(if known).


Modified: py/dist/py/apigen/rest/genrest.py
==============================================================================
--- py/dist/py/apigen/rest/genrest.py	(original)
+++ py/dist/py/apigen/rest/genrest.py	Thu Nov 16 12:30:12 2006
@@ -223,7 +223,7 @@
                     Title('index:', belowchar='=')]
             if classes:
                 rest.append(Title('classes:', belowchar='^'))
-                for cls, cfunclist in classes:
+                for cls, bases, cfunclist in classes:
                     linktarget = self.writer.getlink('class', cls,
                                                      'class_%s' % (cls,))
                     rest.append(ListItem(Link(cls, linktarget)))
@@ -243,12 +243,18 @@
     
     def build_classes(self, classes):
         ret = []
-        for cls, functions in classes:
+        for cls, bases, functions in classes:
             rest = [Title('class: %s' % (cls,), belowchar='='),
                     LiteralBlock(self.dsa.get_doc(cls))]
+            if bases:
+                rest.append(Title('base classes:', belowchar='^')),
+                for base in bases:
+                    linktarget = self.writer.getlink('class', base.name,
+                                                     'class_%s' % (base.name,))
+                    rest.append(ListItem(Link(base.name, linktarget)))
             if functions:
                 rest.append(Title('functions:', belowchar='^'))
-                for func in functions:
+                for (func, origin) in functions:
                     linktarget = self.writer.getlink('method',
                                                      '%s.%s' % (cls, func),
                                                      'method_%s.%s' % (cls,
@@ -262,9 +268,13 @@
     def build_functions(self, functions, parent='', methods=False):
         ret = []
         for function in functions:
+            origin = None
+            if methods:
+                function, origin = function
             if parent:
                 function = '%s.%s' % (parent, function)
-            rest, tbrest = self.write_function(function, ismethod=methods)
+            rest, tbrest = self.write_function(function, origin=origin,
+                                               ismethod=methods)
             ret.append((function, rest, tbrest))
         return ret
 
@@ -291,7 +301,8 @@
                     continue
             elif module != '':
                 continue
-            ret.append((name, self.get_method_list(name)))
+            bases = self.dsa.get_possible_base_classes(name)
+            ret.append((name, bases, self.get_method_list(name)))
         return ret
 
     def get_function_list(self, module=''):
@@ -308,7 +319,9 @@
         return ret
 
     def get_method_list(self, classname):
-        return self.dsa.get_class_methods(classname)
+        methodnames = self.dsa.get_class_methods(classname)
+        return [(mn, self.dsa.get_method_origin('%s.%s' % (classname, mn)))
+                for mn in methodnames]
 
     def process_type_link(self, _type):
         # now we do simple type dispatching and provide a link in this case
@@ -327,18 +340,28 @@
         lst.append(Link(str(_type), linktarget))
         return lst
 
-    def write_function(self, functionname, ismethod=False, belowchar='-'):
+    def write_function(self, functionname, origin=None, ismethod=False,
+                       belowchar='-'):
         # XXX I think the docstring should either be split on \n\n and cleaned
         # from indentation, or treated as ReST too (although this is obviously
         # dangerous for non-ReST docstrings)...
         if ismethod:
-            title = 'method: %s' % (functionname,)
+            title = Title('method: %s' % (functionname,), belowchar=belowchar)
         else:
-            title = 'function: %s' % (functionname,)
-        lst = [Title(title, belowchar=belowchar),
-               LiteralBlock(self.dsa.get_doc(functionname)),
+            title = Title('function: %s' % (functionname,),
+                          belowchar=belowchar)
+        lst = [title, LiteralBlock(self.dsa.get_doc(functionname)),
                LiteralBlock(self.dsa.get_function_definition(functionname))]
         
+        opar = Paragraph('origin: ')
+        if origin:
+            linktarget = self.writer.getlink('class', origin.name,
+                                             'class_%s' % (origin.name,))
+            opar.add(Link(origin.name, linktarget))
+        else:
+            opar.add(Text('<UNKNOWN>'))
+        lst.append(opar)
+
         lst.append(Paragraph("where:"))
         args, retval = self.dsa.get_function_signature(functionname)
         for name, _type in args + [('return value', retval)]:

Modified: py/dist/py/apigen/rest/testing/test_rest.py
==============================================================================
--- py/dist/py/apigen/rest/testing/test_rest.py	(original)
+++ py/dist/py/apigen/rest/testing/test_rest.py	Thu Nov 16 12:30:12 2006
@@ -272,6 +272,11 @@
         assert data.find('method\\: SomeClass.\\_\\_init\\_\\_') > -1
         assert data.find('method\\: SomeClass.\\_\\_init\\_\\_') < data.find(
                                                 'method\\: SomeClass.method')
+        # base class info
+        assert py.std.re.search(r'class\\\: SomeSubClass.*'
+                                r'base classes\\\:\n\^+[\n ]+\* `SomeClass`_.*'
+                                r'`SomeSubClass.__init__',
+                                data, py.std.re.S)
 
     def test_som_fun(self):
         descs = {'fun_': fun_}
@@ -334,15 +339,18 @@
         class A(object):
             def __init__(self, x):
                 pass
+
+            def a(self):
+                pass
         
-        class B(object):
+        class B(A):
             def __init__(self, y):
                 pass
         
         def xxx(x):
             return x
         
-        descs = {'A':A, 'B':B, 'xxx':xxx}
+        descs = {'A': A, 'B': B, 'xxx':xxx}
         ds = DocStorage().from_dict(descs)
         t = Tracer(ds)
         t.start_tracing()
@@ -353,11 +361,14 @@
         tempdir = temppath.ensure("classargs", dir=True)
         r = RestGen(ds, lg, DirWriter(tempdir))
         r.write()
-        source = tempdir.join("function_xxx.txt").open().read()
+        source = tempdir.join("function_xxx.txt").read()
         call_point = source.find("call sites\:")
         assert call_point != -1
-        assert source.find("x \:\: <Instance of AnyOf( `Class B`_ , "
-                           "`Class A`_ )>") < call_point
+        print source
+        assert -1 < source.find("x \:\: <Instance of AnyOf( `Class B`_ , "
+                                "`Class A`_ )>") < call_point
+        source = tempdir.join('method_B.a.txt').read()
+        assert source.find('origin\: `A`_') > -1
         self.check_rest(tempdir)
 
     def test_exc_raising(self):



More information about the pytest-commit mailing list