[py-svn] r37545 - in py/trunk/py/apigen: . testing tracer tracer/testing

guido at codespeak.net guido at codespeak.net
Mon Jan 29 17:11:23 CET 2007


Author: guido
Date: Mon Jan 29 17:11:15 2007
New Revision: 37545

Modified:
   py/trunk/py/apigen/apigen.py
   py/trunk/py/apigen/htmlgen.py
   py/trunk/py/apigen/style.css
   py/trunk/py/apigen/testing/test_apigen_functional.py
   py/trunk/py/apigen/tracer/docstorage.py
   py/trunk/py/apigen/tracer/testing/test_docgen.py
Log:
Moved get_star_import_tree out of the DocStorage class, created 'pkg_to_dict'
function in docstorage.py and using that from apigen.py (to later simplify
py.test integration, and to improve testability). Simplified 'deindent()' a
bit, made the wrap_page use the filenames from the stylesheeturl and the
scripturls instead of having them hard-coded, some minor HTML/CSS changes.



Modified: py/trunk/py/apigen/apigen.py
==============================================================================
--- py/trunk/py/apigen/apigen.py	(original)
+++ py/trunk/py/apigen/apigen.py	Mon Jan 29 17:11:15 2007
@@ -10,11 +10,12 @@
 from py.__.apigen import htmlgen
 from py.__.apigen import linker
 from py.__.apigen import project
+from py.__.apigen.tracer.docstorage import pkg_to_dict
 
 def get_documentable_items(pkgdir):
     sys.path.insert(0, str(pkgdir.dirpath()))
     rootmod = __import__(pkgdir.basename)
-    return rootmod
+    return pkg_to_dict(rootmod)
 
 def build(pkgdir, dsa):
     l = linker.Linker()

