[py-svn] r34854 - in py/dist/py/apigen: rest rest/testing source source/testing

fijal at codespeak.net fijal at codespeak.net
Wed Nov 22 12:16:07 CET 2006


Author: fijal
Date: Wed Nov 22 12:15:58 2006
New Revision: 34854

Added:
   py/dist/py/apigen/source/   (props changed)
   py/dist/py/apigen/source/__init__.py   (contents, props changed)
   py/dist/py/apigen/source/browser.py   (contents, props changed)
   py/dist/py/apigen/source/testing/   (props changed)
   py/dist/py/apigen/source/testing/__init__.py   (contents, props changed)
   py/dist/py/apigen/source/testing/test_browser.py   (contents, props changed)
Modified:
   py/dist/py/apigen/rest/htmlhandlers.py   (props changed)
   py/dist/py/apigen/rest/testing/somemodule.py   (props changed)
   py/dist/py/apigen/rest/testing/someothermodule.py   (props changed)
Log:
Added very silly source browser.


Added: py/dist/py/apigen/source/__init__.py
==============================================================================

Added: py/dist/py/apigen/source/browser.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/source/browser.py	Wed Nov 22 12:15:58 2006
@@ -0,0 +1,88 @@
+
+""" source browser using compiler module
+
+WARNING!!!
+
+This is very simple and very silly attempt to make so.
+
+"""
+
+from compiler import parse, ast
+import py
+
+from py.__.path.common import PathBase
+
+class Module(object):
+    def __init__(self, path, _dict):
+        self.path = path
+        self.dict = _dict
+    
+    def __getattr__(self, attr):
+        try:
+            return self.dict[attr]
+        except KeyError:
+            raise AttributeError(attr)
+
+def get_endline(start, lst):
+    l = reversed(lst)
+    for i in l:
+        if i.lineno:
+            return i.lineno
+        end_ch = get_endline(None, i.getChildNodes())
+        if end_ch:
+            return end_ch
+    return start
+
+class Function(object):
+    def __init__(self, name, firstlineno, endlineno):
+        self.firstlineno = firstlineno
+        self.endlineno = endlineno
+        self.name = name
+
+class Method(object):
+    def __init__(self, name, firstlineno, endlineno):
+        self.name = name
+        self.firstlineno = firstlineno
+        self.endlineno = endlineno
+
+def function_from_ast(ast, cls=Function):
+    startline = ast.lineno
+    endline = get_endline(startline, ast.getChildNodes())
+    assert endline
+    return cls(ast.name, startline, endline)
+
+def class_from_ast(cls_ast):
+    bases = [i.name for i in cls_ast.bases]
+    # XXX
+    methods = {}
+    startline = cls_ast.lineno
+    name = cls_ast.name
+    endline = get_endline(startline, cls_ast.getChildNodes())
+    methods = dict([(i.name, function_from_ast(i, Method)) for i in \
+        cls_ast.code.nodes if isinstance(i, ast.Function)])
+    return Class(name, startline, endline, bases, methods)
+
+class Class(object):
+    def __init__(self, name, firstlineno, endlineno, bases, methods):
+        self.bases = bases
+        self.firstlineno = firstlineno
+        self.endlineno = endlineno
+        self.name = name
+        self.methods = methods
+
+    def __getattr__(self, attr):
+        try:
+            return self.methods[attr]
+        except KeyError:
+            raise AttributeError(attr)
+
+def parse_path(path):
+    assert isinstance(path, PathBase), "Cannot work on files directly"
+    buf = path.open().read()
+    st = parse(buf)
+    # first go - we get all functions and classes defined on top-level
+    function_ast = [i for i in st.node.nodes if isinstance(i, ast.Function)]
+    classes_ast = [i for i in st.node.nodes if isinstance(i, ast.Class)]
+    mod_dict = dict([(i.name, function_from_ast(i)) for i in function_ast]
+       + [(i.name, class_from_ast(i)) for i in classes_ast])
+    return Module(path, mod_dict)

Added: py/dist/py/apigen/source/testing/__init__.py
==============================================================================

Added: py/dist/py/apigen/source/testing/test_browser.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/source/testing/test_browser.py	Wed Nov 22 12:15:58 2006
@@ -0,0 +1,40 @@
+
+""" test source browser abilities
+"""
+
+from py.__.apigen.source.browser import parse_path, Class, Function, Method
+import py
+
+def test_browser():
+    tmp = py.test.ensuretemp("sourcebrowser")
+    tmp.ensure("a.py").write(py.code.Source("""
+    def f():
+        pass
+    
+    def g():
+        pass
+        
+    class X:
+        pass
+        
+    class Z(object):
+        x = 1
+        def zzz(self):
+            1
+            2
+            3
+            4
+    """))
+    mod = parse_path(tmp.join("a.py"))
+    assert isinstance(mod.g, Function)
+    assert isinstance(mod.Z, Class)
+    py.test.raises(AttributeError, "mod.zzz")
+    assert mod.g.firstlineno == 5
+    assert mod.g.name == "g"
+    assert mod.g.endlineno == 6
+    assert mod.X.firstlineno == 8
+    assert mod.X.endlineno == 9
+    assert mod.Z.bases == ["object"]
+    assert isinstance(mod.Z.zzz, Method)
+    assert mod.Z.zzz.firstlineno == 13
+    assert mod.Z.zzz.endlineno == 17


More information about the py-svn mailing list