[py-svn] r33703 - in py/dist/py/apigen/rest: . testing
guido at codespeak.net
guido at codespeak.net
Wed Oct 25 01:24:05 CEST 2006
Author: guido
Date: Wed Oct 25 01:24:04 2006
New Revision: 33703
Added:
py/dist/py/apigen/rest/testing/somemodule.py
py/dist/py/apigen/rest/testing/someothermodule.py
Modified:
py/dist/py/apigen/rest/genrest.py
py/dist/py/apigen/rest/testing/test_rest.py
Log:
Re-written the GenRest class, it's a bit cleaner now (but still quite a chunk
unfortunately), don't replace dots in file names anymore (since that may
cause name clashes), fixed underscore escaping.
Modified: py/dist/py/apigen/rest/genrest.py
==============================================================================
--- py/dist/py/apigen/rest/genrest.py (original)
+++ py/dist/py/apigen/rest/genrest.py Wed Oct 25 01:24:04 2006
@@ -108,99 +108,188 @@
class RestGen(object):
def __init__(self, ds, linkgen, writer=PipeWriter()):
- #assert isinstance(linkgen, DirectPaste), "Cannot use different linkgen by now"
+ #assert isinstance(linkgen, DirectPaste), (
+ # "Cannot use different linkgen by now")
self.dsa = DocStorageAccessor(ds)
self.linkgen = linkgen
self.writer = writer
-
+
def write(self):
"""write the data to the writer"""
- # note that this builds up a list of Rest elements for the index as
- # 'side effect', the list is passed along and filled, while the actual
- # sections (also ReST elements) are returned by the write_* methods
- # XXX this is quite icky! would be nice to have refactored
- indexlst = [Title("Module: %s" % self.dsa.get_module_name(),
- belowchar="="),
- Paragraph(self.dsa.get_module_info()),
- Title("Exported functions:", belowchar="-")]
- funclst = self.write_function_list(indexlst)
- indexlst.append(Title("Exported classes:", belowchar="-"))
- classlst = self.write_class_list(indexlst)
- self.writer.write_section('index', Rest(*indexlst).text())
- for sectionname, restitems in funclst:
- self.writer.write_section(sectionname, Rest(*restitems).text())
- for sectionname, classdata in classlst:
- restitems, classfunclst = classdata
- self.writer.write_section(sectionname, Rest(*restitems).text())
- for fsectionname, frestitems in classfunclst:
- self.writer.write_section(fsectionname,
- Rest(*frestitems).text())
-
- def write_function_list(self, indexlst):
- retlst = []
- for name in self.dsa.get_function_names():
- sectionname = 'function_%s' % (name,)
- linktarget = self.writer.getlink('function', name,
- sectionname)
- indexlst.append(ListItem(Text("Function: "),
- Link(name, linktarget)))
- retlst.append((sectionname,
- self.write_function(sectionname, name)))
- return retlst
+ modlist = self.get_module_list()
+ classlist = self.get_class_list(module='')
+ funclist = self.get_function_list()
+
+ indexrest = self.build_index([t[0] for t in modlist],
+ [t[0] for t in classlist],
+ funclist)
+ self.writer.write_section('index', Rest(*indexrest).text())
+
+ self.build_modrest(modlist)
+ self.build_funcrest(funclist)
+ self.build_classrest(classlist)
+
+ def build_modrest(self, modlist):
+ modrest = self.build_modules(modlist)
+ for name, rest, classlist, funclist in modrest:
+ self.writer.write_section('module_%s' % (name,),
+ Rest(*rest).text())
+ for cname, crest, cfunclist in classlist:
+ self.writer.write_section('class_%s' % (cname,),
+ Rest(*crest).text())
+ for fname, frest in cfunclist:
+ self.writer.write_section('method_%s' % (fname,),
+ Rest(*frest).text())
+ for fname, frest in funclist:
+ self.writer.write_section('function_%s' % (fname,),
+ Rest(*frest).text())
- def write_class_list(self, indexlst):
- retlst = []
- for name in self.dsa.get_class_names():
- sectionname = 'class_%s' % (name,)
- linktarget = self.writer.getlink('class', name, sectionname)
- indexlst.append(ListItem(Text("Class: "), Link(name, linktarget)))
- retlst.append((sectionname, self.write_class(sectionname, name)))
- return retlst
+ def build_classrest(self, classlist):
+ classrest = self.build_classes(classlist)
+ for cname, rest, cfunclist in classrest:
+ self.writer.write_section('class_%s' % (cname,),
+ Rest(*rest).text())
+ for fname, rest in cfunclist:
+ self.writer.write_section('method_%s' % (fname,),
+ Rest(*rest).text())
+
+ def build_funcrest(self, funclist):
+ funcrest = self.build_functions(funclist)
+ for fname, rest in funcrest:
+ self.writer.write_section('function_%s' % (fname,),
+ Rest(*rest).text())
+
+ def build_index(self, modules, classes, functions):
+ rest = [Title('Index', abovechar='=', belowchar='=')]
+ rest.append(Title('Exported modules:', belowchar='='))
+ for module in modules:
+ linktarget = self.writer.getlink('module', module,
+ 'module_%s' % (module,))
+ rest.append(ListItem(Link(module, linktarget)))
+ rest.append(Title('Exported classes:', belowchar='='))
+ for cls in classes:
+ linktarget = self.writer.getlink('class', cls, 'class_%s' % (cls,))
+ rest.append(ListItem(Link(cls, linktarget)))
+ rest.append(Title('Exported functions:', belowchar='='))
+ for func in functions:
+ linktarget = self.writer.getlink('function', func,
+ 'function_%s' % (func,))
+ rest.append(ListItem(Link(func, linktarget)))
+ return rest
+
+ def build_modules(self, modules):
+ ret = []
+ for module, classes, functions in modules:
+ rest = [Title('Module: %s' % (module,), belowchar='-')]
+ rest.append(Title('Classes:', belowchar='^'))
+ for cls, cfunclist in classes:
+ linktarget = self.writer.getlink('class', cls,
+ 'class_%s' % (cls,))
+ rest.append(ListItem(Link(cls, linktarget)))
+ classrest = self.build_classes(classes)
+ rest.append(Title('Functions:', belowchar='^'))
+ for func in functions:
+ linktarget = self.writer.getlink('function',
+ '%s.%s' % (module, func),
+ 'function_%s.%s' % (module,
+ func))
+ rest.append(ListItem(Link(func, linktarget)))
+ funcrest = self.build_functions(functions, module)
+ ret.append((module, rest, classrest, funcrest))
+ return ret
- def write_class(self, section_name, class_name):
- classlst = [Title("Class: %s" % class_name, belowchar='-'),
- LiteralBlock(self.dsa.get_function_doc(class_name))]
-
- # write down exported methods
- classlst.append(Title("Exported methods:", belowchar="^"))
- funclist = []
- for method in self.dsa.get_class_methods(class_name):
- sectionname = 'method_%s_%s' % (class_name, method)
- linktext = '%s.%s' % (class_name, method)
- linktarget = self.writer.getlink('function', linktext,
- sectionname)
- classlst.append(ListItem(Link(linktext, linktarget)))
- # XXX assuming a function is always part of a class section
- funclist.append((sectionname,
- self.write_function(sectionname,
- class_name + "." + method,
- '^')))
- return classlst, funclist
+ def build_classes(self, classes):
+ ret = []
+ for cls, functions in classes:
+ rest = [Title('Class: %s' % (cls,), belowchar='-'),
+ Title('Functions:', belowchar='^')]
+ for func in functions:
+ linktarget = self.writer.getlink('method',
+ '%s.%s' % (cls, func),
+ 'method_%s.%s' % (cls, func))
+ rest.append(ListItem(Link(func, linktarget)))
+ funcrest = self.build_functions(functions, cls)
+ ret.append((cls, rest, funcrest))
+ return ret
- def write_function(self, section_name, fun_name, belowchar='-'):
+ def build_functions(self, functions, parent=''):
+ ret = []
+ for function in functions:
+ if parent:
+ function = '%s.%s' % (parent, function)
+ rest = self.write_function(function)
+ ret.append((function, rest))
+ return ret
+
+ def get_module_list(self):
+ visited = []
+ ret = []
+ for name in self.dsa.get_class_names():
+ if '.' in name:
+ module, classname = name.rsplit('.', 1)
+ if module in visited:
+ continue
+ visited.append(module)
+ ret.append((module, self.get_class_list(module),
+ self.get_function_list(module)))
+ return ret
+
+ def get_class_list(self, module):
+ ret = []
+ for name in self.dsa.get_class_names():
+ classname = name
+ if '.' in name:
+ classmodule, classname = name.rsplit('.', 1)
+ if classmodule != module:
+ continue
+ elif module != '':
+ continue
+ print 'retrieving method list for', name
+ print 'method list:', self.get_method_list(name)
+ ret.append((name, self.get_method_list(name)))
+ return ret
+
+ def get_function_list(self, module=''):
+ ret = []
+ for name in self.dsa.get_function_names():
+ funcname = name
+ if '.' in name:
+ funcpath, funcname = name.rsplit('.', 1)
+ if funcpath != module:
+ continue
+ elif module != '':
+ continue
+ ret.append(funcname)
+ return ret
+
+ def get_method_list(self, classname):
+ return self.dsa.get_class_methods(classname)
+
+ def write_function(self, functionname, 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)...
- lst = [Title("Function: %s" % fun_name, belowchar=belowchar),
- LiteralBlock(self.dsa.get_function_doc(fun_name)),
- LiteralBlock(self.dsa.get_function_definition(fun_name))]
+ lst = [Title("Function: %s" % (functionname,), belowchar=belowchar),
+ LiteralBlock(self.dsa.get_function_doc(functionname)),
+ LiteralBlock(self.dsa.get_function_definition(functionname))]
- args, retval = self.dsa.get_function_signature(fun_name)
- arg_str = "\n".join(["%s :: %s" % (str(name), str(type)) for name, type in args])
+ args, retval = self.dsa.get_function_signature(functionname)
+ arg_str = "\n".join(["%s :: %s" % (str(name), str(type))
+ for name, type in args])
arg_str += "\n" + "Return value :: %s" % str(retval)
lst.append(Paragraph("where:"))
lst.append(LiteralBlock(arg_str))
# XXX missing implementation of dsa.get_function_location()
- #filename, lineno = self.dsa.get_function_location(fun_name)
+ #filename, lineno = self.dsa.get_function_location(functionname)
#linkname, linktarget = self.linkgen.getlink(filename, lineno)
#if linktarget:
# lst.append(Paragraph("Function source: ",
# Link(linkname, linktarget)))
#else:
lst.append(Paragraph('Function source:'))
- lst.append(LiteralBlock(self.dsa.get_function_source(fun_name)))
+ lst.append(LiteralBlock(self.dsa.get_function_source(functionname)))
#arg_str = "(%s)" % (",".join([str(i) for i in args]))
#ret_str = str(retval)
@@ -213,7 +302,7 @@
lst.append(call_site_title)
call_sites = lst
- for call_site, frame in self.dsa.get_function_callpoints(fun_name):
+ for call_site, frame in self.dsa.get_function_callpoints(functionname):
link_str = "File %s:%s" % (call_site.filename,
call_site.lineno)
link_str, link_target = self.linkgen.getlink(call_site.filename,
@@ -230,7 +319,7 @@
except KeyboardInterrupt, SystemError:
raise
except:
- source = ["*Cannot get source*"]
+ source = "*Cannot get source*"
lines = []
for num, line in enumerate(source):
if num == call_site.lineno - frame.code.firstlineno - 1:
Added: py/dist/py/apigen/rest/testing/somemodule.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/rest/testing/somemodule.py Wed Oct 25 01:24:04 2006
@@ -0,0 +1,10 @@
+class SomeClass(object):
+ """Some class definition"""
+
+ def __init__(self, a):
+ self.a = a
+
+ def method(self, a, b, c):
+ """method docstring"""
+ return a + b + c
+
Added: py/dist/py/apigen/rest/testing/someothermodule.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/rest/testing/someothermodule.py Wed Oct 25 01:24:04 2006
@@ -0,0 +1,21 @@
+from somemodule import SomeClass
+
+class SomeSubClass(SomeClass):
+ """Some subclass definition"""
+
+def fun(a, b, c):
+ """Some docstring
+
+ Let's make it span a couple of lines to be interesting...
+
+ Note:
+
+ * rest
+ * should
+ * be
+ * supported
+ * or
+ * ignored...
+ """
+ return "d"
+
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 Wed Oct 25 01:24:04 2006
@@ -133,6 +133,25 @@
fun(1, 3, s2)
t.end_tracing()
return ds
+
+ def get_filled_docstorage_modules(self):
+ import somemodule
+ import someothermodule
+ descs = {
+ 'somemodule.SomeClass': somemodule,
+ 'someothermodule.SomeOtherClass': someothermodule,
+ 'someothermodule.fun': someothermodule.fun,
+ }
+ ds = DocStorage().from_dict(descs)
+ t = Tracer(ds)
+ t.start_tracing()
+ s1 = somemodule.SomeClass("a")
+ someothermodule.fun(1, 2, s1)
+ s2 = someothermodule.SomeSubClass("b")
+ s2.method(1, 2, 3)
+ someothermodule.fun(1, 3, s2)
+ t.end_tracing()
+ return ds
def check_rest(self, tempdir):
from py.__.misc import rest
@@ -151,14 +170,36 @@
'class_SomeSubClass.txt',
'function_fun.txt',
'index.txt',
- 'method_SomeClass___init__.txt',
- 'method_SomeClass_method.txt',
- 'method_SomeSubClass___init__.txt',
- 'method_SomeSubClass_method.txt',
+ 'method_SomeClass.__init__.txt',
+ 'method_SomeClass.method.txt',
+ 'method_SomeSubClass.__init__.txt',
+ 'method_SomeSubClass.method.txt',
]
# now we check out...
self.check_rest(tempdir)
+ def test_generation_modules(self):
+ py.test.skip('borken - fijal, somehow the methods for classes in '
+ 'modules don\'t get picked up... any idea?')
+ ds = self.get_filled_docstorage_modules()
+ lg = DirectPaste()
+ tempdir = temppath.ensure('module_api', dir=True)
+ r = RestGen(ds, lg, DirWriter(tempdir))
+ r.write()
+ basenames = [p.basename for p in tempdir.listdir('*.txt')]
+ assert sorted(basenames) == [
+ 'class_somemodule.SomeClass.txt',
+ 'class_someothermodule.SomeOtherClass.txt',
+ 'function_someothermodule.fun.txt',
+ 'index.txt',
+ 'method_somemodule.SomeClass.__init__.txt',
+ 'method_somemodule.SomeClass.method.txt',
+ 'method_somemodule.SomeSubClass.__init__.txt',
+ 'method_somemodule.SomeSubClass.method.txt',
+ 'module_somemodule.txt',
+ 'module_someothermodule.txt',
+ ]
+
def test_check_internal_links(self):
ds = self.get_filled_docstorage()
lg = DirectFS()
@@ -185,7 +226,6 @@
if not tempfile.check():
py.test.skip('depends on previous test, which failed')
data = tempfile.read()
- print data
# index should be above the rest
assert data.find('Exported classes\\:') > -1
assert data.find('Exported classes\\:') < data.find('Function\\: fun')
@@ -197,13 +237,11 @@
assert data.find('Class\\: SomeClass') < data.find(
'Function\\: SomeClass.method')
# __init__ should be above other methods
- assert data.find('Function\\: SomeClass.__init__') > -1
- # XXX in the future...
- # assert data.find('Function: SomeClass.__init__') < data.find(
- # 'Function: SomeClass.method')
+ assert data.find('Function\\: SomeClass.\\_\\_init\\_\\_') > -1
+ assert data.find('Function\\: SomeClass.\\_\\_init\\_\\_') < data.find(
+ 'Function\\: SomeClass.method')
def test_som_fun(self):
- py.test.skip("Failing")
descs = {'fun_':fun_}
ds = DocStorage().from_dict(descs)
t = Tracer(ds)
@@ -232,7 +270,7 @@
tempdir = temppath.ensure("function_source", dir=True)
r = RestGen(ds, lg, DirWriter(tempdir))
r.write()
- assert tempdir.join("function_blah.txt").open().read().find("a = 3") != -1
+ assert tempdir.join("function_blah.txt").read().find("a = 3") != -1
self.check_rest(tempdir)
def test_function_arguments(self):
@@ -252,7 +290,7 @@
tempdir = temppath.ensure("function_args", dir=True)
r = RestGen(ds, lg, DirWriter(tempdir))
r.write()
- source = tempdir.join("function_blah.txt").open().read()
+ source = tempdir.join("function_blah.txt").read()
call_point = source.find("Call sites\:")
assert call_point != -1
assert source.find("a :: <Int>") < call_point
More information about the pytest-commit
mailing list