Modified: py/trunk/py/apigen/htmlgen.py
==============================================================================
--- py/trunk/py/apigen/htmlgen.py	(original)
+++ py/trunk/py/apigen/htmlgen.py	Mon Jan 29 17:11:15 2007
@@ -19,26 +19,23 @@
         line to the side always, and determines the indentation of the rest
         of the text by taking that of the least indented (filled) line
     """
-    lines = str.split(linesep)
+    lines = str.strip().split(linesep)
     normalized = []
     deindent = None
     normalized.append(lines[0].strip())
+    # replace tabs with spaces, empty lines that contain spaces only, and
+    # find out what the smallest indentation is
     for line in lines[1:]:
-        if not line.strip():
+        line = line.replace('\t', '     ')
+        stripped = line.strip()
+        if not stripped:
             normalized.append('')
         else:
-            line = line.rstrip()
-            line = line.replace('\t', '     ')
-            indent = 0
-            for c in line:
-                if c != ' ':
-                    break
-                indent += 1
+            rstripped = line.rstrip()
+            indent = len(rstripped) - len(stripped)
             if deindent is None or indent < deindent:
                 deindent = indent
             normalized.append(line)
-    while normalized[-1] == '':
-        normalized.pop()
     ret = [normalized[0]]
     for line in normalized[1:]:
         if not line:
@@ -182,10 +179,12 @@
                       stylesheeturl=stylesheeturl, scripturls=scripturls)
     page.set_content(contentel)
     here = py.magic.autopath().dirpath()
-    style = here.join('style.css').read()
-    outputpath.join('style.css').write(style)
-    apijs = here.join('api.js').read()
-    outputpath.join('api.js').write(apijs)
+    style = here.join(stylesheeturl.split('/')[-1]).read()
+    outputpath.join(stylesheeturl.split('/')[-1]).write(style)
+    for spath in scripturls:
+        sname = spath.split('/')[-1]
+        sdata = here.join(sname).read()
+        outputpath.join(sname).write(sdata)
     return page
 
 # the PageBuilder classes take care of producing the docs (using the stuff
@@ -281,6 +280,7 @@
         try:
             tag = H.NonPythonSource(unicode(fspath.read(), 'utf-8'))
         except UnicodeError:
+            # XXX we should fix non-ascii support here!!
             tag = H.NonPythonSource('no source available (binary file?)')
         nav = self.build_navigation(fspath)
         return tag, nav
@@ -380,7 +380,7 @@
             csdiv,
         )
         snippet = H.FunctionDescription(
-            H.FunctionDef(localname, argdesc),
+            H.FunctionDef('def %s' % (localname,), argdesc),
             H.Docstring(docstring or '*no docstring available*'),
             H.div(H.a('show/hide info',
                       href='#',
@@ -684,7 +684,7 @@
                     call_site[0].filename, call_site[0].lineno + 1),
                 href='#',
                 onclick="showhideel(getnextsibling(this)); return false;"),
-            H.div(tbtag, style='display: none')
+            H.div(tbtag, style='display: none', class_='callstackitem'),
         )
         return tag
     

Modified: py/trunk/py/apigen/style.css
==============================================================================
--- py/trunk/py/apigen/style.css	(original)
+++ py/trunk/py/apigen/style.css	Mon Jan 29 17:11:15 2007
@@ -42,12 +42,15 @@
   font-weight: bold;
 }
 
-body, div, p, h1, h2, h3, h4 {
-  font-family: Trebuchet MS, Verdana, Arial;
+body {
   background-color: #FFE;
   color: black;
 }
 
+body, div, p, h1, h2, h3, h4 {
+  font-family: Trebuchet MS, Verdana, Arial;
+}
+
 a {
   color: #006;
   text-decoration: none;
@@ -107,5 +110,11 @@
   border: 1px solid black;
   color: black;
   padding: 1em;
+  background-color: white;
+}
+
+.callstackitem {
+  border: 1px solid black;
+  margin-bottom: 1em;
 }
 

Modified: py/trunk/py/apigen/testing/test_apigen_functional.py
==============================================================================
--- py/trunk/py/apigen/testing/test_apigen_functional.py	(original)
+++ py/trunk/py/apigen/testing/test_apigen_functional.py	Mon Jan 29 17:11:15 2007
@@ -47,6 +47,7 @@
             'main.SomeTestClass': ('./sometestclass.py', 'SomeTestClass'),
             'main.SomeTestSubClass': ('./sometestsubclass.py',
                                       'SomeTestSubClass'),
+            'somenamespace': ('./somenamespace.py', '*'),
         })
     """))
     temp.ensure('pak/test/test_pak.py').write(py.code.Source("""\
@@ -82,9 +83,9 @@
 def test_get_documentable_items():
     fs_root, package_name = setup_fs_project('test_get_documentable_items')
     documentable = apigen.get_documentable_items(fs_root.join(package_name))
-    assert sorted(documentable.__package__.exportdefs.keys()) ==  [
+    assert sorted(documentable.keys()) ==  [
         'main.SomeTestClass', 'main.SomeTestSubClass', 'main.func',
-        'main.sub.func']
+        'main.sub.func', 'somenamespace.baz', 'somenamespace.foo']
 
 def test_apigen_functional():
     fs_root, package_name = setup_fs_project('test_apigen_functional')

Modified: py/trunk/py/apigen/tracer/docstorage.py
==============================================================================
--- py/trunk/py/apigen/tracer/docstorage.py	(original)
+++ py/trunk/py/apigen/tracer/docstorage.py	Mon Jan 29 17:11:15 2007
@@ -15,6 +15,44 @@
 
 sorted = py.builtin.sorted
 
+def pkg_to_dict(module):
+    defs = module.__package__.exportdefs
+    d = {}
+    for key, value in defs.iteritems():
+        chain = key.split('.')
+        base = module
+        for elem in chain:
+            base = getattr(base, elem)
+        if value[1] == '*':
+            d.update(get_star_import_tree(base, key))
+        else:
+            d[key] = base
+    return d
+
+def get_star_import_tree(module, modname):
+    """ deal with '*' entries in an initpkg situation """
+    ret = {}
+    modpath = py.path.local(inspect.getsourcefile(module))
+    pkgpath = module.__package__.getpath()
+    for objname in dir(module):
+        if objname.startswith('_'):
+            continue # also skip __*__ attributes
+        obj = getattr(module, objname)
+        if (isinstance(obj, types.ClassType) or
+                isinstance(obj, types.ObjectType)):
+            try:
+                sourcefile_object = py.path.local(
+                                        inspect.getsourcefile(obj))
+            except TypeError:
+                continue
+            else:
+                if sourcefile_object.strpath != modpath.strpath:
+                    # not in this package
+                    continue
+            dotted_name = '%s.%s' % (modname, objname)
+            ret[dotted_name] = obj
+    return ret
+    
 class DocStorage(object):
     """ Class storing info about API
     """
@@ -117,45 +155,10 @@
 
     def from_pkg(self, module, keep_frames=False):
         self.module = module
-        defs = module.__package__.exportdefs
-        d = {}
-        for key, value in defs.iteritems():
-            chain = key.split('.')
-            base = module
-            for elem in chain:
-                base = getattr(base, elem)
-            if value[1] == '*':
-                d.update(self.get_star_import_tree(base, key))
-            else:
-                d[key] = base
-        self.from_dict(d, keep_frames)
+        self.from_dict(pkg_to_dict(module), keep_frames)
         # XXX
         return self
 
-    def get_star_import_tree(self, module, modname):
-        """ deal with '*' entries in an initpkg situation """
-        ret = {}
-        modpath = py.path.local(inspect.getsourcefile(module))
-        pkgpath = module.__package__.getpath()
-        for objname in dir(module):
-            if objname.startswith('_'):
-                continue # also skip __*__ attributes
-            obj = getattr(module, objname)
-            if (isinstance(obj, types.ClassType) or
-                    isinstance(obj, types.ObjectType)):
-                try:
-                    sourcefile_object = py.path.local(
-                                            inspect.getsourcefile(obj))
-                except TypeError:
-                    continue
-                else:
-                    if sourcefile_object.strpath != modpath.strpath:
-                        # not in this package
-                        continue
-                dotted_name = '%s.%s' % (modname, objname)
-                ret[dotted_name] = obj
-        return ret
-    
     def from_module(self, func):
         raise NotImplementedError("From module")
 

Modified: py/trunk/py/apigen/tracer/testing/test_docgen.py
==============================================================================
--- py/trunk/py/apigen/tracer/testing/test_docgen.py	(original)
+++ py/trunk/py/apigen/tracer/testing/test_docgen.py	Mon Jan 29 17:11:15 2007
@@ -6,8 +6,9 @@
 import sys
 
 #try:
-from py.__.apigen.tracer.tracer import DocStorage, Tracer
-from py.__.apigen.tracer.docstorage import DocStorageAccessor
+from py.__.apigen.tracer.tracer import Tracer
+from py.__.apigen.tracer.docstorage import DocStorageAccessor, DocStorage, \
+                                           get_star_import_tree, pkg_to_dict
 from py.__.apigen.tracer.testing.runtest import cut_pyc
 from py.__.apigen.tracer.description import FunctionDesc
 from py.__.apigen.tracer import model
@@ -426,7 +427,7 @@
 
 def test_get_initpkg_star_items():
     pkg, ds = setup_pkg_docstorage()
-    sit = ds.get_star_import_tree(pkg.other, 'pkg.other')
+    sit = get_star_import_tree(pkg.other, 'pkg.other')
     assert sorted(sit.keys()) == ['pkg.other.baz', 'pkg.other.foo']
     t = Tracer(ds)
     t.start_tracing()
@@ -446,3 +447,11 @@
     assert isinstance(cell, model.SomeInstance)
     assert cell.classdef.cls is desc.pyobj
 
+def test_pkg_to_dict():
+    pkg, ds = setup_pkg_docstorage()
+    assert sorted(pkg_to_dict(pkg).keys()) == ['main.SomeClass',
+                                               'main.SomeSubClass',
+                                               'main.sub.func',
+                                               'other.baz',
+                                               'other.foo']
+



More information about the pytest-commit mailing list