[svn r37922] Made that properties (class attributes) are displayed, fixed the links in the

menubar.

--HG--
branch : trunk
This commit is contained in:
guido 2007-02-04 16:47:33 +01:00
parent a128ecb8cf
commit 16f9103a0a
7 changed files with 107 additions and 26 deletions

View File

@ -48,11 +48,20 @@ class H(html):
H.Hideable('funcinfo', 'funcinfo', valuedesc, csource,
callstack))
class PropertyDescription(html.div):
def __init__(self, name, value):
if type(value) not in [str, unicode]:
value = str(value)
if len(value) > 100:
value = value[:100] + '...'
super(H.PropertyDescription, self).__init__(H.strong(name), ': ',
H.em(value),
class_='property')
class ParameterDescription(html.div):
pass
class Docstring(html.pre):
style = html.Style(width='100%')
pass
class Navigation(html.div):

View File

@ -17,6 +17,17 @@ raw = py.xml.raw
def is_navigateable(name):
return (not is_private(name) and name != '__doc__')
def show_property(name):
if not name.startswith('_'):
return True
if name.startswith('__') and name.endswith('__'):
# XXX do we need to skip more manually here?
if (name not in dir(object) and
name not in ['__doc__', '__dict__', '__name__', '__module__',
'__weakref__']):
return True
return False
def deindent(str, linesep='\n'):
""" de-indent string
@ -351,7 +362,24 @@ class ApiPageBuilder(AbstractPageBuilder):
docstring = cls.__doc__
if docstring:
docstring = deindent(docstring)
methods = self.dsa.get_class_methods(dotted_name)
if not hasattr(cls, '__name__'):
clsname = 'instance of %s' % (cls.__class__.__name__,)
else:
clsname = cls.__name__
bases = self.build_bases(dotted_name)
properties = self.build_properties(cls)
methods = self.build_methods(dotted_name)
snippet = H.ClassDescription(
# XXX bases HTML
H.ClassDef('%s(' % (clsname,), *bases),
H.Docstring(docstring or '*no docstring available*'),
sourcelink,
*(properties+methods)
)
return snippet
def build_bases(self, dotted_name):
basehtml = []
bases = self.dsa.get_possible_base_classes(dotted_name)
for base in bases:
@ -366,23 +394,33 @@ class ApiPageBuilder(AbstractPageBuilder):
if basehtml:
basehtml.pop()
basehtml.append('):')
if not hasattr(cls, '__name__'):
clsname = 'instance of %s' % (cls.__class__.__name__,)
else:
clsname = cls.__name__
snippet = H.ClassDescription(
# XXX bases HTML
H.ClassDef('%s(' % (clsname,), *basehtml),
H.Docstring(docstring or '*no docstring available*'),
sourcelink,
)
return basehtml
def build_properties(self, cls):
properties = []
for attr in dir(cls):
val = getattr(cls, attr)
if show_property(attr) and not callable(val):
if isinstance(val, property):
val = '<property object (dynamically calculated value)>'
properties.append((attr, val))
properties.sort(key=lambda a: a[0]) # sort on name
ret = []
if properties:
ret.append(H.h2('properties:'))
for name, val in properties:
ret.append(H.PropertyDescription(name, val))
return ret
def build_methods(self, dotted_name):
ret = []
methods = self.dsa.get_class_methods(dotted_name)
if methods:
snippet.append(H.h2('methods:'))
ret.append(H.h2('methods:'))
for method in methods:
snippet += self.build_callable_view('%s.%s' % (dotted_name,
ret += self.build_callable_view('%s.%s' % (dotted_name,
method))
# XXX properties
return snippet
return ret
def build_namespace_view(self, namespace_dotted_name, item_dotted_names):
""" build the html for a namespace (module) """

View File

@ -26,9 +26,17 @@ class LayoutPage(confrest.PyPage):
def fill(self):
super(LayoutPage, self).fill()
#self.menubar[:] = []
self.update_menubar_links(self.menubar)
self.body.insert(0, self.nav)
def update_menubar_links(self, node):
for item in node:
if not isinstance(item, py.xml.Tag):
continue
if (item.__class__.__name__ == 'a' and hasattr(item.attr, 'href')
and not item.attr.href.startswith('http://')):
item.attr.href = self.relpath + '../py/doc/' + item.attr.href
def setup_scripts_styles(self, copyto=None):
for path, name in self.stylesheets:
if copyto:

View File

@ -18,7 +18,6 @@ div.sidebar .selected a {
#content {
border: 0px;
height: 95%;
width: 100%;
}
ul {
@ -76,6 +75,10 @@ ul li {
background-color: white;
}
.property {
font-size: 1.2em;
}
.callstackitem {
border: 1px solid black;
margin-bottom: 1em;

View File

@ -19,6 +19,7 @@ def setup_fs_project(name):
temp.ensure('pak/sometestclass.py').write(py.code.Source("""\
class SomeTestClass(object):
" docstring sometestclass "
someattr = 'somevalue'
def __init__(self, somevar):
self.somevar = somevar
@ -129,12 +130,10 @@ def test_apigen_functional():
sometestclass_api = apidir.join('main.SomeTestClass.html')
assert sometestclass_api.check(file=True)
html = sometestclass_api.read()
print html
assert '<a href="main.SomeTestClass.html">SomeTestClass</a>' in html
# XXX not linking to method files anymore
#sometestclass_init_api = apidir.join('main.SomeTestClass.__init__.html')
#assert sometestclass_init_api.check(file=True)
#assert sometestclass_init_api.read().find(
# '<a href="main.SomeTestClass.__init__.html">__init__</a>') > -1
assert '<strong>someattr</strong>: <em>somevalue</em>' in html
namespace_api = apidir.join('main.html')
assert namespace_api.check(file=True)
html = namespace_api.read()
@ -156,4 +155,5 @@ def test_apigen_functional():
html = index.read()
print html
assert '<a href="test/index.html">test</a>' in html
assert 'href="../../py/doc/home.html"'

View File

@ -55,3 +55,12 @@ def test_enumerate_and_color():
' <span class="string">&quot;bar&quot;</span>\n'
'</div>')
def test_show_property():
assert htmlgen.show_property('foo')
assert not htmlgen.show_property('_foo')
assert htmlgen.show_property('__foo__')
assert not htmlgen.show_property('__doc__')
assert not htmlgen.show_property('__dict__')
assert not htmlgen.show_property('__name__')
assert not htmlgen.show_property('__class__')

View File

@ -1,5 +1,7 @@
* format docstrings more nicely (with tests) - DONE I guess
* format docstrings more nicely (with tests)
DONE I guess
* have the API function view be as informative as possible
without having to go to the "single method" view
@ -10,10 +12,12 @@
viewed. method views (when navigating there through
the class view) should also have the source there
DONE I think
DONE I think, single method view is gone
* have class-level attributes be displayed
DONE
* use "inherited" doc strings, i.e. for
class A:
def meth(self):
@ -25,8 +29,12 @@
B.meth should display the A.meth docstring, probably
with special formatting (italics or so).
NOT YET DONE (later?)
* factor out some common code in the build_* functions
(mostly) DONE
* refactor the apigen/rsession interaction to become
cleaner (e.g. apigen's get_documentable_items should
be separately tested and the caller should not need
@ -76,9 +84,15 @@
* add syntax coloring for Python source snippets
DONE
* remove py.test/apigen cruft from stack traces
DONE, thanks to fijal
* fix non-ascii source encoding support
DONE
* XXX