Edit on GitHub

demo_long

Test Module

This is a test module demonstrating pdoc's parsing capabilities.

  • All docstrings support plain markdown.
  • Including code!

    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 sections in your module docstring, which will also show up in the navigation.

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

A happy constant. ✨
pdoc documents constants with their type annotation and default value.

FOO_SINGLETON: demo_long.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:

FOO_SINGLETON: "Foo"

Similar to mypy, pdoc resolves string forward references automatically.

def a_simple_function(a: str) -> str:
66def a_simple_function(a: str) -> str:
67    """
68    This is a basic module-level function.
69
70    For a more complex example, take a look at `a_complex_function`!
71    """
72    return a.upper()

This is a basic module-level function.

For a more complex example, take a look at a_complex_function!

def a_complex_function( a: str, b: Union[demo_long.Foo, str], *, c: Optional[~T] = None) -> Optional[~T]:
78def a_complex_function(
79    a: str, b: Union["Foo", str], *, c: Optional[T] = None
80) -> Optional[T]:
81    """
82    This is a function with a fairly complex signature,
83    involving type annotations with `typing.Union`, a `typing.TypeVar` (~T),
84    as well as a keyword-only arguments (*).
85    """
86    return None

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 (*).

class Foo:
 89class Foo:
 90    """
 91    `Foo` is a basic class without any parent classes (except for the implicit `object` class).
 92
 93    You will see in the definition of `Bar` that docstrings are inherited by default.
 94
 95    Functions in the current scope can be referenced without prefix: `a_regular_function()`.
 96    """
 97
 98    an_attribute: Union[str, List["int"]]
 99    """A regular attribute with type annotations"""
100
101    a_class_attribute: ClassVar[str] = "lots of foo!"
102    """An attribute with a ClassVar annotation."""
103
104    def __init__(self) -> None:
105        """
106        The constructor is currently always listed first as this feels most natural."""
107        self.a_constructor_only_attribute: int = 42
108        """This attribute is defined in the constructor only, but still picked up by pdoc's AST traversal."""
109
110        self.undocumented_constructor_attribute = 42
111        a_complex_function("a", "Foo")
112
113    def a_regular_function(self) -> "Foo":
114        """This is a regular method, returning the object itself."""
115        return self
116
117    @property
118    def a_property(self) -> str:
119        """This is a `@property` attribute. pdoc will display it as a variable."""
120        return "true foo"
121
122    @cached_property
123    def a_cached_property(self) -> str:
124        """This is a `@functools.cached_property` attribute. pdoc will display it as a variable as well."""
125        return "true foo"
126
127    @cache
128    def a_cached_function(self) -> str:
129        """This is method with `@cache` decoration."""
130        return "true foo"
131
132    @classmethod
133    def a_class_method(cls) -> int:
134        """This is what a `@classmethod` looks like."""
135        return 24
136
137    @classmethod  # type: ignore
138    @property
139    def a_class_property(cls) -> int:
140        """This is what a `@classmethod @property` looks like."""
141        return 24
142
143    @staticmethod
144    def a_static_method():
145        """This is what a `@staticmethod` looks like."""
146        print("Hello World")

