forked from mitmproxy/pdoc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo_long.py
223 lines (164 loc) · 6.11 KB
/
demo_long.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
"""
# Test Module
This is a test module demonstrating pdoc's parsing capabilities.
- All docstrings support plain markdown.
- Including code!
```python
print("hello world")
```
- You can link to classes or modules by putting them between backticks: `demo.Dog.bark`
- The only requirement is that you must specify the full qualified path for external modules.
- Module members appear in the order they are listed in the source code.
If you do not like the order in pdoc, you should probably have a different order in your source file as well.
# A Second Section
You can have multiple section in your module docstring,
which will also show up in the navigation.
"""
from __future__ import annotations
import abc
import enum
import os
from dataclasses import dataclass, field
from pdoc._compat import cached_property, cache
from typing import Sequence, TypeVar, Union, ClassVar, Optional, List
FOO_CONSTANT: int = 42
"""
A happy constant. ✨
pdoc documents constants with their type annotation and default value.
"""
FOO_SINGLETON: "Foo"
"""
This variable is annotated with a type only, but not assigned to a value.
We also haven't defined the associated type (`Foo`) yet,
so the type annotation in the code in the source code is actually a string literal:
```python
FOO_SINGLETON: "Foo"
```
Similar to mypy, pdoc resolves
[string forward references](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#class-name-forward-references)
automatically.
"""
def a_simple_function(a: str) -> str:
"""
This is a basic module-level function.
For a more complex example, take a look at `a_complex_function`!
"""
return a.upper()
T = TypeVar("T")
def a_complex_function(
a: str, b: Union["Foo", str], *, c: Optional[T] = None
) -> Optional[T]:
"""
This is a function with a fairly complex signature,
involving type annotations with `typing.Union`, a `typing.TypeVar` (~T),
as well as a keyword-only arguments (*).
"""
return None
class Foo:
"""
`Foo` is a basic class without any parent classes (except for the implict `object` class).
You will see in the definition of `Bar` that docstrings are inherited by default.
Functions in the current scope can be referenced without prefix: `a_regular_function()`.
"""
an_attribute: Union[str, List["int"]]
"""A regular attribute with type annotations"""
a_class_attribute: ClassVar[str] = "lots of foo!"
"""An attribute with a ClassVar annotation."""
def __init__(self):
"""
The constructor is currently always listed first as this feels most natural."""
self.a_constructor_only_attribute: int = 42
"""This attribute is defined in the constructor only, but still picked up by pdoc's AST traversal."""
self.undocumented_constructor_attribute = 42
a_complex_function()
def a_regular_function(self) -> "Foo":
"""This is a regular method, returning the object itself."""
return self
@property
def a_property(self) -> str:
"""This is a `@property` attribute. pdoc will display it as a variable."""
return "true foo"
@cached_property
def a_cached_property(self) -> str:
"""This is a `@functools.cached_property` attribute. pdoc will display it as a variable as well."""
return "true foo"
@cache
def a_cached_function(self) -> str:
"""This is method with `@cache` decoration."""
return "true foo"
@classmethod
def a_class_method(cls) -> int:
"""This is what a `@classmethod` looks like."""
return 24
@classmethod
@property
def a_class_property(cls) -> int:
"""This is what a `@classmethod @property` looks like."""
return 24
@staticmethod
def a_static_method():
"""This is what a `@staticmethod` looks like."""
print("Hello World")
class Bar(Foo):
bar: str
"""A new attribute defined on this subclass."""
class Baz:
"""
This class is an attribute of `Bar`.
To not create overwhelmingly complex trees, pdoc flattens the class hierarchy in the documentation
(but not in the navigation).
It should be noted that inner classes are a pattern you most often want to avoid in Python.
Think about moving stuff in a new package instead!
Below, you see what happens if a class has no constructor defined (and hence no constructor docstring).
"""
def wat(self):
"""A regular method. Above, you see what happens if a class has no constructor defined and
no constructor docstring."""
async def i_am_async(self) -> int:
"""
This is an example of an async function.
- Knock, knock
- An async function
- Who's there?
"""
@cache
def fib(n):
"""
This is an example of decorated function. Decorators are included in the documentation as well.
This is often useful when documenting web APIs, for example.
"""
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
def security(test=os.environ):
"""
Default values are generally rendered using repr(),
but some special cases -- like os.environ -- are overriden to avoid leaking sensitive data.
"""
return False
class DoubleInherit(Foo, Bar.Baz, abc.ABC):
"""This is an example of a class that inherits from multiple parent classes."""
CONST_B = "yes"
"""A constant without type annotation"""
CONST_NO_DOC = "SHOULD NOT APPEAR"
@dataclass
class DataDemo:
"""
This is an example for a dataclass.
Dataclasses generate a relatively pointless docstring by default,
but you can override it by providing your own (like here!).
As usual, you can link to individual properties: `DataDemo.a`.
"""
a: int
"""Again, we can document indivial properties with docstrings."""
b: Sequence[str]
c: bool = field(repr=False, default=True)
"""This property is assigned to `dataclasses.field()`, which works just as well."""
class EnumDemo(enum.Enum):
"""
This is an example for an Enum.
As usual, you can link to individual properties: `GREEN`.
"""
RED = 1
GREEN = 2
BLUE = enum.auto()