Skip to content

Commit b8758dd

Browse files
authored
ENH: Show annotations for class properties (#175)
* Include annotations for class properties * update
1 parent 572bdf2 commit b8758dd

File tree

3 files changed

+41
-15
lines changed

3 files changed

+41
-15
lines changed

pdoc/__init__.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,23 @@ def _toposort(graph: Dict[T, Set[T]]) -> Generator[T, None, None]:
332332
assert not graph, "A cyclic dependency exists amongst %r" % graph
333333

334334

335+
def _return_annotation(name, module, obj, link=None):
336+
try:
337+
annot = typing.get_type_hints(obj).get('return', '')
338+
except NameError as e:
339+
warn("Error handling return annotation for {}: {}".format(name, e.args[0]))
340+
annot = inspect.signature(inspect.unwrap(obj)).return_annotation
341+
if annot == inspect.Parameter.empty:
342+
annot = ''
343+
if not annot:
344+
return ''
345+
s = inspect.formatannotation(annot).replace(' ', '\N{NBSP}') # Better line breaks
346+
if link:
347+
from pdoc.html_helpers import _linkify
348+
s = re.sub(r'[\w\.]+', partial(_linkify, link=link, module=module), s)
349+
return s
350+
351+
335352
def link_inheritance(context: Context = None):
336353
"""
337354
Link inheritance relationsships between `pdoc.Class` objects
@@ -1076,20 +1093,7 @@ def _is_async(self):
10761093

10771094
def return_annotation(self, *, link=None):
10781095
"""Formatted function return type annotation or empty string if none."""
1079-
try:
1080-
annot = typing.get_type_hints(self.obj).get('return', '')
1081-
except NameError as e:
1082-
warn("Error handling return annotation for {}: {}".format(self.name, e.args[0]))
1083-
annot = inspect.signature(inspect.unwrap(self.obj)).return_annotation
1084-
if annot == inspect.Parameter.empty:
1085-
annot = ''
1086-
if not annot:
1087-
return ''
1088-
s = inspect.formatannotation(annot).replace(' ', '\N{NBSP}') # Better line breaks
1089-
if link:
1090-
from pdoc.html_helpers import _linkify
1091-
s = re.sub(r'[\w\.]+', partial(_linkify, link=link, module=self.module), s)
1092-
return s
1096+
return _return_annotation(self.name, self.module, self.obj, link=link)
10931097

10941098
def params(self, *, annotate: bool = False, link: Callable[[Doc], str] = None) -> List[str]:
10951099
"""
@@ -1235,6 +1239,10 @@ def qualname(self):
12351239
def refname(self):
12361240
return (self.cls.refname if self.cls else self.module.refname) + '.' + self.name
12371241

1242+
def type_annotation(self, *, link=None):
1243+
"""Formatted variable type annotation or empty string if none."""
1244+
return _return_annotation(self.name, self.module, self.obj, link=link)
1245+
12381246

12391247
class External(Doc):
12401248
"""

pdoc/templates/html.mako

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,12 @@
224224
<h3>Instance variables</h3>
225225
<dl>
226226
% for v in inst_vars:
227-
<dt id="${v.refname}"><code class="name">var ${ident(v.name)}</code></dt>
227+
<%
228+
var_type = show_type_annotations and v.type_annotation(link=link) or ''
229+
if var_type:
230+
var_type = ' ->\N{NBSP}' + var_type
231+
%>
232+
<dt id="${v.refname}"><code class="name">var ${ident(v.name)}${var_type}</code></dt>
228233
<dd>${show_desc(v)}</dd>
229234
% endfor
230235
</dl>

pdoc/test/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,19 @@ def f() -> typing.List[typing.Union[str, pdoc.Doc]]: pass
727727
func = pdoc.Function('f', pdoc.Module(pdoc), f)
728728
self.assertEqual(func.return_annotation(), 'List[Union[str,\N{NBSP}pdoc.Doc]]')
729729

730+
@ignore_warnings
731+
def test_Variable_type_annotation(self):
732+
import typing
733+
734+
class Foobar:
735+
@property
736+
def prop(self) -> typing.Optional[int]:
737+
pass
738+
739+
cls = pdoc.Class('Foobar', pdoc.Module(pdoc), Foobar)
740+
prop = cls.instance_variables()[0]
741+
self.assertEqual(prop.type_annotation(), 'Union[int,\N{NBSP}NoneType]')
742+
730743
@ignore_warnings
731744
def test_Class_docstring(self):
732745
class A:

0 commit comments

Comments
 (0)