Foo is a basic class without any parent classes (except for the implicit 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().

Foo()
104    def __init__(self) -> None:
105        """
106        The constructor is currently always listed first as this feels most natural."""
107        self.a_constructor_only_attribute: int = 42
108        """This attribute is defined in the constructor only, but still picked up by pdoc's AST traversal."""
109
110        self.undocumented_constructor_attribute = 42
111        a_complex_function("a", "Foo")

The constructor is currently always listed first as this feels most natural.

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.

a_constructor_only_attribute: int

This attribute is defined in the constructor only, but still picked up by pdoc's AST traversal.

def a_regular_function(self) -> demo_long.Foo:
113    def a_regular_function(self) -> "Foo":
114        """This is a regular method, returning the object itself."""
115        return self

This is a regular method, returning the object itself.

a_property: str

This is a @property attribute. pdoc will display it as a variable.

a_cached_property: str

This is a @functools.cached_property attribute. pdoc will display it as a variable as well.

@cache
def a_cached_function(self) -> str:
127    @cache
128    def a_cached_function(self) -> str:
129        """This is method with `@cache` decoration."""
130        return "true foo"

This is method with @cache decoration.

@classmethod
def a_class_method(cls) -> int:
132    @classmethod
133    def a_class_method(cls) -> int:
134        """This is what a `@classmethod` looks like."""
135        return 24

This is what a @classmethod looks like.

a_class_property: int

This is what a @classmethod @property looks like.

@staticmethod
def a_static_method():
143    @staticmethod
144    def a_static_method():
145        """This is what a `@staticmethod` looks like."""
146        print("Hello World")

This is what a @staticmethod looks like.

class Bar(Foo):
149class Bar(Foo):
150    bar: str
151    """A new attribute defined on this subclass."""
152
153    class Baz:
154        """
155        This class is an attribute of `Bar`.
156        To not create overwhelmingly complex trees, pdoc flattens the class hierarchy in the documentation
157        (but not in the navigation).
158
159        It should be noted that inner classes are a pattern you most often want to avoid in Python.
160        Think about moving stuff in a new package instead!
161
162        Below, you see what happens if a class has no constructor defined (and hence no constructor docstring).
163        """
164
165        def wat(self):
166            """A regular method. Above, you see what happens if a class has no constructor defined and
167            no constructor docstring."""

Foo is a basic class without any parent classes (except for the implicit 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().

bar: str

A new attribute defined on this subclass.

class Bar.Baz:
153    class Baz:
154        """
155        This class is an attribute of `Bar`.
156        To not create overwhelmingly complex trees, pdoc flattens the class hierarchy in the documentation
157        (but not in the navigation).
158
159        It should be noted that inner classes are a pattern you most often want to avoid in Python.
160        Think about moving stuff in a new package instead!
161
162        Below, you see what happens if a class has no constructor defined (and hence no constructor docstring).
163        """
164
165        def wat(self):
166            """A regular method. Above, you see what happens if a class has no constructor defined and
167            no constructor docstring."""

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).

Bar.Baz()
def wat(self):
165        def wat(self):
166            """A regular method. Above, you see what happens if a class has no constructor defined and
167            no constructor docstring."""

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:
170async def i_am_async(self) -> int:
171    """
172    This is an example of an async function.
173
174    - Knock, knock
175    - An async function
176    - Who's there?
177    """
178    raise NotImplementedError

This is an example of an async function.

  • Knock, knock
  • An async function
  • Who's there?
@cache
def fib(n):
181@cache
182def fib(n):
183    """
184    This is an example of decorated function. Decorators are included in the documentation as well.
185    This is often useful when documenting web APIs, for example.
186    """
187    if n < 2:
188        return n
189    return fib(n - 1) + fib(n - 2)

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.

def security(test=os.environ):
192def security(test=os.environ):
193    """
194    Default values are generally rendered using repr(),
195    but some special cases -- like os.environ -- are overridden to avoid leaking sensitive data.
196    """
197    return False

Default values are generally rendered using repr(), but some special cases -- like os.environ -- are overridden to avoid leaking sensitive data.

class DoubleInherit(Foo, Bar.Baz, abc.ABC):
200class DoubleInherit(Foo, Bar.Baz, abc.ABC):
201    """This is an example of a class that inherits from multiple parent classes."""

This is an example of a class that inherits from multiple parent classes.

CONST_B = 'yes'

A constant without type annotation

@dataclass
class DataDemo:
210@dataclass
211class DataDemo:
212    """
213    This is an example for a dataclass.
214
215    As usual, you can link to individual properties: `DataDemo.a`.
216    """
217
218    a: int
219    """Again, we can document individual properties with docstrings."""
220    a2: Sequence[str]
221    # This property has a type annotation but is not documented.
222    a3 = "a3"
223    # This property has a default value but is not documented.
224    a4: str = "a4"
225    # This property has a type annotation and a default value but is not documented.
226    b: bool = field(repr=False, default=True)
227    """This property is assigned to `dataclasses.field()`, which works just as well."""

This is an example for a dataclass.

As usual, you can link to individual properties: DataDemo.a.

DataDemo(a: int, a2: Sequence[str], a4: str = 'a4', b: bool = True)
a: int

Again, we can document individual properties with docstrings.

b: bool = True

This property is assigned to dataclasses.field(), which works just as well.

@dataclass
class DataDemoExtended(DataDemo):
230@dataclass
231class DataDemoExtended(DataDemo):
232    c: str = "42"
233    """A new attribute."""
DataDemoExtended( a: int, a2: Sequence[str], a4: str = 'a4', b: bool = True, c: str = '42')
c: str = '42'

A new attribute.

Inherited Members
DataDemo
a
b
class EnumDemo(enum.Enum):
236class EnumDemo(enum.Enum):
237    """
238    This is an example of an Enum.
239
240    As usual, you can link to individual properties: `GREEN`.
241    """
242
243    RED = 1
244    """I am the red."""
245    GREEN = 2
246    """I am green."""
247    BLUE = enum.auto()

This is an example of an Enum.

As usual, you can link to individual properties: GREEN.

RED = <EnumDemo.RED: 1>

I am the red.

GREEN = <EnumDemo.GREEN: 2>

I am green.

BLUE = <EnumDemo.BLUE: 3>
Inherited Members
enum.Enum
name
value
def embed_image():
250def embed_image():
251    """
252    This docstring includes an embedded image:
253
254    ```
255    ![pdoc logo](../docs/logo.png)
256    ```
257
258    ![pdoc logo](../../docs/logo.png)
259    """

This docstring includes an embedded image:

![pdoc logo](../docs/logo.png)

pdoc logo

def admonitions():
262def admonitions():
263    """
264    pdoc also supports basic reStructuredText admonitions:
265
266    ```
267    .. note/warning/danger:: Optional title
268       Body text
269    ```
270
271    .. note::
272       Hi there!
273
274    .. warning:: Be Careful!
275       This warning has both a title and content.
276
277    .. danger::
278       Danger ahead.
279
280    """

pdoc also supports basic reStructuredText admonitions:

.. note/warning/danger:: Optional title
   Body text

Hi there!

Be Careful!

This warning has both a title and content.

Danger ahead.