def heading(self, title, extras=''):
"""Format a page heading."""
return '''
-<table class="heading">
-<tr class="heading-text decor">
-<td class="title"> <br>%s</td>
-<td class="extra">%s</td></tr></table>
- ''' % (title, extras or ' ')
-
- def section(self, title, cls, contents, width=6,
- prelude='', marginalia=None, gap=' '):
- """Format a section with a heading."""
- if marginalia is None:
- marginalia = '<span class="code">' + ' ' * width + '</span>'
- result = '''<p>
-<table class="section">
-<tr class="decor %s-decor heading-text">
-<td class="section-title" colspan=3> <br>%s</td></tr>
- ''' % (cls, title)
+<header class="heading">
+<h1>%s</h1>
+<div class="extra">%s</div>
+</header>
+''' % (title, extras)
+
+ def _section(self, title, cls, contents, prelude, tag):
+ result = '''
+<section class="%s">
+<%s>%s</%s>
+''' % (cls, tag, title, tag)
if prelude:
- result = result + '''
-<tr><td class="decor %s-decor" rowspan=2>%s</td>
-<td class="decor %s-decor" colspan=2>%s</td></tr>
-<tr><td>%s</td>''' % (cls, marginalia, cls, prelude, gap)
- else:
- result = result + '''
-<tr><td class="decor %s-decor">%s</td><td>%s</td>''' % (cls, marginalia, gap)
+ result = result + '<div class="docstring">%s</div>\n' % prelude
+ return result + '%s\n</section>\n' % contents
+
+ def section(self, title, cls, contents, width=None,
+ prelude='', marginalia=None, gap=None):
+ """Format a section with a heading.
- return result + '\n<td class="singlecolumn">%s</td></tr></table>' % contents
+ The width, marginalia and gap arguments are ignored.
+ """
+ return self._section(title, cls, contents, prelude, 'h3')
- def bigsection(self, title, *args):
+ def bigsection(self, title, cls, contents, *ignored):
"""Format a section with a big heading."""
- title = '<strong class="bigsection">%s</strong>' % title
- return self.section(title, *args)
+ return self._section(title, cls, contents, '', 'h2')
def preformat(self, text):
"""Format literal preformatted text."""
- text = self.escape(text.expandtabs())
- return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
- ' ', ' ', '\n', '<br>\n')
+ return self.escape(text.expandtabs())
def multicolumn(self, list, format):
"""Format a list of items into a multi-column list."""
- result = ''
- rows = (len(list) + 3) // 4
- for col in range(4):
- result = result + '<td class="multicolumn">'
- for i in range(rows*col, rows*col+rows):
- if i < len(list):
- result = result + format(list[i]) + '<br>\n'
- result = result + '</td>'
- return '<table><tr>%s</tr></table>' % result
+ result = ''.join('<li>%s</li>\n' % format(item) for item in list)
+ return '<ul class="multicolumn">\n%s</ul>' % result
def grey(self, text): return '<span class="grey">%s</span>' % text
for entry in tree:
if isinstance(entry, tuple):
c, bases = entry
- result = result + '<dt class="heading-text">'
+ result = result + '<dt>'
result = result + self.classlink(c, modname)
if bases and bases != (parent,):
parents = []
elif isinstance(entry, list):
result = result + '<dd>\n%s</dd>\n' % self.formattree(
entry, modname, c)
- return '<dl>\n%s</dl>\n' % result
+ return '<dl class="tree">\n%s</dl>\n' % result
def docmodule(self, object, name=None, mod=None, *ignored):
"""Produce HTML documentation for a module object."""
links = []
for i in range(len(parts)-1):
links.append(
- '<a href="%s.html" class="white">%s</a>' %
+ '<a href="%s.html">%s</a>' %
('.'.join(parts[:i+1]), parts[i]))
linkedname = '.'.join(links + parts[-1:])
- head = '<strong class="title">%s</strong>' % linkedname
+ head = linkedname
try:
path = inspect.getabsfile(object)
url = urllib.parse.quote(path)
data.append((key, value))
doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
- doc = doc and '<span class="code">%s</span>' % doc
- result = result + '<p>%s</p>\n' % doc
+ doc = doc and '<div class="docstring">%s</div>\n' % doc
+ result = result + doc
if hasattr(object, '__path__'):
modpkgs = []
object.__module__))
push('</dl>\n')
+ # Wrap the groups of members inherited from other classes in
+ # <details> so that they are collapsed by default.
+ is_inherited = False
+
+ def begingroup(msg):
+ if is_inherited:
+ push('<details class="inherited">\n'
+ '<summary>%s</summary>\n' % msg)
+ else:
+ push('<h4>%s</h4>\n' % msg)
+
+ def endgroup():
+ if is_inherited:
+ push('</details>\n')
+
def spill(msg, attrs, predicate):
ok, attrs = _split_list(attrs, predicate)
if ok:
hr.maybe()
- push(msg)
+ begingroup(msg)
for name, kind, homecls, value in ok:
try:
value = getattr(object, name)
push(self.document(value, name, mod,
funcs, classes, mdict, object, homecls))
push('\n')
+ endgroup()
return attrs
def spilldescriptors(msg, attrs, predicate):
ok, attrs = _split_list(attrs, predicate)
if ok:
hr.maybe()
- push(msg)
+ begingroup(msg)
for name, kind, homecls, value in ok:
push(self.docdata(value, name, mod))
+ endgroup()
return attrs
def spilldata(msg, attrs, predicate):
ok, attrs = _split_list(attrs, predicate)
if ok:
hr.maybe()
- push(msg)
+ begingroup(msg)
for name, kind, homecls, value in ok:
base = self.docother(getattr(object, name), name, mod)
doc = getdoc(value)
if not doc:
- push('<dl><dt>%s</dl>\n' % base)
+ push('<dl class="doc"><dt>%s</dt></dl>\n' % base)
else:
doc = self.markup(getdoc(value), self.preformat,
funcs, classes, mdict)
- doc = '<dd><span class="code">%s</span>' % doc
- push('<dl><dt>%s%s</dl>\n' % (base, doc))
+ push('<dl class="doc"><dt>%s</dt>'
+ '<dd class="docstring">%s</dd></dl>\n'
+ % (base, doc))
push('\n')
+ endgroup()
return attrs
attrs = [(name, kind, cls, value)
continue
elif thisclass is object:
tag = 'defined here'
+ is_inherited = False
else:
tag = 'inherited from %s' % self.classlink(thisclass,
object.__module__)
- tag += ':<br>\n'
+ is_inherited = True
+ tag += ':'
sort_attributes(attrs, object)
contents = ''.join(contents)
if name == realname:
- title = '<a name="%s">class <strong>%s</strong></a>' % (
+ title = '<a id="%s">class <strong>%s</strong></a>' % (
name, realname)
else:
- title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (
+ title = '<strong>%s</strong> = <a id="%s">class %s</a>' % (
name, name, realname)
if bases:
parents = []
if decl:
doc = decl + (doc or '')
doc = self.markup(doc, self.preformat, funcs, classes, mdict)
- doc = doc and '<span class="code">%s<br> </span>' % doc
- return self.section(title, 'title', contents, 3, doc)
+ return self.section(title, 'title', contents, prelude=doc)
def formatvalue(self, object):
"""Format an argument default value as text."""
asyncqualifier = ''
if name == realname:
- title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
+ title = '<a id="%s"><strong>%s</strong></a>' % (anchor, realname)
else:
if (cl is not None and
inspect.getattr_static(cl, realname, []) is object):
note = ''
else:
reallink = realname
- title = '<a name="%s"><strong>%s</strong></a> = %s' % (
+ title = '<a id="%s"><strong>%s</strong></a> = %s' % (
anchor, name, reallink)
argspec = None
if inspect.isroutine(object):
argspec = '(...)'
decl = asyncqualifier + title + self.escape(argspec) + (note and
- self.grey('<span class="heading-text">%s</span>' % note))
+ '<span class="note">%s</span>' % note)
if skipdocs:
- return '<dl><dt>%s</dt></dl>\n' % decl
+ return '<dl class="doc"><dt>%s</dt></dl>\n' % decl
else:
doc = self.markup(
getdoc(object), self.preformat, funcs, classes, methods)
- doc = doc and '<dd><span class="code">%s</span></dd>' % doc
- return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
+ doc = doc and '<dd class="docstring">%s</dd>' % doc
+ return '<dl class="doc"><dt>%s</dt>%s</dl>\n' % (decl, doc)
def docdata(self, object, name=None, mod=None, cl=None, *ignored):
"""Produce html documentation for a data descriptor."""
push = results.append
if name:
- push('<dl><dt><strong>%s</strong></dt>\n' % name)
+ push('<dl class="doc"><dt><strong>%s</strong></dt>\n' % name)
doc = self.markup(getdoc(object), self.preformat)
if doc:
- push('<dd><span class="code">%s</span></dd>\n' % doc)
+ push('<dd class="docstring">%s</dd>\n' % doc)
push('</dl>\n')
return ''.join(results)
'<link rel="stylesheet" type="text/css" href="%s">' %
css_path)
return '''\
-<!DOCTYPE>
+<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pydoc: %s</title>
-%s</head><body>%s<div style="clear:both;padding-top:.5em;">%s</div>
+%s</head><body>
+%s
+<main>
+%s
+</main>
</body></html>''' % (title, css_link, html_navbar(), contents)
platform.python_build()[0],
platform.python_compiler()))
return """
- <div style='float:left'>
- Python %s<br>%s
- </div>
- <div style='float:right'>
- <div style='text-align:center'>
- <a href="index.html">Module Index</a>
- : <a href="topics.html">Topics</a>
- : <a href="keywords.html">Keywords</a>
- </div>
- <div>
- <form action="get" style='display:inline;'>
- <input type=text name=key size=15>
- <input type=submit value="Get">
- </form>
- <form action="search" style='display:inline;'>
- <input type=text name=key size=15>
- <input type=submit value="Search">
- </form>
- </div>
- </div>
- """ % (version, html.escape(platform.platform(terse=True)))
+<nav class="navbar">
+ <div class="navbar-version">Python %s<br>%s</div>
+ <ul>
+ <li><a href="index.html">Module Index</a></li>
+ <li><a href="topics.html">Topics</a></li>
+ <li><a href="keywords.html">Keywords</a></li>
+ </ul>
+ <div>
+ <form action="get">
+ <input type="search" name="key" size="15" placeholder="Get help on ...">
+ <input type="submit" value="Get">
+ </form>
+ <form action="search">
+ <input type="search" name="key" size="15" placeholder="Search modules">
+ <input type="submit" value="Search">
+ </form>
+ </div>
+</nav>
+""" % (version, html.escape(platform.platform(terse=True)))
def html_index():
"""Module Index page."""
def bltinlink(name):
return '<a href="%s.html">%s</a>' % (name, name)
- heading = html.heading(
- '<strong class="title">Index of Modules</strong>'
- )
+ heading = html.heading('Index of Modules')
names = [name for name in sys.builtin_module_names
if name != '__main__']
contents = html.multicolumn(names, bltinlink)
- contents = [heading, '<p>' + html.bigsection(
+ contents = [heading, html.bigsection(
'Built-in Modules', 'index', contents)]
seen = {}
contents.append(html.index(dir, seen))
contents.append(
- '<p align=right class="heading-text grey"><strong>pydoc</strong> by Ka-Ping Yee'
- '<ping@lfw.org></p>')
+ '<footer><strong>pydoc</strong> by Ka-Ping Yee'
+ ' <ping@lfw.org></footer>')
return 'Index of Modules', ''.join(contents)
def html_search(key):
return '<a href="%s.html">%s</a>' % (name, name)
results = []
- heading = html.heading(
- '<strong class="title">Search Results</strong>',
- )
+ heading = html.heading('Search Results')
for name, desc in search_result:
- results.append(bltinlink(name) + desc)
+ results.append('<li>%s%s</li>' % (bltinlink(name), desc))
contents = heading + html.bigsection(
- 'key = %s' % key, 'index', '<br>'.join(results))
+ 'key = %s' % key, 'index', '<ul>\n%s\n</ul>' % '\n'.join(results))
return 'Search Results', contents
def html_topics():
def bltinlink(name):
return '<a href="topic?key=%s">%s</a>' % (name, name)
- heading = html.heading(
- '<strong class="title">INDEX</strong>',
- )
+ heading = html.heading('Topics')
names = sorted(Helper.topics.keys())
- contents = html.multicolumn(names, bltinlink)
- contents = heading + html.bigsection(
- 'Topics', 'index', contents)
+ contents = heading + html.multicolumn(names, bltinlink)
return 'Topics', contents
def html_keywords():
"""Index of keywords."""
- heading = html.heading(
- '<strong class="title">INDEX</strong>',
- )
+ heading = html.heading('Keywords')
names = sorted(Helper.keywords.keys())
def bltinlink(name):
return '<a href="topic?key=%s">%s</a>' % (name, name)
- contents = html.multicolumn(names, bltinlink)
- contents = heading + html.bigsection(
- 'Keywords', 'index', contents)
+ contents = heading + html.multicolumn(names, bltinlink)
return 'Keywords', contents
def html_topicpage(topic):
title = 'KEYWORD'
else:
title = 'TOPIC'
- heading = html.heading(
- '<strong class="title">%s</strong>' % title,
- )
- contents = '<pre>%s</pre>' % html.markup(contents)
- contents = html.bigsection(topic , 'index', contents)
+ heading = html.heading('%s %s' % (title.capitalize(), topic))
+ contents = ('<pre class="%s">%s</pre>'
+ % (title.lower(), html.markup(contents)))
if xrefs:
xrefs = sorted(xrefs.split())
return '<a href="topic?key=%s">%s</a>' % (name, name)
xrefs = html.multicolumn(xrefs, bltinlink)
- xrefs = html.section('Related help topics: ', 'index', xrefs)
+ xrefs = html.section('Related help topics', 'index', xrefs)
return ('%s %s' % (title, topic),
''.join((heading, contents, xrefs)))
return title, content
def html_error(url, exc):
- heading = html.heading(
- '<strong class="title">Error</strong>',
- )
+ heading = html.heading('Error')
contents = '<br>'.join(html.escape(line) for line in
format_exception_only(type(exc), exc))
contents = heading + html.bigsection(url, 'error', contents)
Contents of this file are subject to change without notice.
+ The colors and fonts follow the python-docs-theme used by
+ docs.python.org.
*/
+:root {
+ color-scheme: light dark;
+ --text-color: #333;
+ --background-color: #fff;
+ --link-color: #0072aa;
+ --link-visited-color: #6363bb;
+ --link-hover-color: #00b0e4;
+ --muted-color: #707070;
+ --code-background-color: #eee;
+ --border-color: #ccc;
+ --target-background-color: #fbe54e;
+ --block-background-color: #eeffcc;
+ --block-border-color: #ac9;
+ --error-color: #ba2121;
+ --repr-color: #c040c0;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --text-color: rgba(255, 255, 255, 0.87);
+ --background-color: #222;
+ --link-color: #77aaff;
+ --link-visited-color: #0099ee;
+ --link-hover-color: #00b0e4;
+ --muted-color: #999;
+ --code-background-color: #424242;
+ --border-color: #616161;
+ --target-background-color: #616161;
+ --block-background-color: #333;
+ --block-border-color: #616161;
+ --error-color: #f44c4e;
+ --repr-color: #d080d0;
+ }
+}
+
body {
- background-color: #f0f0f8;
+ font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
+ segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto,
+ noto, arial, sans-serif;
+ color: var(--text-color);
+ background-color: var(--background-color);
+ line-height: 1.4;
+ margin: 0;
+ padding: 0 1em 1em;
}
-table.heading tr {
- background-color: #7799ee;
+code, pre, .docstring, dl.doc > dt {
+ font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
+ monospace;
+ font-size: 96.5%;
}
-.decor {
- color: #ffffff;
+a:link {
+ color: var(--link-color);
}
-.title-decor {
- background-color: #ffc8d8;
- color: #000000;
+a:visited {
+ color: var(--link-visited-color);
}
-.pkg-content-decor {
- background-color: #aa55cc;
+a:hover {
+ color: var(--link-hover-color);
}
-.index-decor {
- background-color: #ee77aa;
+/* Page heading */
+
+header.heading {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: flex-end;
+ column-gap: 1em;
+ padding: 0.5em 0;
+ border-bottom: 1px solid var(--border-color);
}
-.functions-decor {
- background-color: #eeaa77;
+header.heading h1 {
+ margin: 0;
+ font-size: 1.8em;
}
-.data-decor {
- background-color: #55aa55;
+header.heading .extra {
+ text-align: right;
+ overflow-wrap: anywhere;
}
-.author-decor {
- background-color: #7799ee;
+/* Sections */
+
+h2, h3, h4 {
+ margin: 0.6em 0 0.4em;
}
-.credits-decor {
- background-color: #7799ee;
+section > h2 {
+ border-bottom: 1px solid var(--border-color);
+ padding-bottom: 0.2em;
+ font-size: 1.4em;
}
-.error-decor {
- background-color: #bb0000;
+section > h3 {
+ font-size: 1.1em;
}
-.grey {
- color: #909090;
+section.error > h2 {
+ color: var(--error-color);
}
-.white {
- color: #ffffff;
+section section {
+ border: 1px solid var(--border-color);
+ border-radius: 3px;
+ padding: 0 0.8em 0.5em;
+ margin: 0.8em 0;
}
-.repr {
- color: #c040c0;
+/* Docstrings and other preformatted text */
+
+.docstring {
+ white-space: pre-wrap;
+ margin: 0.3em 0;
}
-table.heading tr td.title {
- vertical-align: bottom;
+pre.topic, pre.keyword {
+ background-color: var(--block-background-color);
+ border: 1px solid var(--block-border-color);
+ border-radius: 3px;
+ padding: 0.5em 0.8em;
+ overflow-x: auto;
}
-table.heading tr td.extra {
- vertical-align: bottom;
- text-align: right;
+/* Documented names (functions, methods, data) */
+
+dl.doc {
+ margin: 0.5em 0;
}
-.heading-text {
- font-family: helvetica, arial;
+dl.doc > dt {
+ overflow-wrap: anywhere;
}
-.bigsection {
- font-size: larger;
+a:target {
+ background-color: var(--target-background-color);
}
-.title {
- font-size: x-large;
+dl.doc > dd {
+ margin: 0.2em 0 0.8em 2em;
}
-.code {
- font-family: monospace;
+.note {
+ font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
+ segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto,
+ noto, arial, sans-serif;
+ color: var(--muted-color);
}
-table {
- width: 100%;
- border-spacing : 0;
- border-collapse : collapse;
+.grey {
+ color: var(--muted-color);
+}
+
+.repr {
+ color: var(--repr-color);
+}
+
+hr {
border: 0;
+ border-top: 1px solid var(--border-color);
+ margin: 0.8em 0;
}
-td {
- padding: 2;
+/* Inherited class members are collapsed by default. */
+
+details.inherited > summary {
+ cursor: pointer;
+ margin: 0.6em 0 0.4em;
}
-td.section-title {
- vertical-align: bottom;
+/* Multi-column lists of modules, topics and keywords */
+
+ul.multicolumn {
+ list-style-type: none;
+ column-width: 14em;
+ column-gap: 1em;
+ margin: 0.5em 0;
+ padding: 0;
}
-td.multicolumn {
- width: 25%;
- vertical-align: bottom;
+ul.multicolumn > li {
+ overflow-wrap: anywhere;
}
-td.singlecolumn {
- width: 100%;
+/* Class hierarchy trees */
+
+dl.tree, dl.tree dl {
+ margin: 0;
+}
+
+dl.tree dd {
+ margin: 0 0 0 2em;
+}
+
+/* Navigation bar of the pydoc server */
+
+nav.navbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ column-gap: 1em;
+ row-gap: 0.3em;
+ padding: 0.5em 0;
+ border-bottom: 1px solid var(--border-color);
+ font-size: smaller;
+}
+
+nav.navbar .navbar-version {
+ color: var(--muted-color);
+}
+
+nav.navbar ul {
+ display: flex;
+ flex-wrap: wrap;
+ column-gap: 1em;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+nav.navbar form {
+ display: inline-block;
+}
+
+nav.navbar input {
+ font-family: inherit;
+ font-size: inherit;
+ color: inherit;
+ background-color: var(--background-color);
+ border: 1px solid #999;
+ border-radius: 3px;
+}
+
+footer {
+ margin-top: 1em;
+ padding-top: 0.3em;
+ border-top: 1px solid var(--border-color);
+ color: var(--muted-color);
+ font-size: smaller;
+ text-align: right;
}
self.client.request("GET", "/")
response = self.client.getresponse()
- self.assertIn((b'<dl><dt><a name="-<lambda>"><strong>'
+ self.assertIn((b'<dl class="doc"><dt><a id="-<lambda>"><strong>'
b'<lambda></strong></a>(x, y)</dt></dl>'),
response.read())
response = self.client.getresponse().read()
self.assertIn(
- (b'<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd>'
- b'<tt>Add two instances together. This '
- b'follows <a href="https://peps.python.org/pep-0008/">'
- b'PEP008</a>, but has nothing<br>\nto do '
- b'with <a href="https://www.rfc-editor.org/rfc/rfc1952.txt">'
- b'RFC1952</a>. Case should matter: pEp008 '
- b'and rFC1952. Things<br>\nthat start '
- b'with http and ftp should be '
- b'auto-linked, too:<br>\n<a href="http://google.com">'
- b'http://google.com</a>.</tt></dd></dl>'), response)
+ (b'<dl class="doc"><dt><a id="-add"><strong>add</strong></a>'
+ b'(x, y)</dt><dd class="docstring">'
+ b'Add two instances together. This '
+ b'follows <a href="https://peps.python.org/pep-0008/">'
+ b'PEP008</a>, but has nothing\nto do '
+ b'with <a href="https://www.rfc-editor.org/rfc/rfc1952.txt">'
+ b'RFC1952</a>. Case should matter: pEp008 '
+ b'and rFC1952. Things\nthat start '
+ b'with http and ftp should be '
+ b'auto-linked, too:\n<a href="http://google.com">'
+ b'http://google.com</a>.</dd></dl>'), response)
@make_request_and_skipIf(sys.flags.optimize >= 2,
"Docstrings are omitted with -O2 and above")
response = self.client.getresponse().read()
self.assertIn(
- (b'<dl><dt><a name="-system.methodHelp"><strong>system.methodHelp'
- b'</strong></a>(method_name)</dt><dd><tt><a href="#-system.method'
- b'Help">system.methodHelp</a>(\'add\') => "Adds '
- b'two integers together"<br>\n <br>\nReturns a'
- b' string containing documentation for '
- b'the specified method.</tt></dd></dl>\n<dl><dt><a name'
- b'="-system.methodSignature"><strong>system.methodSignature</strong>'
- b'</a>(method_name)</dt><dd><tt><a href="#-system.methodSignature">'
- b'system.methodSignature</a>(\'add\') => [double, '
- b'int, int]<br>\n <br>\nReturns a list '
- b'describing the signature of the method.'
- b' In the<br>\nabove example, the add '
- b'method takes two integers as arguments'
- b'<br>\nand returns a double result.<br>\n '
- b'<br>\nThis server does NOT support system'
- b'.methodSignature.</tt></dd></dl>'), response)
+ (b'<dl class="doc"><dt><a id="-system.methodHelp"><strong>'
+ b'system.methodHelp</strong></a>(method_name)</dt>'
+ b'<dd class="docstring"><a href="#-system.method'
+ b'Help">system.methodHelp</a>(\'add\') => "Adds '
+ b'two integers together"\n\nReturns a'
+ b' string containing documentation for '
+ b'the specified method.</dd></dl>\n<dl class="doc"><dt><a id'
+ b'="-system.methodSignature"><strong>system.methodSignature'
+ b'</strong></a>(method_name)</dt><dd class="docstring">'
+ b'<a href="#-system.methodSignature">'
+ b'system.methodSignature</a>(\'add\') => [double, '
+ b'int, int]\n\nReturns a list '
+ b'describing the signature of the method.'
+ b' In the\nabove example, the add '
+ b'method takes two integers as arguments'
+ b'\nand returns a double result.\n\n'
+ b'This server does NOT support system'
+ b'.methodSignature.</dd></dl>'), response)
def test_autolink_dotted_methods(self):
"""Test that selfdot values are made strong automatically in the
self.client.request("GET", "/")
response = self.client.getresponse()
- self.assertIn(b"""Try self.<strong>add</strong>, too.""",
+ self.assertIn(b"""Try self.<strong>add</strong>, too.""",
response.read())
def test_annotations(self):
self.client.request("GET", "/")
response = self.client.getresponse()
docstring = (b'' if sys.flags.optimize >= 2 else
- b'<dd><tt>Use function annotations.</tt></dd>')
+ b'<dd class="docstring">Use function annotations.</dd>')
self.assertIn(
- (b'<dl><dt><a name="-annotation"><strong>annotation</strong></a>'
- b'(x: int)</dt>' + docstring + b'</dl>\n'
- b'<dl><dt><a name="-method_annotation"><strong>'
+ (b'<dl class="doc"><dt><a id="-annotation"><strong>annotation'
+ b'</strong></a>(x: int)</dt>' + docstring + b'</dl>\n'
+ b'<dl class="doc"><dt><a id="-method_annotation"><strong>'
b'method_annotation</strong></a>(x: bytes)</dt></dl>'),
response.read())
generated = self.serv.generate_html_documentation()
title = re.search(r'<title>(.+?)</title>', generated).group()
- documentation = re.search(r'<p><tt>(.+?)</tt></p>', generated).group()
+ documentation = re.search(r'<div class="docstring">(.+?)</div>',
+ generated).group()
self.assertEqual('<title>Python: test_title<script></title>', title)
- self.assertEqual('<p><tt>test_documentation<script></tt></p>', documentation)
+ self.assertEqual('<div class="docstring">test_documentation<script></div>',
+ documentation)
if __name__ == '__main__':