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

View Source
"""

# 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.
"""

NO_DOCSTRING: int
# this variable has a type annotation but not docstring, so it does not show up.


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."""
    a2: Sequence[str]
    # This property has a type annotation but is not documented, so it does not show up.
    b: 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
    """I am the red."""
    GREEN = 2
    """I am green."""
    BLUE = enum.auto()
    """I am blue."""
#   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:
View Source
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()

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]:
View Source
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

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:
View Source
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")

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

#   Foo()
View Source
    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()

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:
View Source
    def a_regular_function(self) -> "Foo":
        """This is a regular method, returning the object itself."""
        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:
View Source
    @cache
    def a_cached_function(self) -> str:
        """This is method with `@cache` decoration."""
        return "true foo"

This is method with @cache decoration.

#  
@classmethod
def a_class_method(cls) -> int:
View Source
    @classmethod
    def a_class_method(cls) -> int:
        """This is what a `@classmethod` looks like."""
        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():
View Source
    @staticmethod
    def a_static_method():
        """This is what a `@staticmethod` looks like."""
        print("Hello World")

This is what a @staticmethod looks like.

#   class Bar(Foo):
View Source
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."""

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

#   bar: str

A new attribute defined on this subclass.

#   class Bar.Baz:
View Source
    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."""

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):
View Source
        def wat(self):
            """A regular method. Above, you see what happens if a class has no constructor defined and
            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:
View Source
async def i_am_async(self) -> int:
    """
    This is an example of an async function.

    - Knock, knock
    - An async function
    - Who's there?
    """

This is an example of an async function.

  • Knock, knock
  • An async function
  • Who's there?
#  
@cache
def fib(n):
View Source
@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)

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):
View Source
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

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

#   class DoubleInherit(Foo, Bar.Baz, abc.ABC):
View Source
class DoubleInherit(Foo, Bar.Baz, abc.ABC):
    """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:
View Source
@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."""
    a2: Sequence[str]
    # This property has a type annotation but is not documented, so it does not show up.
    b: bool = field(repr=False, default=True)
    """This property is assigned to `dataclasses.field()`, which works just as well."""

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.

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

Again, we can document indivial properties with docstrings.

#   b: bool = True

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

#   class EnumDemo(enum.Enum):
View Source
class EnumDemo(enum.Enum):
    """
    This is an example for an Enum.

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

    RED = 1
    """I am the red."""
    GREEN = 2
    """I am green."""
    BLUE = enum.auto()
    """I am blue."""

This is an example for 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>

I am blue.

Inherited Members
enum.Enum
name
value