Skip to content


When parsing source code, Griffe builds enhanced ASTs for type annotations, decorators, parameter defaults, attribute values, etc.

These "expressions" are very similar to what Python's ast module gives you back when parsing source code, with a few differences: attributes like a.b.c. are flattened, and names like a have a parent object attached to them, a Griffe object, allowing to resolve this name to its full path given the scope of its parent.

You can write some code below and print annotations or attribute values with Rich's pretty printer to see how expressions look like.

Editor (session: default) Run
from griffe.tests import temporary_visited_module
from rich.pretty import pprint

code = """
    from dataclasses import dataclass
    from random import randint

    class Bar:
        baz: int

    def get_some_baz() -> int:
        return randint(0, 10)

    foo: Bar = Bar(baz=get_some_baz())

with temporary_visited_module(code) as module:
Output Clear

Ultimately, these expressions are what allow downstream tools such as mkdocstrings' Python handler to render cross-references to every object it knows of, coming from the current code base or loaded from object inventories (objects.inv files).

During static analysis, these expressions also allow to analyze decorators, dataclass fields, and many more things in great details, and in a robust manner, to build third-party libraries support in the form of Griffe extensions.

To learn how to navigate expressions, read their API reference.


Sponsors only Insiders 1.2.0

The Python language keeps evolving, and often library developers must continue supporting a few minor versions of Python. Therefore they cannot use some features that were introduced in the latest versions.

Yet this doesn't mean they can't enjoy latest features in their own docs: Griffe allows to "modernize" expressions, for example by replacing typing.Union with PEP 604 type unions |. Thanks to this, downstream tools like mkdocstrings can automatically transform type annotations into their modern equivalent. This improves consistency in your docs, and shows users how to use your code with the latest features of the language.

To modernize an expression, simply call its modernize() method. It returns a new, modernized expression. Some parts of the expression might be left unchanged, so be careful if you decide to mutate them.

Modernizations applied:

  • typing.Dict[A, B] becomes dict[A, B]
  • typing.List[A] becomes list[A]
  • typing.Set[A] becomes set[A]
  • typing.Tuple[A] becomes tuple[A]
  • typing.Union[A, B] becomes A | B
  • typing.Optional[A] becomes A | None