[svn r37922] Made that properties (class attributes) are displayed, fixed the links in the
menubar. --HG-- branch : trunk
This commit is contained in:
parent
a128ecb8cf
commit
16f9103a0a
|
@ -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):
|
||||
|
|
|
@ -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) """
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"'
|
||||
|
||||
|
|
|
@ -55,3 +55,12 @@ def test_enumerate_and_color():
|
|||
' <span class="string">"bar"</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__')
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue