`
- sponsors.forEach(function (sponsor) {
- html += `
-
-
-
- `
- });
- html += '
Summary.
+Type Aliases:
+ +**Name** | **Description** +------------ | ---------------- +`TypeAlias` | Some type alias. + +TypeAliasSummary.
+//// + +//// tab | Without classes +Summary.
+TypeAliasSummary.
+//// +/// + +[](){#option-show_docstring_modules} ## `show_docstring_modules` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** -Whether to render the "Modules" sections of docstrings. +Whether to render the "Modules" section of docstrings. ```yaml title="in mkdocs.yml (global configuration)" plugins: @@ -847,6 +913,7 @@ Modules: //// /// +[](){#option-show_docstring_description} ## `show_docstring_description` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -910,6 +977,7 @@ class Class: //// /// +[](){#option-show_docstring_examples} ## `show_docstring_examples` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -963,6 +1031,7 @@ hello //// /// +[](){#option-show_docstring_other_parameters} ## `show_docstring_other_parameters` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1013,6 +1082,7 @@ def do_something(**kwargs): //// /// +[](){#option-show_docstring_parameters} ## `show_docstring_parameters` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1063,6 +1133,7 @@ def do_something(whatever: int = 0): //// /// +[](){#option-show_docstring_raises} ## `show_docstring_raises` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1114,6 +1185,7 @@ def raise_runtime_error(): //// /// +[](){#option-show_docstring_receives} ## `show_docstring_receives` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1173,6 +1245,7 @@ def iter_skip( //// /// +[](){#option-show_docstring_returns} ## `show_docstring_returns` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1224,6 +1297,58 @@ def rand() -> int: //// /// +[](){#option-show_docstring_type_parameters} +## `show_docstring_type_parameters` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + + +Whether to render the "Type Parameters" section of docstrings. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + show_docstring_type_parameters: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + show_docstring_type_parameters: false +``` + +```python +class AClass[X: (int, str) = str]: + """Represents something. + + Type Parameters: + X: Something. + """ +``` + +/// admonition | Preview + type: preview + +//// tab | With parameters +AClassRepresents something.
+Type Parameters:
+ +**Name** | **Bound or Constraints** | **Description** | **Default** +---------- | ------------------------ | --------------- | ----------- +`whatever` | `(int, str)` | Something. | `str` +//// + +//// tab | Without parameters +AClassRepresents something.
+//// +/// + +[](){#option-show_docstring_warns} ## `show_docstring_warns` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -1275,6 +1400,7 @@ def warn(): //// /// +[](){#option-show_docstring_yields} ## `show_docstring_yields` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** diff --git a/docs/usage/configuration/general.md b/docs/usage/configuration/general.md index e2a6e169..921f3b27 100644 --- a/docs/usage/configuration/general.md +++ b/docs/usage/configuration/general.md @@ -1,5 +1,6 @@ # General options +[](){#option-allow_inspection} ## `allow_inspection` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -18,6 +19,10 @@ and sometimes the collected data is inaccurate (depending on the tool that was used to compile the module) or too low-level/technical for API documentation. +See also [`force_inspection`](#force_inspection). + +WARNING: **Packages are loaded only once.** When mkdocstrings-python collects data from a Python package (thanks to [Griffe](https://mkdocstrings.github.io/griffe/)), it collects *the entire package* and *caches it*. Next time an object from the same package is rendered, the package is retrieved from the cache and not collected again. The `allow_inspection` option will therefore only have an effect the first time a package is collected, and will do nothing for objects rendered afterwards. + ```yaml title="in mkdocs.yml (global configuration)" plugins: - mkdocstrings: @@ -55,6 +60,406 @@ plugins: //// /// +[](){#option-backlinks} +## `backlinks` + +- **:octicons-package-24: TypeLiteral ["flat", "tree", False] :material-equal: `False`{ title="default value" }**
+
+The `backlinks` option enables rendering of backlinks within your API documentation.
+
+When an arbitrary section of your documentation links to an API symbol, this link will be collected as a backlink, and rendered below your API symbol. In short, the API symbol will link back to the section that links to it. Such backlinks will help your users navigate the documentation, as they will immediately which functions return a specific symbol, or where a specific symbol is accepted as parameter, etc..
+
+Each backlink is a list of breadcrumbs that represent the navigation, from the root page down to the given section.
+
+The available styles for rendering backlinks are **`flat`** and **`tree`**.
+
+- **`flat`** will render backlinks as a single-layer list. This can lead to repetition of breadcrumbs.
+- **`tree`** will combine backlinks into a tree, to remove repetition of breadcrumbs.
+
+WARNING: **Global-only option.** For now, the option only works when set globally in `mkdocs.yml`.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ backlinks: tree
+```
+
+/// admonition | Preview
+ type: preview
+
+//// tab | Flat
+
+////
+
+//// tab | Tree
+
+////
+///
+
+[](){#option-extensions}
+## `extensions`
+
+- **:octicons-package-24: Type list [str | dict [str , dict [str , Any ]]] :material-equal: `[]`{ title="default value" }**
+
+
+The `extensions` option lets you enable [Griffe extensions](https://mkdocstrings.github.io/griffe/extensions/), which enhance or modify the data collected from Python sources (or compiled modules).
+
+Elements in the list can be strings or dictionaries.
+
+Strings denote the path to an extension module, like `griffe_typingdoc`, or to an extension class directly, like `griffe_typingdoc.TypingDocExtension`. When using a module path, all extensions within that module will be loaded and enabled. Strings can also be the path to a Python module, and a class name separated with `:`, like `scripts/griffe_extensions.py` or `scripts/griffe_extensions.py:MyExtension`.
+
+Dictionaries have a single key, which is the module/class path (as a dot-separated qualifier or file path and colon-separated class name, like above), and its value is another dictionary specifying options that will be passed when to class constructors when instantiating extensions.
+
+WARNING: **Packages are loaded only once.** When mkdocstrings-python collects data from a Python package (thanks to [Griffe](https://mkdocstrings.github.io/griffe/)), it collects *the entire package* and *caches it*. Next time an object from the same package is rendered, the package is retrieved from the cache and not collected again. Only the extensions specified the first time the package is loaded will be used. You cannot use a different set of extensions for specific objects rendered afterwards, and you cannot deactivate extensions for objects rendered afterwards either.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ extensions:
+ - griffe_sphinx
+ - griffe_pydantic: {schema: true}
+ - scripts/exts.py:DynamicDocstrings:
+ paths: [mypkg.mymod.myobj]
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: your_package.your_module.your_func
+ options:
+ extensions:
+ - griffe_typingdoc
+```
+
+[](){#option-extra}
+## `extra`
+
+- **:octicons-package-24: Type [`dict`][] :material-equal: `{}`{ title="default value" }**
+
+
+The `extra` option lets you inject additional variables into the Jinja context used when rendering templates. You can then use this extra context in your [overridden templates][templates].
+
+Local `extra` options will be merged into the global `extra` option:
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ extra:
+ hello: world
+```
+
+```md title="in docs/some_page.md (local configuration)"
+::: your_package.your_module.your_func
+ options:
+ extra:
+ foo: bar
+```
+
+...will inject both `hello` and `foo` into the Jinja context when rendering `your_package.your_module.your_func`.
+
+> WARNING: Previously, extra options were supported directly under the `options` key.
+>
+> ```yaml
+> plugins:
+> - mkdocstrings:
+> handlers:
+> python:
+> options:
+> hello: world
+> ```
+>
+> Now that we introduced optional validation of options and automatic JSON schema generation thanks to Pydantic, we require extra options to be put under `options.extra`. Extra options directly under `options` are still supported, but deprecated, and will emit deprecation warnings. Support will be removed in a future version of mkdocstrings-python.
+
+[](){#option-find_stubs_package}
+## `find_stubs_package`
+
+- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
+
+
+When looking for documentation specified in [autodoc instructions][autodoc syntax] (`::: identifier`), also look for
+the stubs package as defined in [PEP 561](https://peps.python.org/pep-0561/) if it exists. This is useful when
+most of your documentation is separately provided by such a package and not inline in your main package.
+
+WARNING: **Packages are loaded only once.** When mkdocstrings-python collects data from a Python package (thanks to [Griffe](https://mkdocstrings.github.io/griffe/)), it collects *the entire package* and *caches it*. Next time an object from the same package is rendered, the package is retrieved from the cache and not collected again. The `find_stubs_package` option will therefore only have an effect the first time a package is collected, and will do nothing for objects rendered afterwards.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ find_stubs_package: true
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: your_package.your_module.your_func
+ options:
+ find_stubs_package: true
+```
+
+```python title="your_package/your_module.py"
+
+def your_func(a, b):
+ # Function code
+ ...
+
+# rest of your code
+```
+
+```python title="your_package-stubs/your_module.pyi"
+
+def your_func(a: int, b: str):
+ """
+ your_funcFunction docstring
+//// + +//// tab | Without find_stubs_package +your_funclist [str ] | None :material-equal: `None`{ title="default value" }**
+
+
+Pre-load modules that are not specified directly in [autodoc instructions][autodoc syntax] (`::: identifier`).
+It is useful when you want to render documentation for a particular member of an object,
+and this member is imported from another package than its parent.
+
+For an imported member to be rendered,
+you need to add it to the [`__all__`][__all__] attribute of the importing module.
+The package from which the imported object originates must be accessible to the handler
+(see [Finding modules](../index.md#finding-modules)).
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ preload_modules:
+ - their_package
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: your_package.your_module
+ options:
+ preload_modules:
+ - their_package
+```
+
+```python title="your_package/your_module.py"
+from their_package.their_module import their_object
+
+__all__ = ["their_object"]
+
+# rest of your code
+```
+
+/// admonition | Preview
+ type: preview
+
+//// tab | With preloaded modules
+your_moduleDocstring of your module.
+their_objectDocstring of their object.
+//// + +//// tab | Without preloaded modules +your_moduleDocstring of your module.
+//// +/// + +[](){#option-show_bases} ## `show_bases` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -92,11 +497,9 @@ plugins: //// /// +[](){#option-show_inheritance_diagram} ## `show_inheritance_diagram` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.7.0](../../insiders/changelog.md#1.7.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** @@ -177,6 +580,7 @@ Mixin2A --> Mixin2B because these classes do not exist in our documentation.* /// +[](){#option-show_source} ## `show_source` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** @@ -222,19 +626,15 @@ def some_function(): //// /// -## `preload_modules` +[](){#option-skip_local_inventory} +## `skip_local_inventory` -- **:octicons-package-24: Typelist [str ] | None :material-equal: `None`{ title="default value" }**
+- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
-Pre-load modules that are not specified directly in [autodoc instructions][autodoc syntax] (`::: identifier`).
-It is useful when you want to render documentation for a particular member of an object,
-and this member is imported from another package than its parent.
+Whether to skip registering symbols in the objects inventory.
-For an imported member to be rendered,
-you need to add it to the [`__all__`][__all__] attribute of the importing module.
-The package from which the imported object originates must be accessible to the handler
-(see [Finding modules](../index.md#finding-modules)).
+With this option enabled, re-rendering docstrings for objects from external inventories is possible with their cross-references pointing to the original external inventory, not local. Similarly, it becomes possible to render the same symbol several times in the same documentation, with only one canonical location being used for cross-references (preventing confusion in mkdocs-autorefs).
```yaml title="in mkdocs.yml (global configuration)"
plugins:
@@ -242,94 +642,46 @@ plugins:
handlers:
python:
options:
- preload_modules:
- - their_package
+ skip_local_inventory: false
```
```md title="or in docs/some_page.md (local configuration)"
-::: your_package.your_module
+::: path.to.module
options:
- preload_modules:
- - their_package
-```
-
-```python title="your_package/your_module.py"
-from their_package.their_module import their_object
-
-__all__ = ["their_object"]
-
-# rest of your code
+ skip_local_inventory: true
```
/// admonition | Preview
type: preview
-//// tab | With preloaded modules
-your_moduleDocstring of your module.
-their_objectDocstring of their object.
-//// - -//// tab | Without preloaded modules -your_moduleDocstring of your module.
-//// -/// - -## `find_stubs_package` -- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** - - -When looking for documentation specified in [autodoc instructions][autodoc syntax] (`::: identifier`), also look for -the stubs package as defined in [PEP 561](https://peps.python.org/pep-0561/) if it exists. This is useful when -most of your documentation is separately provided by such a package and not inline in your main package. +//// tab | Without `skip_local_inventory` -```yaml title="in mkdocs.yml (global configuration)" -plugins: -- mkdocstrings: - handlers: - python: - options: - find_stubs_package: true -``` - -```md title="or in docs/some_page.md (local configuration)" -::: your_package.your_module.your_func +```md exec="on" +::: bisect.bisect_left options: - find_stubs_package: true + heading_level: 3 + skip_local_inventory: false + show_docstring_description: false ``` -```python title="your_package/your_module.py" - -def your_func(a, b): - # Function code - ... +Notice how [`bisect.bisect_left`][] now points to the section above. -# rest of your code -``` +//// -```python title="your_package-stubs/your_module.pyi" +//// tab | With `skip_local_inventory` -def your_func(a: int, b: str): - """ -your_funcFunction docstring
-//// +Notice how [`bisect.bisect_right`][] points to the original Python documentation. -//// tab | Without find_stubs_package -your_func mutate U
+
+To customize symbols, see [Customizing symbol types](../customization.md/#symbol-types).
+
+///
diff --git a/docs/usage/configuration/members.md b/docs/usage/configuration/members.md
index 119d8294..53d955fa 100644
--- a/docs/usage/configuration/members.md
+++ b/docs/usage/configuration/members.md
@@ -1,5 +1,6 @@
# Members options
+[](){#option-members}
## `members`
- **:octicons-package-24: Type list [str ] |
@@ -95,6 +96,7 @@ this_attribute = 0
INFO: **The default behavior (with unspecified `members` or `members: null`) is to use [`filters`][].**
+[](){#option-inherited_members}
## `inherited_members`
- **:octicons-package-24: Type list [str ] |
@@ -259,15 +261,17 @@ class Main(Base):
///
+[](){#option-members_order}
## `members_order`
-- **:octicons-package-24: Type [`str`][] :material-equal: `"alphabetical"`{ title="default value" }**
+- **:octicons-package-24: Type `str | list[str]` :material-equal: `"alphabetical"`{ title="default value" }**
The members ordering to use. Possible values:
-- `alphabetical`: order by the members names.
-- `source`: order members as they appear in the source file.
+- `__all__`: Order according to `__all__` attributes. Since classes do not define `__all__` attributes, you can specify a second ordering method by using a list.
+- `alphabetical`: Order by the members names.
+- `source`: Order members as they appear in the source file.
The order applies for all members, recursively.
The order will be ignored for members that are explicitely sorted using the [`members`][] option.
@@ -289,6 +293,12 @@ plugins:
members_order: source
```
+```md title="or in docs/some_page.md (local configuration)"
+::: package.module
+ options:
+ members_order: [__all__, source]
+```
+
```python title="package/module.py"
"""Module docstring."""
@@ -329,12 +339,21 @@ def function_c():
////
///
+[](){#option-filters}
## `filters`
-- **:octicons-package-24: Type list [str ] | None :material-equal: `["!^_[^_]"]`{ title="default value" }**
+- **:octicons-package-24: Type list [str ] | Literal ["public"] | None :material-equal: `["!^_[^_]"]`{ title="default value" }**
-A list of filters applied to filter objects based on their name.
+A list of filters, or `"public"`.
+
+**Filtering methods**
+
+[](){#option-filters-public}
+
+The `public` filtering method will include only public objects: those added to the `__all__` attribute of modules, or not starting with a single underscore. Special methods and attributes ("dunder" methods/attributes, starting and ending with two underscores), like `__init__`, `__call__`, `__mult__`, etc., are always considered public.
+
+**List of filters**
Filters are regular expressions. These regular expressions are evaluated by Python
and so must match the syntax supported by the [`re`][] module.
@@ -375,13 +394,13 @@ plugins:
python:
options:
filters:
- - "!^_"
+ - "!^_[^_]"
```
```md title="or in docs/some_page.md (local configuration)"
::: package.module
options:
- filters: []
+ filters: public
```
```python title="package/module.py"
@@ -427,6 +446,7 @@ Here are some common filters that you might to want to use.
- `["!^_[^_]"]`: exclude all private/protected objects, keep special ones (default filters)
///
+[](){#option-group_by_category}
## `group_by_category`
- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
@@ -496,6 +516,7 @@ def function_d():
////
///
+[](){#option-show_submodules}
## `show_submodules`
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
@@ -550,18 +571,16 @@ package
////
///
+[](){#option-summary}
## `summary`
-[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } —
-[:octicons-tag-24: Insiders 1.2.0](../../insiders/changelog.md#1.2.0)
-
- **:octicons-package-24: Type bool | dict [str , bool ] :material-equal: `False`{ title="default value" }**
Whether to render summaries of modules, classes, functions (methods) and attributes.
This option accepts a boolean (`yes`, `true`, `no`, `false` in YAML)
-or a dictionary with one or more of the following keys: `attributes`, `functions`, `classes`, `modules`,
+or a dictionary with one or more of the following keys: `attributes`, `functions`, `classes`, `modules`, `type_aliases`,
with booleans as values. Class methods summary is (de)activated with the `functions` key.
By default, `summary` is false, and by extension all values are false.
@@ -644,6 +663,7 @@ plugins:
////
///
+[](){#option-show_labels}
## `show_labels`
- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md
index e5e4cb88..109362e3 100644
--- a/docs/usage/configuration/signatures.md
+++ b/docs/usage/configuration/signatures.md
@@ -1,5 +1,6 @@
# Signatures options
+[](){#option-annotations_path}
## `annotations_path`
- **:octicons-package-24: Type [`str`][] :material-equal: `"brief"`{ title="default value" }**
@@ -146,6 +147,7 @@ def convert(text: str, md: Markdown) -> Markup:
////
///
+[](){#option-line_length}
## `line_length`
- **:octicons-package-24: Type [`int`][] :material-equal: `60`{ title="default value" }**
@@ -154,10 +156,15 @@ def convert(text: str, md: Markdown) -> Markup:
Maximum line length when formatting code/signatures.
When separating signatures from headings with the [`separate_signature`][] option,
-the Python handler will try to format the signatures using [Black] and
+the Python handler will try to format the signatures using a formatter and
the specified line length.
-If Black is not installed, the handler issues an INFO log once.
+The handler will automatically try to format using :
+
+1. [Black]
+2. [Ruff]
+
+If a formatter is not found, the handler issues an INFO log once.
```yaml title="in mkdocs.yml (global configuration)"
plugins:
@@ -193,14 +200,9 @@ plugins:
////
///
+[](){#option-modernize_annotations}
## `modernize_annotations`
-[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } —
-[:octicons-tag-24: Insiders 1.8.0](../../insiders/changelog.md#1.8.0) —
-**This feature also requires
-[Griffe Insiders](https://mkdocstrings.github.io/griffe/insiders/)
-to be installed.**
-
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
@@ -278,8 +280,59 @@ plugins:
///
+[](){#option-overloads_only}
+## `overloads_only`
+
+- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
+Whether to hide the implementation signature if the overloads are shown with [`show_overloads`][].
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ overloads_only: false
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: path.to.module
+ options:
+ overloads_only: true
+```
+
+/// admonition | Preview
+ type: preview
+//// tab | With overloads only
+function
+
+```python
+@overload
+function(param1: int): ...
+@overload
+function(param1: str): ...
+```
+Function docstring.
+
+////
+//// tab | Without overloads only
+function
+
+```python
+@overload
+function(param1: int): ...
+@overload
+function(param1: str): ...
+function(param1: str | int)
+```
+Function docstring.
+
+////
+
+///
+
+[](){#option-show_signature}
## `show_signature`
- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
@@ -318,6 +371,7 @@ plugins:
////
///
+[](){#option-show_signature_annotations}
## `show_signature_annotations`
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
@@ -372,6 +426,62 @@ function(param1, param2=None)
////
///
+[](){#option-show_signature_type_parameters}
+## `show_signature_type_parameters`
+
+- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
+
+
+Show the type parameters in generic classes, methods, functions and type aliases
+signatures.
+
+Since the heading can become quite long when type parameters are rendered, it is
+usually best to [separate the signature][separate_signature] from the heading.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ separate_signature: true
+ show_signature_annotations: true
+ show_signature_type_parameters: true
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: path.to.module
+ options:
+ separate_signature: true
+ show_signature_annotations: true
+ show_signature_type_parameters: false
+```
+
+/// admonition | Preview
+ type: preview
+
+//// tab | With signature type parameters
+function
+
+```python
+function[T, *R](param: T) -> tuple[*R]
+```
+
+Function docstring.
+////
+
+//// tab | Without signature type parameters
+function
+
+```python
+function(param: T) -> tuple[*R]
+```
+
+Function docstring.
+////
+///
+
+[](){#option-separate_signature}
## `separate_signature`
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
@@ -380,10 +490,15 @@ function(param1, param2=None)
Whether to put the whole signature in a code block below the heading.
When separating signatures from headings,
-the Python handler will try to format the signatures using [Black] and
+the Python handler will try to format the signatures using a formatter and
the specified [line length][line_length].
-If Black is not installed, the handler issues an INFO log once.
+The handler will automatically try to format using :
+
+1. [Black]
+2. [Ruff]
+
+If a formatter is not found, the handler issues an INFO log once.
```yaml title="in mkdocs.yml (global configuration)"
plugins:
@@ -419,9 +534,102 @@ function(param1, param2=None)
////
///
-## `signature_crossrefs`
+[](){#option-show_attribute_values}
+## `show_attribute_values`
+
+- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
+
+
+Show initial values of attributes in classes.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ show_attribute_values: true
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: path.to.object
+ options:
+ show_attribute_values: true
+```
+
+```python title="package/module.py"
+class SomeClass:
+ def __init__(self):
+ self.some_attr = 1
+```
+
+/// admonition | Preview
+ type: preview
+
+//// tab | With attribute values visible
+SomeClass
+some_attr = 1
+////
+
+//// tab | With attribute values hidden
+SomeClass
+some_attr
+////
+///
+
+[](){#option-show_overloads}
+## `show_overloads`
-[:octicons-tag-24: Insiders 1.0.0](../../insiders/changelog.md#1.0.0)
+- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }**
+
+Whether to render function / method overloads.
+
+```yaml title="in mkdocs.yml (global configuration)"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ options:
+ show_overloads: true
+```
+
+```md title="or in docs/some_page.md (local configuration)"
+::: path.to.module
+ options:
+ show_overloads: false
+```
+
+/// admonition | Preview
+ type: preview
+//// tab | With overloads
+function
+
+
+```python
+@overload
+function(param1: int): ...
+
+@overload
+function(param1: str): ...
+
+function(param1: str | int)
+```
+Function docstring.
+
+////
+//// tab | Without overloads
+function
+
+```python
+function(param1: str | int)
+```
+Function docstring.
+
+////
+///
+
+[](){#option-signature_crossrefs}
+## `signature_crossrefs`
Whether to render cross-references for type annotations in signatures.
@@ -466,6 +674,7 @@ plugins:
////
///
+[](){#option-unwrap_annotated}
## `unwrap_annotated`
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
diff --git a/docs/usage/customization.md b/docs/usage/customization.md
index 907809c8..d1e66b31 100644
--- a/docs/usage/customization.md
+++ b/docs/usage/customization.md
@@ -34,9 +34,10 @@ The following CSS classes are used in the generated HTML:
- `doc-class`: on `div`s containing a class
- `doc-function`: on `div`s containing a function
- `doc-module`: on `div`s containing a module
+ - `doc-type_alias`: on `div`s containing a type alias
- `doc-heading`: on objects headings
- `doc-object-name`: on `span`s wrapping objects names/paths in the heading
- - `doc-KIND-name`: as above, specific to the kind of object (module, class, function, attribute)
+ - `doc-KIND-name`: as above, specific to the kind of object (module, class, function, attribute, type_alias)
- `doc-contents`: on `div`s wrapping the docstring then the children (if any)
- `first`: same, but only on the root object's contents `div`
- `doc-labels`: on `span`s wrapping the object's labels
@@ -48,7 +49,7 @@ The following CSS classes are used in the generated HTML:
- `doc-symbol`: on `code` tags of symbol types
- `doc-symbol-heading`: on symbol types in headings
- `doc-symbol-toc`: on symbol types in the ToC
- - `doc-symbol-KIND`: specific to the kind of object (`module`, `class`, `function`, `method`, `attribute`)
+ - `doc-symbol-KIND`: specific to the kind of object (`module`, `class`, `function`, `method`, `attribute`, `type_alias`)
/// admonition | Example with colorful labels
type: example
@@ -90,33 +91,41 @@ by overriding the values of our CSS variables, for example:
```css title="docs/css/mkdocstrings.css"
[data-md-color-scheme="default"] {
--doc-symbol-parameter-fg-color: #df50af;
+ --doc-symbol-type_parameter-fg-color: #df50af;
--doc-symbol-attribute-fg-color: #0079ff;
--doc-symbol-function-fg-color: #00dfa2;
--doc-symbol-method-fg-color: #00dfa2;
--doc-symbol-class-fg-color: #d1b619;
+ --doc-symbol-type_alias-fg-color: #d1b619;
--doc-symbol-module-fg-color: #ff0060;
--doc-symbol-parameter-bg-color: #df50af1a;
+ --doc-symbol-type_parameter-bg-color: #df50af1a;
--doc-symbol-attribute-bg-color: #0079ff1a;
--doc-symbol-function-bg-color: #00dfa21a;
--doc-symbol-method-bg-color: #00dfa21a;
--doc-symbol-class-bg-color: #d1b6191a;
+ --doc-symbol-type_alias-bg-color: #d1b6191a;
--doc-symbol-module-bg-color: #ff00601a;
}
[data-md-color-scheme="slate"] {
--doc-symbol-parameter-fg-color: #ffa8cc;
+ --doc-symbol-type_parameter-fg-color: #ffa8cc;
--doc-symbol-attribute-fg-color: #963fb8;
--doc-symbol-function-fg-color: #6d67e4;
--doc-symbol-method-fg-color: #6d67e4;
--doc-symbol-class-fg-color: #46c2cb;
+ --doc-symbol-type_alias-fg-color: #46c2cb;
--doc-symbol-module-fg-color: #f2f7a1;
--doc-symbol-parameter-bg-color: #ffa8cc1a;
+ --doc-symbol-type_parameter-bg-color: #ffa8cc1a;
--doc-symbol-attribute-bg-color: #963fb81a;
--doc-symbol-function-bg-color: #6d67e41a;
--doc-symbol-method-bg-color: #6d67e41a;
--doc-symbol-class-bg-color: #46c2cb1a;
+ --doc-symbol-type_alias-bg-color: #46c2cb1a;
--doc-symbol-module-bg-color: #f2f7a11a;
}
```
@@ -129,17 +138,21 @@ otherwise just override the variables at root level:
```css title="docs/css/mkdocstrings.css"
:root {
--doc-symbol-parameter-fg-color: #df50af;
+ --doc-symbol-type_parameter-fg-color: #df50af;
--doc-symbol-attribute-fg-color: #0079ff;
--doc-symbol-function-fg-color: #00dfa2;
--doc-symbol-method-fg-color: #00dfa2;
--doc-symbol-class-fg-color: #d1b619;
+ --doc-symbol-type_alias-fg-color: #d1b619;
--doc-symbol-module-fg-color: #ff0060;
--doc-symbol-parameter-bg-color: #df50af1a;
+ --doc-symbol-type_parameter-bg-color: #df50af1a;
--doc-symbol-attribute-bg-color: #0079ff1a;
--doc-symbol-function-bg-color: #00dfa21a;
--doc-symbol-method-bg-color: #00dfa21a;
--doc-symbol-class-bg-color: #d1b6191a;
+ --doc-symbol-type_alias-bg-color: #d1b6191a;
--doc-symbol-module-bg-color: #ff00601a;
}
```
@@ -151,33 +164,41 @@ otherwise just override the variables at root level:
@@ -204,6 +225,10 @@ For example, to use single letters instead of truncated types:
content: "P";
}
+.doc-symbol-type_parameter::after {
+ content: "P";
+}
+
.doc-symbol-attribute::after {
content: "A";
}
@@ -220,6 +245,10 @@ For example, to use single letters instead of truncated types:
content: "C";
}
+.doc-symbol-type_alias::after {
+ content: "T";
+}
+
.doc-symbol-module::after {
content: "M";
}
@@ -234,6 +263,10 @@ For example, to use single letters instead of truncated types:
content: "P";
}
+ #preview-symbol-names .doc-symbol-type_parameter::after {
+ content: "P";
+ }
+
#preview-symbol-names .doc-symbol-attribute::after {
content: "A";
}
@@ -250,16 +283,22 @@ For example, to use single letters instead of truncated types:
content: "C";
}
+ #preview-symbol-names .doc-symbol-type_alias::after {
+ content: "T";
+ }
+
#preview-symbol-names .doc-symbol-module::after {
content: "M";
}
- Parameter:
+ - Type Parameter:
- Attribute:
- Function:
- Method:
- Class:
+ - Type Alias:
- Module:
@@ -283,7 +322,7 @@ for filepath in sorted(path for path in Path(basedir).rglob("*") if "_base" not
)
```
-See them [in the repository](https://github.com/mkdocstrings/python/tree/master/src/mkdocstrings_handlers/python/templates/).
+See them [in the repository](https://github.com/mkdocstrings/python/tree/main/src/mkdocstrings_handlers/python/templates/).
See the general *mkdocstrings* documentation to learn how to override them: https://mkdocstrings.github.io/theming/#templates.
Each one of these templates extends a base version in `theme/_base`. Example:
@@ -324,6 +363,19 @@ Available context:
- `config`: The handler configuration (dictionary).
- `module`: The [Module][griffe.Module] instance.
+#### `type_alias.html`
+
+- `heading`: The class heading.
+- `labels`: The class labels.
+- `signature`: The class signature.
+- `contents`: The class contents: bases, docstring, source and children blocks.
+- `docstring`: The class docstring.
+
+Available context:
+
+- `config`: The handler configuration (dictionary).
+- `type_alias`: The [TypeAlias][griffe.TypeAlias] instance.
+
#### `class.html`
- `heading`: The class heading.
@@ -371,14 +423,16 @@ Available context:
#### Docstring sections
In `docstring/attributes.html`,
-`docstring/functions.html`,
-`docstring/classes.html`,
-`docstring/modules.html`,
+`docstring/functions.html`,
+`docstring/classes.html`,
+`docstring/modules.html`,
`docstring/other_parameters.html`,
`docstring/parameters.html`,
`docstring/raises.html`,
`docstring/receives.html`,
`docstring/returns.html`,
+`docstring/type_aliases.html`,
+`docstring/type_parameters.html`,
`docstring/warns.html`,
and `docstring/yields.html`:
@@ -439,4 +493,4 @@ div.doc-contents:not(.first) {
padding-left: 25px;
border-left: .05rem solid rgba(200, 200, 200, 0.2);
}
-```
\ No newline at end of file
+```
diff --git a/docs/usage/docstrings/google.md b/docs/usage/docstrings/google.md
index de35d46e..1c843a3b 100644
--- a/docs/usage/docstrings/google.md
+++ b/docs/usage/docstrings/google.md
@@ -17,11 +17,11 @@ For example:
This admonition has a custom title!
"""
```
-
+
=== "Result"
NOTE: It looks like a section, but it will be rendered as an admonition.
- TIP: **You can even choose a title.**
+ TIP: **You can even choose a title.**
This admonition has a custom title!
See [Napoleon's documentation](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html).
diff --git a/docs/usage/index.md b/docs/usage/index.md
index 57b9fdc1..3348a627 100644
--- a/docs/usage/index.md
+++ b/docs/usage/index.md
@@ -1,6 +1,6 @@
# Usage
-TIP: **This is the documentation for the NEW Python handler.**
+TIP: **This is the documentation for the NEW Python handler.**
To read the documentation for the LEGACY handler,
go to the [legacy handler documentation](https://mkdocstrings.github.io/python-legacy).
@@ -75,10 +75,11 @@ plugins:
Some options are **global only**, and go directly under the handler's name.
-#### `import`
+[](){#setting-inventories}
+#### `inventories`
-This option is used to import Sphinx-compatible objects inventories from other
-documentation sites. For example, you can import the standard library
+This option is used to load Sphinx-compatible objects inventories from other
+documentation sites. For example, you can load the standard library
objects inventory like this:
```yaml title="mkdocs.yml"
@@ -86,23 +87,23 @@ plugins:
- mkdocstrings:
handlers:
python:
- import:
- - https://docs.python-requests.org/en/master/objects.inv
+ inventories:
+ - https://docs.python.org/3/objects.inv
```
-When importing an inventory, you enable automatic cross-references
+When loading an inventory, you enable automatic cross-references
to other documentation sites like the standard library docs
-or any third-party package docs. Typically, you want to import
+or any third-party package docs. Typically, you want to load
the inventories of your project's dependencies, at least those
-that are used in the public API.
+that are used in the public API.
See [*mkdocstrings*' documentation on inventories][inventories]
for more details.
[inventories]: https://mkdocstrings.github.io/usage/#cross-references-to-other-projects-inventories
-Additionally, the Python handler accepts a `domains` option in the import items,
-which allows to select the inventory domains to select.
+Additionally, the Python handler accepts a `domains` option in the inventory options,
+which allows to select the inventory domains to load.
By default the Python handler only selects the `py` domain (for Python objects).
You might find useful to also enable the [`std` domain][std domain]:
@@ -113,29 +114,12 @@ plugins:
- mkdocstrings:
handlers:
python:
- import:
+ inventories:
- url: https://docs.python-requests.org/en/master/objects.inv
domains: [std, py]
```
-NOTE: The `import` option is common to *all* handlers, however
-they might implement it differently, or not even implement it.
-
-#### `paths`
-
-This option is used to provide filesystem paths in which to search for Python modules.
-Non-absolute paths are computed as relative to MkDocs configuration file. Example:
-
-```yaml title="mkdocs.yml"
-plugins:
-- mkdocstrings:
- handlers:
- python:
- paths: [src] # search packages in the src folder
-```
-
-More details at [Finding modules](#finding-modules).
-
+[](){#setting-load_external_modules}
#### `load_external_modules`
This option allows resolving aliases (imports) to any external module.
@@ -165,6 +149,30 @@ plugins:
[__all__]: https://docs.python.org/3/tutorial/modules.html#importing-from-a-package
+[](){#setting-locale}
+#### ~~`locale`~~
+
+**Deprecated.** Use mkdocstrings' own `locale` setting.
+
+~~The locale to use when translating template strings.~~
+
+[](){#setting-paths}
+#### `paths`
+
+This option is used to provide filesystem paths in which to search for Python modules.
+Non-absolute paths are computed as relative to MkDocs configuration file. Example:
+
+```yaml title="mkdocs.yml"
+plugins:
+- mkdocstrings:
+ handlers:
+ python:
+ paths: [src] # search packages in the src folder
+```
+
+More details at [Finding modules](#finding-modules).
+
+[](){#setting-options}
### Global/local options
The other options can be used both globally *and* locally, under the `options` key.
@@ -199,13 +207,6 @@ in the following pages:
- [Docstrings options](configuration/docstrings.md): options related to docstrings (parsing and rendering)
- [Signature options](configuration/signatures.md): options related to signatures and type annotations
-#### Options summary
-
-::: mkdocstrings_handlers.python.handler.PythonHandler.default_config
- options:
- show_root_heading: false
- show_root_toc_entry: false
-
## Finding modules
There are multiple ways to tell the handler where to find your packages/modules.
@@ -292,7 +293,7 @@ to make sure anyone can build your docs from any location on their filesystem.
### Using the PYTHONPATH environment variable
-WARNING: **This method has limitations.**
+WARNING: **This method has limitations.**
This method might work for you, with your current setup,
but not for others trying your build your docs with their own setup/environment.
We recommend using the [`paths` method](#using-the-paths-option) instead.
@@ -348,10 +349,10 @@ In Bash and other shells, you can run your command like this
```bash
PYTHONPATH=src mkdocs build -f docs/mkdocs.yml
```
-
+
### Installing your package in the current Python environment
-WARNING: **This method has limitations.**
+WARNING: **This method has limitations.**
This method might work for you, with your current setup,
but not for others trying your build your docs with their own setup/environment.
We recommend using the [`paths` method](#using-the-paths-option) instead.
@@ -379,3 +380,107 @@ poetry install
poetry run mkdocs build
```
///
+
+## Recommended settings
+
+If you're in a hurry, here is the configuration we recommend for the Python handler.
+
+```yaml
+- mkdocstrings:
+ handlers:
+ python:
+
+ # Where to find your sources, see "Finding modules".
+ paths: [src]
+
+ # Load object inventories to enable cross-references to other projects.
+ inventories:
+ - https://docs.python.org/3/objects.inv
+ # Also load inventories of your dependencies, generally served at
+ # https://docs-url-for-your-dependency/objects.inv.
+
+ options:
+
+ # DOCSTRINGS -------------------------------------------------------------
+ docstring_options:
+ # Discard first line of `__init__` method docstrings,
+ # useful when merging such docstrings into their parent class'.
+ ignore_init_summary: true
+
+ # Tables are generally too large, lists will fix this.
+ docstring_section_style: list
+
+ # CROSS-REFERENCES -------------------------------------------------------
+ # Enable relative crossrefs and scoped crossrefs, see Docstrings options.
+ relative_crossrefs: true # Sponsors only!
+ scoped_crossrefs: true # Sponsors only!
+
+ # Enable cross-references in signatures.
+ signature_crossrefs: true
+
+ # Unwrap actual types from `Annotated` type annotations.
+ unwrap_annotated: true
+
+ # MEMBERS ----------------------------------------------------------------
+ # Only render pulic symbols.
+ filters: public # Sponsors only!
+ # Comment the option otherwise to get the default filters.
+
+ # Show class inherited members.
+ inherited_members: true
+
+ # Render auto-generated summaries of attributes, functions, etc.
+ # at the start of each symbol's documentation.
+ summary: true
+
+ # HEADINGS ---------------------------------------------------------------
+ # For auto-generated pages, one module per page,
+ # make the module heading be the H1 heading of the page.
+ heading_level: 1
+
+ # Render headings for parameters, making them linkable.
+ parameter_headings: true
+
+ # Render headings for type parameters too.
+ type_parameter_headings: true
+
+ # Always show the heading for the symbol you render with `::: id`.
+ show_root_heading: true
+
+ # Only show the name of the symbols you inject render `::: id`.
+ show_root_full_path: false
+
+ # Show the type of symbol (class, function, etc.) in the heading.
+ show_symbol_type_heading: true
+
+ # Show the type of symbol (class, function, etc.) in the table of contents.
+ show_symbol_type_toc: true
+
+ # SIGNATURES -------------------------------------------------------------
+ # Format code to 80 + 10% margin (Black and Ruff defaults)
+ # in signatures and attribute value code blocks.
+ # Needs Black/Ruff installed.
+ line_length: 88
+
+ # Merge signature and docstring of `__init__` methods
+ # into their parent class signature and docstring.
+ merge_init_into_class: true
+
+ # Render signatures and attribute values in a separate code block,
+ # below the symbol heading.
+ separate_signature: true
+
+ # Show type annotations in signatures.
+ show_signature_annotations: true
+
+ # Show type parameters in signatures.
+ show_signature_type_parameters: true
+
+ # OTHER ------------------------------------------------------------------
+ # Show backlinks to other documentation sections within each symbol.
+ backlinks: tree # Sponsors only!
+
+ # Show base classes OR inheritance diagram.
+ show_bases: false
+ show_inheritance_diagram: true # Sponsors only!
+```
diff --git a/duties.py b/duties.py
index f1909cc1..3aa9b662 100644
--- a/duties.py
+++ b/duties.py
@@ -3,11 +3,10 @@
from __future__ import annotations
import os
+import re
import sys
-from contextlib import contextmanager
-from importlib.metadata import version as pkgversion
from pathlib import Path
-from typing import TYPE_CHECKING, Iterator
+from typing import TYPE_CHECKING
from duty import duty, tools
@@ -22,25 +21,21 @@
WINDOWS = os.name == "nt"
PTY = not WINDOWS and not CI
MULTIRUN = os.environ.get("MULTIRUN", "0") == "1"
+PY_VERSION = f"{sys.version_info.major}{sys.version_info.minor}"
+PY_DEV = "314"
-def pyprefix(title: str) -> str: # noqa: D103
+def pyprefix(title: str) -> str:
if MULTIRUN:
prefix = f"(python{sys.version_info.major}.{sys.version_info.minor})"
return f"{prefix:14}{title}"
return title
-@contextmanager
-def material_insiders() -> Iterator[bool]: # noqa: D103
- if "+insiders" in pkgversion("mkdocs-material"):
- os.environ["MATERIAL_INSIDERS"] = "true"
- try:
- yield True
- finally:
- os.environ.pop("MATERIAL_INSIDERS")
- else:
- yield False
+def _get_changelog_version() -> str:
+ changelog_version_re = re.compile(r"^## \[(\d+\.\d+\.\d+)\].*$")
+ with Path(__file__).parent.joinpath("CHANGELOG.md").open("r", encoding="utf8") as file:
+ return next(filter(bool, map(changelog_version_re.match, file))).group(1) # type: ignore[union-attr]
@duty
@@ -51,14 +46,15 @@ def changelog(ctx: Context, bump: str = "") -> None:
bump: Bump option passed to git-changelog.
"""
ctx.run(tools.git_changelog(bump=bump or None), title="Updating changelog")
+ ctx.run(tools.yore.check(bump=bump or _get_changelog_version()), title="Checking legacy code")
-@duty(pre=["check_quality", "check_types", "check_docs", "check-api"])
+@duty(pre=["check-quality", "check-types", "check-docs", "check-api"])
def check(ctx: Context) -> None:
"""Check it all!"""
-@duty
+@duty(nofail=PY_VERSION == PY_DEV)
def check_quality(ctx: Context) -> None:
"""Check the code quality."""
ctx.run(
@@ -67,29 +63,35 @@ def check_quality(ctx: Context) -> None:
)
-@duty
+@duty(
+ nofail=PY_VERSION == PY_DEV,
+ skip_if=sys.version_info < (3, 13),
+ skip_reason=pyprefix("Skipped: docs require modern generics syntax"),
+)
def check_docs(ctx: Context) -> None:
"""Check if the documentation builds correctly."""
Path("htmlcov").mkdir(parents=True, exist_ok=True)
Path("htmlcov/index.html").touch(exist_ok=True)
- with material_insiders():
- ctx.run(
- tools.mkdocs.build(strict=True, verbose=True),
- title=pyprefix("Building documentation"),
- )
+ ctx.run(
+ tools.mkdocs.build(strict=True, verbose=True),
+ title=pyprefix("Building documentation"),
+ )
-@duty
+@duty(nofail=PY_VERSION == PY_DEV)
def check_types(ctx: Context) -> None:
"""Check that the code is correctly typed."""
os.environ["MYPYPATH"] = "src"
+ os.environ["FORCE_COLOR"] = "1"
ctx.run(
tools.mypy(*PY_SRC_LIST, config_file="config/mypy.ini"),
title=pyprefix("Type-checking"),
+ # TODO: Update when Pydantic supports 3.14.
+ nofail=sys.version_info >= (3, 14),
)
-@duty
+@duty(nofail=PY_VERSION == PY_DEV)
def check_api(ctx: Context, *cli_args: str) -> None:
"""Check for API breaking changes."""
ctx.run(
@@ -99,7 +101,7 @@ def check_api(ctx: Context, *cli_args: str) -> None:
)
-@duty
+@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax"))
def docs(ctx: Context, *cli_args: str, host: str = "127.0.0.1", port: int = 8000) -> None:
"""Serve the documentation (localhost:8000).
@@ -107,38 +109,18 @@ def docs(ctx: Context, *cli_args: str, host: str = "127.0.0.1", port: int = 8000
host: The host to serve the docs from.
port: The port to serve the docs on.
"""
- with material_insiders():
- ctx.run(
- tools.mkdocs.serve(dev_addr=f"{host}:{port}").add_args(*cli_args),
- title="Serving documentation",
- capture=False,
- )
+ ctx.run(
+ tools.mkdocs.serve(dev_addr=f"{host}:{port}").add_args(*cli_args),
+ title="Serving documentation",
+ capture=False,
+ )
-@duty
+@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax"))
def docs_deploy(ctx: Context) -> None:
"""Deploy the documentation to GitHub pages."""
os.environ["DEPLOY"] = "true"
- with material_insiders() as insiders:
- if not insiders:
- ctx.run(lambda: False, title="Not deploying docs without Material for MkDocs Insiders!")
- origin = ctx.run("git config --get remote.origin.url", silent=True)
- if "pawamoy-insiders/mkdocstrings-python" in origin:
- ctx.run(
- "git remote add upstream git@github.com:mkdocstrings/python",
- silent=True,
- nofail=True,
- )
- ctx.run(
- tools.mkdocs.gh_deploy(remote_name="upstream", force=True),
- title="Deploying documentation",
- )
- else:
- ctx.run(
- lambda: False,
- title="Not deploying docs from public repository (do that from insiders instead!)",
- nofail=True,
- )
+ ctx.run(tools.mkdocs.gh_deploy(force=True), title="Deploying documentation")
@duty
@@ -181,17 +163,11 @@ def release(ctx: Context, version: str = "") -> None:
Parameters:
version: The new version number to use.
"""
- origin = ctx.run("git config --get remote.origin.url", silent=True)
- if "pawamoy-insiders/mkdocstrings-python" in origin:
- ctx.run(
- lambda: False,
- title="Not releasing from insiders repository (do that from public repo instead!)",
- )
if not (version := (version or input("> Version to release: ")).strip()):
ctx.run("false", title="A version must be provided")
ctx.run("git add pyproject.toml CHANGELOG.md", title="Staging files", pty=PTY)
ctx.run(["git", "commit", "-m", f"chore: Prepare release {version}"], title="Committing changes", pty=PTY)
- ctx.run(f"git tag {version}", title="Tagging commit", pty=PTY)
+ ctx.run(f"git tag -m '' -a {version}", title="Tagging commit", pty=PTY)
ctx.run("git push", title="Pushing commits", pty=False)
ctx.run("git push --tags", title="Pushing tags", pty=False)
@@ -204,21 +180,21 @@ def coverage(ctx: Context) -> None:
ctx.run(tools.coverage.html(rcfile="config/coverage.ini"))
-@duty
-def test(ctx: Context, *cli_args: str, match: str = "") -> None:
- """Run the test suite.
-
- Parameters:
- match: A pytest expression to filter selected tests.
- """
- py_version = f"{sys.version_info.major}{sys.version_info.minor}"
- os.environ["COVERAGE_FILE"] = f".coverage.{py_version}"
+@duty(nofail=PY_VERSION == PY_DEV)
+def test(ctx: Context, *cli_args: str, snapshot: str = "report") -> None: # noqa: PT028
+ """Run the test suite."""
+ os.environ["COVERAGE_FILE"] = f".coverage.{PY_VERSION}"
+ os.environ["PYTHONWARNDEFAULTENCODING"] = "1"
+ args = list(cli_args)
+ if snapshot == "disable" or not snapshot:
+ args = ["-n", "auto", "--inline-snapshot=disable"]
+ else:
+ args = [f"--inline-snapshot={snapshot}"]
ctx.run(
tools.pytest(
"tests",
config_file="config/pytest.ini",
- select=match,
color="yes",
- ).add_args("-n", "auto", *cli_args),
+ ).add_args(*args),
title=pyprefix("Running tests"),
)
diff --git a/mkdocs.yml b/mkdocs.yml
index 19aa90d9..64d0de3a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -13,6 +13,9 @@ validation:
absolute_links: warn
unrecognized_links: warn
+hooks:
+- scripts/mkdocs_hooks.py
+
nav:
- Home:
- Overview: index.md
@@ -34,19 +37,12 @@ nav:
- Advanced:
- Customization: usage/customization.md
- Extensions: usage/extensions.md
-# defer to gen-files + literate-nav
-- API reference:
- - mkdocstrings-python: reference/
+- API reference: reference/api.md
- Development:
- Contributing: contributing.md
- Code of Conduct: code_of_conduct.md
- # - Coverage report: coverage.md
-- Insiders:
- - insiders/index.md
- - Getting started:
- - Installation: insiders/installation.md
- - Changelog: insiders/changelog.md
-- mkdocstrings: https://mkdocstrings.github.io/
+ - Coverage report: coverage.md
+ - mkdocstrings: https://mkdocstrings.github.io/
theme:
name: material
@@ -60,7 +56,8 @@ theme:
- content.code.copy
- content.tooltips
- navigation.footer
- - navigation.indexes
+ - navigation.instant.preview
+ - navigation.path
- navigation.sections
- navigation.tabs
- navigation.tabs.sticky
@@ -91,7 +88,6 @@ theme:
extra_css:
- css/material.css
- css/mkdocstrings.css
-- css/insiders.css
extra_javascript:
- js/feedback.js
@@ -137,34 +133,34 @@ markdown_extensions:
permalink: "¤"
plugins:
-- autorefs
- search
+- autorefs
- markdown-exec
-- gen-files:
- scripts:
- - scripts/gen_ref_nav.py
-- literate-nav:
- nav_file: SUMMARY.md
-# - coverage
+- section-index
+- coverage
- mkdocstrings:
handlers:
python:
paths: [src, docs/snippets]
- import:
+ inventories:
- https://docs.python.org/3/objects.inv
- https://mkdocstrings.github.io/objects.inv
- https://mkdocstrings.github.io/autorefs/objects.inv
- https://mkdocstrings.github.io/griffe/objects.inv
- https://python-markdown.github.io/objects.inv
options:
+ backlinks: tree
docstring_options:
ignore_init_summary: true
docstring_section_style: list
- filters: ["!^_"]
+ extensions: [scripts/griffe_extensions.py]
+ filters: public
heading_level: 1
inherited_members: true
+ line_length: 88
merge_init_into_class: true
parameter_headings: true
+ type_parameter_headings: true
preload_modules: [mkdocstrings]
relative_crossrefs: true
scoped_crossrefs: true
@@ -174,21 +170,34 @@ plugins:
show_root_heading: true
show_root_full_path: false
show_signature_annotations: true
- show_source: false
+ show_signature_type_parameters: true
+ show_source: true
show_symbol_type_heading: true
show_symbol_type_toc: true
signature_crossrefs: true
summary: true
unwrap_annotated: true
-- git-committers:
+- llmstxt:
+ full_output: llms-full.txt
+ sections:
+ Usage:
+ - index.md
+ API:
+ - reference/api.md
+- git-revision-date-localized:
enabled: !ENV [DEPLOY, false]
- repository: mkdocstrings/python
+ enable_creation_date: true
+ type: timeago
- minify:
minify_html: !ENV [DEPLOY, false]
-- group:
- enabled: !ENV [MATERIAL_INSIDERS, false]
- plugins:
- - typeset
+- redirects:
+ redirect_maps:
+ reference/mkdocstrings_handlers/python/index.md: reference/api.md
+ reference/mkdocstrings_handlers/python/config.md: reference/api.md#mkdocstrings_handlers.python.config
+ reference/mkdocstrings_handlers/python/debug.md: reference/api.md#mkdocstrings_handlers.python.debug
+ reference/mkdocstrings_handlers/python/handler.md: reference/api.md#mkdocstrings_handlers.python.handler
+ reference/mkdocstrings_handlers/python/rendering.md: reference/api.md#mkdocstrings_handlers.python.rendering
+- typeset
extra:
social:
diff --git a/pyproject.toml b/pyproject.toml
index 0eccf7fe..2d6c7188 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,9 +6,10 @@ build-backend = "pdm.backend"
name = "mkdocstrings-python"
description = "A Python handler for mkdocstrings."
authors = [{name = "Timothée Mazzucotelli", email = "dev@pawamoy.fr"}]
-license = {text = "ISC"}
+license = "ISC"
+license-files = ["LICENSE"]
readme = "README.md"
-requires-python = ">=3.8"
+requires-python = ">=3.10"
keywords = []
dynamic = ["version"]
classifiers = [
@@ -17,21 +18,22 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: Documentation",
"Topic :: Software Development",
+ "Topic :: Software Development :: Documentation",
"Topic :: Utilities",
"Typing :: Typed",
]
dependencies = [
- "mkdocstrings>=0.26",
- "mkdocs-autorefs>=1.2",
- "griffe>=0.49",
+ "mkdocstrings>=0.30",
+ "mkdocs-autorefs>=1.4",
+ "griffe>=1.13",
+ "typing-extensions>=4.0; python_version < '3.11'",
]
[project.urls]
@@ -44,21 +46,23 @@ Discussions = "https://github.com/mkdocstrings/python/discussions"
Gitter = "https://gitter.im/mkdocstrings/python"
Funding = "https://github.com/sponsors/pawamoy"
-[tool.pdm]
-version = {source = "scm"}
+[tool.pdm.version]
+source = "call"
+getter = "scripts.get_version:get_version"
[tool.pdm.build]
package-dir = "src"
includes = ["src/mkdocstrings_handlers"]
editable-backend = "editables"
-excludes = ["**/.pytest_cache"]
+
+# Include as much as possible in the source distribution, to help redistributors.
+excludes = ["**/.pytest_cache", "**/.mypy_cache"]
source-includes = [
"config",
"docs",
"scripts",
"share",
"tests",
- "devdeps.txt",
"duties.py",
"mkdocs.yml",
"*.md",
@@ -66,6 +70,54 @@ source-includes = [
]
[tool.pdm.build.wheel-data]
+# Manual pages can be included in the wheel.
+# Depending on the installation tool, they will be accessible to users.
+# pipx supports it, uv does not yet, see https://github.com/astral-sh/uv/issues/4731.
data = [
{path = "share/**/*", relative-to = "."},
]
+
+[dependency-groups]
+maintain = [
+ "build>=1.2",
+ "git-changelog>=2.5",
+ "twine>=5.1",
+ "yore>=0.3.3",
+]
+ci = [
+ "black>=25.1",
+ "duty>=1.6",
+ "ruff>=0.4",
+ "pytest>=8.2",
+ "pytest-cov>=5.0",
+ "pytest-randomly>=3.15",
+ "pytest-xdist>=3.6",
+ "beautifulsoup4>=4.12.3",
+ "inline-snapshot>=0.25",
+ "mypy>=1.10",
+ "types-markdown>=3.6",
+ "types-pyyaml>=6.0",
+]
+ docs = [
+ "markdown-callouts>=0.4",
+ "markdown-exec>=1.8",
+ "mkdocs>=1.6",
+ "mkdocs-coverage>=1.0",
+ "mkdocs-git-revision-date-localized-plugin>=1.2",
+ "mkdocs-llmstxt>=0.2",
+ "mkdocs-material>=9.5",
+ "mkdocs-minify-plugin>=0.8",
+ "mkdocs-redirects>=1.2",
+ "mkdocs-section-index>=0.3",
+ "mkdocstrings>=0.29",
+ "pydantic>=2.10",
+ # YORE: EOL 3.10: Remove line.
+ "tomli>=2.0; python_version < '3.11'",
+]
+
+[tool.inline-snapshot]
+storage-dir = "tests/snapshots"
+format-command = "ruff format --config config/ruff.toml --stdin-filename {filename}"
+
+[tool.uv]
+default-groups = ["maintain", "ci", "docs"]
diff --git a/scripts/gen_credits.py b/scripts/gen_credits.py
index b2f6d3e4..6a81e239 100644
--- a/scripts/gen_credits.py
+++ b/scripts/gen_credits.py
@@ -1,21 +1,22 @@
-"""Script to generate the project's credits."""
+# Script to generate the project's credits.
from __future__ import annotations
import os
import sys
from collections import defaultdict
+from collections.abc import Iterable
from importlib.metadata import distributions
from itertools import chain
from pathlib import Path
from textwrap import dedent
-from typing import Dict, Iterable, Union
+from typing import Union
from jinja2 import StrictUndefined
from jinja2.sandbox import SandboxedEnvironment
from packaging.requirements import Requirement
-# TODO: Remove once support for Python 3.10 is dropped.
+# YORE: EOL 3.10: Replace block with line 2.
if sys.version_info >= (3, 11):
import tomllib
else:
@@ -26,11 +27,10 @@
pyproject = tomllib.load(pyproject_file)
project = pyproject["project"]
project_name = project["name"]
-with project_dir.joinpath("devdeps.txt").open() as devdeps_file:
- devdeps = [line.strip() for line in devdeps_file if line.strip() and not line.strip().startswith(("-e", "#"))]
+devdeps = [dep for group in pyproject["dependency-groups"].values() for dep in group if not dep.startswith("-e")]
-PackageMetadata = Dict[str, Union[str, Iterable[str]]]
-Metadata = Dict[str, PackageMetadata]
+PackageMetadata = dict[str, Union[str, Iterable[str]]]
+Metadata = dict[str, PackageMetadata]
def _merge_fields(metadata: dict) -> PackageMetadata:
diff --git a/scripts/gen_ref_nav.py b/scripts/gen_ref_nav.py
deleted file mode 100644
index 6939e864..00000000
--- a/scripts/gen_ref_nav.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Generate the code reference pages and navigation."""
-
-from pathlib import Path
-
-import mkdocs_gen_files
-
-nav = mkdocs_gen_files.Nav()
-mod_symbol = ''
-
-root = Path(__file__).parent.parent
-src = root / "src"
-
-for path in sorted(src.rglob("*.py")):
- module_path = path.relative_to(src).with_suffix("")
- doc_path = path.relative_to(src).with_suffix(".md")
- full_doc_path = Path("reference", doc_path)
-
- parts = tuple(module_path.parts)
-
- if parts[-1] == "__init__":
- parts = parts[:-1]
- doc_path = doc_path.with_name("index.md")
- full_doc_path = full_doc_path.with_name("index.md")
- elif parts[-1].startswith("_"):
- continue
-
- nav_parts = [f"{mod_symbol} {part}" for part in parts]
- nav[tuple(nav_parts)] = doc_path.as_posix()
-
- with mkdocs_gen_files.open(full_doc_path, "w") as fd:
- ident = ".".join(parts)
- fd.write(f"---\ntitle: {ident}\n---\n\n::: {ident}")
-
- mkdocs_gen_files.set_edit_path(full_doc_path, ".." / path.relative_to(root))
-
-with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
- nav_file.writelines(nav.build_literate_nav())
diff --git a/scripts/get_version.py b/scripts/get_version.py
new file mode 100644
index 00000000..3c425a73
--- /dev/null
+++ b/scripts/get_version.py
@@ -0,0 +1,31 @@
+# Get current project version from Git tags or changelog.
+
+import re
+from contextlib import suppress
+from pathlib import Path
+
+from pdm.backend.hooks.version import ( # ty: ignore[unresolved-import]
+ SCMVersion,
+ Version,
+ default_version_formatter,
+ get_version_from_scm,
+)
+
+_root = Path(__file__).parent.parent
+_changelog = _root / "CHANGELOG.md"
+_changelog_version_re = re.compile(r"^## \[(\d+\.\d+\.\d+)\].*$")
+_default_scm_version = SCMVersion(Version("0.0.0"), None, False, None, None) # noqa: FBT003
+
+
+def get_version() -> str:
+ scm_version = get_version_from_scm(_root) or _default_scm_version
+ if scm_version.version <= Version("0.1"): # Missing Git tags?
+ with suppress(OSError, StopIteration): # noqa: SIM117
+ with _changelog.open("r", encoding="utf8") as file:
+ match = next(filter(None, map(_changelog_version_re.match, file)))
+ scm_version = scm_version._replace(version=Version(match.group(1)))
+ return default_version_formatter(scm_version)
+
+
+if __name__ == "__main__":
+ print(get_version())
diff --git a/scripts/griffe_extensions.py b/scripts/griffe_extensions.py
new file mode 100644
index 00000000..eb50f5f2
--- /dev/null
+++ b/scripts/griffe_extensions.py
@@ -0,0 +1,46 @@
+# Custom extensions for Griffe.
+
+from __future__ import annotations
+
+import ast
+from typing import Any
+
+import griffe
+
+_logger = griffe.get_logger("griffe_extensions")
+
+
+class CustomFields(griffe.Extension):
+ """Support our custom dataclass fields."""
+
+ def on_attribute_instance(
+ self,
+ *,
+ attr: griffe.Attribute,
+ agent: griffe.Visitor | griffe.Inspector,
+ **kwargs: Any, # noqa: ARG002
+ ) -> None:
+ """Fetch descriptions from `Field` annotations."""
+ if attr.docstring:
+ return
+ try:
+ field: griffe.ExprCall = attr.annotation.slice.elements[1] # type: ignore[union-attr]
+ except AttributeError:
+ return
+
+ if field.canonical_path == "mkdocstrings_handlers.python._internal.config._Field":
+ description = next(
+ attr.value
+ for attr in field.arguments
+ if isinstance(attr, griffe.ExprKeyword) and attr.name == "description"
+ )
+ if not isinstance(description, str):
+ _logger.warning(f"Field description of {attr.path} is not a static string")
+ description = str(description)
+
+ attr.docstring = griffe.Docstring(
+ ast.literal_eval(description),
+ parent=attr,
+ parser=agent.docstring_parser,
+ parser_options=agent.docstring_options,
+ )
diff --git a/scripts/insiders.py b/scripts/insiders.py
deleted file mode 100644
index 15212486..00000000
--- a/scripts/insiders.py
+++ /dev/null
@@ -1,203 +0,0 @@
-"""Functions related to Insiders funding goals."""
-
-from __future__ import annotations
-
-import json
-import logging
-import os
-import posixpath
-from dataclasses import dataclass
-from datetime import date, datetime, timedelta
-from itertools import chain
-from pathlib import Path
-from typing import Iterable, cast
-from urllib.error import HTTPError
-from urllib.parse import urljoin
-from urllib.request import urlopen
-
-import yaml
-
-logger = logging.getLogger(f"mkdocs.logs.{__name__}")
-
-
-def human_readable_amount(amount: int) -> str: # noqa: D103
- str_amount = str(amount)
- if len(str_amount) >= 4: # noqa: PLR2004
- return f"{str_amount[:len(str_amount)-3]},{str_amount[-3:]}"
- return str_amount
-
-
-@dataclass
-class Project:
- """Class representing an Insiders project."""
-
- name: str
- url: str
-
-
-@dataclass
-class Feature:
- """Class representing an Insiders feature."""
-
- name: str
- ref: str | None
- since: date | None
- project: Project | None
-
- def url(self, rel_base: str = "..") -> str | None: # noqa: D102
- if not self.ref:
- return None
- if self.project:
- rel_base = self.project.url
- return posixpath.join(rel_base, self.ref.lstrip("/"))
-
- def render(self, rel_base: str = "..", *, badge: bool = False) -> None: # noqa: D102
- new = ""
- if badge:
- recent = self.since and date.today() - self.since <= timedelta(days=60) # noqa: DTZ011
- if recent:
- ft_date = self.since.strftime("%B %d, %Y") # type: ignore[union-attr]
- new = f' :material-alert-decagram:{{ .new-feature .vibrate title="Added on {ft_date}" }}'
- project = f"[{self.project.name}]({self.project.url}) — " if self.project else ""
- feature = f"[{self.name}]({self.url(rel_base)})" if self.ref else self.name
- print(f"- [{'x' if self.since else ' '}] {project}{feature}{new}")
-
-
-@dataclass
-class Goal:
- """Class representing an Insiders goal."""
-
- name: str
- amount: int
- features: list[Feature]
- complete: bool = False
-
- @property
- def human_readable_amount(self) -> str: # noqa: D102
- return human_readable_amount(self.amount)
-
- def render(self, rel_base: str = "..") -> None: # noqa: D102
- print(f"#### $ {self.human_readable_amount} — {self.name}\n")
- if self.features:
- for feature in self.features:
- feature.render(rel_base)
- print("")
- else:
- print("There are no features in this goal for this project. ")
- print(
- "[See the features in this goal **for all Insiders projects.**]"
- f"(https://pawamoy.github.io/insiders/#{self.amount}-{self.name.lower().replace(' ', '-')})",
- )
-
-
-def load_goals(data: str, funding: int = 0, project: Project | None = None) -> dict[int, Goal]:
- """Load goals from JSON data.
-
- Parameters:
- data: The JSON data.
- funding: The current total funding, per month.
- origin: The origin of the data (URL).
-
- Returns:
- A dictionaries of goals, keys being their target monthly amount.
- """
- goals_data = yaml.safe_load(data)["goals"]
- return {
- amount: Goal(
- name=goal_data["name"],
- amount=amount,
- complete=funding >= amount,
- features=[
- Feature(
- name=feature_data["name"],
- ref=feature_data.get("ref"),
- since=feature_data.get("since") and datetime.strptime(feature_data["since"], "%Y/%m/%d").date(), # noqa: DTZ007
- project=project,
- )
- for feature_data in goal_data["features"]
- ],
- )
- for amount, goal_data in goals_data.items()
- }
-
-
-def _load_goals_from_disk(path: str, funding: int = 0) -> dict[int, Goal]:
- project_dir = os.getenv("MKDOCS_CONFIG_DIR", ".")
- try:
- data = Path(project_dir, path).read_text()
- except OSError as error:
- raise RuntimeError(f"Could not load data from disk: {path}") from error
- return load_goals(data, funding)
-
-
-def _load_goals_from_url(source_data: tuple[str, str, str], funding: int = 0) -> dict[int, Goal]:
- project_name, project_url, data_fragment = source_data
- data_url = urljoin(project_url, data_fragment)
- try:
- with urlopen(data_url) as response: # noqa: S310
- data = response.read()
- except HTTPError as error:
- raise RuntimeError(f"Could not load data from network: {data_url}") from error
- return load_goals(data, funding, project=Project(name=project_name, url=project_url))
-
-
-def _load_goals(source: str | tuple[str, str, str], funding: int = 0) -> dict[int, Goal]:
- if isinstance(source, str):
- return _load_goals_from_disk(source, funding)
- return _load_goals_from_url(source, funding)
-
-
-def funding_goals(source: str | list[str | tuple[str, str, str]], funding: int = 0) -> dict[int, Goal]:
- """Load funding goals from a given data source.
-
- Parameters:
- source: The data source (local file path or URL).
- funding: The current total funding, per month.
-
- Returns:
- A dictionaries of goals, keys being their target monthly amount.
- """
- if isinstance(source, str):
- return _load_goals_from_disk(source, funding)
- goals = {}
- for src in source:
- source_goals = _load_goals(src, funding)
- for amount, goal in source_goals.items():
- if amount not in goals:
- goals[amount] = goal
- else:
- goals[amount].features.extend(goal.features)
- return {amount: goals[amount] for amount in sorted(goals)}
-
-
-def feature_list(goals: Iterable[Goal]) -> list[Feature]:
- """Extract feature list from funding goals.
-
- Parameters:
- goals: A list of funding goals.
-
- Returns:
- A list of features.
- """
- return list(chain.from_iterable(goal.features for goal in goals))
-
-
-def load_json(url: str) -> str | list | dict: # noqa: D103
- with urlopen(url) as response: # noqa: S310
- return json.loads(response.read().decode())
-
-
-data_source = globals()["data_source"]
-sponsor_url = "https://github.com/sponsors/pawamoy"
-data_url = "https://raw.githubusercontent.com/pawamoy/sponsors/main"
-numbers: dict[str, int] = load_json(f"{data_url}/numbers.json") # type: ignore[assignment]
-sponsors: list[dict] = load_json(f"{data_url}/sponsors.json") # type: ignore[assignment]
-current_funding = numbers["total"]
-sponsors_count = numbers["count"]
-goals = funding_goals(data_source, funding=current_funding)
-ongoing_goals = [goal for goal in goals.values() if not goal.complete]
-unreleased_features = sorted(
- (ft for ft in feature_list(ongoing_goals) if ft.since),
- key=lambda ft: cast(date, ft.since),
- reverse=True,
-)
diff --git a/scripts/make b/scripts/make
deleted file mode 100755
index d898022e..00000000
--- a/scripts/make
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/usr/bin/env python3
-"""Management commands."""
-
-from __future__ import annotations
-
-import os
-import shutil
-import subprocess
-import sys
-from contextlib import contextmanager
-from pathlib import Path
-from typing import Any, Iterator
-
-PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.8 3.9 3.10 3.11 3.12 3.13").split()
-
-exe = ""
-prefix = ""
-
-
-def shell(cmd: str, capture_output: bool = False, **kwargs: Any) -> str | None:
- """Run a shell command."""
- if capture_output:
- return subprocess.check_output(cmd, shell=True, text=True, **kwargs) # noqa: S602
- subprocess.run(cmd, shell=True, check=True, stderr=subprocess.STDOUT, **kwargs) # noqa: S602
- return None
-
-
-@contextmanager
-def environ(**kwargs: str) -> Iterator[None]:
- """Temporarily set environment variables."""
- original = dict(os.environ)
- os.environ.update(kwargs)
- try:
- yield
- finally:
- os.environ.clear()
- os.environ.update(original)
-
-
-def uv_install() -> None:
- """Install dependencies using uv."""
- uv_opts = ""
- if "UV_RESOLUTION" in os.environ:
- uv_opts = f"--resolution={os.getenv('UV_RESOLUTION')}"
- requirements = shell(f"uv pip compile {uv_opts} pyproject.toml devdeps.txt", capture_output=True)
- shell("uv pip install -r -", input=requirements, text=True)
- if "CI" not in os.environ:
- shell("uv pip install --no-deps -e .")
- else:
- shell("uv pip install --no-deps .")
-
-
-def setup() -> None:
- """Setup the project."""
- if not shutil.which("uv"):
- raise ValueError("make: setup: uv must be installed, see https://github.com/astral-sh/uv")
-
- print("Installing dependencies (default environment)") # noqa: T201
- default_venv = Path(".venv")
- if not default_venv.exists():
- shell("uv venv --python python")
- uv_install()
-
- if PYTHON_VERSIONS:
- for version in PYTHON_VERSIONS:
- print(f"\nInstalling dependencies (python{version})") # noqa: T201
- venv_path = Path(f".venvs/{version}")
- if not venv_path.exists():
- shell(f"uv venv --python {version} {venv_path}")
- with environ(VIRTUAL_ENV=str(venv_path.resolve())):
- uv_install()
-
-
-def activate(path: str) -> None:
- """Activate a virtual environment."""
- global exe, prefix # noqa: PLW0603
-
- if (bin := Path(path, "bin")).exists():
- activate_script = bin / "activate_this.py"
- elif (scripts := Path(path, "Scripts")).exists():
- activate_script = scripts / "activate_this.py"
- exe = ".exe"
- prefix = f"{path}/Scripts/"
- else:
- raise ValueError(f"make: activate: Cannot find activation script in {path}")
-
- if not activate_script.exists():
- raise ValueError(f"make: activate: Cannot find activation script in {path}")
-
- exec(activate_script.read_text(), {"__file__": str(activate_script)}) # noqa: S102
-
-
-def run(version: str, cmd: str, *args: str, **kwargs: Any) -> None:
- """Run a command in a virtual environment."""
- kwargs = {"check": True, **kwargs}
- if version == "default":
- activate(".venv")
- subprocess.run([f"{prefix}{cmd}{exe}", *args], **kwargs) # noqa: S603, PLW1510
- else:
- activate(f".venvs/{version}")
- os.environ["MULTIRUN"] = "1"
- subprocess.run([f"{prefix}{cmd}{exe}", *args], **kwargs) # noqa: S603, PLW1510
-
-
-def multirun(cmd: str, *args: str, **kwargs: Any) -> None:
- """Run a command for all configured Python versions."""
- if PYTHON_VERSIONS:
- for version in PYTHON_VERSIONS:
- run(version, cmd, *args, **kwargs)
- else:
- run("default", cmd, *args, **kwargs)
-
-
-def allrun(cmd: str, *args: str, **kwargs: Any) -> None:
- """Run a command in all virtual environments."""
- run("default", cmd, *args, **kwargs)
- if PYTHON_VERSIONS:
- multirun(cmd, *args, **kwargs)
-
-
-def clean() -> None:
- """Delete build artifacts and cache files."""
- paths_to_clean = ["build", "dist", "htmlcov", "site", ".coverage*", ".pdm-build"]
- for path in paths_to_clean:
- shell(f"rm -rf {path}")
-
- cache_dirs = [".cache", ".pytest_cache", ".mypy_cache", ".ruff_cache", "__pycache__"]
- for dirpath in Path(".").rglob("*"):
- if any(dirpath.match(pattern) for pattern in cache_dirs) and not (dirpath.match(".venv") or dirpath.match(".venvs")):
- shutil.rmtree(path, ignore_errors=True)
-
-
-def vscode() -> None:
- """Configure VSCode to work on this project."""
- Path(".vscode").mkdir(parents=True, exist_ok=True)
- shell("cp -v config/vscode/* .vscode")
-
-
-def main() -> int:
- """Main entry point."""
- args = list(sys.argv[1:])
- if not args or args[0] == "help":
- if len(args) > 1:
- run("default", "duty", "--help", args[1])
- else:
- print("Available commands") # noqa: T201
- print(" help Print this help. Add task name to print help.") # noqa: T201
- print(" setup Setup all virtual environments (install dependencies).") # noqa: T201
- print(" run Run a command in the default virtual environment.") # noqa: T201
- print(" multirun Run a command for all configured Python versions.") # noqa: T201
- print(" allrun Run a command in all virtual environments.") # noqa: T201
- print(" 3.x Run a command in the virtual environment for Python 3.x.") # noqa: T201
- print(" clean Delete build artifacts and cache files.") # noqa: T201
- print(" vscode Configure VSCode to work on this project.") # noqa: T201
- try:
- run("default", "python", "-V", capture_output=True)
- except (subprocess.CalledProcessError, ValueError):
- pass
- else:
- print("\nAvailable tasks") # noqa: T201
- run("default", "duty", "--list")
- return 0
-
- while args:
- cmd = args.pop(0)
-
- if cmd == "run":
- run("default", *args)
- return 0
-
- if cmd == "multirun":
- multirun(*args)
- return 0
-
- if cmd == "allrun":
- allrun(*args)
- return 0
-
- if cmd.startswith("3."):
- run(cmd, *args)
- return 0
-
- opts = []
- while args and (args[0].startswith("-") or "=" in args[0]):
- opts.append(args.pop(0))
-
- if cmd == "clean":
- clean()
- elif cmd == "setup":
- setup()
- elif cmd == "vscode":
- vscode()
- elif cmd == "check":
- multirun("duty", "check-quality", "check-types", "check-docs")
- run("default", "duty", "check-api")
- elif cmd in {"check-quality", "check-docs", "check-types", "test"}:
- multirun("duty", cmd, *opts)
- else:
- run("default", "duty", cmd, *opts)
-
- return 0
-
-
-if __name__ == "__main__":
- try:
- sys.exit(main())
- except subprocess.CalledProcessError as process:
- if process.output:
- print(process.output, file=sys.stderr) # noqa: T201
- sys.exit(process.returncode)
diff --git a/scripts/make b/scripts/make
new file mode 120000
index 00000000..c2eda0df
--- /dev/null
+++ b/scripts/make
@@ -0,0 +1 @@
+make.py
\ No newline at end of file
diff --git a/scripts/make.py b/scripts/make.py
new file mode 100755
index 00000000..b741a366
--- /dev/null
+++ b/scripts/make.py
@@ -0,0 +1,224 @@
+#!/usr/bin/env python3
+from __future__ import annotations
+
+import os
+import shutil
+import subprocess
+import sys
+from contextlib import contextmanager
+from pathlib import Path
+from textwrap import dedent
+from typing import TYPE_CHECKING, Any
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+
+PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.10 3.11 3.12 3.13 3.14 3.15").split()
+PYTHON_DEV = "3.15"
+
+
+def shell(cmd: str, *, capture_output: bool = False, **kwargs: Any) -> str | None:
+ """Run a shell command."""
+ if capture_output:
+ return subprocess.check_output(cmd, shell=True, text=True, **kwargs) # noqa: S602
+ subprocess.run(cmd, shell=True, check=True, stderr=subprocess.STDOUT, **kwargs) # noqa: S602
+ return None
+
+
+@contextmanager
+def environ(**kwargs: str) -> Iterator[None]:
+ """Temporarily set environment variables."""
+ original = dict(os.environ)
+ os.environ.update(kwargs)
+ try:
+ yield
+ finally:
+ os.environ.clear()
+ os.environ.update(original)
+
+
+def uv_install(venv: Path) -> None:
+ """Install dependencies using uv."""
+ with environ(UV_PROJECT_ENVIRONMENT=str(venv), PYO3_USE_ABI3_FORWARD_COMPATIBILITY="1"):
+ if "CI" in os.environ:
+ shell("uv sync --no-editable")
+ else:
+ shell("uv sync")
+
+
+def setup() -> None:
+ """Setup the project."""
+ if not shutil.which("uv"):
+ raise ValueError("make: setup: uv must be installed, see https://github.com/astral-sh/uv")
+
+ print("Installing dependencies (default environment)")
+ default_venv = Path(".venv")
+ if not default_venv.exists():
+ shell("uv venv")
+ uv_install(default_venv)
+
+ if PYTHON_VERSIONS:
+ for version in PYTHON_VERSIONS:
+ print(f"\nInstalling dependencies (python{version})")
+ venv_path = Path(f".venvs/{version}")
+ if not venv_path.exists():
+ shell(f"uv venv --python {version} {venv_path}")
+ with environ(UV_PROJECT_ENVIRONMENT=str(venv_path.resolve())):
+ uv_install(venv_path)
+
+
+class _RunError(subprocess.CalledProcessError):
+ def __init__(self, *args: Any, python_version: str, **kwargs: Any):
+ super().__init__(*args, **kwargs)
+ self.python_version = python_version
+
+
+def run(version: str, cmd: str, *args: str, **kwargs: Any) -> None:
+ """Run a command in a virtual environment."""
+ kwargs = {"check": True, **kwargs}
+ uv_run = ["uv", "run", "--no-sync"]
+ try:
+ if version == "default":
+ with environ(UV_PROJECT_ENVIRONMENT=".venv"):
+ subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510
+ else:
+ with environ(UV_PROJECT_ENVIRONMENT=f".venvs/{version}", MULTIRUN="1"):
+ subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510
+ except subprocess.CalledProcessError as process:
+ raise _RunError(
+ returncode=process.returncode,
+ python_version=version,
+ cmd=process.cmd,
+ output=process.output,
+ stderr=process.stderr,
+ ) from process
+
+
+def multirun(cmd: str, *args: str, **kwargs: Any) -> None:
+ """Run a command for all configured Python versions."""
+ if PYTHON_VERSIONS:
+ for version in PYTHON_VERSIONS:
+ run(version, cmd, *args, **kwargs)
+ else:
+ run("default", cmd, *args, **kwargs)
+
+
+def allrun(cmd: str, *args: str, **kwargs: Any) -> None:
+ """Run a command in all virtual environments."""
+ run("default", cmd, *args, **kwargs)
+ if PYTHON_VERSIONS:
+ multirun(cmd, *args, **kwargs)
+
+
+def clean() -> None:
+ """Delete build artifacts and cache files."""
+ paths_to_clean = ["build", "dist", "htmlcov", "site", ".coverage*", ".pdm-build"]
+ for path in paths_to_clean:
+ shutil.rmtree(path, ignore_errors=True)
+
+ cache_dirs = {".cache", ".pytest_cache", ".mypy_cache", ".ruff_cache", "__pycache__"}
+ for dirpath in Path(".").rglob("*/"):
+ if dirpath.parts[0] not in (".venv", ".venvs") and dirpath.name in cache_dirs:
+ shutil.rmtree(dirpath, ignore_errors=True)
+
+
+def vscode() -> None:
+ """Configure VSCode to work on this project."""
+ shutil.copytree("config/vscode", ".vscode", dirs_exist_ok=True)
+
+
+def main() -> int:
+ """Main entry point."""
+ args = list(sys.argv[1:])
+ if not args or args[0] == "help":
+ if len(args) > 1:
+ run("default", "duty", "--help", args[1])
+ else:
+ print(
+ dedent(
+ """
+ Available commands
+ help Print this help. Add task name to print help.
+ setup Setup all virtual environments (install dependencies).
+ run Run a command in the default virtual environment.
+ multirun Run a command for all configured Python versions.
+ allrun Run a command in all virtual environments.
+ 3.x Run a command in the virtual environment for Python 3.x.
+ clean Delete build artifacts and cache files.
+ vscode Configure VSCode to work on this project.
+ """,
+ ),
+ flush=True,
+ )
+ if os.path.exists(".venv"):
+ print("\nAvailable tasks", flush=True)
+ run("default", "duty", "--list")
+ return 0
+
+ while args:
+ cmd = args.pop(0)
+
+ if cmd == "run":
+ if not args:
+ print("make: run: missing command", file=sys.stderr)
+ return 1
+ run("default", *args) # ty: ignore[missing-argument]
+ return 0
+
+ if cmd == "multirun":
+ if not args:
+ print("make: run: missing command", file=sys.stderr)
+ return 1
+ multirun(*args) # ty: ignore[missing-argument]
+ return 0
+
+ if cmd == "allrun":
+ if not args:
+ print("make: run: missing command", file=sys.stderr)
+ return 1
+ allrun(*args) # ty: ignore[missing-argument]
+ return 0
+
+ if cmd.startswith("3."):
+ if not args:
+ print("make: run: missing command", file=sys.stderr)
+ return 1
+ run(cmd, *args) # ty: ignore[missing-argument]
+ return 0
+
+ opts = []
+ while args and (args[0].startswith("-") or "=" in args[0]):
+ opts.append(args.pop(0))
+
+ if cmd == "clean":
+ clean()
+ elif cmd == "setup":
+ setup()
+ elif cmd == "vscode":
+ vscode()
+ elif cmd == "check":
+ multirun("duty", "check-quality", "check-types", "check-docs")
+ run("default", "duty", "check-api")
+ elif cmd in {"check-quality", "check-docs", "check-types", "test"}:
+ multirun("duty", cmd, *opts)
+ else:
+ run("default", "duty", cmd, *opts)
+
+ return 0
+
+
+if __name__ == "__main__":
+ try:
+ sys.exit(main())
+ except _RunError as process:
+ if process.output:
+ print(process.output, file=sys.stderr)
+ if (code := process.returncode) == 139: # noqa: PLR2004
+ print(
+ f"✗ (python{process.python_version}) '{' '.join(process.cmd)}' failed with return code {code} (segfault)",
+ file=sys.stderr,
+ )
+ if process.python_version == PYTHON_DEV:
+ code = 0
+ sys.exit(code)
diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py
new file mode 100644
index 00000000..739f93b3
--- /dev/null
+++ b/scripts/mkdocs_hooks.py
@@ -0,0 +1,46 @@
+# Generate a JSON schema of the Python handler configuration.
+
+import json
+from dataclasses import dataclass, fields
+from os.path import join
+from typing import Any
+
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.plugins import get_plugin_logger
+
+from mkdocstrings_handlers.python import PythonInputConfig, PythonInputOptions
+
+# TODO: Update when Pydantic supports Python 3.14 (sources and duties as well).
+try:
+ from pydantic import TypeAdapter
+except ImportError:
+ TypeAdapter = None # type: ignore[assignment,misc]
+
+
+_logger = get_plugin_logger(__name__)
+
+
+def on_post_build(config: MkDocsConfig, **kwargs: Any) -> None: # noqa: ARG001
+ """Write `schema.json` to the site directory."""
+ if TypeAdapter is None:
+ _logger.info("Pydantic is not installed, skipping JSON schema generation")
+ return
+
+ @dataclass
+ class PythonHandlerSchema:
+ python: PythonInputConfig
+
+ adapter = TypeAdapter(PythonHandlerSchema)
+ schema = adapter.json_schema()
+ schema["$schema"] = "https://json-schema.org/draft-07/schema"
+ with open(join(config.site_dir, "schema.json"), "w") as file:
+ json.dump(schema, file, indent=2)
+ _logger.debug("Generated JSON schema")
+
+ autorefs = config["plugins"]["autorefs"]
+ for field in fields(PythonInputConfig):
+ if f"setting-{field.name}" not in autorefs._primary_url_map:
+ _logger.warning(f"Handler setting `{field.name}` is not documented")
+ for field in fields(PythonInputOptions):
+ if f"option-{field.name}" not in autorefs._primary_url_map:
+ _logger.warning(f"Configuration option `{field.name}` is not documented")
diff --git a/src/mkdocstrings_handlers/python/__init__.py b/src/mkdocstrings_handlers/python/__init__.py
index 0432a90d..dbad0355 100644
--- a/src/mkdocstrings_handlers/python/__init__.py
+++ b/src/mkdocstrings_handlers/python/__init__.py
@@ -1,5 +1,70 @@
"""Python handler for mkdocstrings."""
-from mkdocstrings_handlers.python.handler import get_handler
+from mkdocstrings_handlers.python._internal.config import (
+ AutoStyleOptions,
+ GoogleStyleOptions,
+ Inventory,
+ NumpyStyleOptions,
+ PerStyleOptions,
+ PythonConfig,
+ PythonInputConfig,
+ PythonInputOptions,
+ PythonOptions,
+ SphinxStyleOptions,
+ SummaryOption,
+)
+from mkdocstrings_handlers.python._internal.handler import PythonHandler, get_handler
+from mkdocstrings_handlers.python._internal.rendering import (
+ AutorefsHook,
+ Order,
+ Tree,
+ do_as_attributes_section,
+ do_as_classes_section,
+ do_as_functions_section,
+ do_as_modules_section,
+ do_as_type_aliases_section,
+ do_backlink_tree,
+ do_filter_objects,
+ do_format_attribute,
+ do_format_code,
+ do_format_signature,
+ do_format_type_alias,
+ do_get_template,
+ do_order_members,
+ do_split_path,
+ do_stash_crossref,
+)
-__all__ = ["get_handler"]
+__all__ = [
+ "AutoStyleOptions",
+ "AutorefsHook",
+ "GoogleStyleOptions",
+ "Inventory",
+ "NumpyStyleOptions",
+ "Order",
+ "PerStyleOptions",
+ "PythonConfig",
+ "PythonHandler",
+ "PythonInputConfig",
+ "PythonInputOptions",
+ "PythonOptions",
+ "SphinxStyleOptions",
+ "SummaryOption",
+ "Tree",
+ "do_as_attributes_section",
+ "do_as_classes_section",
+ "do_as_functions_section",
+ "do_as_modules_section",
+ "do_as_type_aliases_section",
+ "do_backlink_tree",
+ "do_filter_objects",
+ "do_format_attribute",
+ "do_format_code",
+ "do_format_signature",
+ "do_format_type_alias",
+ "do_get_template",
+ "do_order_members",
+ "do_split_path",
+ "do_stash_crossref",
+ "get_handler",
+]
diff --git a/src/mkdocstrings_handlers/python/_internal/__init__.py b/src/mkdocstrings_handlers/python/_internal/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py
new file mode 100644
index 00000000..79ba87f9
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/config.py
@@ -0,0 +1,1166 @@
+# Configuration and options dataclasses.
+
+from __future__ import annotations
+
+import re
+import sys
+from dataclasses import field, fields
+from typing import TYPE_CHECKING, Annotated, Any, Literal
+
+from mkdocstrings import get_logger
+
+from mkdocstrings_handlers.python._internal.rendering import Order # noqa: TC001
+
+# YORE: EOL 3.10: Replace block with line 2.
+if sys.version_info >= (3, 11):
+ from typing import Self
+else:
+ from typing_extensions import Self
+
+
+_logger = get_logger(__name__)
+
+_DEFAULT_FILTERS = ["!^_[^_]"]
+
+try:
+ # When Pydantic is available, use it to validate options (done automatically).
+ # Users can therefore opt into validation by installing Pydantic in development/CI.
+ # When building the docs to deploy them, Pydantic is not required anymore.
+
+ # When building our own docs, Pydantic is always installed (see `docs` group in `pyproject.toml`)
+ # to allow automatic generation of a JSON Schema. The JSON Schema is then referenced by mkdocstrings,
+ # which is itself referenced by mkdocs-material's schema system. For example in VSCode:
+ #
+ # "yaml.schemas": {
+ # "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
+ # }
+ import pydantic
+
+ if getattr(pydantic, "__version__", "1.").startswith("1."):
+ raise ImportError # noqa: TRY301
+
+ from inspect import cleandoc
+
+ from pydantic import Field as BaseField
+ from pydantic.dataclasses import dataclass
+
+ _base_url = "https://mkdocstrings.github.io/python/usage"
+
+ def _Field( # noqa: N802
+ *args: Any,
+ description: str,
+ group: Literal["general", "headings", "members", "docstrings", "signatures"] | None = None,
+ parent: str | None = None,
+ **kwargs: Any,
+ ) -> None:
+ def _add_markdown_description(schema: dict[str, Any]) -> None:
+ url = f"{_base_url}/{f'configuration/{group}/' if group else ''}#{parent or schema['title']}"
+ schema["markdownDescription"] = f"[DOCUMENTATION]({url})\n\n{schema['description']}"
+
+ return BaseField(
+ *args,
+ description=cleandoc(description),
+ field_title_generator=lambda name, _: name,
+ json_schema_extra=_add_markdown_description,
+ **kwargs,
+ )
+except ImportError:
+ from dataclasses import dataclass # type: ignore[no-redef]
+
+ def _Field(*args: Any, **kwargs: Any) -> None: # type: ignore[misc] # noqa: N802
+ pass
+
+
+if TYPE_CHECKING:
+ from collections.abc import MutableMapping
+
+
+@dataclass(frozen=True, kw_only=True)
+class GoogleStyleOptions:
+ """Google style docstring options."""
+
+ ignore_init_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to ignore the summary in `__init__` methods' docstrings.",
+ ),
+ ] = False
+
+ returns_multiple_items: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse multiple items in `Yields` and `Returns` sections.
+
+ When true, each item's continuation lines must be indented.
+ When false (single item), no further indentation is required.
+ """,
+ ),
+ ] = True
+
+ returns_named_value: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse `Yields` and `Returns` section items as name and description, rather than type and description.
+
+ When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
+ When false, parentheses are optional but the items cannot be named: `int: Description`.
+ """,
+ ),
+ ] = True
+
+ returns_type_in_property_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to parse the return type of properties at the beginning of their summary: `str: Summary of the property`.",
+ ),
+ ] = False
+
+ receives_multiple_items: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse multiple items in `Receives` sections.
+
+ When true, each item's continuation lines must be indented.
+ When false (single item), no further indentation is required.
+ """,
+ ),
+ ] = True
+
+ receives_named_value: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse `Receives` section items as name and description, rather than type and description.
+
+ When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
+ When false, parentheses are optional but the items cannot be named: `int: Description`.
+ """,
+ ),
+ ] = True
+
+ trim_doctest_flags: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to remove doctest flags from Python example blocks.",
+ ),
+ ] = True
+
+ warn_unknown_params: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about documented parameters not appearing in the signature.",
+ ),
+ ] = True
+
+ warn_missing_types: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about missing type/annotation for parameters, return values, etc.",
+ ),
+ ] = True
+
+ warnings: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Generally enable/disable warnings when parsing docstrings.",
+ ),
+ ] = True
+
+
+@dataclass(frozen=True, kw_only=True)
+class NumpyStyleOptions:
+ """Numpy style docstring options."""
+
+ ignore_init_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to ignore the summary in `__init__` methods' docstrings.",
+ ),
+ ] = False
+
+ trim_doctest_flags: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to remove doctest flags from Python example blocks.",
+ ),
+ ] = True
+
+ warn_unknown_params: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about documented parameters not appearing in the signature.",
+ ),
+ ] = True
+
+ warn_missing_types: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about missing type/annotation for parameters, return values, etc.",
+ ),
+ ] = True
+
+ warnings: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Generally enable/disable warnings when parsing docstrings.",
+ ),
+ ] = True
+
+
+@dataclass(frozen=True, kw_only=True)
+class SphinxStyleOptions:
+ """Sphinx style docstring options."""
+
+ warn_unknown_params: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about documented parameters not appearing in the signature.",
+ ),
+ ] = True
+
+ warn_missing_types: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about missing type/annotation for return values.",
+ ),
+ ] = True
+
+ warnings: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Generally enable/disable warnings when parsing docstrings.",
+ ),
+ ] = True
+
+
+@dataclass(frozen=True, kw_only=True)
+class PerStyleOptions:
+ """Per style options."""
+
+ google: Annotated[
+ GoogleStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Google-style options.",
+ ),
+ ] = field(default_factory=GoogleStyleOptions)
+
+ numpy: Annotated[
+ NumpyStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Numpydoc-style options.",
+ ),
+ ] = field(default_factory=NumpyStyleOptions)
+
+ sphinx: Annotated[
+ SphinxStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Sphinx-style options.",
+ ),
+ ] = field(default_factory=SphinxStyleOptions)
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ if "google" in data:
+ data["google"] = GoogleStyleOptions(**data["google"])
+ if "numpy" in data:
+ data["numpy"] = NumpyStyleOptions(**data["numpy"])
+ if "sphinx" in data:
+ data["sphinx"] = SphinxStyleOptions(**data["sphinx"])
+ return cls(**data)
+
+
+@dataclass(frozen=True, kw_only=True)
+class AutoStyleOptions:
+ """Auto style docstring options."""
+
+ method: Annotated[
+ Literal["heuristics", "max_sections"],
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The method to use to determine the docstring style.",
+ ),
+ ] = "heuristics"
+
+ style_order: Annotated[
+ list[str],
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The order of the docstring styles to try.",
+ ),
+ ] = field(default_factory=lambda: ["sphinx", "google", "numpy"])
+
+ default: Annotated[
+ str | None,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The default docstring style to use if no other style is detected.",
+ ),
+ ] = None
+
+ per_style_options: Annotated[
+ PerStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Per-style options.",
+ ),
+ ] = field(default_factory=PerStyleOptions)
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ if "per_style_options" in data:
+ data["per_style_options"] = PerStyleOptions.from_data(**data["per_style_options"])
+ return cls(**data)
+
+
+@dataclass(frozen=True, kw_only=True)
+class SummaryOption:
+ """Summary option."""
+
+ attributes: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of attributes.",
+ ),
+ ] = False
+
+ functions: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of functions (methods).",
+ ),
+ ] = False
+
+ classes: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of classes.",
+ ),
+ ] = False
+
+ modules: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of modules.",
+ ),
+ ] = False
+
+ type_aliases: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of type aliases.",
+ ),
+ ] = False
+
+
+@dataclass(frozen=True, kw_only=True)
+class PythonInputOptions:
+ """Accepted input options."""
+
+ allow_inspection: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to allow inspecting modules when visiting them is not possible.",
+ ),
+ ] = True
+
+ force_inspection: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to force using dynamic analysis when loading data.",
+ ),
+ ] = False
+
+ annotations_path: Annotated[
+ Literal["brief", "source", "full"],
+ _Field(
+ group="signatures",
+ description="The verbosity for annotations path: `brief` (recommended), `source` (as written in the source), or `full`.",
+ ),
+ ] = "brief"
+
+ backlinks: Annotated[
+ Literal["flat", "tree", False],
+ _Field(
+ group="general",
+ description="Whether to render backlinks, and how.",
+ ),
+ ] = False
+
+ docstring_options: Annotated[
+ GoogleStyleOptions | NumpyStyleOptions | SphinxStyleOptions | AutoStyleOptions | None,
+ _Field(
+ group="docstrings",
+ description="""The options for the docstring parser.
+
+ See [docstring parsers](https://mkdocstrings.github.io/griffe/reference/docstrings/) and their options in Griffe docs.
+ """,
+ ),
+ ] = None
+
+ docstring_section_style: Annotated[
+ Literal["table", "list", "spacy"],
+ _Field(
+ group="docstrings",
+ description="The style used to render docstring sections.",
+ ),
+ ] = "table"
+
+ docstring_style: Annotated[
+ Literal["auto", "google", "numpy", "sphinx"] | None,
+ _Field(
+ group="docstrings",
+ description="The docstring style to use: `auto`, `google`, `numpy`, `sphinx`, or `None`.",
+ ),
+ ] = "google"
+
+ extensions: Annotated[
+ list[str | dict[str, Any]],
+ _Field(
+ group="general",
+ description="A list of Griffe extensions to load.",
+ ),
+ ] = field(default_factory=list)
+
+ filters: Annotated[
+ list[str] | Literal["public"],
+ _Field(
+ group="members",
+ description="""A list of filters, or `"public"`.
+
+ **List of filters**
+
+ A filter starting with `!` will exclude matching objects instead of including them.
+ The `members` option takes precedence over `filters` (filters will still be applied recursively
+ to lower members in the hierarchy).
+
+ **Filtering methods**
+
+ The `public` method will include only public objects:
+ those added to `__all__` or not starting with an underscore (except for special methods/attributes).
+ """,
+ ),
+ ] = field(default_factory=lambda: _DEFAULT_FILTERS.copy())
+
+ find_stubs_package: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to load stubs package (package-stubs) when extracting docstrings.",
+ ),
+ ] = False
+
+ group_by_category: Annotated[
+ bool,
+ _Field(
+ group="members",
+ description="Group the object's children by categories: attributes, classes, functions, and modules.",
+ ),
+ ] = True
+
+ heading: Annotated[
+ str,
+ _Field(
+ group="headings",
+ description="A custom string to override the autogenerated heading of the root object.",
+ ),
+ ] = ""
+
+ heading_level: Annotated[
+ int,
+ _Field(
+ group="headings",
+ description="The initial heading level to use.",
+ ),
+ ] = 2
+
+ inheritance_diagram_direction: Annotated[
+ Literal["TB", "TD", "BT", "RL", "LR"],
+ _Field(
+ group="docstrings",
+ description="The direction of the Mermaid chart presenting the inheritance diagram of a class.",
+ ),
+ ] = "TD"
+
+ inherited_members: Annotated[
+ bool | list[str],
+ _Field(
+ group="members",
+ description="""A boolean, or an explicit list of inherited members to render.
+
+ If true, select all inherited members, which can then be filtered with `members`.
+ If false or empty list, do not select any inherited member.
+ """,
+ ),
+ ] = False
+
+ line_length: Annotated[
+ int,
+ _Field(
+ group="signatures",
+ description="Maximum line length when formatting code/signatures.",
+ ),
+ ] = 60
+
+ members: Annotated[
+ list[str] | bool | None,
+ _Field(
+ group="members",
+ description="""A boolean, or an explicit list of members to render.
+
+ If true, select all members without further filtering.
+ If false or empty list, do not render members.
+ If none, select all members and apply further filtering with filters and docstrings.
+ """,
+ ),
+ ] = None
+
+ members_order: Annotated[
+ Order | list[Order],
+ _Field(
+ group="members",
+ description="""The members ordering to use.
+
+ - `__all__`: order members according to `__all__` module attributes, if declared;
+ - `alphabetical`: order members alphabetically;
+ - `source`: order members as they appear in the source file.
+
+ Since `__all__` is a module-only attribute, it can't be used to sort class members,
+ therefore the `members_order` option accepts a list of ordering methods,
+ indicating ordering preferences.
+ """,
+ ),
+ ] = "alphabetical"
+
+ merge_init_into_class: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to merge the `__init__` method into the class' signature and docstring.",
+ ),
+ ] = False
+
+ modernize_annotations: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to modernize annotations, for example `Optional[str]` into `str | None`.",
+ ),
+ ] = False
+
+ overloads_only: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to hide the implementation signature if the overloads are shown.",
+ ),
+ ] = False
+
+ parameter_headings: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Whether to render headings for parameters (therefore showing parameters in the ToC).",
+ ),
+ ] = False
+
+ preload_modules: Annotated[
+ list[str],
+ _Field(
+ group="general",
+ description="""Pre-load modules that are not specified directly in autodoc instructions (`::: identifier`).
+
+ It is useful when you want to render documentation for a particular member of an object,
+ and this member is imported from another package than its parent.
+
+ For an imported member to be rendered, you need to add it to the `__all__` attribute
+ of the importing module.
+
+ The modules must be listed as an array of strings.
+ """,
+ ),
+ ] = field(default_factory=list)
+
+ relative_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to enable the relative crossref syntax.",
+ ),
+ ] = False
+
+ scoped_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to enable the scoped crossref ability.",
+ ),
+ ] = False
+
+ show_overloads: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show the overloads of a function or method.",
+ ),
+ ] = True
+
+ separate_signature: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="""Whether to put the whole signature in a code block below the heading.
+
+ If Black or Ruff are installed, the signature is also formatted using them.
+ """,
+ ),
+ ] = False
+
+ show_attribute_values: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show initial values of attributes in classes.",
+ ),
+ ] = True
+
+ show_bases: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Show the base classes of a class.",
+ ),
+ ] = True
+
+ show_category_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="When grouped by categories, show a heading for each category.",
+ ),
+ ] = False
+
+ show_docstring_attributes: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Attributes' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_classes: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Classes' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_description: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the textual block (including admonitions) in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_examples: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Examples' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_functions: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Functions' or 'Methods' sections in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_modules: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Modules' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_other_parameters: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Other Parameters' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_parameters: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Parameters' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_raises: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Raises' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_receives: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Receives' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_returns: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Returns' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_type_aliases: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Type Aliases' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_type_parameters: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Type Parameters' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_warns: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Warns' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_yields: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Yields' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_if_no_docstring: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the object heading even if it has no docstring or children with docstrings.",
+ ),
+ ] = False
+
+ show_inheritance_diagram: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the inheritance diagram of a class using Mermaid.",
+ ),
+ ] = False
+
+ show_labels: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to show labels of the members.",
+ ),
+ ] = True
+
+ show_object_full_path: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the full Python path of every object.",
+ ),
+ ] = False
+
+ show_root_full_path: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the full Python path for the root object heading.",
+ ),
+ ] = True
+
+ show_root_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="""Show the heading of the object at the root of the documentation tree.
+
+ The root object is the object referenced by the identifier after `:::`.
+ """,
+ ),
+ ] = False
+
+ show_root_members_full_path: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the full Python path of the root members.",
+ ),
+ ] = False
+
+ show_root_toc_entry: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="If the root heading is not shown, at least add a ToC entry for it.",
+ ),
+ ] = True
+
+ show_signature_annotations: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show the type annotations in methods and functions signatures.",
+ ),
+ ] = False
+
+ show_signature_type_parameters: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show the type parameters in generic classes, methods, functions and type aliases signatures.",
+ ),
+ ] = False
+
+ show_signature: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show methods and functions signatures.",
+ ),
+ ] = True
+
+ show_source: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Show the source code of this object.",
+ ),
+ ] = True
+
+ show_submodules: Annotated[
+ bool,
+ _Field(
+ group="members",
+ description="When rendering a module, show its submodules recursively.",
+ ),
+ ] = False
+
+ show_symbol_type_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the symbol type in headings (e.g. mod, class, meth, func and attr).",
+ ),
+ ] = False
+
+ show_symbol_type_toc: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the symbol type in the Table of Contents (e.g. mod, class, methd, func and attr).",
+ ),
+ ] = False
+
+ skip_local_inventory: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to prevent objects from being registered in the local objects inventory.",
+ ),
+ ] = False
+
+ signature_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to render cross-references for type annotations in signatures.",
+ ),
+ ] = False
+
+ summary: Annotated[
+ bool | SummaryOption,
+ _Field(
+ group="members",
+ description="Whether to render summaries of modules, classes, functions (methods) and attributes.",
+ ),
+ ] = field(default_factory=SummaryOption)
+
+ toc_label: Annotated[
+ str,
+ _Field(
+ group="headings",
+ description="A custom string to override the autogenerated toc label of the root object.",
+ ),
+ ] = ""
+
+ type_parameter_headings: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Whether to render headings for type parameters (therefore showing type parameters in the ToC).",
+ ),
+ ] = False
+
+ unwrap_annotated: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to unwrap `Annotated` types to show only the type without the annotations.",
+ ),
+ ] = False
+
+ extra: Annotated[
+ dict[str, Any],
+ _Field(
+ group="general",
+ description="Extra options.",
+ ),
+ ] = field(default_factory=dict)
+
+ @classmethod
+ def _extract_extra(cls, data: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
+ field_names = {field.name for field in fields(cls)}
+ copy = data.copy()
+ return {name: copy.pop(name) for name in data if name not in field_names}, copy
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ if "docstring_options" in data:
+ docstring_style = data.get("docstring_style", "google")
+ docstring_options = data["docstring_options"]
+ if docstring_options is not None:
+ if docstring_style == "auto":
+ docstring_options = AutoStyleOptions.from_data(**docstring_options)
+ elif docstring_style == "google":
+ docstring_options = GoogleStyleOptions(**docstring_options)
+ elif docstring_style == "numpy":
+ docstring_options = NumpyStyleOptions(**docstring_options)
+ elif docstring_style == "sphinx":
+ docstring_options = SphinxStyleOptions(**docstring_options)
+ data["docstring_options"] = docstring_options
+ if "summary" in data:
+ summary = data["summary"]
+ if summary is True:
+ summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True, type_aliases=True)
+ elif summary is False:
+ summary = SummaryOption(
+ attributes=False,
+ functions=False,
+ classes=False,
+ modules=False,
+ type_aliases=False,
+ )
+ else:
+ summary = SummaryOption(**summary)
+ data["summary"] = summary
+ return data
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ return cls(**cls.coerce(**data))
+
+
+@dataclass(frozen=True, kw_only=True)
+class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
+ """Final options passed as template context."""
+
+ filters: list[tuple[re.Pattern, bool]] | Literal["public"] = field( # type: ignore[assignment]
+ default_factory=lambda: [
+ (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in _DEFAULT_FILTERS
+ ],
+ )
+ """A list of filters, or `"public"`."""
+
+ summary: SummaryOption = field(default_factory=SummaryOption)
+ """Whether to render summaries of modules, classes, functions (methods), attributes and type aliases."""
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Create an instance from a dictionary."""
+ if "filters" in data and not isinstance(data["filters"], str):
+ # Filters are `None` or a sequence of strings (tests use tuples).
+ data["filters"] = [
+ (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
+ ]
+ return super().coerce(**data)
+
+
+@dataclass(frozen=True, kw_only=True)
+class Inventory:
+ """An inventory."""
+
+ url: Annotated[
+ str,
+ _Field(
+ parent="inventories",
+ description="The URL of the inventory.",
+ ),
+ ]
+
+ base_url: Annotated[
+ str | None,
+ _Field(
+ parent="inventories",
+ description="The base URL of the inventory.",
+ ),
+ ] = None
+
+ domains: Annotated[
+ list[str],
+ _Field(
+ parent="inventories",
+ description="The domains to load from the inventory.",
+ ),
+ ] = field(default_factory=lambda: ["py"])
+
+ @property
+ def _config(self) -> dict[str, Any]:
+ return {"base_url": self.base_url, "domains": self.domains}
+
+
+@dataclass(frozen=True, kw_only=True)
+class PythonInputConfig:
+ """Python handler configuration."""
+
+ inventories: Annotated[
+ list[str | Inventory],
+ _Field(description="The inventories to load."),
+ ] = field(default_factory=list)
+
+ paths: Annotated[
+ list[str],
+ _Field(description="The paths in which to search for Python packages."),
+ ] = field(default_factory=lambda: ["."])
+
+ load_external_modules: Annotated[
+ bool | None,
+ _Field(description="Whether to always load external modules/packages."),
+ ] = None
+
+ options: Annotated[
+ PythonInputOptions,
+ _Field(description="Configuration options for collecting and rendering objects."),
+ ] = field(default_factory=PythonInputOptions)
+
+ locale: Annotated[
+ str | None,
+ _Field(
+ description="Deprecated. Use mkdocstrings' own `locale` setting instead. The locale to use when translating template strings.",
+ ),
+ ] = None
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ return data
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ return cls(**cls.coerce(**data))
+
+
+@dataclass(frozen=True, kw_only=True)
+class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore]
+ """Python handler configuration."""
+
+ inventories: Annotated[
+ list[Inventory],
+ _Field(description="The object inventories to load."),
+ ] = field(default_factory=list) # type: ignore[assignment]
+
+ options: Annotated[
+ dict[str, Any],
+ _Field(description="Configuration options for collecting and rendering objects."),
+ ] = field(default_factory=dict) # type: ignore[assignment]
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ if "inventories" in data:
+ data["inventories"] = [
+ Inventory(url=inv) if isinstance(inv, str) else Inventory(**inv) for inv in data["inventories"]
+ ]
+ return data
diff --git a/src/mkdocstrings_handlers/python/debug.py b/src/mkdocstrings_handlers/python/_internal/debug.py
similarity index 80%
rename from src/mkdocstrings_handlers/python/debug.py
rename to src/mkdocstrings_handlers/python/_internal/debug.py
index e44f2be5..a3c99d75 100644
--- a/src/mkdocstrings_handlers/python/debug.py
+++ b/src/mkdocstrings_handlers/python/_internal/debug.py
@@ -1,5 +1,3 @@
-"""Debugging utilities."""
-
from __future__ import annotations
import os
@@ -10,7 +8,7 @@
@dataclass
-class Variable:
+class _Variable:
"""Dataclass describing an environment variable."""
name: str
@@ -20,7 +18,7 @@ class Variable:
@dataclass
-class Package:
+class _Package:
"""Dataclass describing a Python package."""
name: str
@@ -30,7 +28,7 @@ class Package:
@dataclass
-class Environment:
+class _Environment:
"""Dataclass to store environment information."""
interpreter_name: str
@@ -41,9 +39,9 @@ class Environment:
"""Path to Python executable."""
platform: str
"""Operating System."""
- packages: list[Package]
+ packages: list[_Package]
"""Installed packages."""
- variables: list[Variable]
+ variables: list[_Variable]
"""Environment variables."""
@@ -58,7 +56,7 @@ def _interpreter_name_version() -> tuple[str, str]:
return "", "0.0.0"
-def get_version(dist: str = "mkdocstrings-python") -> str:
+def _get_version(dist: str = "mkdocstrings-python") -> str:
"""Get version of the given distribution.
Parameters:
@@ -73,28 +71,28 @@ def get_version(dist: str = "mkdocstrings-python") -> str:
return "0.0.0"
-def get_debug_info() -> Environment:
+def _get_debug_info() -> _Environment:
"""Get debug/environment information.
Returns:
Environment information.
"""
py_name, py_version = _interpreter_name_version()
- packages = ["mkdocs", "mkdocstrings", "mkdocstrings-python", "griffe"]
+ packages = ["mkdocstrings-python"]
variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("MKDOCSTRINGS_PYTHON")]]
- return Environment(
+ return _Environment(
interpreter_name=py_name,
interpreter_version=py_version,
interpreter_path=sys.executable,
platform=platform.platform(),
- variables=[Variable(var, val) for var in variables if (val := os.getenv(var))],
- packages=[Package(pkg, get_version(pkg)) for pkg in packages],
+ variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))], # ty: ignore[invalid-argument-type]
+ packages=[_Package(pkg, _get_version(pkg)) for pkg in packages],
)
-def print_debug_info() -> None:
+def _print_debug_info() -> None:
"""Print debug/environment information."""
- info = get_debug_info()
+ info = _get_debug_info()
print(f"- __System__: {info.platform}")
print(f"- __Python__: {info.interpreter_name} {info.interpreter_version} ({info.interpreter_path})")
print("- __Environment variables__:")
@@ -106,4 +104,4 @@ def print_debug_info() -> None:
if __name__ == "__main__":
- print_debug_info()
+ _print_debug_info()
diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py
new file mode 100644
index 00000000..bd95023f
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/handler.py
@@ -0,0 +1,406 @@
+# This module implements a handler for the Python language.
+
+from __future__ import annotations
+
+import glob
+import os
+import posixpath
+import sys
+from contextlib import suppress
+from dataclasses import asdict
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
+
+from griffe import (
+ AliasResolutionError,
+ GriffeLoader,
+ LinesCollection,
+ ModulesCollection,
+ Parser,
+ load_extensions,
+ patch_loggers,
+)
+from mkdocs.exceptions import PluginError
+from mkdocs_autorefs import BacklinkCrumb
+from mkdocstrings import BaseHandler, CollectionError, CollectorItem, HandlerOptions, Inventory, get_logger
+
+from mkdocstrings_handlers.python._internal import rendering
+from mkdocstrings_handlers.python._internal.config import PythonConfig, PythonOptions
+
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Iterator, Mapping, MutableMapping, Sequence
+
+ from mkdocs.config.defaults import MkDocsConfig
+ from mkdocs_autorefs import Backlink
+
+
+# YORE: EOL 3.10: Replace block with line 2.
+if sys.version_info >= (3, 11):
+ from contextlib import chdir
+else:
+ from contextlib import contextmanager
+
+ @contextmanager
+ def chdir(path: str) -> Iterator[None]:
+ old_wd = os.getcwd()
+ os.chdir(path)
+ try:
+ yield
+ finally:
+ os.chdir(old_wd)
+
+
+_logger = get_logger(__name__)
+
+patch_loggers(get_logger)
+
+
+class PythonHandler(BaseHandler):
+ """The Python handler class."""
+
+ name: ClassVar[str] = "python"
+ """The handler's name."""
+
+ domain: ClassVar[str] = "py"
+ """The cross-documentation domain/language for this handler."""
+
+ enable_inventory: ClassVar[bool] = True
+ """Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file."""
+
+ fallback_theme: ClassVar[str] = "material"
+ """The fallback theme."""
+
+ def __init__(self, config: PythonConfig, base_dir: Path, **kwargs: Any) -> None:
+ """Initialize the handler.
+
+ Parameters:
+ config: The handler configuration.
+ base_dir: The base directory of the project.
+ **kwargs: Arguments passed to the parent constructor.
+ """
+ super().__init__(**kwargs)
+
+ self.config = config
+ """The handler configuration."""
+ self.base_dir = base_dir
+ """The base directory of the project."""
+
+ self.global_options = config.options
+ """The global configuration options (in `mkdocs.yml`)."""
+
+ # Warn if user overrides base templates.
+ if self.custom_templates:
+ for theme_dir in base_dir.joinpath(self.custom_templates, "python").iterdir():
+ if theme_dir.joinpath("_base").is_dir():
+ _logger.warning(
+ f"Overriding base template '{theme_dir.name}/_base/.html.jinja' is not supported, "
+ f"override '{theme_dir.name}/.html.jinja' instead",
+ )
+
+ paths = config.paths or []
+
+ # Expand paths with glob patterns.
+ with chdir(str(base_dir)):
+ resolved_globs = [glob.glob(path) for path in paths]
+ paths = [path for glob_list in resolved_globs for path in glob_list]
+
+ # By default, add the base directory to the search paths.
+ if not paths:
+ paths.append(str(base_dir))
+
+ # Initialize search paths from `sys.path`, eliminating empty paths.
+ search_paths = [path for path in sys.path if path]
+
+ for path in reversed(paths):
+ # If it's not absolute, make path relative to the config file path, then make it absolute.
+ if not os.path.isabs(path):
+ path = os.path.abspath(base_dir / path) # noqa: PLW2901
+ # Remove pre-listed paths.
+ if path in search_paths:
+ search_paths.remove(path)
+ # Give precedence to user-provided paths.
+ search_paths.insert(0, path)
+
+ self._paths = search_paths
+ self._modules_collection: ModulesCollection = ModulesCollection()
+ self._lines_collection: LinesCollection = LinesCollection()
+
+ def get_inventory_urls(self) -> list[tuple[str, dict[str, Any]]]:
+ """Return the URLs of the inventory files to download."""
+ return [(inv.url, inv._config) for inv in self.config.inventories]
+
+ @staticmethod
+ def load_inventory(
+ in_file: BinaryIO,
+ url: str,
+ base_url: str | None = None,
+ domains: list[str] | None = None,
+ **kwargs: Any, # noqa: ARG004
+ ) -> Iterator[tuple[str, str]]:
+ """Yield items and their URLs from an inventory file streamed from `in_file`.
+
+ This implements mkdocstrings' `load_inventory` "protocol" (see [`mkdocstrings.BaseHandler.load_inventory`][]).
+
+ Arguments:
+ in_file: The binary file-like object to read the inventory from.
+ url: The URL that this file is being streamed from (used to guess `base_url`).
+ base_url: The URL that this inventory's sub-paths are relative to.
+ domains: A list of domain strings to filter the inventory by, when not passed, "py" will be used.
+ **kwargs: Ignore additional arguments passed from the config.
+
+ Yields:
+ Tuples of (item identifier, item URL).
+ """
+ domains = domains or ["py"]
+ if base_url is None:
+ base_url = posixpath.dirname(url)
+
+ for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values():
+ yield item.name, posixpath.join(base_url, item.uri)
+
+ def get_options(self, local_options: Mapping[str, Any]) -> HandlerOptions:
+ """Get combined default, global and local options.
+
+ Arguments:
+ local_options: The local options.
+
+ Returns:
+ The combined options.
+ """
+ extra = {**self.global_options.get("extra", {}), **local_options.get("extra", {})}
+ options = {**self.global_options, **local_options, "extra": extra}
+ try:
+ return PythonOptions.from_data(**options)
+ except Exception as error:
+ raise PluginError(f"Invalid options: {error}") from error
+
+ def collect(self, identifier: str, options: PythonOptions) -> CollectorItem:
+ """Collect the documentation for the given identifier.
+
+ Parameters:
+ identifier: The identifier of the object to collect.
+ options: The options to use for the collection.
+
+ Returns:
+ The collected item.
+ """
+ module_name = identifier.split(".", 1)[0]
+ unknown_module = module_name not in self._modules_collection
+ reapply = True
+ if options == {}:
+ if unknown_module:
+ raise CollectionError("Not loading additional modules during fallback")
+ options = self.get_options({})
+ reapply = False
+
+ parser_name = options.docstring_style
+ parser = parser_name and Parser(parser_name)
+ parser_options = options.docstring_options and asdict(options.docstring_options)
+
+ if unknown_module:
+ extensions = self.normalize_extension_paths(options.extensions)
+ loader = GriffeLoader(
+ extensions=load_extensions(*extensions),
+ search_paths=self._paths,
+ docstring_parser=parser,
+ docstring_options=parser_options, # type: ignore[arg-type]
+ modules_collection=self._modules_collection,
+ lines_collection=self._lines_collection,
+ allow_inspection=options.allow_inspection,
+ force_inspection=options.force_inspection,
+ )
+ try:
+ for pre_loaded_module in options.preload_modules:
+ if pre_loaded_module not in self._modules_collection:
+ loader.load(
+ pre_loaded_module,
+ try_relative_path=False,
+ find_stubs_package=options.find_stubs_package,
+ )
+ loader.load(
+ module_name,
+ try_relative_path=False,
+ find_stubs_package=options.find_stubs_package,
+ )
+ except ImportError as error:
+ raise CollectionError(str(error)) from error
+ unresolved, iterations = loader.resolve_aliases(
+ implicit=False,
+ external=self.config.load_external_modules,
+ )
+ if unresolved:
+ _logger.debug(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
+ _logger.debug(f"Unresolved aliases: {', '.join(sorted(unresolved))}")
+
+ try:
+ doc_object = self._modules_collection[identifier]
+ except KeyError as error:
+ raise CollectionError(f"{identifier} could not be found") from error
+ except AliasResolutionError as error:
+ raise CollectionError(str(error)) from error
+
+ if not unknown_module and reapply:
+ with suppress(AliasResolutionError):
+ if doc_object.docstring is not None:
+ doc_object.docstring.parser = parser
+ doc_object.docstring.parser_options = parser_options or {}
+
+ return doc_object
+
+ def render(self, data: CollectorItem, options: PythonOptions, locale: str | None = None) -> str:
+ """Render the collected data.
+
+ Parameters:
+ data: The collected data.
+ options: The options to use for rendering.
+ locale: The locale to use for rendering (default is "en").
+
+ Returns:
+ The rendered data (HTML).
+ """
+ template_name = rendering.do_get_template(data)
+ template = self.env.get_template(template_name)
+
+ return template.render(
+ **{
+ "config": options,
+ data.kind.value.replace(" ", "_"): data,
+ # Heading level is a "state" variable, that will change at each step
+ # of the rendering recursion. Therefore, it's easier to use it as a plain value
+ # than as an item in a dictionary.
+ "heading_level": options.heading_level,
+ "root": True,
+ "locale": locale or "en",
+ },
+ )
+
+ def render_backlinks(self, backlinks: Mapping[str, Iterable[Backlink]], *, locale: str | None = None) -> str: # noqa: ARG002
+ """Render the backlinks.
+
+ Parameters:
+ backlinks: The backlinks to render.
+
+ Returns:
+ The rendered backlinks (HTML).
+ """
+ template = self.env.get_template("backlinks.html.jinja")
+ verbose_type = {key: key.capitalize().replace("-by", " by") for key in backlinks.keys()} # noqa: SIM118
+ return template.render(
+ backlinks=backlinks,
+ config=self.get_options({}),
+ verbose_type=verbose_type,
+ default_crumb=BacklinkCrumb(title="", url=""),
+ )
+
+ def update_env(self, config: Any) -> None: # noqa: ARG002
+ """Update the Jinja environment with custom filters and tests.
+
+ Parameters:
+ config: The SSG configuration.
+ """
+ self.env.trim_blocks = True
+ self.env.lstrip_blocks = True
+ self.env.keep_trailing_newline = False
+ self.env.filters["split_path"] = rendering.do_split_path
+ self.env.filters["order_members"] = rendering.do_order_members
+ self.env.filters["format_code"] = rendering.do_format_code
+ self.env.filters["format_signature"] = rendering.do_format_signature
+ self.env.filters["format_attribute"] = rendering.do_format_attribute
+ self.env.filters["format_type_alias"] = rendering.do_format_type_alias
+ self.env.filters["filter_objects"] = rendering.do_filter_objects
+ self.env.filters["stash_crossref"] = rendering.do_stash_crossref
+ self.env.filters["get_template"] = rendering.do_get_template
+ self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section
+ self.env.filters["as_functions_section"] = rendering.do_as_functions_section
+ self.env.filters["as_classes_section"] = rendering.do_as_classes_section
+ self.env.filters["as_type_aliases_section"] = rendering.do_as_type_aliases_section
+ self.env.filters["as_modules_section"] = rendering.do_as_modules_section
+ self.env.filters["backlink_tree"] = rendering.do_backlink_tree
+ self.env.globals["AutorefsHook"] = rendering.AutorefsHook
+ self.env.tests["existing_template"] = lambda template_name: template_name in self.env.list_templates()
+
+ def get_aliases(self, identifier: str) -> tuple[str, ...]:
+ """Get the aliases for the given identifier.
+
+ Parameters:
+ identifier: The identifier to get the aliases for.
+
+ Returns:
+ The aliases.
+ """
+ if "(" in identifier:
+ identifier, parameter = identifier.split("(", 1)
+ parameter.removesuffix(")")
+ else:
+ parameter = ""
+ try:
+ data = self._modules_collection[identifier]
+ except (KeyError, AliasResolutionError):
+ return ()
+ aliases = [data.path]
+ try:
+ for alias in [data.canonical_path, *data.aliases]:
+ if alias not in aliases:
+ aliases.append(alias)
+ except AliasResolutionError:
+ pass
+ if parameter:
+ return tuple(f"{alias}({parameter})" for alias in aliases)
+ return tuple(aliases)
+
+ def normalize_extension_paths(self, extensions: Sequence) -> list[str | dict[str, Any]]:
+ """Resolve extension paths relative to config file.
+
+ Parameters:
+ extensions: The extensions (configuration) to normalize.
+
+ Returns:
+ The normalized extensions.
+ """
+ normalized: list[str | dict[str, Any]] = []
+
+ for ext in extensions:
+ if isinstance(ext, dict):
+ pth, options = next(iter(ext.items()))
+ pth = str(pth)
+ else:
+ pth = str(ext)
+ options = None
+
+ if pth.endswith(".py") or ".py:" in pth or "/" in pth or "\\" in pth:
+ # This is a system path. Normalize it, make it absolute relative to config file path.
+ pth = os.path.abspath(self.base_dir / pth)
+
+ if options is not None:
+ normalized.append({pth: options})
+ else:
+ normalized.append(pth)
+
+ return normalized
+
+
+def get_handler(
+ handler_config: MutableMapping[str, Any],
+ tool_config: MkDocsConfig,
+ **kwargs: Any,
+) -> PythonHandler:
+ """Return an instance of `PythonHandler`.
+
+ Parameters:
+ handler_config: The handler configuration.
+ tool_config: The tool (SSG) configuration.
+ **kwargs: Additional arguments to pass to the handler.
+
+ Returns:
+ An instance of `PythonHandler`.
+ """
+ # In rare cases, Griffe hits the recursion limit because of deeply-nested ASTs.
+ # We therefore increase the limit here, once, before Griffe is used to collect or render stuff.
+ sys.setrecursionlimit(max(sys.getrecursionlimit(), 2000))
+
+ base_dir = Path(getattr(tool_config, "config_file_path", None) or "./mkdocs.yml").parent
+ return PythonHandler(
+ config=PythonConfig.from_data(**handler_config),
+ base_dir=base_dir,
+ **kwargs,
+ )
diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py
new file mode 100644
index 00000000..20ae7c54
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/rendering.py
@@ -0,0 +1,868 @@
+# This module implements rendering utilities.
+
+from __future__ import annotations
+
+import random
+import re
+import string
+import subprocess
+import sys
+from collections import defaultdict
+from contextlib import suppress
+from dataclasses import replace
+from functools import lru_cache
+from re import Pattern
+from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, TypeVar
+
+from griffe import (
+ Alias,
+ AliasResolutionError,
+ CyclicAliasError,
+ DocstringAttribute,
+ DocstringClass,
+ DocstringFunction,
+ DocstringModule,
+ DocstringSectionAttributes,
+ DocstringSectionClasses,
+ DocstringSectionFunctions,
+ DocstringSectionModules,
+ DocstringSectionTypeAliases,
+ DocstringTypeAlias,
+ Object,
+ TypeAlias,
+)
+from jinja2 import pass_context
+from markupsafe import Markup
+from mkdocs_autorefs import AutorefsHookInterface, Backlink, BacklinkCrumb
+from mkdocstrings import get_logger
+
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Iterator, Sequence
+
+ from griffe import Attribute, Class, Function, Module
+ from jinja2.runtime import Context
+ from mkdocstrings import CollectorItem
+
+_logger = get_logger(__name__)
+
+
+def _sort_key_alphabetical(item: CollectorItem) -> str:
+ # `chr(sys.maxunicode)` is a string that contains the final unicode character,
+ # so if `name` isn't found on the object, the item will go to the end of the list.
+ return item.name or chr(sys.maxunicode)
+
+
+def _sort_key_source(item: CollectorItem) -> float:
+ # If `lineno` is none, the item will go to the end of the list.
+ if item.is_alias:
+ return item.alias_lineno if item.alias_lineno is not None else float("inf")
+ return item.lineno if item.lineno is not None else float("inf")
+
+
+def _sort__all__(item: CollectorItem) -> float:
+ if item.parent.exports is not None:
+ try:
+ return item.parent.exports.index(item.name)
+ except ValueError:
+ # If the item is not in `__all__`, it will go to the end of the list.
+ return float("inf")
+ # No exports declared, refuse to sort (try other methods or return members as they are).
+ raise ValueError(f"Parent object {item.parent.path} doesn't declare exports")
+
+
+Order = Literal["__all__", "alphabetical", "source"]
+"""Ordering methods.
+
+- `__all__`: order members according to `__all__` module attributes, if declared;
+- `alphabetical`: order members alphabetically;
+- `source`: order members as they appear in the source file.
+"""
+
+_order_map: dict[str, Callable[[Object | Alias], str | float]] = {
+ "alphabetical": _sort_key_alphabetical,
+ "source": _sort_key_source,
+ "__all__": _sort__all__,
+}
+
+
+def do_format_code(code: str, line_length: int) -> str:
+ """Format code.
+
+ Parameters:
+ code: The code to format.
+ line_length: The line length.
+
+ Returns:
+ The same code, formatted.
+ """
+ code = code.strip()
+ if len(code) < line_length:
+ return code
+ formatter = _get_formatter()
+ return formatter(code, line_length)
+
+
+class _StashCrossRefFilter:
+ stash: ClassVar[dict[str, str]] = {}
+
+ @staticmethod
+ def _gen_key(length: int) -> str:
+ return "_" + "".join(random.choice(string.ascii_letters + string.digits) for _ in range(max(1, length - 1))) # noqa: S311
+
+ def _gen_stash_key(self, length: int) -> str:
+ key = self._gen_key(length)
+ while key in self.stash:
+ key = self._gen_key(length)
+ return key
+
+ def __call__(self, crossref: str, *, length: int) -> str:
+ key = self._gen_stash_key(length)
+ self.stash[key] = crossref
+ return key
+
+
+do_stash_crossref = _StashCrossRefFilter()
+"""Filter to stash cross-references (and restore them after formatting and highlighting)."""
+
+
+def _format_signature(name: Markup, signature: str, line_length: int) -> str:
+ name = str(name).strip() # type: ignore[assignment]
+ signature = signature.strip()
+ if len(name + signature) < line_length:
+ return name + signature
+
+ # Black cannot format names with dots, so we replace
+ # the whole name with a string of equal length
+ name_length = len(name)
+ formatter = _get_formatter()
+ formatable = f"def {'x' * name_length}{signature}: pass"
+ formatted = formatter(formatable, line_length)
+
+ # We put back the original name
+ # and remove starting `def ` and trailing `: pass`
+ return name + formatted[4:-5].strip()[name_length:-1]
+
+
+@pass_context
+def do_format_signature(
+ context: Context,
+ callable_path: Markup,
+ function: Function,
+ line_length: int,
+ *,
+ annotations: bool | None = None,
+ crossrefs: bool = False, # noqa: ARG001
+) -> str:
+ """Format a signature.
+
+ Parameters:
+ context: Jinja context, passed automatically.
+ callable_path: The path of the callable we render the signature of.
+ function: The function we render the signature of.
+ line_length: The line length.
+ annotations: Whether to show type annotations.
+ crossrefs: Whether to cross-reference types in the signature.
+
+ Returns:
+ The same code, formatted.
+ """
+ env = context.environment
+ type_params_template = env.get_template("type_parameters.html.jinja")
+ signature_template = env.get_template("signature.html.jinja")
+
+ if annotations is None:
+ new_context = context.parent
+ else:
+ new_context = dict(context.parent)
+ new_context["config"] = replace(new_context["config"], show_signature_annotations=annotations)
+
+ signature = type_params_template.render(context.parent, obj=function, signature=True)
+ signature += signature_template.render(new_context, function=function, signature=True)
+
+ signature = _format_signature(callable_path, signature, line_length)
+ signature = str(
+ env.filters["highlight"](
+ Markup.escape(signature),
+ language="python",
+ inline=False,
+ classes=["doc-signature"],
+ linenums=False,
+ ),
+ )
+
+ # Since we highlight the signature without `def`,
+ # Pygments sees it as a function call and not a function definition.
+ # The result is that the function name is not parsed as such,
+ # but instead as a regular name: `n` CSS class instead of `nf`.
+ # When the function name is a known special name like `__exit__`,
+ # Pygments will set an `fm` (function -> magic) CSS class.
+ # To fix this, we replace the CSS class in the first span with `nf`,
+ # unless we already found an `nf` span.
+ if not re.search(r'', signature):
+ signature = re.sub(r'', '', signature, count=1)
+
+ if stash := env.filters["stash_crossref"].stash:
+ for key, value in stash.items():
+ signature = re.sub(rf"\b{key}\b", value, signature)
+ stash.clear()
+
+ return signature
+
+
+@pass_context
+def do_format_attribute(
+ context: Context,
+ attribute_path: Markup,
+ attribute: Attribute,
+ line_length: int,
+ *,
+ crossrefs: bool = False, # noqa: ARG001
+ show_value: bool = True,
+) -> str:
+ """Format an attribute.
+
+ Parameters:
+ context: Jinja context, passed automatically.
+ attribute_path: The path of the callable we render the signature of.
+ attribute: The attribute we render the signature of.
+ line_length: The line length.
+ crossrefs: Whether to cross-reference types in the signature.
+
+ Returns:
+ The same code, formatted.
+ """
+ env = context.environment
+ template = env.get_template("expression.html.jinja")
+ annotations = context.parent["config"].show_signature_annotations
+
+ signature = str(attribute_path).strip()
+ if annotations and attribute.annotation:
+ annotation = template.render(
+ context.parent,
+ expression=attribute.annotation,
+ signature=True,
+ backlink_type="returned-by",
+ )
+ signature += f": {annotation}"
+ if show_value and attribute.value:
+ value = template.render(context.parent, expression=attribute.value, signature=True, backlink_type="used-by")
+ signature += f" = {value}"
+
+ signature = do_format_code(signature, line_length)
+ signature = str(
+ env.filters["highlight"](
+ Markup.escape(signature),
+ language="python",
+ inline=False,
+ classes=["doc-signature"],
+ linenums=False,
+ ),
+ )
+
+ if stash := env.filters["stash_crossref"].stash:
+ for key, value in stash.items():
+ signature = re.sub(rf"\b{key}\b", value, signature)
+ stash.clear()
+
+ return signature
+
+
+@pass_context
+def do_format_type_alias(
+ context: Context,
+ type_alias_path: Markup,
+ type_alias: TypeAlias,
+ line_length: int,
+ *,
+ crossrefs: bool = False, # noqa: ARG001
+) -> str:
+ """Format a type alias.
+
+ Parameters:
+ context: Jinja context, passed automatically.
+ type_alias_path: The path of the type alias we render the signature of.
+ type_alias: The type alias we render the signature of.
+ line_length: The line length.
+ crossrefs: Whether to cross-reference types in the signature.
+
+ Returns:
+ The same code, formatted.
+ """
+ env = context.environment
+ type_params_template = env.get_template("type_parameters.html.jinja")
+ expr_template = env.get_template("expression.html.jinja")
+
+ signature = str(type_alias_path).strip()
+ signature += type_params_template.render(context.parent, obj=type_alias, signature=True)
+ value = expr_template.render(context.parent, expression=type_alias.value, signature=True)
+ signature += f" = {value}"
+
+ signature = do_format_code(signature, line_length)
+ signature = str(
+ env.filters["highlight"](
+ Markup.escape(signature),
+ language="python",
+ inline=False,
+ classes=["doc-signature"],
+ linenums=False,
+ ),
+ )
+
+ # Since we highlight the signature without `type`,
+ # Pygments sees only an assignment, not a type alias definition
+ # (at the moment it does not understand type alias definitions anyway).
+ # The result is that the type alias name is not parsed as such,
+ # but instead as a regular name: `n` CSS class instead of `nc`.
+ # To fix it, we replace the first occurrence of an `n` CSS class
+ # with an `nc` one, unless we found `nc` already.
+ if not re.search(r'', signature):
+ signature = re.sub(r'', '', signature, count=1)
+
+ if stash := env.filters["stash_crossref"].stash:
+ for key, value in stash.items():
+ signature = re.sub(rf"\b{key}\b", value, signature)
+ stash.clear()
+
+ return signature
+
+
+def do_order_members(
+ members: Sequence[Object | Alias],
+ order: Order | list[Order],
+ members_list: bool | list[str] | None, # noqa: FBT001
+) -> Sequence[Object | Alias]:
+ """Order members given an ordering method.
+
+ Parameters:
+ members: The members to order.
+ order: The ordering method.
+ members_list: An optional member list (manual ordering).
+
+ Returns:
+ The same members, ordered.
+ """
+ if isinstance(members_list, list) and members_list:
+ sorted_members = []
+ members_dict = {member.name: member for member in members}
+ for name in members_list:
+ if name in members_dict:
+ sorted_members.append(members_dict[name])
+ return sorted_members
+ if isinstance(order, str):
+ order = [order]
+ for method in order:
+ with suppress(ValueError):
+ return sorted(members, key=_order_map[method])
+ return members
+
+
+_split_path_re = re.compile(r"([.(]?)([\w]+)(\))?")
+_splitable_re = re.compile(r"[().]")
+
+
+def do_split_path(path: str, full_path: str) -> Iterator[tuple[str, str, str, str]]:
+ """Split object paths for building cross-references.
+
+ Parameters:
+ path: The path to split.
+ full_path: The full path, used to compute correct paths for each part of the path.
+
+ Yields:
+ 4-tuples: prefix, word, full path, suffix.
+ """
+ # Path is a single word, yield full path directly.
+ if not _splitable_re.search(path):
+ yield ("", path, full_path, "")
+ return
+
+ current_path = ""
+ if path == full_path:
+ # Split full path and yield directly without storing data in a dict.
+ for match in _split_path_re.finditer(full_path):
+ prefix, word, suffix = match.groups()
+ current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
+ yield prefix or "", word, current_path, suffix or ""
+ return
+
+ # Split full path first to store tuples in a dict.
+ elements = {}
+ for match in _split_path_re.finditer(full_path):
+ prefix, word, suffix = match.groups()
+ current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
+ elements[word] = (prefix or "", word, current_path, suffix or "")
+
+ # Then split path and pick tuples from the dict.
+ first = True
+ for match in _split_path_re.finditer(path):
+ prefix, word, current_path, suffix = elements[match.group(2)]
+ yield "" if first else prefix, word, current_path, suffix
+ first = False
+
+
+def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
+ keep = None
+ rules = set()
+ for regex, exclude in filters:
+ rules.add(exclude)
+ if regex.search(name):
+ keep = not exclude
+ if keep is None:
+ # When we only include stuff, no match = reject.
+ # When we only exclude stuff, or include and exclude stuff, no match = keep.
+ return rules != {False}
+ return keep
+
+
+def _parents(obj: Alias) -> set[str]:
+ parent: Object | Alias = obj.parent # type: ignore[assignment]
+ parents = {obj.path, parent.path}
+ if parent.is_alias:
+ parents.add(parent.final_target.path) # type: ignore[union-attr]
+ while parent.parent:
+ parent = parent.parent
+ parents.add(parent.path)
+ if parent.is_alias:
+ parents.add(parent.final_target.path) # type: ignore[union-attr]
+ return parents
+
+
+def _remove_cycles(objects: list[Object | Alias]) -> Iterator[Object | Alias]:
+ suppress_errors = suppress(AliasResolutionError, CyclicAliasError)
+ for obj in objects:
+ if obj.is_alias:
+ with suppress_errors:
+ if obj.final_target.path in _parents(obj): # type: ignore[arg-type,union-attr]
+ continue
+ yield obj
+
+
+def do_filter_objects(
+ objects_dictionary: dict[str, Object | Alias],
+ *,
+ filters: Sequence[tuple[Pattern, bool]] | Literal["public"] | None = None,
+ members_list: bool | list[str] | None = None,
+ inherited_members: bool | list[str] = False,
+ keep_no_docstrings: bool = True,
+) -> list[Object | Alias]:
+ """Filter a dictionary of objects based on their docstrings.
+
+ Parameters:
+ objects_dictionary: The dictionary of objects.
+ filters: Filters to apply, based on members' names, or `"public"`.
+ Each element is a tuple: a pattern, and a boolean indicating whether
+ to reject the object if the pattern matches.
+ members_list: An optional, explicit list of members to keep.
+ When given and empty, return an empty list.
+ When given and not empty, ignore filters and docstrings presence/absence.
+ inherited_members: Whether to keep inherited members or exclude them.
+ keep_no_docstrings: Whether to keep objects with no/empty docstrings (recursive check).
+
+ Returns:
+ A list of objects.
+ """
+ inherited_members_specified = False
+ if inherited_members is True:
+ # Include all inherited members.
+ objects = list(objects_dictionary.values())
+ elif inherited_members is False:
+ # Include no inherited members.
+ objects = [obj for obj in objects_dictionary.values() if not obj.inherited]
+ else:
+ # Include specific inherited members.
+ inherited_members_specified = True
+ objects = [
+ obj for obj in objects_dictionary.values() if not obj.inherited or obj.name in set(inherited_members)
+ ]
+
+ if members_list is True:
+ # Return all pre-selected members.
+ return objects
+
+ if members_list is False or members_list == []:
+ # Return selected inherited members, if any.
+ return [obj for obj in objects if obj.inherited]
+
+ if members_list is not None:
+ # Return selected members (keeping any pre-selected inherited members).
+ return [
+ obj for obj in objects if obj.name in set(members_list) or (inherited_members_specified and obj.inherited)
+ ]
+
+ # Use filters and docstrings.
+ if filters == "public":
+ objects = [obj for obj in objects if obj.is_public]
+ elif filters:
+ objects = [
+ obj for obj in objects if _keep_object(obj.name, filters) or (inherited_members_specified and obj.inherited)
+ ]
+ if not keep_no_docstrings:
+ objects = [obj for obj in objects if obj.has_docstrings or (inherited_members_specified and obj.inherited)]
+
+ # Prevent infinite recursion.
+ if objects:
+ objects = list(_remove_cycles(objects))
+
+ return objects
+
+
+@lru_cache(maxsize=1)
+def _get_formatter() -> Callable[[str, int], str]:
+ for formatter_function in [
+ _get_black_formatter,
+ _get_ruff_formatter,
+ ]:
+ if (formatter := formatter_function()) is not None:
+ return formatter
+
+ _logger.info("Formatting signatures requires either Black or Ruff to be installed.")
+ return lambda text, _: text
+
+
+def _get_ruff_formatter() -> Callable[[str, int], str] | None:
+ try:
+ from ruff.__main__ import find_ruff_bin # noqa: PLC0415
+ except ImportError:
+ return None
+
+ try:
+ ruff_bin = find_ruff_bin()
+ except FileNotFoundError:
+ ruff_bin = "ruff"
+
+ def formatter(code: str, line_length: int) -> str:
+ try:
+ completed_process = subprocess.run( # noqa: S603
+ [
+ ruff_bin,
+ "format",
+ "--config",
+ f"line-length={line_length}",
+ "--stdin-filename",
+ "file.py",
+ "-",
+ ],
+ check=True,
+ capture_output=True,
+ text=True,
+ input=code,
+ )
+ except subprocess.CalledProcessError:
+ return code
+ else:
+ return completed_process.stdout
+
+ return formatter
+
+
+def _get_black_formatter() -> Callable[[str, int], str] | None:
+ try:
+ from black import InvalidInput, Mode, format_str # noqa: PLC0415
+ except ModuleNotFoundError:
+ return None
+
+ def formatter(code: str, line_length: int) -> str:
+ mode = Mode(line_length=line_length)
+ try:
+ return format_str(code, mode=mode)
+ except InvalidInput:
+ return code
+
+ return formatter
+
+
+def do_get_template(obj: Object | Alias) -> str:
+ """Get the template name used to render an object.
+
+ Parameters:
+ obj: A Griffe object.
+
+ Returns:
+ A template name.
+ """
+ extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
+ if name := extra_data.get("template", ""):
+ return name
+ name = obj.kind.value.replace(" ", "_")
+ return f"{name}.html.jinja"
+
+
+@pass_context
+def do_as_attributes_section(
+ context: Context, # noqa: ARG001
+ attributes: Sequence[Attribute],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionAttributes:
+ """Build an attributes section from a list of attributes.
+
+ Parameters:
+ attributes: The attributes to build the section from.
+ check_public: Whether to check if the attribute is public.
+
+ Returns:
+ An attributes docstring section.
+ """
+
+ def _parse_docstring_summary(attribute: Attribute) -> str:
+ if attribute.docstring is None:
+ return ""
+ line = attribute.docstring.value.split("\n", 1)[0]
+ if ":" in line and attribute.docstring.parser_options.get("returns_type_in_property_summary", False):
+ _, line = line.split(":", 1)
+ return line
+
+ return DocstringSectionAttributes(
+ [
+ DocstringAttribute(
+ name=attribute.name,
+ description=_parse_docstring_summary(attribute),
+ annotation=attribute.annotation,
+ value=attribute.value,
+ )
+ for attribute in attributes
+ if not check_public or attribute.is_public
+ ],
+ )
+
+
+@pass_context
+def do_as_functions_section(
+ context: Context,
+ functions: Sequence[Function],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionFunctions:
+ """Build a functions section from a list of functions.
+
+ Parameters:
+ functions: The functions to build the section from.
+ check_public: Whether to check if the function is public.
+
+ Returns:
+ A functions docstring section.
+ """
+ keep_init_method = not context.parent["config"].merge_init_into_class
+ return DocstringSectionFunctions(
+ [
+ DocstringFunction(
+ name=function.name,
+ description=function.docstring.value.split("\n", 1)[0] if function.docstring else "",
+ )
+ for function in functions
+ if (not check_public or function.is_public) and (function.name != "__init__" or keep_init_method)
+ ],
+ )
+
+
+@pass_context
+def do_as_classes_section(
+ context: Context, # noqa: ARG001
+ classes: Sequence[Class],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionClasses:
+ """Build a classes section from a list of classes.
+
+ Parameters:
+ classes: The classes to build the section from.
+ check_public: Whether to check if the class is public.
+
+ Returns:
+ A classes docstring section.
+ """
+ return DocstringSectionClasses(
+ [
+ DocstringClass(
+ name=cls.name,
+ description=cls.docstring.value.split("\n", 1)[0] if cls.docstring else "",
+ )
+ for cls in classes
+ if not check_public or cls.is_public
+ ],
+ )
+
+
+@pass_context
+def do_as_modules_section(
+ context: Context, # noqa: ARG001
+ modules: Sequence[Module],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionModules:
+ """Build a modules section from a list of modules.
+
+ Parameters:
+ modules: The modules to build the section from.
+ check_public: Whether to check if the module is public.
+
+ Returns:
+ A modules docstring section.
+ """
+ return DocstringSectionModules(
+ [
+ DocstringModule(
+ name=module.name,
+ description=module.docstring.value.split("\n", 1)[0] if module.docstring else "",
+ )
+ for module in modules
+ if not check_public or module.is_public
+ ],
+ )
+
+
+@pass_context
+def do_as_type_aliases_section(
+ context: Context, # noqa: ARG001
+ type_aliases: Sequence[TypeAlias],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionTypeAliases:
+ """Build a type aliases section from a list of type aliases.
+
+ Parameters:
+ type_aliases: The type aliases to build the section from.
+ check_public: Whether to check if the type_alias is public.
+
+ Returns:
+ A type aliases docstring section.
+ """
+ return DocstringSectionTypeAliases(
+ [
+ DocstringTypeAlias(
+ name=type_alias.name,
+ description=type_alias.docstring.value.split("\n", 1)[0] if type_alias.docstring else "",
+ )
+ for type_alias in type_aliases
+ if not check_public or type_alias.is_public
+ ],
+ )
+
+
+class AutorefsHook(AutorefsHookInterface):
+ """Autorefs hook.
+
+ With this hook, we're able to add context to autorefs (cross-references),
+ such as originating file path and line number, to improve error reporting.
+ """
+
+ def __init__(self, current_object: Object | Alias, config: dict[str, Any]) -> None:
+ """Initialize the hook.
+
+ Parameters:
+ current_object: The object being rendered.
+ config: The configuration dictionary.
+ """
+ self.current_object = current_object
+ """The current object being rendered."""
+ self.config = config
+ """The configuration options."""
+
+ def expand_identifier(self, identifier: str) -> str:
+ """Expand an identifier.
+
+ Parameters:
+ identifier: The identifier to expand.
+
+ Returns:
+ The expanded identifier.
+ """
+ # Handle leading dots in the identifier:
+ # - `.name` is a reference to the current object's `name` member.
+ # - `..name` is a reference to the parent object's `name` member.
+ # - etc.
+ # TODO: We should update the protocol to allow modifying the title too.
+ # In this case it would likely be better to strip dots from the title,
+ # when it's not explicitly specified.
+ if self.config.relative_crossrefs and identifier.startswith("."): # type: ignore[attr-defined]
+ identifier = identifier[1:]
+ obj = self.current_object
+ while identifier and identifier[0] == ".":
+ identifier = identifier[1:]
+ obj = obj.parent # type: ignore[assignment]
+ identifier = f"{obj.path}.{identifier}" if identifier else obj.path
+
+ # We resolve the identifier to its full path.
+ # For this we take out the first name, resolve it, and then append the rest.
+ if self.config.scoped_crossrefs: # type: ignore[attr-defined]
+ if "." in identifier:
+ identifier, remaining = identifier.split(".", 1)
+ else:
+ remaining = ""
+ with suppress(Exception):
+ identifier = self.current_object.resolve(identifier)
+ if remaining:
+ identifier = f"{identifier}.{remaining}"
+
+ return identifier
+
+ def get_context(self) -> AutorefsHookInterface.Context:
+ """Get the context for the current object.
+
+ Returns:
+ The context.
+ """
+ role = {
+ "attribute": "data" if self.current_object.parent and self.current_object.parent.is_module else "attr",
+ "class": "class",
+ "function": "meth" if self.current_object.parent and self.current_object.parent.is_class else "func",
+ "module": "mod",
+ }.get(self.current_object.kind.value.lower(), "obj")
+ origin = self.current_object.path
+ try:
+ filepath = self.current_object.docstring.parent.filepath # type: ignore[union-attr]
+ lineno = self.current_object.docstring.lineno or 0 # type: ignore[union-attr]
+ except AttributeError:
+ filepath = self.current_object.filepath
+ lineno = 0
+
+ return AutorefsHookInterface.Context(
+ domain="py",
+ role=role,
+ origin=origin,
+ filepath=str(filepath),
+ lineno=lineno,
+ )
+
+
+_T = TypeVar("_T")
+_Tree = dict[_T, "_Tree"]
+_rtree = lambda: defaultdict(_rtree) # type: ignore[has-type,var-annotated] # noqa: E731
+
+Tree = dict[tuple[_T, ...], "Tree"]
+"""A tree type. Each node holds a tuple of items."""
+
+
+def _tree(data: Iterable[tuple[_T, ...]]) -> _Tree:
+ new_tree = _rtree()
+ for nav in data:
+ *path, leaf = nav
+ node = new_tree
+ for key in path:
+ node = node[key]
+ node[leaf] = _rtree()
+ return new_tree
+
+
+def _compact_tree(tree: _Tree) -> Tree:
+ new_tree = _rtree()
+ for key, value in tree.items():
+ child = _compact_tree(value)
+ if len(child) == 1:
+ child_key, child_value = next(iter(child.items()))
+ new_key = (key, *child_key)
+ new_tree[new_key] = child_value
+ else:
+ new_tree[(key,)] = child
+ return new_tree
+
+
+def do_backlink_tree(backlinks: list[Backlink]) -> Tree[BacklinkCrumb]:
+ """Build a tree of backlinks.
+
+ Parameters:
+ backlinks: The list of backlinks.
+
+ Returns:
+ A tree of backlinks.
+ """
+ return _compact_tree(_tree(backlink.crumbs for backlink in backlinks))
diff --git a/src/mkdocstrings_handlers/python/handler.py b/src/mkdocstrings_handlers/python/handler.py
deleted file mode 100644
index ef93ee3b..00000000
--- a/src/mkdocstrings_handlers/python/handler.py
+++ /dev/null
@@ -1,510 +0,0 @@
-"""This module implements a handler for the Python language."""
-
-from __future__ import annotations
-
-import glob
-import os
-import posixpath
-import re
-import sys
-from collections import ChainMap
-from contextlib import suppress
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar, Iterator, Mapping, Sequence
-
-from griffe import (
- AliasResolutionError,
- GriffeLoader,
- LinesCollection,
- ModulesCollection,
- Parser,
- load_extensions,
- patch_loggers,
-)
-from mkdocstrings.extension import PluginError
-from mkdocstrings.handlers.base import BaseHandler, CollectionError, CollectorItem
-from mkdocstrings.inventory import Inventory
-from mkdocstrings.loggers import get_logger
-
-from mkdocstrings_handlers.python import rendering
-
-if TYPE_CHECKING:
- from markdown import Markdown
-
-
-if sys.version_info >= (3, 11):
- from contextlib import chdir
-else:
- # TODO: remove once support for Python 3.10 is dropped
- from contextlib import contextmanager
-
- @contextmanager
- def chdir(path: str) -> Iterator[None]: # noqa: D103
- old_wd = os.getcwd()
- os.chdir(path)
- try:
- yield
- finally:
- os.chdir(old_wd)
-
-
-logger = get_logger(__name__)
-
-patch_loggers(get_logger)
-
-
-class PythonHandler(BaseHandler):
- """The Python handler class."""
-
- name: str = "python"
- """The handler's name."""
- domain: str = "py" # to match Sphinx's default domain
- """The cross-documentation domain/language for this handler."""
- enable_inventory: bool = True
- """Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file."""
- fallback_theme = "material"
- """The fallback theme."""
- fallback_config: ClassVar[dict] = {"fallback": True}
- """The configuration used to collect item during autorefs fallback."""
- default_config: ClassVar[dict] = {
- "find_stubs_package": False,
- "docstring_style": "google",
- "docstring_options": {},
- "show_symbol_type_heading": False,
- "show_symbol_type_toc": False,
- "show_root_heading": False,
- "show_root_toc_entry": True,
- "show_root_full_path": True,
- "show_root_members_full_path": False,
- "show_object_full_path": False,
- "show_category_heading": False,
- "show_if_no_docstring": False,
- "show_signature": True,
- "show_signature_annotations": False,
- "signature_crossrefs": False,
- "separate_signature": False,
- "line_length": 60,
- "merge_init_into_class": False,
- "relative_crossrefs": False,
- "scoped_crossrefs": False,
- "show_docstring_attributes": True,
- "show_docstring_functions": True,
- "show_docstring_classes": True,
- "show_docstring_modules": True,
- "show_docstring_description": True,
- "show_docstring_examples": True,
- "show_docstring_other_parameters": True,
- "show_docstring_parameters": True,
- "show_docstring_raises": True,
- "show_docstring_receives": True,
- "show_docstring_returns": True,
- "show_docstring_warns": True,
- "show_docstring_yields": True,
- "show_source": True,
- "show_bases": True,
- "show_submodules": False,
- "group_by_category": True,
- "heading_level": 2,
- "members_order": rendering.Order.alphabetical.value,
- "docstring_section_style": "table",
- "members": None,
- "inherited_members": False,
- "filters": ["!^_[^_]"],
- "annotations_path": "brief",
- "preload_modules": None,
- "allow_inspection": True,
- "summary": False,
- "show_labels": True,
- "unwrap_annotated": False,
- }
- """Default handler configuration.
-
- Attributes: General options:
- find_stubs_package (bool): Whether to load stubs package (package-stubs) when extracting docstrings. Default `False`.
- allow_inspection (bool): Whether to allow inspecting modules when visiting them is not possible. Default: `True`.
- show_bases (bool): Show the base classes of a class. Default: `True`.
- show_source (bool): Show the source code of this object. Default: `True`.
- preload_modules (list[str] | None): Pre-load modules that are
- not specified directly in autodoc instructions (`::: identifier`).
- It is useful when you want to render documentation for a particular member of an object,
- and this member is imported from another package than its parent.
-
- For an imported member to be rendered, you need to add it to the `__all__` attribute
- of the importing module.
-
- The modules must be listed as an array of strings. Default: `None`.
-
- Attributes: Headings options:
- heading_level (int): The initial heading level to use. Default: `2`.
- show_root_heading (bool): Show the heading of the object at the root of the documentation tree
- (i.e. the object referenced by the identifier after `:::`). Default: `False`.
- show_root_toc_entry (bool): If the root heading is not shown, at least add a ToC entry for it. Default: `True`.
- show_root_full_path (bool): Show the full Python path for the root object heading. Default: `True`.
- show_root_members_full_path (bool): Show the full Python path of the root members. Default: `False`.
- show_object_full_path (bool): Show the full Python path of every object. Default: `False`.
- show_category_heading (bool): When grouped by categories, show a heading for each category. Default: `False`.
- show_symbol_type_heading (bool): Show the symbol type in headings (e.g. mod, class, meth, func and attr). Default: `False`.
- show_symbol_type_toc (bool): Show the symbol type in the Table of Contents (e.g. mod, class, methd, func and attr). Default: `False`.
-
- Attributes: Members options:
- inherited_members (list[str] | bool | None): A boolean, or an explicit list of inherited members to render.
- If true, select all inherited members, which can then be filtered with `members`.
- If false or empty list, do not select any inherited member. Default: `False`.
- members (list[str] | bool | None): A boolean, or an explicit list of members to render.
- If true, select all members without further filtering.
- If false or empty list, do not render members.
- If none, select all members and apply further filtering with filters and docstrings. Default: `None`.
- members_order (str): The members ordering to use. Options: `alphabetical` - order by the members names,
- `source` - order members as they appear in the source file. Default: `"alphabetical"`.
- filters (list[str] | None): A list of filters applied to filter objects based on their name.
- A filter starting with `!` will exclude matching objects instead of including them.
- The `members` option takes precedence over `filters` (filters will still be applied recursively
- to lower members in the hierarchy). Default: `["!^_[^_]"]`.
- group_by_category (bool): Group the object's children by categories: attributes, classes, functions, and modules. Default: `True`.
- show_submodules (bool): When rendering a module, show its submodules recursively. Default: `False`.
- summary (bool | dict[str, bool]): Whether to render summaries of modules, classes, functions (methods) and attributes.
- show_labels (bool): Whether to show labels of the members. Default: `True`.
-
- Attributes: Docstrings options:
- docstring_style (str): The docstring style to use: `google`, `numpy`, `sphinx`, or `None`. Default: `"google"`.
- docstring_options (dict): The options for the docstring parser. See [docstring parsers](https://mkdocstrings.github.io/griffe/reference/docstrings/) and their options in Griffe docs.
- docstring_section_style (str): The style used to render docstring sections. Options: `table`, `list`, `spacy`. Default: `"table"`.
- merge_init_into_class (bool): Whether to merge the `__init__` method into the class' signature and docstring. Default: `False`.
- relative_crossrefs (bool): Whether to enable the relative crossref syntax. Default: `False`.
- scoped_crossrefs (bool): Whether to enable the scoped crossref ability. Default: `False`.
- show_if_no_docstring (bool): Show the object heading even if it has no docstring or children with docstrings. Default: `False`.
- show_docstring_attributes (bool): Whether to display the "Attributes" section in the object's docstring. Default: `True`.
- show_docstring_functions (bool): Whether to display the "Functions" or "Methods" sections in the object's docstring. Default: `True`.
- show_docstring_classes (bool): Whether to display the "Classes" section in the object's docstring. Default: `True`.
- show_docstring_modules (bool): Whether to display the "Modules" section in the object's docstring. Default: `True`.
- show_docstring_description (bool): Whether to display the textual block (including admonitions) in the object's docstring. Default: `True`.
- show_docstring_examples (bool): Whether to display the "Examples" section in the object's docstring. Default: `True`.
- show_docstring_other_parameters (bool): Whether to display the "Other Parameters" section in the object's docstring. Default: `True`.
- show_docstring_parameters (bool): Whether to display the "Parameters" section in the object's docstring. Default: `True`.
- show_docstring_raises (bool): Whether to display the "Raises" section in the object's docstring. Default: `True`.
- show_docstring_receives (bool): Whether to display the "Receives" section in the object's docstring. Default: `True`.
- show_docstring_returns (bool): Whether to display the "Returns" section in the object's docstring. Default: `True`.
- show_docstring_warns (bool): Whether to display the "Warns" section in the object's docstring. Default: `True`.
- show_docstring_yields (bool): Whether to display the "Yields" section in the object's docstring. Default: `True`.
-
- Attributes: Signatures/annotations options:
- annotations_path (str): The verbosity for annotations path: `brief` (recommended), or `source` (as written in the source). Default: `"brief"`.
- line_length (int): Maximum line length when formatting code/signatures. Default: `60`.
- show_signature (bool): Show methods and functions signatures. Default: `True`.
- show_signature_annotations (bool): Show the type annotations in methods and functions signatures. Default: `False`.
- signature_crossrefs (bool): Whether to render cross-references for type annotations in signatures. Default: `False`.
- separate_signature (bool): Whether to put the whole signature in a code block below the heading.
- If Black is installed, the signature is also formatted using it. Default: `False`.
- unwrap_annotated (bool): Whether to unwrap `Annotated` types to show only the type without the annotations. Default: `False`.
- """
-
- def __init__(
- self,
- *args: Any,
- config_file_path: str | None = None,
- paths: list[str] | None = None,
- locale: str = "en",
- load_external_modules: bool | None = None,
- **kwargs: Any,
- ) -> None:
- """Initialize the handler.
-
- Parameters:
- *args: Handler name, theme and custom templates.
- config_file_path: The MkDocs configuration file path.
- paths: A list of paths to use as Griffe search paths.
- locale: The locale to use when rendering content.
- load_external_modules: Load external modules when resolving aliases.
- **kwargs: Same thing, but with keyword arguments.
- """
- super().__init__(*args, **kwargs)
-
- # Warn if user overrides base templates.
- if custom_templates := kwargs.get("custom_templates", ()):
- config_dir = Path(config_file_path or "./mkdocs.yml").parent
- for theme_dir in config_dir.joinpath(custom_templates, "python").iterdir():
- if theme_dir.joinpath("_base").is_dir():
- logger.warning(
- f"Overriding base template '{theme_dir.name}/_base/.html.jinja' is not supported, "
- f"override '{theme_dir.name}/.html.jinja' instead",
- )
-
- self._config_file_path = config_file_path
- self._load_external_modules = load_external_modules
- paths = paths or []
-
- # Expand paths with glob patterns.
- glob_base_dir = os.path.dirname(os.path.abspath(config_file_path)) if config_file_path else "."
- with chdir(glob_base_dir):
- resolved_globs = [glob.glob(path) for path in paths]
- paths = [path for glob_list in resolved_globs for path in glob_list]
-
- # By default, add the directory of the config file to the search paths.
- if not paths and config_file_path:
- paths.append(os.path.dirname(config_file_path))
-
- # Initialize search paths from `sys.path`, eliminating empty paths.
- search_paths = [path for path in sys.path if path]
-
- for path in reversed(paths):
- # If it's not absolute, make path relative to the config file path, then make it absolute.
- if not os.path.isabs(path) and config_file_path:
- path = os.path.abspath(os.path.join(os.path.dirname(config_file_path), path)) # noqa: PLW2901
- # Don't add duplicates.
- if path not in search_paths:
- search_paths.insert(0, path)
-
- self._paths = search_paths
- self._modules_collection: ModulesCollection = ModulesCollection()
- self._lines_collection: LinesCollection = LinesCollection()
- self._locale = locale
-
- @classmethod
- def load_inventory(
- cls,
- in_file: BinaryIO,
- url: str,
- base_url: str | None = None,
- domains: list[str] | None = None,
- **kwargs: Any, # noqa: ARG003
- ) -> Iterator[tuple[str, str]]:
- """Yield items and their URLs from an inventory file streamed from `in_file`.
-
- This implements mkdocstrings' `load_inventory` "protocol" (see [`mkdocstrings.plugin`][mkdocstrings.plugin]).
-
- Arguments:
- in_file: The binary file-like object to read the inventory from.
- url: The URL that this file is being streamed from (used to guess `base_url`).
- base_url: The URL that this inventory's sub-paths are relative to.
- domains: A list of domain strings to filter the inventory by, when not passed, "py" will be used.
- **kwargs: Ignore additional arguments passed from the config.
-
- Yields:
- Tuples of (item identifier, item URL).
- """
- domains = domains or ["py"]
- if base_url is None:
- base_url = posixpath.dirname(url)
-
- for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values():
- yield item.name, posixpath.join(base_url, item.uri)
-
- def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem: # noqa: D102
- module_name = identifier.split(".", 1)[0]
- unknown_module = module_name not in self._modules_collection
- if config.get("fallback", False) and unknown_module:
- raise CollectionError("Not loading additional modules during fallback")
-
- final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
- parser_name = final_config["docstring_style"]
- parser_options = final_config["docstring_options"]
- parser = parser_name and Parser(parser_name)
-
- if unknown_module:
- extensions = self.normalize_extension_paths(final_config.get("extensions", []))
- loader = GriffeLoader(
- extensions=load_extensions(*extensions),
- search_paths=self._paths,
- docstring_parser=parser,
- docstring_options=parser_options,
- modules_collection=self._modules_collection,
- lines_collection=self._lines_collection,
- allow_inspection=final_config["allow_inspection"],
- )
- try:
- for pre_loaded_module in final_config.get("preload_modules") or []:
- if pre_loaded_module not in self._modules_collection:
- loader.load(
- pre_loaded_module,
- try_relative_path=False,
- find_stubs_package=final_config["find_stubs_package"],
- )
- loader.load(
- module_name,
- try_relative_path=False,
- find_stubs_package=final_config["find_stubs_package"],
- )
- except ImportError as error:
- raise CollectionError(str(error)) from error
- unresolved, iterations = loader.resolve_aliases(
- implicit=False,
- external=self._load_external_modules,
- )
- if unresolved:
- logger.debug(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
- logger.debug(f"Unresolved aliases: {', '.join(sorted(unresolved))}")
-
- try:
- doc_object = self._modules_collection[identifier]
- except KeyError as error:
- raise CollectionError(f"{identifier} could not be found") from error
- except AliasResolutionError as error:
- raise CollectionError(str(error)) from error
-
- if not unknown_module:
- with suppress(AliasResolutionError):
- if doc_object.docstring is not None:
- doc_object.docstring.parser = parser
- doc_object.docstring.parser_options = parser_options
-
- return doc_object
-
- def render(self, data: CollectorItem, config: Mapping[str, Any]) -> str: # noqa: D102 (ignore missing docstring)
- final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
-
- template_name = rendering.do_get_template(self.env, data)
- template = self.env.get_template(template_name)
-
- # Heading level is a "state" variable, that will change at each step
- # of the rendering recursion. Therefore, it's easier to use it as a plain value
- # than as an item in a dictionary.
- heading_level = final_config["heading_level"]
- try:
- final_config["members_order"] = rendering.Order(final_config["members_order"])
- except ValueError as error:
- choices = "', '".join(item.value for item in rendering.Order)
- raise PluginError(
- f"Unknown members_order '{final_config['members_order']}', choose between '{choices}'.",
- ) from error
-
- if final_config["filters"]:
- final_config["filters"] = [
- (re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in final_config["filters"]
- ]
-
- summary = final_config["summary"]
- if summary is True:
- final_config["summary"] = {
- "attributes": True,
- "functions": True,
- "classes": True,
- "modules": True,
- }
- elif summary is False:
- final_config["summary"] = {
- "attributes": False,
- "functions": False,
- "classes": False,
- "modules": False,
- }
- else:
- final_config["summary"] = {
- "attributes": summary.get("attributes", False),
- "functions": summary.get("functions", False),
- "classes": summary.get("classes", False),
- "modules": summary.get("modules", False),
- }
-
- return template.render(
- **{
- "config": final_config,
- data.kind.value: data,
- "heading_level": heading_level,
- "root": True,
- "locale": self._locale,
- },
- )
-
- def update_env(self, md: Markdown, config: dict) -> None:
- """Update the Jinja environment with custom filters and tests.
-
- Parameters:
- md: The Markdown instance.
- config: The configuration dictionary.
- """
- super().update_env(md, config)
- self.env.trim_blocks = True
- self.env.lstrip_blocks = True
- self.env.keep_trailing_newline = False
- self.env.filters["split_path"] = rendering.do_split_path
- self.env.filters["crossref"] = rendering.do_crossref
- self.env.filters["multi_crossref"] = rendering.do_multi_crossref
- self.env.filters["order_members"] = rendering.do_order_members
- self.env.filters["format_code"] = rendering.do_format_code
- self.env.filters["format_signature"] = rendering.do_format_signature
- self.env.filters["format_attribute"] = rendering.do_format_attribute
- self.env.filters["filter_objects"] = rendering.do_filter_objects
- self.env.filters["stash_crossref"] = lambda ref, length: ref
- self.env.filters["get_template"] = rendering.do_get_template
- self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section
- self.env.filters["as_functions_section"] = rendering.do_as_functions_section
- self.env.filters["as_classes_section"] = rendering.do_as_classes_section
- self.env.filters["as_modules_section"] = rendering.do_as_modules_section
- self.env.globals["AutorefsHook"] = rendering.AutorefsHook
- self.env.tests["existing_template"] = lambda template_name: template_name in self.env.list_templates()
-
- def get_anchors(self, data: CollectorItem) -> tuple[str, ...]: # noqa: D102 (ignore missing docstring)
- anchors = [data.path]
- try:
- if data.canonical_path != data.path:
- anchors.append(data.canonical_path)
- for anchor in data.aliases:
- if anchor not in anchors:
- anchors.append(anchor)
- except AliasResolutionError:
- return tuple(anchors)
- return tuple(anchors)
-
- def normalize_extension_paths(self, extensions: Sequence) -> Sequence:
- """Resolve extension paths relative to config file."""
- if self._config_file_path is None:
- return extensions
-
- base_path = os.path.dirname(self._config_file_path)
- normalized = []
-
- for ext in extensions:
- if isinstance(ext, dict):
- pth, options = next(iter(ext.items()))
- pth = str(pth)
- else:
- pth = str(ext)
- options = None
-
- if pth.endswith(".py") or ".py:" in pth or "/" in pth or "\\" in pth: # noqa: SIM102
- # This is a sytem path. Normalize it.
- if not os.path.isabs(pth):
- # Make path absolute relative to config file path.
- pth = os.path.normpath(os.path.join(base_path, pth))
-
- if options is not None:
- normalized.append({pth: options})
- else:
- normalized.append(pth)
-
- return normalized
-
-
-def get_handler(
- *,
- theme: str,
- custom_templates: str | None = None,
- config_file_path: str | None = None,
- paths: list[str] | None = None,
- locale: str = "en",
- load_external_modules: bool | None = None,
- **config: Any, # noqa: ARG001
-) -> PythonHandler:
- """Simply return an instance of `PythonHandler`.
-
- Arguments:
- theme: The theme to use when rendering contents.
- custom_templates: Directory containing custom templates.
- config_file_path: The MkDocs configuration file path.
- paths: A list of paths to use as Griffe search paths.
- locale: The locale to use when rendering content.
- load_external_modules: Load external modules when resolving aliases.
- **config: Configuration passed to the handler.
-
- Returns:
- An instance of `PythonHandler`.
- """
- return PythonHandler(
- handler="python",
- theme=theme,
- custom_templates=custom_templates,
- config_file_path=config_file_path,
- paths=paths,
- locale=locale,
- load_external_modules=load_external_modules,
- )
diff --git a/src/mkdocstrings_handlers/python/rendering.py b/src/mkdocstrings_handlers/python/rendering.py
deleted file mode 100644
index 2c4a4893..00000000
--- a/src/mkdocstrings_handlers/python/rendering.py
+++ /dev/null
@@ -1,631 +0,0 @@
-"""This module implements rendering utilities."""
-
-from __future__ import annotations
-
-import enum
-import random
-import re
-import string
-import sys
-import warnings
-from functools import lru_cache, partial
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, Callable, Match, Pattern, Sequence
-
-from griffe import (
- Alias,
- DocstringSectionAttributes,
- DocstringSectionClasses,
- DocstringSectionFunctions,
- DocstringSectionModules,
- Object,
-)
-from jinja2 import TemplateNotFound, pass_context, pass_environment
-from markupsafe import Markup
-from mkdocs_autorefs.references import AutorefsHookInterface
-from mkdocstrings.loggers import get_logger
-
-if TYPE_CHECKING:
- from griffe import Attribute, Class, Function, Module
- from jinja2 import Environment, Template
- from jinja2.runtime import Context
- from mkdocstrings.handlers.base import CollectorItem
-
-logger = get_logger(__name__)
-
-
-class Order(enum.Enum):
- """Enumeration for the possible members ordering."""
-
- alphabetical = "alphabetical"
- """Alphabetical order."""
- source = "source"
- """Source code order."""
-
-
-def _sort_key_alphabetical(item: CollectorItem) -> Any:
- # chr(sys.maxunicode) is a string that contains the final unicode
- # character, so if 'name' isn't found on the object, the item will go to
- # the end of the list.
- return item.name or chr(sys.maxunicode)
-
-
-def _sort_key_source(item: CollectorItem) -> Any:
- # if 'lineno' is none, the item will go to the start of the list.
- if item.is_alias:
- return item.alias_lineno if item.alias_lineno is not None else -1
- return item.lineno if item.lineno is not None else -1
-
-
-order_map = {
- Order.alphabetical: _sort_key_alphabetical,
- Order.source: _sort_key_source,
-}
-
-
-def do_format_code(code: str, line_length: int) -> str:
- """Format code using Black.
-
- Parameters:
- code: The code to format.
- line_length: The line length to give to Black.
-
- Returns:
- The same code, formatted.
- """
- code = code.strip()
- if len(code) < line_length:
- return code
- formatter = _get_black_formatter()
- return formatter(code, line_length)
-
-
-_stash_key_alphabet = string.ascii_letters + string.digits
-
-
-def _gen_key(length: int) -> str:
- return "_" + "".join(random.choice(_stash_key_alphabet) for _ in range(max(1, length - 1))) # noqa: S311
-
-
-def _gen_stash_key(stash: dict[str, str], length: int) -> str:
- key = _gen_key(length)
- while key in stash:
- key = _gen_key(length)
- return key
-
-
-def _stash_crossref(stash: dict[str, str], crossref: str, *, length: int) -> str:
- key = _gen_stash_key(stash, length)
- stash[key] = crossref
- return key
-
-
-def _format_signature(name: Markup, signature: str, line_length: int) -> str:
- name = str(name).strip() # type: ignore[assignment]
- signature = signature.strip()
- if len(name + signature) < line_length:
- return name + signature
-
- # Black cannot format names with dots, so we replace
- # the whole name with a string of equal length
- name_length = len(name)
- formatter = _get_black_formatter()
- formatable = f"def {'x' * name_length}{signature}: pass"
- formatted = formatter(formatable, line_length)
-
- # We put back the original name
- # and remove starting `def ` and trailing `: pass`
- return name + formatted[4:-5].strip()[name_length:-1]
-
-
-@pass_context
-def do_format_signature(
- context: Context,
- callable_path: Markup,
- function: Function,
- line_length: int,
- *,
- annotations: bool | None = None,
- crossrefs: bool = False,
-) -> str:
- """Format a signature using Black.
-
- Parameters:
- context: Jinja context, passed automatically.
- callable_path: The path of the callable we render the signature of.
- function: The function we render the signature of.
- line_length: The line length to give to Black.
- annotations: Whether to show type annotations.
- crossrefs: Whether to cross-reference types in the signature.
-
- Returns:
- The same code, formatted.
- """
- env = context.environment
- # TODO: Stop using `do_get_template` when `*.html` templates are removed.
- template = env.get_template(do_get_template(env, "signature"))
- config_annotations = context.parent["config"]["show_signature_annotations"]
- old_stash_ref_filter = env.filters["stash_crossref"]
-
- stash: dict[str, str] = {}
- if (annotations or config_annotations) and crossrefs:
- env.filters["stash_crossref"] = partial(_stash_crossref, stash)
-
- if annotations is None:
- new_context = context.parent
- else:
- new_context = dict(context.parent)
- new_context["config"] = dict(new_context["config"])
- new_context["config"]["show_signature_annotations"] = annotations
- try:
- signature = template.render(new_context, function=function, signature=True)
- finally:
- env.filters["stash_crossref"] = old_stash_ref_filter
-
- signature = _format_signature(callable_path, signature, line_length)
- signature = str(
- env.filters["highlight"](
- Markup.escape(signature),
- language="python",
- inline=False,
- classes=["doc-signature"],
- ),
- )
-
- # Since we highlight the signature without `def`,
- # Pygments sees it as a function call and not a function definition.
- # The result is that the function name is not parsed as such,
- # but instead as a regular name: `n` CSS class instead of `nf`.
- # To fix it, we replace the first occurrence of an `n` CSS class
- # with an `nf` one, unless we found `nf` already.
- if signature.find('class="nf"') == -1:
- signature = signature.replace('class="n"', 'class="nf"', 1)
-
- if stash:
- for key, value in stash.items():
- signature = re.sub(rf"\b{key}\b", value, signature)
-
- return signature
-
-
-@pass_context
-def do_format_attribute(
- context: Context,
- attribute_path: Markup,
- attribute: Attribute,
- line_length: int,
- *,
- crossrefs: bool = False,
-) -> str:
- """Format an attribute using Black.
-
- Parameters:
- context: Jinja context, passed automatically.
- attribute_path: The path of the callable we render the signature of.
- attribute: The attribute we render the signature of.
- line_length: The line length to give to Black.
- crossrefs: Whether to cross-reference types in the signature.
-
- Returns:
- The same code, formatted.
- """
- env = context.environment
- # TODO: Stop using `do_get_template` when `*.html` templates are removed.
- template = env.get_template(do_get_template(env, "expression"))
- annotations = context.parent["config"]["show_signature_annotations"]
- separate_signature = context.parent["config"]["separate_signature"]
- old_stash_ref_filter = env.filters["stash_crossref"]
-
- stash: dict[str, str] = {}
- if separate_signature and crossrefs:
- env.filters["stash_crossref"] = partial(_stash_crossref, stash)
-
- try:
- signature = str(attribute_path).strip()
- if annotations and attribute.annotation:
- annotation = template.render(context.parent, expression=attribute.annotation, signature=True)
- signature += f": {annotation}"
- if attribute.value:
- value = template.render(context.parent, expression=attribute.value, signature=True)
- signature += f" = {value}"
- finally:
- env.filters["stash_crossref"] = old_stash_ref_filter
-
- signature = do_format_code(signature, line_length)
- signature = str(
- env.filters["highlight"](
- Markup.escape(signature),
- language="python",
- inline=False,
- classes=["doc-signature"],
- ),
- )
-
- if stash:
- for key, value in stash.items():
- signature = re.sub(rf"\b{key}\b", value, signature)
-
- return signature
-
-
-def do_order_members(
- members: Sequence[Object | Alias],
- order: Order,
- members_list: bool | list[str] | None,
-) -> Sequence[Object | Alias]:
- """Order members given an ordering method.
-
- Parameters:
- members: The members to order.
- order: The ordering method.
- members_list: An optional member list (manual ordering).
-
- Returns:
- The same members, ordered.
- """
- if isinstance(members_list, list) and members_list:
- sorted_members = []
- members_dict = {member.name: member for member in members}
- for name in members_list:
- if name in members_dict:
- sorted_members.append(members_dict[name])
- return sorted_members
- return sorted(members, key=order_map[order])
-
-
-@lru_cache
-def _warn_crossref() -> None:
- warnings.warn(
- "The `crossref` filter is deprecated and will be removed in a future version",
- DeprecationWarning,
- stacklevel=1,
- )
-
-
-def do_crossref(path: str, *, brief: bool = True) -> Markup:
- """Deprecated. Filter to create cross-references.
-
- Parameters:
- path: The path to link to.
- brief: Show only the last part of the path, add full path as hover.
-
- Returns:
- Markup text.
- """
- _warn_crossref()
- full_path = path
- if brief:
- path = full_path.split(".")[-1]
- return Markup("{path} ").format(
- full_path=full_path,
- path=path,
- )
-
-
-@lru_cache
-def _warn_multi_crossref() -> None:
- warnings.warn(
- "The `multi_crossref` filter is deprecated and will be removed in a future version",
- DeprecationWarning,
- stacklevel=1,
- )
-
-
-def do_multi_crossref(text: str, *, code: bool = True) -> Markup:
- """Deprecated. Filter to create cross-references.
-
- Parameters:
- text: The text to scan.
- code: Whether to wrap the result in a code tag.
-
- Returns:
- Markup text.
- """
- _warn_multi_crossref()
- group_number = 0
- variables = {}
-
- def repl(match: Match) -> str:
- nonlocal group_number
- group_number += 1
- path = match.group()
- path_var = f"path{group_number}"
- variables[path_var] = path
- return f"{{{path_var}}} "
-
- text = re.sub(r"([\w.]+)", repl, text)
- if code:
- text = f"{text}"
- return Markup(text).format(**variables)
-
-
-def do_split_path(path: str, full_path: str) -> list[tuple[str, str]]:
- """Split object paths for building cross-references.
-
- Parameters:
- path: The path to split.
-
- Returns:
- A list of pairs (title, full path).
- """
- if "." not in path:
- return [(path, full_path)]
- pairs = []
- full_path = ""
- for part in path.split("."):
- if full_path:
- full_path += f".{part}"
- else:
- full_path = part
- pairs.append((part, full_path))
- return pairs
-
-
-def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
- keep = None
- rules = set()
- for regex, exclude in filters:
- rules.add(exclude)
- if regex.search(name):
- keep = not exclude
- if keep is None:
- # When we only include stuff, no match = reject.
- # When we only exclude stuff, or include and exclude stuff, no match = keep.
- return rules != {False}
- return keep
-
-
-def do_filter_objects(
- objects_dictionary: dict[str, Object | Alias],
- *,
- filters: Sequence[tuple[Pattern, bool]] | None = None,
- members_list: bool | list[str] | None = None,
- inherited_members: bool | list[str] = False,
- keep_no_docstrings: bool = True,
-) -> list[Object | Alias]:
- """Filter a dictionary of objects based on their docstrings.
-
- Parameters:
- objects_dictionary: The dictionary of objects.
- filters: Filters to apply, based on members' names.
- Each element is a tuple: a pattern, and a boolean indicating whether
- to reject the object if the pattern matches.
- members_list: An optional, explicit list of members to keep.
- When given and empty, return an empty list.
- When given and not empty, ignore filters and docstrings presence/absence.
- inherited_members: Whether to keep inherited members or exclude them.
- keep_no_docstrings: Whether to keep objects with no/empty docstrings (recursive check).
-
- Returns:
- A list of objects.
- """
- inherited_members_specified = False
- if inherited_members is True:
- # Include all inherited members.
- objects = list(objects_dictionary.values())
- elif inherited_members is False:
- # Include no inherited members.
- objects = [obj for obj in objects_dictionary.values() if not obj.inherited]
- else:
- # Include specific inherited members.
- inherited_members_specified = True
- objects = [
- obj for obj in objects_dictionary.values() if not obj.inherited or obj.name in set(inherited_members)
- ]
-
- if members_list is True:
- # Return all pre-selected members.
- return objects
-
- if members_list is False or members_list == []:
- # Return selected inherited members, if any.
- return [obj for obj in objects if obj.inherited]
-
- if members_list is not None:
- # Return selected members (keeping any pre-selected inherited members).
- return [
- obj for obj in objects if obj.name in set(members_list) or (inherited_members_specified and obj.inherited)
- ]
-
- # Use filters and docstrings.
- if filters:
- objects = [
- obj for obj in objects if _keep_object(obj.name, filters) or (inherited_members_specified and obj.inherited)
- ]
- if keep_no_docstrings:
- return objects
-
- return [obj for obj in objects if obj.has_docstrings or (inherited_members_specified and obj.inherited)]
-
-
-@lru_cache(maxsize=1)
-def _get_black_formatter() -> Callable[[str, int], str]:
- try:
- from black import InvalidInput, Mode, format_str
- except ModuleNotFoundError:
- logger.info("Formatting signatures requires Black to be installed.")
- return lambda text, _: text
-
- def formatter(code: str, line_length: int) -> str:
- mode = Mode(line_length=line_length)
- try:
- return format_str(code, mode=mode)
- except InvalidInput:
- return code
-
- return formatter
-
-
-@pass_environment
-def do_get_template(env: Environment, obj: str | Object) -> str | Template:
- """Get the template name used to render an object.
-
- Parameters:
- env: The Jinja environment, passed automatically.
- obj: A Griffe object, or a template name.
-
- Returns:
- A template name.
- """
- name = obj
- if isinstance(obj, (Alias, Object)):
- extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
- if name := extra_data.get("template", ""):
- return name
- name = obj.kind.value
- try:
- template = env.get_template(f"{name}.html")
- except TemplateNotFound:
- return f"{name}.html.jinja"
- # TODO: Remove once support for Python 3.8 is dropped.
- if sys.version_info < (3, 9):
- try:
- Path(template.filename).relative_to(Path(__file__).parent) # type: ignore[arg-type]
- except ValueError:
- our_template = False
- else:
- our_template = True
- else:
- our_template = Path(template.filename).is_relative_to(Path(__file__).parent) # type: ignore[arg-type]
- if our_template:
- return f"{name}.html.jinja"
- # TODO: Switch to a warning log after some time.
- logger.info(
- f"DeprecationWarning: Overriding '{name}.html' is deprecated, override '{name}.html.jinja' instead. "
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- )
- return f"{name}.html"
-
-
-@pass_context
-def do_as_attributes_section(
- context: Context, # noqa: ARG001
- attributes: Sequence[Attribute], # noqa: ARG001
- *,
- check_public: bool = True, # noqa: ARG001
-) -> DocstringSectionAttributes:
- """Build an attributes section from a list of attributes.
-
- Parameters:
- attributes: The attributes to build the section from.
- check_public: Whether to check if the attribute is public.
-
- Returns:
- An attributes docstring section.
- """
- return DocstringSectionAttributes([])
-
-
-@pass_context
-def do_as_functions_section(
- context: Context, # noqa: ARG001
- functions: Sequence[Function], # noqa: ARG001
- *,
- check_public: bool = True, # noqa: ARG001
-) -> DocstringSectionFunctions:
- """Build a functions section from a list of functions.
-
- Parameters:
- functions: The functions to build the section from.
- check_public: Whether to check if the function is public.
-
- Returns:
- A functions docstring section.
- """
- return DocstringSectionFunctions([])
-
-
-@pass_context
-def do_as_classes_section(
- context: Context, # noqa: ARG001
- classes: Sequence[Class], # noqa: ARG001
- *,
- check_public: bool = True, # noqa: ARG001
-) -> DocstringSectionClasses:
- """Build a classes section from a list of classes.
-
- Parameters:
- classes: The classes to build the section from.
- check_public: Whether to check if the class is public.
-
- Returns:
- A classes docstring section.
- """
- return DocstringSectionClasses([])
-
-
-@pass_context
-def do_as_modules_section(
- context: Context, # noqa: ARG001
- modules: Sequence[Module], # noqa: ARG001
- *,
- check_public: bool = True, # noqa: ARG001
-) -> DocstringSectionModules:
- """Build a modules section from a list of modules.
-
- Parameters:
- modules: The modules to build the section from.
- check_public: Whether to check if the module is public.
-
- Returns:
- A modules docstring section.
- """
- return DocstringSectionModules([])
-
-
-class AutorefsHook(AutorefsHookInterface):
- """Autorefs hook.
-
- With this hook, we're able to add context to autorefs (cross-references),
- such as originating file path and line number, to improve error reporting.
- """
-
- def __init__(self, current_object: Object | Alias, config: dict[str, Any]) -> None:
- """Initialize the hook.
-
- Parameters:
- current_object: The object being rendered.
- config: The configuration dictionary.
- """
- self.current_object = current_object
- self.config = config
-
- def expand_identifier(self, identifier: str) -> str:
- """Expand an identifier.
-
- Parameters:
- identifier: The identifier to expand.
-
- Returns:
- The expanded identifier.
- """
- return identifier
-
- def get_context(self) -> AutorefsHookInterface.Context:
- """Get the context for the current object.
-
- Returns:
- The context.
- """
- role = {
- "attribute": "data" if self.current_object.parent and self.current_object.parent.is_module else "attr",
- "class": "class",
- "function": "meth" if self.current_object.parent and self.current_object.parent.is_class else "func",
- "module": "mod",
- }.get(self.current_object.kind.value.lower(), "obj")
- origin = self.current_object.path
- try:
- filepath = self.current_object.docstring.parent.filepath # type: ignore[union-attr]
- lineno = self.current_object.docstring.lineno or 0 # type: ignore[union-attr]
- except AttributeError:
- filepath = self.current_object.filepath
- lineno = 0
-
- return AutorefsHookInterface.Context(
- domain="py",
- role=role,
- origin=origin,
- filepath=str(filepath),
- lineno=lineno,
- )
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html
deleted file mode 100644
index 7effc590..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/attribute.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/attribute.html' is deprecated, extend '_base/attribute.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
index 0716b171..65054689 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
@@ -12,7 +12,7 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering " + attribute.path) }}
@@ -39,32 +39,35 @@ Context:
role="data" if attribute.parent.kind.value == "module" else "attr",
id=html_id,
class="doc doc-heading",
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + attribute.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute.name),
+ skip_inventory=config.skip_local_inventory,
) %}
{% block heading scoped %}
{#- Heading block.
-
+
This block renders the heading for the attribute.
-#}
{% if config.show_symbol_type_heading %}{% endif %}
- {% if config.separate_signature %}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
{{ attribute_name }}
{% else %}
{%+ filter highlight(language="python", inline=True) %}
- {{ attribute_name }}{% if attribute.annotation %}: {{ attribute.annotation }}{% endif %}
- {% if attribute.value %} = {{ attribute.value }}{% endif %}
+ {{ attribute_name }}{% if attribute.annotation and config.show_signature_annotations %}: {{ attribute.annotation }}{% endif %}
+ {% if config.show_attribute_values and attribute.value %} = {{ attribute.value }}{% endif %}
{% endfilter %}
{% endif %}
{% endblock heading %}
{% block labels scoped %}
{#- Labels block.
-
+
This block renders the labels for the attribute.
-#}
{% with labels = attribute.labels %}
- {% include "labels"|get_template with context %}
+ {% include "labels.html.jinja" with context %}
{% endwith %}
{% endblock labels %}
@@ -72,11 +75,11 @@ Context:
{% block signature scoped %}
{#- Signature block.
-
+
This block renders the signature for the attribute.
-#}
{% if config.separate_signature %}
- {% filter format_attribute(attribute, config.line_length, crossrefs=config.signature_crossrefs) %}
+ {% filter format_attribute(attribute, config.line_length, crossrefs=config.signature_crossrefs, show_value=config.show_attribute_values) %}
{{ attribute.name }}
{% endfilter %}
{% endif %}
@@ -88,8 +91,9 @@ Context:
{% filter heading(heading_level,
role="data" if attribute.parent.kind.value == "module" else "attr",
id=html_id,
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + attribute.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute_name),
hidden=True,
+ skip_inventory=config.skip_local_inventory,
) %}
{% endfilter %}
{% endif %}
@@ -99,20 +103,24 @@ Context:
{% block contents scoped %}
{#- Contents block.
-
+
This block renders the contents of the attribute.
It contains other blocks that users can override.
Overriding the contents block allows to rearrange the order of the blocks.
-#}
{% block docstring scoped %}
{#- Docstring block.
-
+
This block renders the docstring for the attribute.
-#}
{% with docstring_sections = attribute.docstring.parsed %}
- {% include "docstring"|get_template with context %}
+ {% include "docstring.html.jinja" with context %}
{% endwith %}
{% endblock docstring %}
+
+ {% if config.backlinks %}
+
+ {% endif %}
{% endblock contents %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja
new file mode 100644
index 00000000..930da3e8
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja
@@ -0,0 +1,66 @@
+{#- Template for backlinks.
+
+This template renders backlinks.
+
+Context:
+ backlinks (Mapping[str, Iterable[str]]): The backlinks to render.
+ config (dict): The configuration options.
+ verbose_type (Mapping[str, str]): The verbose backlink types.
+ default_crumb (BacklinkCrumb): A default, empty crumb.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+{% endblock logs %}
+
+{% macro render_crumb(crumb, last=false) %}
+
+ {% if crumb.url and crumb.title %}
+ {{ crumb.title | safe }}
+ {% elif crumb.title %}
+ {{ crumb.title | safe }}
+ {% endif %}
+
+{% endmacro %}
+
+{% macro render_tree(tree) %}
+
+ {% for node, child in tree | dictsort %}
+ -
+ {% for crumb in node %}
+ {{ render_crumb(crumb, last=loop.last and not child) }}
+ {% endfor %}
+ {% if child %}
+ {{ render_tree(child) }}
+ {% endif %}
+
+ {% endfor %}
+
+{% endmacro %}
+
+{% if config.backlinks %}
+
+ {% if config.backlinks == "tree" %}
+ {% for backlink_type, backlink_list in backlinks | dictsort %}
+ {{ verbose_type[backlink_type] }}:
+ {{ render_tree(backlink_list|backlink_tree) }}
+ {% endfor %}
+ {% elif config.backlinks == "flat" %}
+ {% for backlink_type, backlink_list in backlinks | dictsort %}
+ {{ verbose_type[backlink_type] }}:
+
+ {% for backlink in backlink_list | sort(attribute="crumbs") %}
+ -
+ {% for crumb in backlink.crumbs %}
+ {{ render_crumb(crumb, last=loop.last) }}
+ {% endfor %}
+
+ {% endfor %}
+
+ {% endfor %}
+ {% endif %}
+
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html b/src/mkdocstrings_handlers/python/templates/material/_base/children.html
deleted file mode 100644
index 15fada5a..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/children.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/children.html' is deprecated, extend '_base/children.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
index c9c23156..63f3b1a6 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
@@ -13,12 +13,15 @@ Context:
{% if obj.all_members %}
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering children of " + obj.path) }}
{% endblock logs %}
+ {% import "language.html.jinja" as lang with context %}
+ {#- Language module providing the `t` translation method. -#}
+
{% if root_members %}
@@ -45,11 +48,11 @@ Context:
) %}
{% if attributes %}
{% if config.show_category_heading %}
- {% filter heading(heading_level, id=html_id ~ "-attributes") %}Attributes{% endfilter %}
+ {% filter heading(heading_level, id=html_id ~ "-attributes", skip_inventory=config.skip_local_inventory) %}{{ lang.t("Attributes") }}{% endfilter %}
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for attribute in attributes|order_members(config.members_order, members_list) %}
- {% if members_list is not none or (not attribute.is_imported or attribute.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not attribute.is_imported or attribute.is_public) %}
{% include attribute|get_template with context %}
{% endif %}
{% endfor %}
@@ -57,6 +60,26 @@ Context:
{% endif %}
{% endwith %}
+ {% with type_aliases = obj.type_aliases|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if type_aliases %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-type_aliases") %}{{ lang.t("Type Aliases") }}{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for type_alias in type_aliases|order_members(config.members_order, members_list) %}
+ {% if config.filters == "public" or members_list is not none or (not type_alias.is_imported or type_alias.is_public) %}
+ {% include type_alias|get_template with context %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+
{% with classes = obj.classes|filter_objects(
filters=config.filters,
members_list=members_list,
@@ -65,11 +88,11 @@ Context:
) %}
{% if classes %}
{% if config.show_category_heading %}
- {% filter heading(heading_level, id=html_id ~ "-classes") %}Classes{% endfilter %}
+ {% filter heading(heading_level, id=html_id ~ "-classes", skip_inventory=config.skip_local_inventory) %}{{ lang.t("Classes") }}{% endfilter %}
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for class in classes|order_members(config.members_order, members_list) %}
- {% if members_list is not none or (not class.is_imported or class.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not class.is_imported or class.is_public) %}
{% include class|get_template with context %}
{% endif %}
{% endfor %}
@@ -85,12 +108,12 @@ Context:
) %}
{% if functions %}
{% if config.show_category_heading %}
- {% filter heading(heading_level, id=html_id ~ "-functions") %}Functions{% endfilter %}
+ {% filter heading(heading_level, id=html_id ~ "-functions", skip_inventory=config.skip_local_inventory) %}{{ lang.t("Functions") }}{% endfilter %}
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for function in functions|order_members(config.members_order, members_list) %}
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
- {% if members_list is not none or (not function.is_imported or function.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not function.is_imported or function.is_public) %}
{% include function|get_template with context %}
{% endif %}
{% endif %}
@@ -108,11 +131,11 @@ Context:
) %}
{% if modules %}
{% if config.show_category_heading %}
- {% filter heading(heading_level, id=html_id ~ "-modules") %}Modules{% endfilter %}
+ {% filter heading(heading_level, id=html_id ~ "-modules", skip_inventory=config.skip_local_inventory) %}{{ lang.t("Modules") }}{% endfilter %}
{% endif %}
{% with heading_level = heading_level + extra_level %}
- {% for module in modules|order_members(config.members_order.alphabetical, members_list) %}
- {% if members_list is not none or (not module.is_alias or module.is_public) %}
+ {% for module in modules|order_members("alphabetical", members_list) %}
+ {% if config.filters == "public" or members_list is not none or (not module.is_alias or module.is_public) %}
{% include module|get_template with context %}
{% endif %}
{% endfor %}
@@ -137,12 +160,17 @@ Context:
{% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}
- {% if members_list is not none or child.is_public %}
+ {% if config.filters == "public" or members_list is not none or (not child.is_imported or child.is_public) %}
{% if child.is_attribute %}
{% with attribute = child %}
{% include attribute|get_template with context %}
{% endwith %}
+ {% elif child.is_type_alias %}
+ {% with type_alias = child %}
+ {% include type_alias|get_template with context %}
+ {% endwith %}
+
{% elif child.is_class %}
{% with class = child %}
{% include class|get_template with context %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
index fd13661b..57f9fd5a 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
@@ -11,14 +11,17 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering " + class.path) }}
{% endblock logs %}
+{% import "language.html.jinja" as lang with context %}
+{#- Language module providing the `t` translation method. -#}
+
- {% with obj = class, html_id = class.path %}
+ {% with obj = class, html_id = class.path, all_members = class.all_members %}
{% if root %}
{% set show_full_path = config.show_root_full_path %}
@@ -38,35 +41,43 @@ Context:
role="class",
id=html_id,
class="doc doc-heading",
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else class.name),
+ skip_inventory=config.skip_local_inventory,
) %}
{% block heading scoped %}
{#- Heading block.
-
+
This block renders the heading for the class.
-#}
{% if config.show_symbol_type_heading %}{% endif %}
- {% if config.separate_signature %}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
{{ class_name }}
- {% elif config.merge_init_into_class and "__init__" in class.all_members %}
- {% with function = class.all_members["__init__"] %}
+ {% elif config.merge_init_into_class and "__init__" in all_members %}
+ {% with function = all_members["__init__"] %}
{%+ filter highlight(language="python", inline=True) %}
- {{ class_name }}{% include "signature"|get_template with context %}
+ {{ class_name -}}
+ {%- with obj = function -%}
+ {%- include "type_parameters.html.jinja" with context -%}
+ {%- endwith -%}
+ {%- include "signature.html.jinja" with context -%}
{% endfilter %}
{% endwith %}
{% else %}
+ {# TODO: Maybe render type parameters here. #}
{{ class_name }}
{% endif %}
{% endblock heading %}
{% block labels scoped %}
{#- Labels block.
-
+
This block renders the labels for the class.
-#}
{% with labels = class.labels %}
- {% include "labels"|get_template with context %}
+ {% include "labels.html.jinja" with context %}
{% endwith %}
{% endblock labels %}
@@ -74,17 +85,34 @@ Context:
{% block signature scoped %}
{#- Signature block.
-
+
This block renders the signature for the class.
+ Overloads of the `__init__` method are rendered if `merge_init_into_class` is enabled.
+ The actual `__init__` method signature is only rendered if `separate_signature` is also enabled.
+
+ If the class is generic, but the `__init__` method isn't or `merge_init_into_class` is disabled,
+ the class signature is rendered if `separate_signature` and `show_signature_type_parameters` are enabled.
+
+ If the `__init__` method or any overloads are generic, they are rendered as methods if
+ `merge_init_into_class`, `separate_signature` and `show_signature_type_parameters` are enabled.
-#}
- {% if config.separate_signature and config.merge_init_into_class %}
- {% if "__init__" in class.all_members %}
- {% with function = class.all_members["__init__"] %}
+ {% if config.merge_init_into_class and "__init__" in all_members %}
+ {% with function = all_members["__init__"] %}
+ {% if function.overloads and config.show_overloads %}
+
+ {% for overload in function.overloads %}
+ {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %}
+ {{ class.name }}
+ {% endfilter %}
+ {% endfor %}
+
+ {% endif %}
+ {% if config.separate_signature and not (config.show_overloads and function.overloads and config.overloads_only) %}
{% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %}
{{ class.name }}
{% endfilter %}
- {% endwith %}
- {% endif %}
+ {% endif %}
+ {% endwith %}
{% endif %}
{% endblock signature %}
@@ -93,8 +121,9 @@ Context:
{% filter heading(heading_level,
role="class",
id=html_id,
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else class.name),
hidden=True,
+ skip_inventory=config.skip_local_inventory,
) %}
{% endfilter %}
{% endif %}
@@ -104,55 +133,123 @@ Context:
{% block contents scoped %}
{#- Contents block.
-
+
This block renders the contents of the class.
It contains other blocks that users can override.
Overriding the contents block allows to rearrange the order of the blocks.
-#}
{% block bases scoped %}
{#- Class bases block.
-
+
This block renders the bases for the class.
-#}
{% if config.show_bases and class.bases %}
Bases: {% for expression in class.bases -%}
- {% include "expression"|get_template with context %}{% if not loop.last %}, {% endif %}
+
+ {%- with backlink_type = "subclassed-by" -%}
+ {%- include "expression.html.jinja" with context -%}
+ {%- endwith -%}
+ {% if not loop.last %}, {% endif %}
{% endfor -%}
{% endif %}
{% endblock bases %}
+ {% block inheritance_diagram scoped %}
+ {#- Inheritance diagram block.
+
+ This block renders the inheritance diagram for the class,
+ using Mermaid syntax and a bit of JavaScript to make the nodes clickable,
+ linking to the corresponding class documentation.
+ -#}
+ {% if config.show_inheritance_diagram and class.bases %}
+ {% macro edges(class) %}
+ {% for base in class.resolved_bases %}
+ {{ base.path }} --> {{ class.path }}
+ {{ edges(base) }}
+ {% endfor %}
+ {% endmacro %}
+
+
+ flowchart {{ config.inheritance_diagram_direction }}
+ {{ class.path }}[{{ class.name }}]
+ {% for base in class.mro() %}
+ {{ base.path }}[{{ base.name }}]
+ {% endfor %}
+
+ {{ edges(class) | safe }}
+
+ click {{ class.path }} href "" "{{ class.path }}"
+ {% for base in class.mro() %}
+ click {{ base.path }} href "" "{{ base.path }}"
+ {% endfor %}
+
+
+ {% endif %}
+ {% endblock inheritance_diagram %}
+
{% block docstring scoped %}
{#- Docstring block.
-
+
This block renders the docstring for the class.
-#}
{% with docstring_sections = class.docstring.parsed %}
- {% include "docstring"|get_template with context %}
+ {% include "docstring.html.jinja" with context %}
{% endwith %}
{% if config.merge_init_into_class %}
- {% if "__init__" in class.all_members and class.all_members["__init__"].has_docstring %}
- {% with function = class.all_members["__init__"] %}
- {% with obj = function, docstring_sections = function.docstring.parsed %}
- {% include "docstring"|get_template with context %}
+ {# We don't want to merge the inherited `__init__` method docstring into the class docstring #}
+ {# if such inherited method was not selected through `inherited_members`. #}
+ {% with check_members = all_members if (config.inherited_members is true or (config.inherited_members is iterable and "__init__" in config.inherited_members)) else class.members %}
+ {% if "__init__" in check_members and check_members["__init__"].has_docstring %}
+ {% with function = check_members["__init__"] %}
+ {% with obj = function, docstring_sections = function.docstring.parsed %}
+ {% include "docstring.html.jinja" with context %}
+ {% endwith %}
{% endwith %}
- {% endwith %}
- {% endif %}
+ {% endif %}
+ {% endwith %}
{% endif %}
{% endblock docstring %}
+ {% if config.backlinks %}
+
+ {% endif %}
+
+ {% block summary scoped %}
+ {#- Summary block.
+
+ This block renders auto-summaries for classes, methods, and attributes.
+ -#}
+ {% include "summary.html.jinja" with context %}
+ {% endblock summary %}
+
{% block source scoped %}
{#- Source block.
-
+
This block renders the source code for the class.
-#}
{% if config.show_source %}
{% if config.merge_init_into_class %}
- {% if "__init__" in class.all_members and class.all_members["__init__"].source %}
- {% with init = class.all_members["__init__"] %}
-
- Source code in
+ {% if "__init__" in all_members and all_members["__init__"].source %}
+ {% with init = all_members["__init__"] %}
+
+ {{ lang.t("Source code in") }}
{%- if init.relative_filepath.is_absolute() -%}
{{ init.relative_package_filepath }}
{%- else -%}
@@ -164,8 +261,8 @@ Context:
{% endwith %}
{% endif %}
{% elif class.source %}
-
- Source code in
+
+ {{ lang.t("Source code in") }}
{%- if class.relative_filepath.is_absolute() -%}
{{ class.relative_package_filepath }}
{%- else -%}
@@ -180,12 +277,12 @@ Context:
{% block children scoped %}
{#- Children block.
-
+
This block renders the children (members) of the class.
-#}
{% set root = False %}
{% set heading_level = heading_level + 1 %}
- {% include "children"|get_template with context %}
+ {% include "children.html.jinja" with context %}
{% endblock children %}
{% endblock contents %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html
deleted file mode 100644
index 5ef9da3e..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring.html' is deprecated, extend '_base/docstring.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
index 14d11d03..a00a0249 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
@@ -14,7 +14,7 @@ Context:
{% if docstring_sections %}
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering docstring") }}
@@ -24,31 +24,35 @@ Context:
{% if config.show_docstring_description and section.kind.value == "text" %}
{{ section.value|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
{% elif config.show_docstring_attributes and section.kind.value == "attributes" %}
- {% include "docstring/attributes"|get_template with context %}
+ {% include "docstring/attributes.html.jinja" with context %}
{% elif config.show_docstring_functions and section.kind.value == "functions" %}
- {% include "docstring/functions"|get_template with context %}
+ {% include "docstring/functions.html.jinja" with context %}
{% elif config.show_docstring_classes and section.kind.value == "classes" %}
- {% include "docstring/classes"|get_template with context %}
+ {% include "docstring/classes.html.jinja" with context %}
+ {% elif config.show_docstring_type_aliases and section.kind.value == "type aliases" %}
+ {% include "docstring/type_aliases.html.jinja" with context %}
{% elif config.show_docstring_modules and section.kind.value == "modules" %}
- {% include "docstring/modules"|get_template with context %}
+ {% include "docstring/modules.html.jinja" with context %}
+ {% elif config.show_docstring_type_parameters and section.kind.value == "type parameters" %}
+ {% include "docstring/type_parameters.html.jinja" with context %}
{% elif config.show_docstring_parameters and section.kind.value == "parameters" %}
- {% include "docstring/parameters"|get_template with context %}
+ {% include "docstring/parameters.html.jinja" with context %}
{% elif config.show_docstring_other_parameters and section.kind.value == "other parameters" %}
- {% include "docstring/other_parameters"|get_template with context %}
+ {% include "docstring/other_parameters.html.jinja" with context %}
{% elif config.show_docstring_raises and section.kind.value == "raises" %}
- {% include "docstring/raises"|get_template with context %}
+ {% include "docstring/raises.html.jinja" with context %}
{% elif config.show_docstring_warns and section.kind.value == "warns" %}
- {% include "docstring/warns"|get_template with context %}
+ {% include "docstring/warns.html.jinja" with context %}
{% elif config.show_docstring_yields and section.kind.value == "yields" %}
- {% include "docstring/yields"|get_template with context %}
+ {% include "docstring/yields.html.jinja" with context %}
{% elif config.show_docstring_receives and section.kind.value == "receives" %}
- {% include "docstring/receives"|get_template with context %}
+ {% include "docstring/receives.html.jinja" with context %}
{% elif config.show_docstring_returns and section.kind.value == "returns" %}
- {% include "docstring/returns"|get_template with context %}
+ {% include "docstring/returns.html.jinja" with context %}
{% elif config.show_docstring_examples and section.kind.value == "examples" %}
- {% include "docstring/examples"|get_template with context %}
+ {% include "docstring/examples.html.jinja" with context %}
{% elif config.show_docstring_description and section.kind.value == "admonition" %}
- {% include "docstring/admonition"|get_template with context %}
+ {% include "docstring/admonition.html.jinja" with context %}
{% endif %}
{% endfor %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
deleted file mode 100644
index a8a75542..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/admonition.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/admonition.html' is deprecated, extend '_base/docstring/admonition.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html.jinja
index ff6e9cbc..7f949130 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html.jinja
@@ -8,7 +8,7 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering admonition") }}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html
deleted file mode 100644
index cd4b05be..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/attributes.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
index 0bb416e0..894639a7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering attributes section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -37,7 +37,7 @@ Context:
{% if attribute.annotation %}
{% with expression = attribute.annotation %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -61,7 +61,7 @@ Context:
{{ attribute.name }}
{% if attribute.annotation %}
{% with expression = attribute.annotation %}
- ({% include "expression"|get_template with context %})
+ ({% include "expression.html.jinja" with context %})
{% endwith %}
{% endif %}
–
@@ -93,9 +93,9 @@ Context:
{% if attribute.annotation %}
- TYPE:
+ {{ lang.t("TYPE:") }}
{% with expression = attribute.annotation %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html
deleted file mode 100644
index 78b47e2d..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/classes.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/classes.html' is deprecated, extend '_base/docstring/classes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
index 82bae98c..b139a761 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering classes section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html
deleted file mode 100644
index 37674811..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/examples.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/examples.html' is deprecated, extend '_base/docstring/examples.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
index dd0b503f..32360f7d 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering examples section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{{ section.title or lang.t("Examples:") }}
@@ -23,6 +23,6 @@ Context:
{% if section_type.value == "text" %}
{{ sub_section|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
{% elif section_type.value == "examples" %}
- {{ sub_section|highlight(language="pycon", linenums=False) }}
+ {{ sub_section|highlight(language="pycon") }}
{% endif %}
{% endfor %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html
deleted file mode 100644
index a61c48fb..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/functions.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/functions.html' is deprecated, extend '_base/docstring/functions.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
index f979f4e5..afec8f60 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering functions section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html
deleted file mode 100644
index d0b303b4..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/modules.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/modules.html' is deprecated, extend '_base/docstring/modules.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
index b18e69f0..5556cf15 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering modules section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html
deleted file mode 100644
index eae60aa7..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/other_parameters.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
index 24c6b194..5e0a75f5 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering other parameters section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -36,8 +36,8 @@ Context:
{{ parameter.name }}
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -60,8 +60,8 @@ Context:
{{ parameter.name }}
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- ({% include "expression"|get_template with context %})
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ ({% include "expression.html.jinja" with context %})
{% endwith %}
{% endif %}
–
@@ -94,8 +94,8 @@ Context:
{% if parameter.annotation %}
{{ lang.t("TYPE:") }}
- {% with expression = parameter.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html
deleted file mode 100644
index f5745464..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/parameters.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
index 8b0556f3..a67113fa 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering parameters section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -34,11 +34,26 @@ Context:
{% for parameter in section.value %}
- {{ parameter.name }}
+
+ {% if config.parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="param",
+ id=html_id ~ "(" ~ parameter.name ~ ")",
+ class="doc doc-heading doc-heading-parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name,
+ skip_inventory=config.skip_local_inventory,
+ ) %}
+ {{ parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ parameter.name }}
+ {% endif %}
+
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -49,8 +64,8 @@ Context:
{% if parameter.default %}
- {% with expression = parameter.default %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.default, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% else %}
{{ lang.t("required") }}
@@ -68,13 +83,26 @@ Context:
{% for parameter in section.value %}
-
-
{{ parameter.name }}
+ {% if config.parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="param",
+ id=html_id ~ "(" ~ parameter.name ~ ")",
+ class="doc doc-heading doc-heading-parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name,
+ skip_inventory=config.skip_local_inventory,
+ ) %}
+ {{ parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ parameter.name }}
+ {% endif %}
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- ({% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ ({% include "expression.html.jinja" with context %}
{%- if parameter.default %}, {{ lang.t("default:") }}
- {% with expression = parameter.default %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.default, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %})
{% endwith %}
@@ -100,7 +128,22 @@ Context:
{% for parameter in section.value %}
- {{ parameter.name }}
+
+ {% if config.parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="param",
+ id=html_id ~ "(" ~ parameter.name ~ ")",
+ class="doc doc-heading doc-heading-parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name,
+ skip_inventory=config.skip_local_inventory,
+ ) %}
+ {{ parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ parameter.name }}
+ {% endif %}
+
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
@@ -109,16 +152,16 @@ Context:
{% if parameter.annotation %}
{{ lang.t("TYPE:") }}
- {% with expression = parameter.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
{% if parameter.default %}
{{ lang.t("DEFAULT:") }}
- {% with expression = parameter.default %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.default, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html
deleted file mode 100644
index 361b9732..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/raises.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
index f796494b..7d548035 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering raises section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -34,8 +34,8 @@ Context:
{% if raises.annotation %}
- {% with expression = raises.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = raises.annotation, backlink_type = "raised-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -57,8 +57,8 @@ Context:
{% for raises in section.value %}
-
{% if raises.annotation %}
- {% with expression = raises.annotation %}
-
{% include "expression"|get_template with context %}
+ {% with expression = raises.annotation, backlink_type = "raised-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
–
{% endif %}
@@ -84,8 +84,8 @@ Context:
- {% with expression = raises.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = raises.annotation, backlink_type = "raised-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html
deleted file mode 100644
index e5a115c1..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/receives.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
index 57df473f..6830d434 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering receives section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -37,8 +37,8 @@ Context:
{% if name_column %}{% if receives.name %}{{ receives.name }}{% endif %} {% endif %}
{% if receives.annotation %}
- {% with expression = receives.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = receives.annotation, backlink_type = "received-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -61,9 +61,9 @@ Context:
-
{% if receives.name %}
{{ receives.name }}{% endif %}
{% if receives.annotation %}
- {% with expression = receives.annotation %}
+ {% with expression = receives.annotation, backlink_type = "received-by" %}
{% if receives.name %} ({% endif %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if receives.name %}){% endif %}
{% endwith %}
{% endif %}
@@ -93,8 +93,8 @@ Context:
{{ receives.name }}
{% elif receives.annotation %}
- {% with expression = receives.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = receives.annotation, backlink_type = "received-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -107,8 +107,8 @@ Context:
{{ lang.t("TYPE:") }}
- {% with expression = receives.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = receives.annotation, backlink_type = "received-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html
deleted file mode 100644
index 0e7807ac..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/returns.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
index cab2ca77..da693da7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering returns section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -37,8 +37,8 @@ Context:
{% if name_column %}{% if returns.name %}{{ returns.name }}{% endif %} {% endif %}
{% if returns.annotation %}
- {% with expression = returns.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = returns.annotation, backlink_type = "returned-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -61,9 +61,9 @@ Context:
-
{% if returns.name %}
{{ returns.name }}{% endif %}
{% if returns.annotation %}
- {% with expression = returns.annotation %}
+ {% with expression = returns.annotation, backlink_type = "returned-by" %}
{% if returns.name %} ({% endif %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if returns.name %}){% endif %}
{% endwith %}
{% endif %}
@@ -93,8 +93,8 @@ Context:
{{ returns.name }}
{% elif returns.annotation %}
- {% with expression = returns.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = returns.annotation, backlink_type = "returned-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -107,8 +107,8 @@ Context:
{{ lang.t("TYPE:") }}
- {% with expression = returns.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = returns.annotation, backlink_type = "returned-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja
new file mode 100644
index 00000000..e1c87754
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja
@@ -0,0 +1,86 @@
+{#- Template for "Type Aliases" sections in docstrings.
+
+This template renders a list of documented type aliases in the format
+specified with the [`docstring_section_style`][] configuration option.
+
+Context:
+ section (griffe.DocstringSectionTypeAliases): The section to render.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type aliases section") }}
+{% endblock logs %}
+
+{% import "language.html.jinja" as lang with context %}
+{#- Language module providing the `t` translation method. -#}
+
+{% if config.docstring_section_style == "table" %}
+ {% block table_style scoped %}
+ {#- Block for the `table` section style. -#}
+ {{ section.title or lang.t("Type Aliases:") }}
+
+
+
+ {{ lang.t("Name") }}
+ {{ lang.t("Description") }}
+
+
+
+ {% for type_alias in section.value %}
+
+ {{ type_alias.name }}
+
+
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+
+ {% endfor %}
+
+
+ {% endblock table_style %}
+{% elif config.docstring_section_style == "list" %}
+ {% block list_style scoped %}
+ {#- Block for the `list` section style. -#}
+ {{ section.title or lang.t("Type Aliases:") }}
+
+ {% for type_alias in section.value %}
+ -
+
{{ type_alias.name }}
+ –
+
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+ {% endfor %}
+
+ {% endblock list_style %}
+{% elif config.docstring_section_style == "spacy" %}
+ {% block spacy_style scoped %}
+ {#- Block for the `spacy` section style. -#}
+
+
+
+ {{ (section.title or lang.t("TYPE ALIAS")).rstrip(":").upper() }}
+ {{ lang.t("DESCRIPTION") }}
+
+
+
+ {% for type_alias in section.value %}
+
+ {{ type_alias.name }}
+
+
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+
+ {% endfor %}
+
+
+ {% endblock spacy_style %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja
new file mode 100644
index 00000000..6fe8bb4e
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja
@@ -0,0 +1,208 @@
+{#- Template for "Parameters" sections in docstrings.
+
+This template renders a list of documented type parameters in the format
+specified with the [`docstring_section_style`][] configuration option.
+
+Context:
+ section (griffe.DocstringSectionTypeParameters): The section to render.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type parameters section") }}
+{% endblock logs %}
+
+{% import "language.html.jinja" as lang with context %}
+{#- Language module providing the `t` translation method. -#}
+
+{% if config.docstring_section_style == "table" %}
+ {% block table_style scoped %}
+ {#- Block for the `table` section style. -#}
+
+
+ {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }}
+
+
+
+
+
+ {{ lang.t("Name") }}
+ {{ lang.t("Bound or Constraints") }}
+ {{ lang.t("Description") }}
+ {{ lang.t("Default") }}
+
+
+
+ {% for type_parameter in section.value %}
+
+
+ {% if config.type_parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="typeparam",
+ id=obj.path ~ "[" ~ type_parameter.name ~ "]",
+ class="doc doc-heading doc-heading-type_parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name,
+ ) %}
+ {{ type_parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ type_parameter.name }}
+ {% endif %}
+
+
+ {% if type_parameter.annotation %}
+ {% with expression = type_parameter.annotation %}
+ {% include "expression.html.jinja" with context %}
+ {% endwith %}
+ {% endif %}
+
+
+
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+
+ {% if type_parameter.default %}
+ {% with expression = type_parameter.default %}
+ {% include "expression.html.jinja" with context %}
+ {% endwith %}
+ {% else %}
+ {{ lang.t("required") }}
+ {% endif %}
+
+
+ {% endfor %}
+
+
+ {% endblock table_style %}
+{% elif config.docstring_section_style == "list" %}
+ {% block list_style scoped %}
+ {#- Block for the `list` section style. -#}
+
+
+ {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }}
+
+
+
+ {% for type_parameter in section.value %}
+ -
+ {% if config.type_parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="typeparam",
+ id=obj.path ~ "[" ~ type_parameter.name ~ "]",
+ class="doc doc-heading doc-heading-type_parameter",
+ toc_label=('
'|safe if config.show_symbol_type_toc else '') + type_parameter.name,
+ ) %}
+ {{ type_parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ type_parameter.name }}
+ {% endif %}
+ {%- if type_parameter.bound or type_parameter.constraints or type_parameter.default -%}
+ (
+ {%- endif -%}
+ {%- if type_parameter.bound -%}
+ {%- with expression = type_parameter.bound -%}
+ {% include "expression.html.jinja" with context %}
+ {%- endwith -%}
+ {%- if type_parameter.default %}, {% endif -%}
+ {%- elif type_parameter.constraints -%}
+ {%- for expression in type_parameter.constraints -%}
+ {% include "expression.html.jinja" with context %}
+ {%- if not loop.last %}, {% endif -%}
+ {%- endfor -%}
+ {%- if type_parameter.default %}, {% endif -%}
+ {%- endif -%}
+ {%- if type_parameter.default -%}
+ {{ lang.t("default:") }}
+ {% with expression = type_parameter.default %}
+ {% include "expression.html.jinja" with context %}
+ {%- endwith -%}
+ {%- endif -%}
+ {%- if type_parameter.constraints or type_parameter.default -%}
+ )
+ {% endif -%}
+ –
+
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+ {% endfor %}
+
+ {% endblock list_style %}
+{% elif config.docstring_section_style == "spacy" %}
+ {% block spacy_style scoped %}
+ {#- Block for the `spacy` section style. -#}
+
+
+
+
+
+ {{ (section.title or lang.t(("CLASS " if obj.is_class else "INIT " if obj.is_init_method else "") ~ "TYPE PARAMETER")).rstrip(":").upper() }}
+
+
+ {{ lang.t("DESCRIPTION") }}
+
+
+
+ {% for type_parameter in section.value %}
+
+
+ {% if config.type_parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="typeparam",
+ id=obj.path ~ "[" ~ type_parameter.name ~ "]",
+ class="doc doc-heading doc-heading-type_parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name,
+ ) %}
+ {{ type_parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ type_parameter.name }}
+ {% endif %}
+
+
+
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+ {% if type_parameter.constraints %}
+
+ {{ lang.t("CONSTRAINTS:") }}
+ {% for constraint in type_parameter.constraints -%}
+ {%- with expression = constraint -%}
+ {% include "expression.html.jinja" with context %}
+ {%- endwith -%}
+ {%- if not loop.last %}, {% endif -%}
+ {% endfor %}
+
+ {% elif type_parameter.bound %}
+
+ {{ lang.t("BOUND:") }}
+ {% with expression = type_parameter.bound %}
+ {% include "expression.html.jinja" with context %}
+ {% endwith %}
+
+ {% endif %}
+ {% if type_parameter.default %}
+
+ {{ lang.t("DEFAULT:") }}
+ {% with expression = type_parameter.default %}
+ {% include "expression.html.jinja" with context %}
+ {% endwith %}
+
+ {% endif %}
+
+
+
+ {% endfor %}
+
+
+ {% endblock spacy_style %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html
deleted file mode 100644
index b7b937a9..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/warns.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
index a892244a..6f7e69de 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering warns section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -34,8 +34,8 @@ Context:
{% if warns.annotation %}
- {% with expression = warns.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = warns.annotation, backlink_type = "emitted-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -57,8 +57,8 @@ Context:
{% for warns in section.value %}
-
{% if warns.annotation %}
- {% with expression = warns.annotation %}
-
{% include "expression"|get_template with context %}
+ {% with expression = warns.annotation, backlink_type = "emitted-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
–
{% endif %}
@@ -84,8 +84,8 @@ Context:
- {% with expression = warns.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = warns.annotation, backlink_type = "emitted-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html
deleted file mode 100644
index ecd6f513..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/yields.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
index 96c373dd..69e5ea6d 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering yields section") }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
{% if config.docstring_section_style == "table" %}
@@ -37,8 +37,8 @@ Context:
{% if name_column %}{% if yields.name %}{{ yields.name }}{% endif %} {% endif %}
{% if yields.annotation %}
- {% with expression = yields.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = yields.annotation, backlink_type = "yielded-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -61,9 +61,9 @@ Context:
-
{% if yields.name %}
{{ yields.name }}{% endif %}
{% if yields.annotation %}
- {% with expression = yields.annotation %}
+ {% with expression = yields.annotation, backlink_type = "yielded-by" %}
{% if yields.name %} ({% endif %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if yields.name %}){% endif %}
{% endwith %}
{% endif %}
@@ -93,8 +93,8 @@ Context:
{{ yields.name }}
{% elif yields.annotation %}
- {% with expression = yields.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = yields.annotation, backlink_type = "yielded-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
@@ -107,8 +107,8 @@ Context:
{{ lang.t("TYPE:") }}:
- {% with expression = yields.annotation %}
- {% include "expression"|get_template with context %}
+ {% with expression = yields.annotation, backlink_type = "yielded-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html
deleted file mode 100644
index 556b3e2b..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/expression.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/expression.html' is deprecated, extend '_base/expression.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
index f150afd1..4f44ae00 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
@@ -2,18 +2,41 @@
This template renders a Griffe expression,
which is a tree-like structure representing a Python expression.
+
+Context:
+ expression (griffe.Expr): The expression to render.
+ config (dict): The configuration options.
-#}
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
-{%- macro crossref(name, annotation_path) -%}
+{%- macro crossref(name, annotation_path, backlink_type="") -%}
{#- Output a cross-reference.
-
+
+ This macro outputs a cross-reference to the given name.
+
+ Parameters:
+ name (griffe.ExprName): The name to cross-reference.
+ annotation_path (str): Either "brief", "source", or "full".
+
+ Returns:
+ Either a cross-reference (using an autoref element) or the name itself.
+ -#}
+ {%- if name.classname == "ExprName" and name.is_type_parameter -%}
+ {{ type_param_crossref(name) }}
+ {%- else -%}
+ {{ object_crossref(name, annotation_path) }}
+ {%- endif -%}
+{%- endmacro -%}
+
+{%- macro object_crossref(name, annotation_path) -%}
+ {#- Output a cross-reference to a Griffe object.
+
This macro outputs a cross-reference to the given name.
Parameters:
@@ -31,20 +54,68 @@ which is a tree-like structure representing a Python expression.
{%- elif annotation_path == "full" -%}
{%- set annotation = full -%}
{%- endif -%}
- {%- for title, path in annotation|split_path(full) -%}
- {%- if not signature or config.signature_crossrefs -%}
+ {%- for prefix, title, path, suffix in annotation|split_path(full) -%}
+ {{ prefix }}
+ {%- if not signature -%}
+ {#- Always render cross-references outside of signatures. We don't need to stash them. -#}
+ {{ title }}
+ {%- elif config.signature_crossrefs -%}
+ {#- We're in a signature and cross-references are enabled, we must render one and stash it. -#}
{%- filter stash_crossref(length=title|length) -%}
- {{ title }}
+ {{ title }}
{%- endfilter -%}
{%- else -%}
+ {#- We're in a signature but cross-references are disabled, we just render the title. -#}
{{ title }}
{%- endif -%}
- {%- if not loop.last -%}.{%- endif -%}
+ {{ suffix }}
{%- endfor -%}
{%- endwith -%}
{%- endmacro -%}
-{%- macro render(expression, annotations_path) -%}
+{%- macro type_param_crossref(name) -%}
+ {#- Render a cross-reference to a type parameter heading.
+
+ Parameters:
+ name (griffe.ExprName): The name to cross-reference.
+
+ Returns:
+ The autorefs cross-reference, or the type parameter name.
+ -#}
+ {%- if not signature -%}
+ {{ name.name }}
+ {%- elif config.signature_crossrefs -%}
+ {%- filter stash_crossref(length=name.name|length) -%}
+ {{ name.name }}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ name.name }}
+ {%- endif -%}
+{%- endmacro -%}
+
+{%- macro param_crossref(expression) -%}
+ {#- Render a cross-reference to a parameter heading.
+
+ Parameters:
+ expression (griffe.expressions.Expr): The expression to render.
+
+ Returns:
+ The autorefs cross-reference, or the parameter name.
+ -#}
+ {%- if config.signature_crossrefs -%}
+ {%- if signature -%}
+ {%- filter stash_crossref(length=expression.name|length) -%}
+ {{ expression.name }}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ expression.name }}
+ {%- endif -%}
+ {%- else -%}
+ {{ expression.name }}
+ {%- endif -%}
+{%- endmacro -%}
+
+{%- macro render(expression, annotations_path, backlink_type="") -%}
{#- Render an expression.
Parameters:
@@ -57,13 +128,20 @@ which is a tree-like structure representing a Python expression.
{%- if expression is string -%}
{%- if signature -%}{{ expression|safe }}{%- else -%}{{ expression }}{%- endif -%}
{%- elif expression.classname == "ExprName" -%}
- {{ crossref(expression, annotations_path) }}
+ {{ crossref(expression, annotations_path, backlink_type) }}
{%- elif config.unwrap_annotated and expression.classname == "ExprSubscript" and expression.canonical_path in ("typing.Annotated", "typing_extensions.Annotated") -%}
{{ render(expression.slice.elements[0], annotations_path) }}
{%- elif expression.classname == "ExprAttribute" -%}
- {%- if annotations_path == "brief" -%}
+ {%- if expression.first.is_type_parameter -%}
+ {{ type_param_crossref(expression.first) }}
+ {%- for element in expression -%}
+ {%- if not loop.first -%}
+ {{ render(element, "brief") }}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- elif annotations_path == "brief" -%}
{%- if expression.last.is_enum_value -%}
- {{ crossref(expression.last.parent, "brief") }}.value
+ {{ crossref(expression.last.parent, "brief", backlink_type) }}.value
{%- else -%}
{{ render(expression.last, "brief") }}
{%- endif -%}
@@ -79,6 +157,8 @@ which is a tree-like structure representing a Python expression.
{{ render(element, annotations_path) }}
{%- endfor -%}
{%- endif -%}
+ {%- elif expression.classname == "ExprKeyword" -%}
+ {{ param_crossref(expression) }}={{ render(expression.value, annotations_path) }}
{%- else -%}
{%- for element in expression -%}
{{ render(element, annotations_path) }}
@@ -86,4 +166,7 @@ which is a tree-like structure representing a Python expression.
{%- endif -%}
{%- endmacro -%}
-{{ render(expression, config.annotations_path) }}
+{%- if config.modernize_annotations and expression is not string -%}
+ {%- set expression = expression.modernize() -%}
+{%- endif -%}
+{{ render(expression, config.annotations_path, backlink_type|default("")) }}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html b/src/mkdocstrings_handlers/python/templates/material/_base/function.html
deleted file mode 100644
index 07be5abb..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/function.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/function.html' is deprecated, extend '_base/function.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
index 3631b699..3cfc7f30 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
@@ -11,13 +11,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering " + function.path) }}
{% endblock logs %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -44,31 +44,36 @@ Context:
role="function",
id=html_id,
class="doc doc-heading",
- toc_label=((' ')|safe if config.show_symbol_type_toc else '') + function.name,
+ toc_label=((' ')|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else function.name),
+ skip_inventory=config.skip_local_inventory,
) %}
{% block heading scoped %}
{#- Heading block.
-
+
This block renders the heading for the function.
-#}
{% if config.show_symbol_type_heading %}{% endif %}
- {% if config.separate_signature %}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
{{ function_name }}
{% else %}
- {%+ filter highlight(language="python", inline=True) %}
- {{ function_name }}{% include "signature"|get_template with context %}
- {% endfilter %}
+ {%+ filter highlight(language="python", inline=True) -%}
+ {{ function_name }}
+ {%- include "type_parameters.html.jinja" with context -%}
+ {%- include "signature.html.jinja" with context -%}
+ {%- endfilter %}
{% endif %}
{% endblock heading %}
{% block labels scoped %}
{#- Labels block.
-
+
This block renders the labels for the function.
-#}
{% with labels = function.labels %}
- {% include "labels"|get_template with context %}
+ {% include "labels.html.jinja" with context %}
{% endwith %}
{% endblock labels %}
@@ -76,10 +81,20 @@ Context:
{% block signature scoped %}
{#- Signature block.
-
- This block renders the signature for the function.
+
+ This block renders the signature for the function,
+ as well as its overloaded signatures if any.
-#}
- {% if config.separate_signature %}
+ {% if function.overloads and config.show_overloads %}
+
+ {% for overload in function.overloads %}
+ {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %}
+ {{ overload.name }}
+ {% endfilter %}
+ {% endfor %}
+
+ {% endif %}
+ {% if config.separate_signature and not (config.show_overloads and function.overloads and config.overloads_only) %}
{% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %}
{{ function.name }}
{% endfilter %}
@@ -93,8 +108,9 @@ Context:
heading_level,
role="function",
id=html_id,
- toc_label=((' ')|safe if config.show_symbol_type_toc else '') + function.name,
+ toc_label=((' ')|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else function.name),
hidden=True,
+ skip_inventory=config.skip_local_inventory,
) %}
{% endfilter %}
{% endif %}
@@ -104,28 +120,32 @@ Context:
{% block contents scoped %}
{#- Contents block.
-
+
This block renders the contents of the function.
It contains other blocks that users can override.
Overriding the contents block allows to rearrange the order of the blocks.
-#}
{% block docstring scoped %}
{#- Docstring block.
-
+
This block renders the docstring for the function.
-#}
{% with docstring_sections = function.docstring.parsed %}
- {% include "docstring"|get_template with context %}
+ {% include "docstring.html.jinja" with context %}
{% endwith %}
{% endblock docstring %}
+ {% if config.backlinks %}
+
+ {% endif %}
+
{% block source scoped %}
{#- Source block.
-
+
This block renders the source code for the function.
-#}
{% if config.show_source and function.source %}
-
+
{{ lang.t("Source code in") }}
{%- if function.relative_filepath.is_absolute() -%}
{{ function.relative_package_filepath }}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html b/src/mkdocstrings_handlers/python/templates/material/_base/labels.html
deleted file mode 100644
index 784150c4..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/labels.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/labels.html' is deprecated, extend '_base/labels.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/labels.html.jinja
index dced4913..bbd3a7c1 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/labels.html.jinja
@@ -12,7 +12,7 @@ Context:
{% if config.show_labels and labels %}
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering labels") }}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/language.html b/src/mkdocstrings_handlers/python/templates/material/_base/language.html
deleted file mode 100644
index c97d0c31..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/language.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/language.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
index 5b643726..31ecfdd6 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
@@ -2,17 +2,17 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
-{% set lang_pth = "languages/" ~ locale | get_template %}
+{% set lang_pth = "languages/" ~ locale ~ ".html.jinja" %}
{% if lang_pth is existing_template %}
- {% import lang_pth as lang %}
- {% import "languages/en"|get_template as fallback %}
- {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
+ {% import lang_pth as lang %}
+ {% import "languages/en.html.jinja" as fallback %}
+ {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
{% else %}
- {% import "languages/en"|get_template as lang %}
- {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
+ {% import "languages/en.html.jinja" as lang %}
+ {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html
deleted file mode 100644
index eab87415..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/en.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
index d988b6ab..d2bbba03 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
@@ -2,26 +2,37 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
{% macro t(key) %}{{ {
"ATTRIBUTE": "ATTRIBUTE",
+ "Attributes": "Attributes",
"Attributes:": "Attributes:",
+ "BOUND:": "BOUND:",
+ "Bound or Constraints": "Bound or Constraints",
+ "Classes": "Classes",
"Classes:": "Classes:",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
"CLASS": "CLASS",
+ "CONSTRAINTS:": "CONSTRAINTS:",
"DEFAULT:": "DEFAULT:",
"Default": "Default",
"default:": "default:",
"DESCRIPTION": "DESCRIPTION",
"Description": "Description",
"Examples:": "Examples:",
+ "Functions": "Functions",
"Functions:": "Functions:",
"FUNCTION": "FUNCTION",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
"Methods:": "Methods:",
"METHOD": "METHOD",
+ "Modules": "Modules",
"Modules:": "Modules:",
"MODULE": "MODULE",
"Name": "Name",
@@ -38,6 +49,11 @@
"Source code in": "Source code in",
"TYPE:": "TYPE:",
"Type": "Type",
+ "Type Aliases": "Type Aliases",
+ "Type Aliases:": "Type Aliases:",
+ "TYPE ALIAS": "TYPE ALIAS",
+ "Type Parameters:": "Type Parameters:",
+ "TYPE PARAMETER": "TYPE PARAMETER",
"WARNS": "WARNS",
"Warns:": "Warns:",
"YIELDS": "YIELDS",
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html
deleted file mode 100644
index 14319499..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/ja.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
index a6b7728b..840da89c 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
@@ -2,28 +2,39 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
+ "Attributes": "属性",
"Attributes:": "属性:",
- "Classes:": "",
- "CLASS": "",
+ "BOUND:": "境界:",
+ "Bound or Constraints": "境界や制約",
+ "Classes": "クラス",
+ "Classes:": "クラス:",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
+ "CLASS": "クラス",
+ "CONSTRAINTS:": "制約:",
"DEFAULT:": "デフォルト:",
"Default": "デフォルト",
"default:": "デフォルト:",
"DESCRIPTION": "デスクリプション",
"Description": "デスクリプション",
"Examples:": "例:",
- "Functions:": "",
- "FUNCTION": "",
- "Methods:": "",
- "METHOD": "",
- "Modules:": "",
- "MODULE": "",
+ "Functions": "関数",
+ "Functions:": "関数:",
+ "FUNCTION": "関数",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
+ "Methods:": "メソッド:",
+ "METHOD": "メソッド",
+ "Modules": "モジュール",
+ "Modules:": "モジュール:",
+ "MODULE": "モジュール",
"Name": "名前",
"Other Parameters:": "他の引数:",
"PARAMETER": "引数",
@@ -38,6 +49,11 @@
"Source code in": "ソースコード位置:",
"TYPE:": "タイプ:",
"Type": "タイプ",
+ "Type Aliases": "型エイリアス",
+ "Type Aliases:": "型エイリアス:",
+ "TYPE ALIAS": "型エイリアス",
+ "Type Parameters:": "型パラメータ:",
+ "TYPE PARAMETER": "型パラメータ",
"WARNS": "警告",
"Warns:": "警告:",
"YIELDS": "返す",
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html
deleted file mode 100644
index 0b281195..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/zh.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
index f748b83c..53888779 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
@@ -2,28 +2,39 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
+ "Attributes": "属性",
"Attributes:": "属性:",
- "Classes:": "",
- "CLASS": "",
+ "BOUND:": "边界:",
+ "Bound or Constraints": "边界或约束",
+ "Classes": "类",
+ "Classes:": "类:",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
+ "CLASS": "类",
+ "CONSTRAINTS:": "约束:",
"DEFAULT:": "默认:",
"Default": "默认",
"default:": "默认:",
"DESCRIPTION": "描述",
"Description": "描述",
"Examples:": "示例:",
- "Functions:": "",
- "FUNCTION": "",
- "Methods:": "",
- "METHOD": "",
- "Modules:": "",
- "MODULE": "",
+ "Functions": "函数",
+ "Functions:": "函数:",
+ "FUNCTION": "函数",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
+ "Methods:": "方法:",
+ "METHOD": "方法",
+ "Modules": "模块",
+ "Modules:": "模块:",
+ "MODULE": "模块",
"Name": "名称",
"Other Parameters:": "其他参数:",
"PARAMETER": "参数",
@@ -38,6 +49,11 @@
"Source code in": "源代码位于:",
"TYPE:": "类型:",
"Type": "类型",
+ "Type Aliases": "类型别名",
+ "Type Aliases:": "类型别名:",
+ "TYPE ALIAS": "类型别名",
+ "Type Parameters:": "类型形参:",
+ "TYPE PARAMETER": "类型形参",
"Warns:": "警告:",
"WARNS": "警告",
"YIELDS": "产生",
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html b/src/mkdocstrings_handlers/python/templates/material/_base/module.html
deleted file mode 100644
index 918ab6d0..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/module.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/module.html' is deprecated, extend '_base/module.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
index ae7d88d9..c0f4a7cb 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
@@ -11,7 +11,7 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering " + module.path) }}
@@ -38,16 +38,19 @@ Context:
role="module",
id=html_id,
class="doc doc-heading",
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + module.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else module.name),
+ skip_inventory=config.skip_local_inventory,
) %}
{% block heading scoped %}
{#- Heading block.
-
+
This block renders the heading for the module.
-#}
{% if config.show_symbol_type_heading %}{% endif %}
- {% if config.separate_signature %}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
{{ module_name }}
{% else %}
{{ module_name }}
@@ -56,11 +59,11 @@ Context:
{% block labels scoped %}
{#- Labels block.
-
+
This block renders the labels for the module.
-#}
{% with labels = module.labels %}
- {% include "labels"|get_template with context %}
+ {% include "labels.html.jinja" with context %}
{% endwith %}
{% endblock labels %}
@@ -71,8 +74,9 @@ Context:
{% filter heading(heading_level,
role="module",
id=html_id,
- toc_label=(' '|safe if config.show_symbol_type_toc else '') + module.name,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else module.name),
hidden=True,
+ skip_inventory=config.skip_local_inventory,
) %}
{% endfilter %}
{% endif %}
@@ -82,29 +86,41 @@ Context:
{% block contents scoped %}
{#- Contents block.
-
+
This block renders the contents of the module.
It contains other blocks that users can override.
Overriding the contents block allows to rearrange the order of the blocks.
-#}
{% block docstring scoped %}
{#- Docstring block.
-
+
This block renders the docstring for the module.
-#}
{% with docstring_sections = module.docstring.parsed %}
- {% include "docstring"|get_template with context %}
+ {% include "docstring.html.jinja" with context %}
{% endwith %}
{% endblock docstring %}
+ {% if config.backlinks %}
+
+ {% endif %}
+
+ {% block summary scoped %}
+ {#- Summary block.
+
+ This block renders auto-summaries for classes, methods, and attributes.
+ -#}
+ {% include "summary.html.jinja" with context %}
+ {% endblock summary %}
+
{% block children scoped %}
{#- Children block.
-
+
This block renders the children (members) of the module.
-#}
{% set root = False %}
{% set heading_level = heading_level + 1 %}
- {% include "children"|get_template with context %}
+ {% include "children.html.jinja" with context %}
{% endblock children %}
{% endblock contents %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html
deleted file mode 100644
index 623879db..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/signature.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/signature.html' is deprecated, extend '_base/signature.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
index 1107458c..7167f1d7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
@@ -12,7 +12,7 @@ Context:
{%- if config.show_signature -%}
{%- block logs scoped -%}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug("Rendering signature") }}
@@ -25,6 +25,7 @@ Context:
render_kw_only_separator=True,
annotation="",
equal="=",
+ default=False,
) -%}
(
@@ -46,9 +47,11 @@ Context:
{#- Prepare type annotation. -#}
{%- if config.show_signature_annotations and parameter.annotation is not none -%}
{%- set ns.equal = " = " -%}
- {%- if config.separate_signature and config.signature_crossrefs -%}
+ {%- if config.separate_signature -%}
{%- with expression = parameter.annotation -%}
- {%- set ns.annotation -%}: {% include "expression"|get_template with context %}{%- endset -%}
+ {%- set ns.annotation -%}: {% with backlink_type = "used-by" -%}
+ {%- include "expression.html.jinja" with context -%}
+ {%- endwith -%}{%- endset -%}
{%- endwith -%}
{%- else -%}
{%- set ns.annotation = ": " + parameter.annotation|safe -%}
@@ -60,7 +63,9 @@ Context:
{#- Prepare default value. -#}
{%- if parameter.default is not none and parameter.kind.value != "variadic positional" and parameter.kind.value != "variadic keyword" -%}
- {%- set default = ns.equal + parameter.default|safe -%}
+ {%- set ns.default = True -%}
+ {%- else -%}
+ {%- set ns.default = False -%}
{%- endif -%}
{#- TODO: Move inside kind handling above? -#}
@@ -68,9 +73,45 @@ Context:
{%- set ns.render_kw_only_separator = False -%}
{%- endif -%}
- {#- Render name, annotation and default. -#}
- {% if parameter.kind.value == "variadic positional" %}*{% elif parameter.kind.value == "variadic keyword" %}**{% endif -%}
- {{ parameter.name }}{{ ns.annotation }}{{ default }}
+ {#- Prepare name. -#}
+ {%- set param_prefix -%}
+ {%- if parameter.kind.value == "variadic positional" -%}
+ *
+ {%- elif parameter.kind.value == "variadic keyword" -%}
+ **
+ {%- endif -%}
+ {%- endset -%}
+
+ {#- Render parameter name with optional cross-reference to its heading. -#}
+ {{ param_prefix }}
+ {%- if config.separate_signature and config.parameter_headings and config.signature_crossrefs -%}
+ {%- filter stash_crossref(length=parameter.name|length) -%}
+ {%- with func_path = function.path -%}
+ {%- if config.merge_init_into_class and func_path.endswith(".__init__") -%}
+ {%- set func_path = func_path[:-9] -%}
+ {%- endif -%}
+ {{ parameter.name }}
+ {%- endwith -%}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ parameter.name }}
+ {%- endif -%}
+
+ {#- Render parameter annotation. -#}
+ {{ ns.annotation }}
+
+ {#- Render parameter default value. -#}
+ {%- if ns.default -%}
+ {{ ns.equal }}
+ {%- if config.signature_crossrefs and config.separate_signature -%}
+ {%- with expression = parameter.default, backlink_type = "used-by" -%}
+ {%- include "expression.html.jinja" with context -%}
+ {%- endwith -%}
+ {%- else -%}
+ {{ parameter.default|safe }}
+ {%- endif -%}
+ {%- endif -%}
+
{%- if not loop.last %}, {% endif -%}
{%- endif -%}
@@ -82,7 +123,9 @@ Context:
and function.annotation
and not (config.merge_init_into_class and function.name == "__init__" )
%} -> {% if config.separate_signature and config.signature_crossrefs -%}
- {%- with expression = function.annotation %}{% include "expression"|get_template with context %}{%- endwith -%}
+ {%- with expression = function.annotation, backlink_type = "returned-by" -%}
+ {%- include "expression.html.jinja" with context -%}
+ {%- endwith -%}
{%- else -%}
{{ function.annotation|safe }}
{%- endif -%}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html
deleted file mode 100644
index aa33dc9c..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/summary.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary.html' is deprecated, extend '_base/summary.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
index 5770fdb0..852af437 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
@@ -2,7 +2,29 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
+
+{% with members_list = config.members if root_members else None %}
+ {% if config.summary.modules %}
+ {% include "summary/modules.html.jinja" with context %}
+ {% endif %}
+
+ {% if config.summary.type_aliases %}
+ {% include "summary/type_aliases.html.jinja" with context %}
+ {% endif %}
+
+ {% if config.summary.classes %}
+ {% include "summary/classes.html.jinja" with context %}
+ {% endif %}
+
+ {% if config.summary.functions %}
+ {% include "summary/functions.html.jinja" with context %}
+ {% endif %}
+
+ {% if config.summary.attributes %}
+ {% include "summary/attributes.html.jinja" with context %}
+ {% endif %}
+{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html
deleted file mode 100644
index f2643791..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/summary/attributes.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/attributes.html' is deprecated, extend '_base/summary/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
index cb966fb1..be42ed0f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
@@ -2,7 +2,22 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "attributes") | list %}
+ {% with section = obj.attributes
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members(config.members_order, members_list)
+ |as_attributes_section(check_public=not members_list)
+ %}
+ {% if section %}{% include "docstring/attributes.html.jinja" with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html
deleted file mode 100644
index 5c6275b4..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/summary/classes.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/classes.html' is deprecated, extend '_base/summary/classes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
index 94456775..3c0406dd 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
@@ -2,7 +2,22 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "classes") | list %}
+ {% with section = obj.classes
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members(config.members_order, members_list)
+ |as_classes_section(check_public=not members_list)
+ %}
+ {% if section %}{% include "docstring/classes.html.jinja" with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html
deleted file mode 100644
index 31887e0a..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/summary/functions.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/functions.html' is deprecated, extend '_base/summary/functions.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
index 5e8305aa..9fc6ea87 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
@@ -2,7 +2,22 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "functions") | list %}
+ {% with section = obj.functions
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members(config.members_order, members_list)
+ |as_functions_section(check_public=not members_list)
+ %}
+ {% if section %}{% include "docstring/functions.html.jinja" with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html
deleted file mode 100644
index 31dcb5f0..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/summary/modules.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/modules.html' is deprecated, extend '_base/summary/modules.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
index 04387b32..6206c6d1 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
@@ -2,7 +2,22 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "modules") | list %}
+ {% with section = obj.modules
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members("alphabetical", members_list)
+ |as_modules_section(check_public=not members_list)
+ %}
+ {% if section %}{% include "docstring/modules.html.jinja" with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja
new file mode 100644
index 00000000..ed0d2ef5
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja
@@ -0,0 +1,23 @@
+{#- Summary of type aliases. -#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "type aliases") | list %}
+ {% with section = obj.type_aliases
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members("alphabetical", members_list)
+ |as_type_aliases_section(check_public=not members_list)
+ %}
+ {% if section %}{% include "docstring/type_aliases.html.jinja" with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja
new file mode 100644
index 00000000..ff1e8464
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja
@@ -0,0 +1,117 @@
+{#- Template for Python type aliases.
+
+This template renders a Python type alias.
+
+Context:
+ type_alias (griffe.TypeAlias): The type alias to render.
+ root (bool): Whether this is the root object, injected with `:::` in a Markdown page.
+ heading_level (int): The HTML heading level to use.
+ config (dict): The configuration options.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering " + type_alias.path) }}
+{% endblock logs %}
+
+
+ {% with obj = type_alias, html_id = type_alias.path %}
+
+ {% if root %}
+ {% set show_full_path = config.show_root_full_path %}
+ {% set root_members = True %}
+ {% elif root_members %}
+ {% set show_full_path = config.show_root_members_full_path or config.show_object_full_path %}
+ {% set root_members = False %}
+ {% else %}
+ {% set show_full_path = config.show_object_full_path %}
+ {% endif %}
+
+ {% set type_alias_name = type_alias.path if show_full_path else type_alias.name %}
+
+ {% if not root or config.show_root_heading %}
+ {% filter heading(
+ heading_level,
+ role="typealias",
+ id=html_id,
+ class="doc doc-heading",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_alias.name,
+ ) %}
+
+ {% block heading scoped %}
+ {#- Heading block.
+
+ This block renders the heading for the type alias.
+ -#}
+ {% if config.show_symbol_type_heading %}{% endif %}
+ {% if config.separate_signature %}
+ {{ type_alias_name }}
+ {% else %}
+ {%+ filter highlight(language="python", inline=True) %}
+ {{ type_alias_name }}{% include "type_parameters.html.jinja" with context %} = {{ type_alias.value }}
+ {% endfilter %}
+ {% endif %}
+ {% endblock heading %}
+
+ {% block labels scoped %}
+ {#- Labels block.
+
+ This block renders the labels for the type alias.
+ -#}
+ {% with labels = type_alias.labels %}
+ {% include "labels.html.jinja" with context %}
+ {% endwith %}
+ {% endblock labels %}
+
+ {% endfilter %}
+
+ {% block signature scoped %}
+ {#- Signature block.
+
+ This block renders the signature for the type alias.
+ -#}
+ {% if config.separate_signature %}
+ {% filter format_type_alias(type_alias, config.line_length, crossrefs=config.signature_crossrefs) %}
+ {{ type_alias.name }}
+ {% endfilter %}
+ {% endif %}
+ {% endblock signature %}
+
+ {% else %}
+ {% if config.show_root_toc_entry %}
+ {% filter heading(heading_level,
+ role="typealias",
+ id=html_id,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_alias.name,
+ hidden=True,
+ ) %}
+ {% endfilter %}
+ {% endif %}
+ {% set heading_level = heading_level - 1 %}
+ {% endif %}
+
+
+ {% block contents scoped %}
+ {#- Contents block.
+
+ This block renders the contents of the type alias.
+ It contains other blocks that users can override.
+ Overriding the contents block allows to rearrange the order of the blocks.
+ -#}
+ {% block docstring scoped %}
+ {#- Docstring block.
+
+ This block renders the docstring for the type alias.
+ -#}
+ {% with docstring_sections = type_alias.docstring.parsed %}
+ {% include "docstring.html.jinja" with context %}
+ {% endwith %}
+ {% endblock docstring %}
+ {% endblock contents %}
+
+
+ {% endwith %}
+
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja
new file mode 100644
index 00000000..47100924
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja
@@ -0,0 +1,87 @@
+{#- Template for type parameters.
+
+This template renders the type parameters of a generic obj.
+It iterates over the type parameters of the object to rebuild the signature.
+The signature is the list of type parameters of a generic object, including their names, default values, and bound or constraints.
+
+Context:
+ obj (griffe.Object): The object to render.
+ config (dict): The configuration options.
+-#}
+
+{%- if config.show_signature_type_parameters -%}
+ {%- block logs scoped -%}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type parameters") }}
+ {%- endblock logs -%}
+
+ {%- with ns = namespace(annotation="", equal="=", default=False) -%}
+ {%- if obj.is_generic -%}
+ [
+ {%- for type_parameter in obj.type_parameters -%}
+ {#- Prepare type bound or constraints. -#}
+ {%- if config.show_signature_annotations and type_parameter.annotation is not none -%}
+ {%- set ns.equal = " = " -%}
+ {%- if config.separate_signature and config.signature_crossrefs -%}
+ {%- with expression = type_parameter.annotation -%}
+ {%- set ns.annotation -%}: {% include "expression.html.jinja" with context %}{%- endset -%}
+ {%- endwith -%}
+ {%- else -%}
+ {%- set ns.annotation = ": " + type_parameter.annotation|safe -%}
+ {%- endif -%}
+ {%- else -%}
+ {%- set ns.equal = "=" -%}
+ {%- set ns.annotation = "" -%}
+ {%- endif -%}
+
+ {#- Prepare default value. -#}
+ {%- if type_parameter.default is not none -%}
+ {%- set ns.default = True -%}
+ {%- else -%}
+ {%- set ns.default = False -%}
+ {%- endif -%}
+
+ {#- Prepare name. -#}
+ {%- set type_param_prefix -%}
+ {%- if type_parameter.kind == "type-var-tuple" -%}
+ *
+ {%- elif type_parameter.kind == "param-spec" -%}
+ **
+ {%- endif -%}
+ {%- endset -%}
+
+ {#- Render type parameter name with optional cross-reference to its heading. -#}
+ {{ type_param_prefix }}
+ {%- if config.separate_signature and config.type_parameter_headings and config.signature_crossrefs -%}
+ {%- filter stash_crossref(length=type_parameter.name|length) -%}
+ {{ type_parameter.name }}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ type_parameter.name }}
+ {%- endif -%}
+
+ {#- Render type parameter bound or constraints. -#}
+ {{ ns.annotation }}
+
+ {#- Render type parameter default value. -#}
+ {%- if ns.default -%}
+ {{ ns.equal }}
+ {%- if config.signature_crossrefs and config.separate_signature -%}
+ {%- with expression = type_parameter.default -%}
+ {%- include "expression.html.jinja" with context -%}
+ {%- endwith -%}
+ {%- else -%}
+ {{ type_parameter.default|safe }}
+ {%- endif -%}
+ {%- endif -%}
+
+ {%- if not loop.last %}, {% endif -%}
+ {%- endfor -%}
+ ]
+ {%- endif -%}
+
+ {%- endwith -%}
+{%- endif -%}
diff --git a/src/mkdocstrings_handlers/python/templates/material/attribute.html b/src/mkdocstrings_handlers/python/templates/material/attribute.html
deleted file mode 100644
index a3c27503..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/attribute.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/attribute.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/backlinks.html.jinja b/src/mkdocstrings_handlers/python/templates/material/backlinks.html.jinja
new file mode 100644
index 00000000..08ba4922
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/backlinks.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/backlinks.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/children.html b/src/mkdocstrings_handlers/python/templates/material/children.html
deleted file mode 100644
index 2c2a73ab..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/children.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/children.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring.html b/src/mkdocstrings_handlers/python/templates/material/docstring.html
deleted file mode 100644
index a7ccd66c..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html b/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html
deleted file mode 100644
index e9da5e9a..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/admonition.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html
deleted file mode 100644
index 4ac364b0..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html b/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html
deleted file mode 100644
index 035b3102..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/classes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html b/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html
deleted file mode 100644
index 34e9c4ba..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/examples.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html b/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html
deleted file mode 100644
index f3eaed78..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/functions.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html b/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html
deleted file mode 100644
index 8ea02a33..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/modules.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html
deleted file mode 100644
index 7c50379b..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/other_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html
deleted file mode 100644
index 70c557fb..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html
deleted file mode 100644
index f8c3cf03..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/raises.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html
deleted file mode 100644
index 004ff00e..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/receives.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html
deleted file mode 100644
index 979ce9ef..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/returns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html
new file mode 100644
index 00000000..78bd497a
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja
new file mode 100644
index 00000000..78bd497a
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html
new file mode 100644
index 00000000..223fbb04
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja
new file mode 100644
index 00000000..223fbb04
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html
deleted file mode 100644
index bb06cc85..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/warns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html
deleted file mode 100644
index 717ef5d4..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/yields.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/expression.html b/src/mkdocstrings_handlers/python/templates/material/expression.html
deleted file mode 100644
index 60c64d79..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/expression.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/expression.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/function.html b/src/mkdocstrings_handlers/python/templates/material/function.html
deleted file mode 100644
index 54bba061..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/function.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/function.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/labels.html b/src/mkdocstrings_handlers/python/templates/material/labels.html
deleted file mode 100644
index 51cb29d6..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/labels.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/labels.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/language.html b/src/mkdocstrings_handlers/python/templates/material/language.html
deleted file mode 100644
index b905cff4..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/language.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/language.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/en.html b/src/mkdocstrings_handlers/python/templates/material/languages/en.html
deleted file mode 100644
index 931967c1..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/languages/en.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/en.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/ja.html b/src/mkdocstrings_handlers/python/templates/material/languages/ja.html
deleted file mode 100644
index 17070edf..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/languages/ja.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/ja.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/zh.html b/src/mkdocstrings_handlers/python/templates/material/languages/zh.html
deleted file mode 100644
index e4ea3116..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/languages/zh.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/zh.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/module.html b/src/mkdocstrings_handlers/python/templates/material/module.html
deleted file mode 100644
index 9d8efea5..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/module.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/module.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/signature.html b/src/mkdocstrings_handlers/python/templates/material/signature.html
deleted file mode 100644
index 33b266c8..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/signature.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/signature.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css
index 154be85d..7bb97041 100644
--- a/src/mkdocstrings_handlers/python/templates/material/style.css
+++ b/src/mkdocstrings_handlers/python/templates/material/style.css
@@ -9,6 +9,11 @@
display: inline;
}
+/* No text transformation from Material for MkDocs for H5 headings. */
+.md-typeset h5 .doc-object-name {
+ text-transform: none;
+}
+
/* Max width for docstring sections tables. */
.doc .md-typeset__table,
.doc .md-typeset__table table {
@@ -21,42 +26,95 @@
}
/* Defaults in Spacy table style. */
-.doc-param-default {
+.doc-param-default,
+.doc-type_param-default {
float: right;
}
+/* Parameter headings must be inline, not blocks. */
+.doc-heading-parameter,
+.doc-heading-type_parameter {
+ display: inline;
+}
+
+/* Default font size for parameter headings. */
+.md-typeset .doc-heading-parameter {
+ font-size: inherit;
+}
+
+/* Prefer space on the right, not the left of parameter permalinks. */
+.doc-heading-parameter .headerlink,
+.doc-heading-type_parameter .headerlink {
+ margin-left: 0 !important;
+ margin-right: 0.2rem;
+}
+
/* Backward-compatibility: docstring section titles in bold. */
.doc-section-title {
font-weight: bold;
}
+/* Backlinks crumb separator. */
+.doc-backlink-crumb {
+ display: inline-flex;
+ gap: .2rem;
+ white-space: nowrap;
+ align-items: center;
+ vertical-align: middle;
+}
+.doc-backlink-crumb:not(:first-child)::before {
+ background-color: var(--md-default-fg-color--lighter);
+ content: "";
+ display: inline;
+ height: 1rem;
+ --md-path-icon: url('data:image/svg+xml;charset=utf-8,');
+ -webkit-mask-image: var(--md-path-icon);
+ mask-image: var(--md-path-icon);
+ width: 1rem;
+}
+.doc-backlink-crumb.last {
+ font-weight: bold;
+}
+
/* Symbols in Navigation and ToC. */
-:root,
+:root, :host,
[data-md-color-scheme="default"] {
+ --doc-symbol-parameter-fg-color: #df50af;
+ --doc-symbol-type_parameter-fg-color: #df50af;
--doc-symbol-attribute-fg-color: #953800;
--doc-symbol-function-fg-color: #8250df;
--doc-symbol-method-fg-color: #8250df;
--doc-symbol-class-fg-color: #0550ae;
+ --doc-symbol-type_alias-fg-color: #0550ae;
--doc-symbol-module-fg-color: #5cad0f;
+ --doc-symbol-parameter-bg-color: #df50af1a;
+ --doc-symbol-type_parameter-bg-color: #df50af1a;
--doc-symbol-attribute-bg-color: #9538001a;
--doc-symbol-function-bg-color: #8250df1a;
--doc-symbol-method-bg-color: #8250df1a;
--doc-symbol-class-bg-color: #0550ae1a;
+ --doc-symbol-type_alias-bg-color: #0550ae1a;
--doc-symbol-module-bg-color: #5cad0f1a;
}
[data-md-color-scheme="slate"] {
+ --doc-symbol-parameter-fg-color: #ffa8cc;
+ --doc-symbol-type_parameter-fg-color: #ffa8cc;
--doc-symbol-attribute-fg-color: #ffa657;
--doc-symbol-function-fg-color: #d2a8ff;
--doc-symbol-method-fg-color: #d2a8ff;
--doc-symbol-class-fg-color: #79c0ff;
+ --doc-symbol-type_alias-fg-color: #79c0ff;
--doc-symbol-module-fg-color: #baff79;
+ --doc-symbol-parameter-bg-color: #ffa8cc1a;
+ --doc-symbol-type_parameter-bg-color: #ffa8cc1a;
--doc-symbol-attribute-bg-color: #ffa6571a;
--doc-symbol-function-bg-color: #d2a8ff1a;
--doc-symbol-method-bg-color: #d2a8ff1a;
--doc-symbol-class-bg-color: #79c0ff1a;
+ --doc-symbol-type_alias-bg-color: #79c0ff1a;
--doc-symbol-module-bg-color: #baff791a;
}
@@ -67,7 +125,28 @@ code.doc-symbol {
font-weight: bold;
}
-code.doc-symbol-attribute {
+code.doc-symbol-parameter,
+a code.doc-symbol-parameter {
+ color: var(--doc-symbol-parameter-fg-color);
+ background-color: var(--doc-symbol-parameter-bg-color);
+}
+
+code.doc-symbol-parameter::after {
+ content: "param";
+}
+
+code.doc-symbol-type_parameter,
+a code.doc-symbol-type_parameter {
+ color: var(--doc-symbol-type_parameter-fg-color);
+ background-color: var(--doc-symbol-type_parameter-bg-color);
+}
+
+code.doc-symbol-type_parameter::after {
+ content: "type-param";
+}
+
+code.doc-symbol-attribute,
+a code.doc-symbol-attribute {
color: var(--doc-symbol-attribute-fg-color);
background-color: var(--doc-symbol-attribute-bg-color);
}
@@ -76,7 +155,8 @@ code.doc-symbol-attribute::after {
content: "attr";
}
-code.doc-symbol-function {
+code.doc-symbol-function,
+a code.doc-symbol-function {
color: var(--doc-symbol-function-fg-color);
background-color: var(--doc-symbol-function-bg-color);
}
@@ -85,7 +165,8 @@ code.doc-symbol-function::after {
content: "func";
}
-code.doc-symbol-method {
+code.doc-symbol-method,
+a code.doc-symbol-method {
color: var(--doc-symbol-method-fg-color);
background-color: var(--doc-symbol-method-bg-color);
}
@@ -94,7 +175,8 @@ code.doc-symbol-method::after {
content: "meth";
}
-code.doc-symbol-class {
+code.doc-symbol-class,
+a code.doc-symbol-class {
color: var(--doc-symbol-class-fg-color);
background-color: var(--doc-symbol-class-bg-color);
}
@@ -103,7 +185,19 @@ code.doc-symbol-class::after {
content: "class";
}
-code.doc-symbol-module {
+
+code.doc-symbol-type_alias,
+a code.doc-symbol-type_alias {
+ color: var(--doc-symbol-type_alias-fg-color);
+ background-color: var(--doc-symbol-type_alias-bg-color);
+}
+
+code.doc-symbol-type_alias::after {
+ content: "type";
+}
+
+code.doc-symbol-module,
+a code.doc-symbol-module {
color: var(--doc-symbol-module-fg-color);
background-color: var(--doc-symbol-module-bg-color);
}
@@ -116,3 +210,27 @@ code.doc-symbol-module::after {
color: inherit;
border-bottom: 1px dotted currentcolor;
}
+
+/* Source code blocks (admonitions). */
+:root {
+ --md-admonition-icon--mkdocstrings-source: url('data:image/svg+xml;charset=utf-8,')
+}
+.md-typeset .admonition.mkdocstrings-source,
+.md-typeset details.mkdocstrings-source {
+ border: none;
+ padding: 0;
+}
+.md-typeset .admonition.mkdocstrings-source:focus-within,
+.md-typeset details.mkdocstrings-source:focus-within {
+ box-shadow: none;
+}
+.md-typeset .mkdocstrings-source > .admonition-title,
+.md-typeset .mkdocstrings-source > summary {
+ background-color: inherit;
+}
+.md-typeset .mkdocstrings-source > .admonition-title::before,
+.md-typeset .mkdocstrings-source > summary::before {
+ background-color: var(--md-default-fg-color);
+ -webkit-mask-image: var(--md-admonition-icon--mkdocstrings-source);
+ mask-image: var(--md-admonition-icon--mkdocstrings-source);
+}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary.html b/src/mkdocstrings_handlers/python/templates/material/summary.html
deleted file mode 100644
index 59eddea0..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/summary.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/summary.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html b/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html
deleted file mode 100644
index c69755c6..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/summary/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/classes.html b/src/mkdocstrings_handlers/python/templates/material/summary/classes.html
deleted file mode 100644
index 825eb1bb..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/summary/classes.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/summary/classes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/functions.html b/src/mkdocstrings_handlers/python/templates/material/summary/functions.html
deleted file mode 100644
index fc609bda..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/summary/functions.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/summary/functions.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/modules.html b/src/mkdocstrings_handlers/python/templates/material/summary/modules.html
deleted file mode 100644
index 46db0023..00000000
--- a/src/mkdocstrings_handlers/python/templates/material/summary/modules.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/summary/modules.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html
new file mode 100644
index 00000000..ca10bc88
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html
@@ -0,0 +1 @@
+{% extends "_base/summary/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja
new file mode 100644
index 00000000..ca10bc88
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/summary/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html b/src/mkdocstrings_handlers/python/templates/material/type_alias.html
new file mode 100644
index 00000000..5139a2db
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html
@@ -0,0 +1 @@
+{% extends "_base/type_alias.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja
new file mode 100644
index 00000000..5139a2db
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/type_alias.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html
new file mode 100644
index 00000000..c39ca528
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html
@@ -0,0 +1 @@
+{% extends "_base/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja
new file mode 100644
index 00000000..c39ca528
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html
similarity index 100%
rename from src/mkdocstrings_handlers/python/templates/material/_base/class.html
rename to src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja
new file mode 100644
index 00000000..64b41ea6
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja
@@ -0,0 +1,251 @@
+{#- Template for Python classes.
+
+This template renders a Python class.
+
+Context:
+ class (griffe.Class): The class to render.
+ root (bool): Whether this is the root object, injected with `:::` in a Markdown page.
+ heading_level (int): The HTML heading level to use.
+ config (dict): The configuration options.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering " + class.path) }}
+{% endblock logs %}
+
+
+ {% with obj = class, html_id = class.path %}
+
+ {% if root %}
+ {% set show_full_path = config.show_root_full_path %}
+ {% set root_members = True %}
+ {% elif root_members %}
+ {% set show_full_path = config.show_root_members_full_path or config.show_object_full_path %}
+ {% set root_members = False %}
+ {% else %}
+ {% set show_full_path = config.show_object_full_path %}
+ {% endif %}
+
+ {% set class_name = class.path if show_full_path else class.name %}
+
+ {% if not root or config.show_root_heading %}
+ {% filter heading(
+ heading_level,
+ role="class",
+ id=html_id,
+ class="doc doc-heading",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name,
+ ) %}
+
+ {% block heading scoped %}
+ {#- Heading block.
+
+ This block renders the heading for the class.
+ -#}
+ {% if config.show_symbol_type_heading %}{% endif %}
+ {% if config.separate_signature %}
+ {{ class_name }}
+ {% elif config.merge_init_into_class and "__init__" in class.all_members %}
+ {% with function = class.all_members["__init__"] %}
+ {%+ filter highlight(language="python", inline=True) %}
+ {{ class_name }}{% include "signature.html.jinja" with context %}
+ {% endfilter %}
+ {% endwith %}
+ {% else %}
+ {{ class_name }}
+ {% endif %}
+ {% endblock heading %}
+
+ {% block labels scoped %}
+ {#- Labels block.
+
+ This block renders the labels for the class.
+ -#}
+ {% with labels = class.labels %}
+ {% include "labels.html.jinja" with context %}
+ {% endwith %}
+ {% endblock labels %}
+
+ {% endfilter %}
+
+ {% block signature scoped %}
+ {#- Signature block.
+
+ This block renders the signature for the class.
+ -#}
+ {% if config.separate_signature and config.merge_init_into_class %}
+ {% if "__init__" in class.all_members %}
+ {% with function = class.all_members["__init__"] %}
+ {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %}
+ {{ class.name }}
+ {% endfilter %}
+ {% endwith %}
+ {% endif %}
+ {% endif %}
+ {% endblock signature %}
+
+ {% else %}
+ {% if config.show_root_toc_entry %}
+ {% filter heading(heading_level,
+ role="class",
+ id=html_id,
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name,
+ hidden=True,
+ ) %}
+ {% endfilter %}
+ {% endif %}
+ {% set heading_level = heading_level - 1 %}
+ {% endif %}
+
+
+ {% block contents scoped %}
+ {#- Contents block.
+
+ This block renders the contents of the class.
+ It contains other blocks that users can override.
+ Overriding the contents block allows to rearrange the order of the blocks.
+ -#}
+ {% block bases scoped %}
+ {#- Class bases block.
+
+ This block renders the bases for the class.
+ -#}
+ {% if config.show_bases and class.bases %}
+
+ Bases: {% for expression in class.bases -%}
+ {% include "expression.html.jinja" with context %}{% if not loop.last %}, {% endif %}
+ {% endfor -%}
+
+ {% endif %}
+ {% endblock bases %}
+
+ {% block inheritance_diagram scoped %}
+ {#- Inheritance diagram block.
+
+ This block renders the inheritance diagram for the class,
+ using Mermaid syntax and a bit of JavaScript to make the nodes clickable,
+ linking to the corresponding class documentation.
+ -#}
+ {% if config.show_inheritance_diagram and class.bases %}
+ {% macro edges(class) %}
+ {% for base in class.resolved_bases %}
+ {{ base.path }} --> {{ class.path }}
+ {{ edges(base) }}
+ {% endfor %}
+ {% endmacro %}
+
+
+ flowchart {{ config.inheritance_diagram_direction }}
+ {{ class.path }}[{{ class.name }}]
+ {% for base in class.mro() %}
+ {{ base.path }}[{{ base.name }}]
+ {% endfor %}
+
+ {{ edges(class) | safe }}
+
+ click {{ class.path }} href "" "{{ class.path }}"
+ {% for base in class.mro() %}
+ click {{ base.path }} href "" "{{ base.path }}"
+ {% endfor %}
+
+
+ {% endif %}
+ {% endblock inheritance_diagram %}
+
+ {% block docstring scoped %}
+ {#- Docstring block.
+
+ This block renders the docstring for the class.
+ -#}
+ {% with docstring_sections = class.docstring.parsed %}
+ {% include "docstring.html.jinja" with context %}
+ {% endwith %}
+ {% if config.merge_init_into_class %}
+ {% if "__init__" in class.all_members and class.all_members["__init__"].has_docstring %}
+ {% with function = class.all_members["__init__"] %}
+ {% with obj = function, docstring_sections = function.docstring.parsed %}
+ {% include "docstring.html.jinja" with context %}
+ {% endwith %}
+ {% endwith %}
+ {% endif %}
+ {% endif %}
+ {% endblock docstring %}
+
+ {% block summary scoped %}
+ {#- Summary block.
+
+ This block renders auto-summaries for classes, methods, and attributes.
+ -#}
+ {% include "summary.html.jinja" with context %}
+ {% endblock summary %}
+
+ {% block source scoped %}
+ {#- Source block.
+
+ This block renders the source code for the class.
+ -#}
+ {% if config.show_source %}
+ {% if config.merge_init_into_class %}
+ {% if "__init__" in class.all_members and class.all_members["__init__"].source %}
+ {% with init = class.all_members["__init__"] %}
+
+ Source code in
+ {%- if init.relative_filepath.is_absolute() -%}
+ {{ init.relative_package_filepath }}
+ {%- else -%}
+ {{ init.relative_filepath }}
+ {%- endif -%}
+
+ {{ init.source|highlight(language="python", linestart=init.lineno or 0, linenums=True) }}
+
+ {% endwith %}
+ {% endif %}
+ {% elif class.source %}
+
+ Source code in
+ {%- if class.relative_filepath.is_absolute() -%}
+ {{ class.relative_package_filepath }}
+ {%- else -%}
+ {{ class.relative_filepath }}
+ {%- endif -%}
+
+ {{ class.source|highlight(language="python", linestart=class.lineno or 0, linenums=True) }}
+
+ {% endif %}
+ {% endif %}
+ {% endblock source %}
+
+ {% block children scoped %}
+ {#- Children block.
+
+ This block renders the children (members) of the class.
+ -#}
+ {% set root = False %}
+ {% set heading_level = heading_level + 1 %}
+ {% include "children.html.jinja" with context %}
+ {% endblock children %}
+ {% endblock contents %}
+
+
+ {% endwith %}
+
+
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html
deleted file mode 100644
index cd4b05be..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/attributes.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
index 8df3f9f3..a3817449 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -33,7 +33,7 @@ Context:
{{ attribute.name }}
{% if attribute.annotation %}
{% with expression = attribute.annotation %}
- ({% include "expression"|get_template with context %})
+ ({% include "expression.html.jinja" with context %})
{% endwith %}
{% endif %}
–
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html
deleted file mode 100644
index eae60aa7..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/other_parameters.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
index 287bbf3d..f7af2121 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,8 +32,8 @@ Context:
-
{{ parameter.name }}
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- ({% include "expression"|get_template with context %})
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ ({% include "expression.html.jinja" with context %})
{% endwith %}
{% endif %}
–
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html
deleted file mode 100644
index f5745464..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/parameters.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
index da30d60a..95c480fa 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,11 +32,11 @@ Context:
-
{{ parameter.name }}
{% if parameter.annotation %}
- {% with expression = parameter.annotation %}
- ({% include "expression"|get_template with context %}
+ {% with expression = parameter.annotation, backlink_type = "used-by" %}
+ ({% include "expression.html.jinja" with context %}
{%- if parameter.default %}, {{ lang.t("default:") }}
- {% with expression = parameter.default %}
- {% include "expression"|get_template with context %}
+ {% with expression = parameter.default, backlink_type = "used-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %})
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html
deleted file mode 100644
index 361b9732..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/raises.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
index ffa3fad1..71beb34c 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -31,8 +31,8 @@ Context:
{% for raises in section.value %}
-
{% if raises.annotation %}
- {% with expression = raises.annotation %}
-
{% include "expression"|get_template with context %}
+ {% with expression = raises.annotation, backlink_type = "raised-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
–
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html
deleted file mode 100644
index e5a115c1..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/receives.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
index 40c77846..8ad9cae3 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,9 +32,9 @@ Context:
-
{% if receives.name %}
{{ receives.name }}{% endif %}
{% if receives.annotation %}
- {% with expression = receives.annotation %}
+ {% with expression = receives.annotation, backlink_type = "received-by" %}
{% if receives.name %}({% endif %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if receives.name %}){% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html
deleted file mode 100644
index 0e7807ac..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/returns.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
index 597d8932..2201f545 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,9 +32,9 @@ Context:
-
{% if returns.name %}
{{ returns.name }}{% endif %}
{% if returns.annotation %}
- {% with expression = returns.annotation %}
+ {% with expression = returns.annotation, backlink_type = "returned-by" %}
{% if returns.name %}({% endif %}
- {% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if returns.name %}){% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html
deleted file mode 100644
index b7b937a9..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/warns.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
index d66ac431..97cbc1de 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -31,8 +31,8 @@ Context:
{% for warns in section.value %}
-
{% if warns.annotation %}
- {% with expression = warns.annotation %}
-
{% include "expression"|get_template with context %}
+ {% with expression = warns.annotation, backlink_type = "emitted-by" %}
+ {% include "expression.html.jinja" with context %}
{% endwith %}
{% endif %}
–
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html
deleted file mode 100644
index ecd6f513..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/docstring/yields.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
index 4d4fc3d5..8298421f 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
@@ -9,13 +9,13 @@ Context:
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{{ log.debug() }}
{% endblock %}
-{% import "language"|get_template as lang with context %}
+{% import "language.html.jinja" as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,9 +32,9 @@ Context:
-
{% if yields.name %}{{ yields.name }}{% endif %}
{% if yields.annotation %}
- {% with expression = yields.annotation %}
+ {% with expression = yields.annotation, backlink_type = "yielded-by" %}
{% if yields.name %}({% endif %}
-
{% include "expression"|get_template with context %}
+ {% include "expression.html.jinja" with context %}
{% if yields.name %}){% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html
deleted file mode 100644
index c97d0c31..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/language.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
index 5b643726..31ecfdd6 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
@@ -2,17 +2,17 @@
{% block logs scoped %}
{#- Logging block.
-
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
-#}
{% endblock logs %}
-{% set lang_pth = "languages/" ~ locale | get_template %}
+{% set lang_pth = "languages/" ~ locale ~ ".html.jinja" %}
{% if lang_pth is existing_template %}
- {% import lang_pth as lang %}
- {% import "languages/en"|get_template as fallback %}
- {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
+ {% import lang_pth as lang %}
+ {% import "languages/en.html.jinja" as fallback %}
+ {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
{% else %}
- {% import "languages/en"|get_template as lang %}
- {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
+ {% import "languages/en.html.jinja" as lang %}
+ {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html
deleted file mode 100644
index eab87415..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/en.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html
deleted file mode 100644
index 14319499..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/ja.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html.jinja
index 748fd8b7..b6279ef0 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html.jinja
@@ -4,20 +4,20 @@
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
"Attributes:": "属性:",
- "Classes:": "",
- "CLASS": "",
+ "Classes:": "クラス:",
+ "CLASS": "クラス",
"DEFAULT:": "デフォルト:",
"Default": "デフォルト",
"default:": "デフォルト:",
"DESCRIPTION": "デスクリプション",
"Description": "デスクリプション",
"Examples:": "例:",
- "Functions:": "",
- "FUNCTION": "",
- "Methods:": "",
- "METHOD": "",
- "Modules:": "",
- "MODULE": "",
+ "Functions:": "関数:",
+ "FUNCTION": "関数",
+ "Methods:": "メソッド:",
+ "METHOD": "メソッド",
+ "Modules:": "モジュール:",
+ "MODULE": "モジュール",
"Name": "名前",
"Other Parameters:": "他の引数:",
"PARAMETER": "引数",
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html
deleted file mode 100644
index 0b281195..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "_base/languages/zh.html.jinja" %}
-
-{% block logs scoped %}
- {{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- ) }}
-{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html.jinja
index 772e33cd..f25ff721 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html.jinja
@@ -4,20 +4,20 @@
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
"Attributes:": "属性:",
- "Classes:": "",
- "CLASS": "",
+ "Classes:": "类:",
+ "CLASS": "类",
"DEFAULT:": "默认:",
"Default": "默认",
"default:": "默认:",
"DESCRIPTION": "描述",
"Description": "描述",
"Examples:": "示例:",
- "Functions:": "",
- "FUNCTION": "",
- "Methods:": "",
- "METHOD": "",
- "Modules:": "",
- "MODULE": "",
+ "Functions:": "函数:",
+ "FUNCTION": "函数",
+ "Methods:": "方法:",
+ "METHOD": "方法",
+ "Modules:": "模块:",
+ "MODULE": "模块",
"Name": "名称",
"Other Parameters:": "其他参数:",
"PARAMETER": "参数",
diff --git a/src/mkdocstrings_handlers/python/templates/material/class.html b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html
similarity index 100%
rename from src/mkdocstrings_handlers/python/templates/material/class.html
rename to src/mkdocstrings_handlers/python/templates/readthedocs/class.html
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja
new file mode 100644
index 00000000..5e7329df
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/class.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html
deleted file mode 100644
index 4ac364b0..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html
deleted file mode 100644
index 7c50379b..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/other_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html
deleted file mode 100644
index 70c557fb..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html
deleted file mode 100644
index f8c3cf03..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/raises.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html
deleted file mode 100644
index 004ff00e..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/receives.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html
deleted file mode 100644
index 979ce9ef..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/returns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html
deleted file mode 100644
index bb06cc85..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/warns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html
deleted file mode 100644
index 717ef5d4..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/docstring/yields.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/language.html b/src/mkdocstrings_handlers/python/templates/readthedocs/language.html
deleted file mode 100644
index b905cff4..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/language.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/language.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html
deleted file mode 100644
index 931967c1..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/en.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html
deleted file mode 100644
index 17070edf..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/ja.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html
deleted file mode 100644
index e4ea3116..00000000
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html
+++ /dev/null
@@ -1 +0,0 @@
-{% extends "_base/languages/zh.html.jinja" %}
diff --git a/tests/conftest.py b/tests/conftest.py
index f7b28105..926c4b83 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2,24 +2,29 @@
from __future__ import annotations
-from collections import ChainMap
-from typing import TYPE_CHECKING, Any, Iterator
+from collections.abc import Iterator
+from typing import TYPE_CHECKING
import pytest
-from markdown.core import Markdown
-from mkdocs.config.defaults import MkDocsConfig
+
+from tests import helpers
if TYPE_CHECKING:
+ from collections.abc import Iterator
from pathlib import Path
- from mkdocs import config
- from mkdocstrings.plugin import MkdocstringsPlugin
+ from markdown.core import Markdown
+ from mkdocs.config.defaults import MkDocsConfig
+ from mkdocstrings import MkdocstringsPlugin
- from mkdocstrings_handlers.python.handler import PythonHandler
+ from mkdocstrings_handlers.python import PythonHandler
+# --------------------------------------------
+# Function-scoped fixtures.
+# --------------------------------------------
@pytest.fixture(name="mkdocs_conf")
-def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Iterator[config.Config]:
+def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Iterator[MkDocsConfig]:
"""Yield a MkDocs configuration object.
Parameters:
@@ -29,34 +34,12 @@ def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Itera
Yields:
MkDocs config.
"""
- conf = MkDocsConfig()
- while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"):
- request = request._parent_request
-
- conf_dict = {
- "site_name": "foo",
- "site_url": "https://example.org/",
- "site_dir": str(tmp_path),
- "plugins": [{"mkdocstrings": {"default_handler": "python"}}],
- **getattr(request, "param", {}),
- }
- # Re-create it manually as a workaround for https://github.com/mkdocs/mkdocs/issues/2289
- mdx_configs: dict[str, Any] = dict(ChainMap(*conf_dict.get("markdown_extensions", [])))
-
- conf.load_dict(conf_dict)
- assert conf.validate() == ([], [])
-
- conf["mdx_configs"] = mdx_configs
- conf["markdown_extensions"].insert(0, "toc") # Guaranteed to be added by MkDocs.
-
- conf = conf["plugins"]["mkdocstrings"].on_config(conf)
- conf = conf["plugins"]["autorefs"].on_config(conf)
- yield conf
- conf["plugins"]["mkdocstrings"].on_post_build(conf)
+ with helpers.mkdocs_conf(request, tmp_path) as mkdocs_conf:
+ yield mkdocs_conf
@pytest.fixture(name="plugin")
-def fixture_plugin(mkdocs_conf: config.Config) -> MkdocstringsPlugin:
+def fixture_plugin(mkdocs_conf: MkDocsConfig) -> MkdocstringsPlugin:
"""Return a plugin instance.
Parameters:
@@ -65,11 +48,11 @@ def fixture_plugin(mkdocs_conf: config.Config) -> MkdocstringsPlugin:
Returns:
mkdocstrings plugin instance.
"""
- return mkdocs_conf["plugins"]["mkdocstrings"]
+ return helpers.plugin(mkdocs_conf)
@pytest.fixture(name="ext_markdown")
-def fixture_ext_markdown(mkdocs_conf: config.Config) -> Markdown:
+def fixture_ext_markdown(mkdocs_conf: MkDocsConfig) -> Markdown:
"""Return a Markdown instance with MkdocstringsExtension.
Parameters:
@@ -78,7 +61,7 @@ def fixture_ext_markdown(mkdocs_conf: config.Config) -> Markdown:
Returns:
A Markdown instance.
"""
- return Markdown(extensions=mkdocs_conf["markdown_extensions"], extension_configs=mkdocs_conf["mdx_configs"])
+ return helpers.ext_markdown(mkdocs_conf)
@pytest.fixture(name="handler")
@@ -91,6 +74,64 @@ def fixture_handler(plugin: MkdocstringsPlugin, ext_markdown: Markdown) -> Pytho
Returns:
A handler instance.
"""
- handler = plugin.handlers.get_handler("python")
- handler._update_env(ext_markdown, plugin.handlers._config)
- return handler # type: ignore[return-value]
+ return helpers.handler(plugin, ext_markdown)
+
+
+# --------------------------------------------
+# Session-scoped fixtures.
+# --------------------------------------------
+@pytest.fixture(name="session_mkdocs_conf", scope="session")
+def fixture_session_mkdocs_conf(
+ request: pytest.FixtureRequest,
+ tmp_path_factory: pytest.TempPathFactory,
+) -> Iterator[MkDocsConfig]:
+ """Yield a MkDocs configuration object.
+
+ Parameters:
+ request: Pytest fixture.
+ tmp_path: Pytest fixture.
+
+ Yields:
+ MkDocs config.
+ """
+ with helpers.mkdocs_conf(request, tmp_path_factory.mktemp("project")) as mkdocs_conf:
+ yield mkdocs_conf
+
+
+@pytest.fixture(name="session_plugin", scope="session")
+def fixture_session_plugin(session_mkdocs_conf: MkDocsConfig) -> MkdocstringsPlugin:
+ """Return a plugin instance.
+
+ Parameters:
+ mkdocs_conf: Pytest fixture (see conftest.py).
+
+ Returns:
+ mkdocstrings plugin instance.
+ """
+ return helpers.plugin(session_mkdocs_conf)
+
+
+@pytest.fixture(name="session_ext_markdown", scope="session")
+def fixture_session_ext_markdown(session_mkdocs_conf: MkDocsConfig) -> Markdown:
+ """Return a Markdown instance with MkdocstringsExtension.
+
+ Parameters:
+ mkdocs_conf: Pytest fixture (see conftest.py).
+
+ Returns:
+ A Markdown instance.
+ """
+ return helpers.ext_markdown(session_mkdocs_conf)
+
+
+@pytest.fixture(name="session_handler", scope="session")
+def fixture_session_handler(session_plugin: MkdocstringsPlugin, session_ext_markdown: Markdown) -> PythonHandler:
+ """Return a handler instance.
+
+ Parameters:
+ plugin: Pytest fixture (see conftest.py).
+
+ Returns:
+ A handler instance.
+ """
+ return helpers.handler(session_plugin, session_ext_markdown)
diff --git a/tests/helpers.py b/tests/helpers.py
new file mode 100644
index 00000000..d7fb7e1d
--- /dev/null
+++ b/tests/helpers.py
@@ -0,0 +1,97 @@
+"""Configuration for the pytest test suite."""
+
+from __future__ import annotations
+
+from collections import ChainMap
+from contextlib import contextmanager
+from typing import TYPE_CHECKING, Any
+
+from markdown.core import Markdown
+from mkdocs.config.defaults import MkDocsConfig
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+ from pathlib import Path
+
+ import pytest
+ from mkdocstrings import MkdocstringsPlugin
+
+ from mkdocstrings_handlers.python import PythonHandler
+
+
+@contextmanager
+def mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Iterator[MkDocsConfig]:
+ """Yield a MkDocs configuration object.
+
+ Parameters:
+ request: Pytest request fixture.
+ tmp_path: Temporary path.
+
+ Yields:
+ MkDocs config.
+ """
+ while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"):
+ request = request._parent_request
+
+ params = getattr(request, "param", {})
+ plugins = params.pop("plugins", [{"mkdocstrings": {}}])
+
+ conf = MkDocsConfig()
+ conf_dict = {
+ "site_name": "foo",
+ "site_url": "https://example.org/",
+ "site_dir": str(tmp_path),
+ "plugins": plugins,
+ **getattr(request, "param", {}),
+ }
+ # Re-create it manually as a workaround for https://github.com/mkdocs/mkdocs/issues/2289
+ mdx_configs: dict[str, Any] = dict(ChainMap(*conf_dict.get("markdown_extensions", [])))
+
+ conf.load_dict(conf_dict)
+ assert conf.validate() == ([], [])
+
+ conf["mdx_configs"] = mdx_configs
+ conf["markdown_extensions"].insert(0, "toc") # Guaranteed to be added by MkDocs.
+
+ conf = conf["plugins"]["mkdocstrings"].on_config(conf)
+ conf = conf["plugins"]["autorefs"].on_config(conf)
+ yield conf
+ conf["plugins"]["mkdocstrings"].on_post_build(conf)
+
+
+def plugin(mkdocs_conf: MkDocsConfig) -> MkdocstringsPlugin:
+ """Return a plugin instance.
+
+ Parameters:
+ mkdocs_conf: MkDocs configuration.
+
+ Returns:
+ mkdocstrings plugin instance.
+ """
+ return mkdocs_conf["plugins"]["mkdocstrings"]
+
+
+def ext_markdown(mkdocs_conf: MkDocsConfig) -> Markdown:
+ """Return a Markdown instance with MkdocstringsExtension.
+
+ Parameters:
+ mkdocs_conf: MkDocs configuration.
+
+ Returns:
+ A Markdown instance.
+ """
+ return Markdown(extensions=mkdocs_conf["markdown_extensions"], extension_configs=mkdocs_conf["mdx_configs"])
+
+
+def handler(plugin: MkdocstringsPlugin, ext_markdown: Markdown) -> PythonHandler:
+ """Return a handler instance.
+
+ Parameters:
+ plugin: Plugin instance.
+
+ Returns:
+ A handler instance.
+ """
+ handler = plugin.handlers.get_handler("python")
+ handler._update_env(ext_markdown)
+ return handler # type: ignore[return-value]
diff --git a/tests/snapshots/headings/heading=,separate_signature=False.html b/tests/snapshots/headings/heading=,separate_signature=False.html
new file mode 100644
index 00000000..2be154b9
--- /dev/null
+++ b/tests/snapshots/headings/heading=,separate_signature=False.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ headings_package
+
+
+
+
+
+
+
diff --git a/tests/snapshots/headings/heading=,separate_signature=True.html b/tests/snapshots/headings/heading=,separate_signature=True.html
new file mode 100644
index 00000000..c73f0184
--- /dev/null
+++ b/tests/snapshots/headings/heading=,separate_signature=True.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ headings_package
+
+
+
+
+
+
+
diff --git a/tests/snapshots/headings/heading=Some heading,separate_signature=False.html b/tests/snapshots/headings/heading=Some heading,separate_signature=False.html
new file mode 100644
index 00000000..b000bf14
--- /dev/null
+++ b/tests/snapshots/headings/heading=Some heading,separate_signature=False.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Some heading
+
+
+
+
+
+
diff --git a/tests/snapshots/headings/heading=Some heading,separate_signature=True.html b/tests/snapshots/headings/heading=Some heading,separate_signature=True.html
new file mode 100644
index 00000000..852b7487
--- /dev/null
+++ b/tests/snapshots/headings/heading=Some heading,separate_signature=True.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Some heading
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html
new file mode 100644
index 00000000..271501b7
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html
@@ -0,0 +1,59 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=().html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=().html
new file mode 100644
index 00000000..52ada349
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=().html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html
new file mode 100644
index 00000000..e96d72c3
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html
new file mode 100644
index 00000000..dce4e148
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html
@@ -0,0 +1,324 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html
new file mode 100644
index 00000000..6d460dd2
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html
@@ -0,0 +1,355 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html
new file mode 100644
index 00000000..93503606
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=().html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=().html
new file mode 100644
index 00000000..fb55bdd1
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=False.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=False.html
new file mode 100644
index 00000000..3ae3af4d
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=None.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=None.html
new file mode 100644
index 00000000..793f43a4
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=None.html
@@ -0,0 +1,289 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=True.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=True.html
new file mode 100644
index 00000000..07120341
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=True.html
@@ -0,0 +1,320 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html
new file mode 100644
index 00000000..c27a4c82
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=().html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=().html
new file mode 100644
index 00000000..ec61d8e3
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=False.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=False.html
new file mode 100644
index 00000000..53b5e455
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=None.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=None.html
new file mode 100644
index 00000000..5a87832a
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=None.html
@@ -0,0 +1,289 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=True.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=True.html
new file mode 100644
index 00000000..40ebfa36
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=True.html
@@ -0,0 +1,320 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html
new file mode 100644
index 00000000..9aa9c3c1
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=().html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=().html
new file mode 100644
index 00000000..06640b9d
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=False.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=False.html
new file mode 100644
index 00000000..1f45fb80
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=None.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=None.html
new file mode 100644
index 00000000..cb43eee6
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=None.html
@@ -0,0 +1,477 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=True.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=True.html
new file mode 100644
index 00000000..8357168e
--- /dev/null
+++ b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=True.html
@@ -0,0 +1,508 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html
new file mode 100644
index 00000000..e908da32
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html
@@ -0,0 +1,59 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=().html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=().html
new file mode 100644
index 00000000..d1e4f8bd
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=().html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=False.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=False.html
new file mode 100644
index 00000000..5fbd6650
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=False.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=None.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=None.html
new file mode 100644
index 00000000..d543f794
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=None.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=True.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=True.html
new file mode 100644
index 00000000..795378be
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=True.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html
new file mode 100644
index 00000000..79900273
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=().html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=().html
new file mode 100644
index 00000000..a0685468
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=False.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=False.html
new file mode 100644
index 00000000..bed00768
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=None.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=None.html
new file mode 100644
index 00000000..79a5ff40
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=None.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=True.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=True.html
new file mode 100644
index 00000000..a7eb7dce
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=True.html
@@ -0,0 +1,132 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html
new file mode 100644
index 00000000..8fd78409
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=().html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=().html
new file mode 100644
index 00000000..23e66fd7
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=False.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=False.html
new file mode 100644
index 00000000..27fcc6c1
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=None.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=None.html
new file mode 100644
index 00000000..1a8842f9
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=None.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=True.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=True.html
new file mode 100644
index 00000000..e196b599
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=True.html
@@ -0,0 +1,132 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html
new file mode 100644
index 00000000..eb755e52
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=().html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=().html
new file mode 100644
index 00000000..f827f125
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=False.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=False.html
new file mode 100644
index 00000000..48c42b3d
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=None.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=None.html
new file mode 100644
index 00000000..eddcbb25
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=None.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=True.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=True.html
new file mode 100644
index 00000000..26cb9e39
--- /dev/null
+++ b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=True.html
@@ -0,0 +1,132 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=('method1',),members=('module_attribute',).html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=('module_attribute',).html
new file mode 100644
index 00000000..a6ee2831
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=('method1',),members=().html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=().html
new file mode 100644
index 00000000..3b41766d
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=('method1',),members=False.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=False.html
new file mode 100644
index 00000000..3933bd9d
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=('method1',),members=None.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=None.html
new file mode 100644
index 00000000..d9ae307d
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=None.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=('method1',),members=True.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=True.html
new file mode 100644
index 00000000..a52964c3
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=True.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=(),members=('module_attribute',).html b/tests/snapshots/members/filters=(),inherited_members=(),members=('module_attribute',).html
new file mode 100644
index 00000000..1232ad5e
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=(),members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=(),members=().html b/tests/snapshots/members/filters=(),inherited_members=(),members=().html
new file mode 100644
index 00000000..46cd4aee
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=(),members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=(),members=False.html b/tests/snapshots/members/filters=(),inherited_members=(),members=False.html
new file mode 100644
index 00000000..b6a621d2
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=(),members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=(),members=None.html b/tests/snapshots/members/filters=(),inherited_members=(),members=None.html
new file mode 100644
index 00000000..9058ed13
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=(),members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=(),members=True.html b/tests/snapshots/members/filters=(),inherited_members=(),members=True.html
new file mode 100644
index 00000000..ccfa8d64
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=(),members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=False,members=('module_attribute',).html b/tests/snapshots/members/filters=(),inherited_members=False,members=('module_attribute',).html
new file mode 100644
index 00000000..f2597daf
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=False,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=False,members=().html b/tests/snapshots/members/filters=(),inherited_members=False,members=().html
new file mode 100644
index 00000000..ff8087d4
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=False,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=False,members=False.html b/tests/snapshots/members/filters=(),inherited_members=False,members=False.html
new file mode 100644
index 00000000..eb15c707
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=False,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=False,members=None.html b/tests/snapshots/members/filters=(),inherited_members=False,members=None.html
new file mode 100644
index 00000000..7c90168c
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=False,members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=False,members=True.html b/tests/snapshots/members/filters=(),inherited_members=False,members=True.html
new file mode 100644
index 00000000..d6c51063
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=False,members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=True,members=('module_attribute',).html b/tests/snapshots/members/filters=(),inherited_members=True,members=('module_attribute',).html
new file mode 100644
index 00000000..0ee900fb
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=True,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=True,members=().html b/tests/snapshots/members/filters=(),inherited_members=True,members=().html
new file mode 100644
index 00000000..26f0f5ef
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=True,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=True,members=False.html b/tests/snapshots/members/filters=(),inherited_members=True,members=False.html
new file mode 100644
index 00000000..bbd48b9e
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=True,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=True,members=None.html b/tests/snapshots/members/filters=(),inherited_members=True,members=None.html
new file mode 100644
index 00000000..b2490df7
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=True,members=None.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=(),inherited_members=True,members=True.html b/tests/snapshots/members/filters=(),inherited_members=True,members=True.html
new file mode 100644
index 00000000..7c65c72b
--- /dev/null
+++ b/tests/snapshots/members/filters=(),inherited_members=True,members=True.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=('method1',),members=('module_attribute',).html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=('module_attribute',).html
new file mode 100644
index 00000000..8501bce2
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=('method1',),members=().html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=().html
new file mode 100644
index 00000000..7d734fba
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=('method1',),members=False.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=False.html
new file mode 100644
index 00000000..8c035cc8
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=('method1',),members=None.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=None.html
new file mode 100644
index 00000000..ddce47f6
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=None.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=('method1',),members=True.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=True.html
new file mode 100644
index 00000000..fa970eca
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=True.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=(),members=('module_attribute',).html b/tests/snapshots/members/filters=None,inherited_members=(),members=('module_attribute',).html
new file mode 100644
index 00000000..b194ddc9
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=(),members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=(),members=().html b/tests/snapshots/members/filters=None,inherited_members=(),members=().html
new file mode 100644
index 00000000..4be85a18
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=(),members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=(),members=False.html b/tests/snapshots/members/filters=None,inherited_members=(),members=False.html
new file mode 100644
index 00000000..2bfbdbf4
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=(),members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=(),members=None.html b/tests/snapshots/members/filters=None,inherited_members=(),members=None.html
new file mode 100644
index 00000000..91614cf0
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=(),members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=(),members=True.html b/tests/snapshots/members/filters=None,inherited_members=(),members=True.html
new file mode 100644
index 00000000..2d79edd5
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=(),members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=False,members=('module_attribute',).html b/tests/snapshots/members/filters=None,inherited_members=False,members=('module_attribute',).html
new file mode 100644
index 00000000..96cff9d7
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=False,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=False,members=().html b/tests/snapshots/members/filters=None,inherited_members=False,members=().html
new file mode 100644
index 00000000..0ed1d57b
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=False,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=False,members=False.html b/tests/snapshots/members/filters=None,inherited_members=False,members=False.html
new file mode 100644
index 00000000..ce4ee8a7
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=False,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=False,members=None.html b/tests/snapshots/members/filters=None,inherited_members=False,members=None.html
new file mode 100644
index 00000000..332a5c53
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=False,members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=False,members=True.html b/tests/snapshots/members/filters=None,inherited_members=False,members=True.html
new file mode 100644
index 00000000..cce2be49
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=False,members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=True,members=('module_attribute',).html b/tests/snapshots/members/filters=None,inherited_members=True,members=('module_attribute',).html
new file mode 100644
index 00000000..aa4ebf15
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=True,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=True,members=().html b/tests/snapshots/members/filters=None,inherited_members=True,members=().html
new file mode 100644
index 00000000..898bab70
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=True,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=True,members=False.html b/tests/snapshots/members/filters=None,inherited_members=True,members=False.html
new file mode 100644
index 00000000..8b4491f3
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=True,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=True,members=None.html b/tests/snapshots/members/filters=None,inherited_members=True,members=None.html
new file mode 100644
index 00000000..68c7d720
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=True,members=None.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=None,inherited_members=True,members=True.html b/tests/snapshots/members/filters=None,inherited_members=True,members=True.html
new file mode 100644
index 00000000..e9f375b2
--- /dev/null
+++ b/tests/snapshots/members/filters=None,inherited_members=True,members=True.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=('method1',),members=('module_attribute',).html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=('module_attribute',).html
new file mode 100644
index 00000000..befa0078
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=('module_attribute',).html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=('method1',),members=().html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=().html
new file mode 100644
index 00000000..f7385cf9
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=().html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=('method1',),members=False.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=False.html
new file mode 100644
index 00000000..e649c2e7
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=False.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=('method1',),members=None.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=None.html
new file mode 100644
index 00000000..5ca6f9fe
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=None.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=('method1',),members=True.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=True.html
new file mode 100644
index 00000000..a191cb33
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=True.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=(),members=('module_attribute',).html b/tests/snapshots/members/filters=public,inherited_members=(),members=('module_attribute',).html
new file mode 100644
index 00000000..c8211de8
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=(),members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=(),members=().html b/tests/snapshots/members/filters=public,inherited_members=(),members=().html
new file mode 100644
index 00000000..ac0222f5
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=(),members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=(),members=False.html b/tests/snapshots/members/filters=public,inherited_members=(),members=False.html
new file mode 100644
index 00000000..6f76b142
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=(),members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=(),members=None.html b/tests/snapshots/members/filters=public,inherited_members=(),members=None.html
new file mode 100644
index 00000000..5540be65
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=(),members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=(),members=True.html b/tests/snapshots/members/filters=public,inherited_members=(),members=True.html
new file mode 100644
index 00000000..7d596388
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=(),members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=False,members=('module_attribute',).html b/tests/snapshots/members/filters=public,inherited_members=False,members=('module_attribute',).html
new file mode 100644
index 00000000..e40923d9
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=False,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=False,members=().html b/tests/snapshots/members/filters=public,inherited_members=False,members=().html
new file mode 100644
index 00000000..e8d65a7e
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=False,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=False,members=False.html b/tests/snapshots/members/filters=public,inherited_members=False,members=False.html
new file mode 100644
index 00000000..12da79f0
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=False,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=False,members=None.html b/tests/snapshots/members/filters=public,inherited_members=False,members=None.html
new file mode 100644
index 00000000..39cf1b20
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=False,members=None.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=False,members=True.html b/tests/snapshots/members/filters=public,inherited_members=False,members=True.html
new file mode 100644
index 00000000..1973e99b
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=False,members=True.html
@@ -0,0 +1,318 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=True,members=('module_attribute',).html b/tests/snapshots/members/filters=public,inherited_members=True,members=('module_attribute',).html
new file mode 100644
index 00000000..7b0e60a5
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=True,members=('module_attribute',).html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=True,members=().html b/tests/snapshots/members/filters=public,inherited_members=True,members=().html
new file mode 100644
index 00000000..e8f0258e
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=True,members=().html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=True,members=False.html b/tests/snapshots/members/filters=public,inherited_members=True,members=False.html
new file mode 100644
index 00000000..85cb268c
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=True,members=False.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=True,members=None.html b/tests/snapshots/members/filters=public,inherited_members=True,members=None.html
new file mode 100644
index 00000000..40c14a7b
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=True,members=None.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/members/filters=public,inherited_members=True,members=True.html b/tests/snapshots/members/filters=public,inherited_members=True,members=True.html
new file mode 100644
index 00000000..13b2239c
--- /dev/null
+++ b/tests/snapshots/members/filters=public,inherited_members=True,members=True.html
@@ -0,0 +1,506 @@
+
+
+
+
+
+ members_package
+
+
+
+
+ Docstring for the package.
+
+
+
+
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+ Subclass
+
+
+
+
+ Bases:
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+
+
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+
+
+
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+
+
+
+
+
+ NestedClass
+
+
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=False.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=False.html
new file mode 100644
index 00000000..76234631
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=False.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=True.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=True.html
new file mode 100644
index 00000000..afa94fae
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=True.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=False.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=False.html
new file mode 100644
index 00000000..96629ba3
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=False.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=True.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=True.html
new file mode 100644
index 00000000..3f231581
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=True.html
@@ -0,0 +1,137 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=False.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=False.html
new file mode 100644
index 00000000..23a1a9c5
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=False.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=True.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=True.html
new file mode 100644
index 00000000..79b078af
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=True.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+
+ bar
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+
+ foo
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=False.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=False.html
new file mode 100644
index 00000000..1f1c5822
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=False.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+ foo(a, b)
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=True.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=True.html
new file mode 100644
index 00000000..7d4b3416
--- /dev/null
+++ b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=True.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+ overloads_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ Class.bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ Class.foo
+
+ .
+
+
+
+
+
+
+
+
+
+ bar
+
+
+
+ bar(a, b)
+
+
+
+
+ Docstring for
+
+ bar
+
+ .
+
+
+
+
+
+
+ foo
+
+
+
+
+ foo(a: int, b: str) -> float
+
+
+
+ foo(a: str, b: int) -> None
+
+
+
+
+
+ Docstring for
+
+ foo
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html
new file mode 100644
index 00000000..599197fe
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html
@@ -0,0 +1,136 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html
new file mode 100644
index 00000000..70567c97
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html
@@ -0,0 +1,136 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html
new file mode 100644
index 00000000..65e87e01
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html
new file mode 100644
index 00000000..44516fe5
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ :
+
+
+ int
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ str
+
+
+ )
+
+
+ ->
+
+
+ None
+
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html
new file mode 100644
index 00000000..03d9e14d
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ __init__
+
+
+
+ __init__(a, b)
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+ method1
+
+
+
+ method1(a, b)
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+
+ module_function(a, b)
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html
new file mode 100644
index 00000000..8454da6d
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ __init__
+
+
+
+ __init__(a, b)
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+ method1
+
+
+
+ method1(a, b)
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+
+ module_function(a, b)
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html
new file mode 100644
index 00000000..9edcf4c5
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ __init__
+
+
+
+ __init__(a: int, b: str) -> None
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+ method1
+
+
+
+ method1(a: int, b: str) -> None
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+
+ module_function(a: int, b: str) -> None
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html
new file mode 100644
index 00000000..e9ac18ce
--- /dev/null
+++ b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html
@@ -0,0 +1,97 @@
+
+
+
+
+
+ signature_package
+
+
+
+
+
+
+
+ Class
+
+
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+
+
+
+ __init__
+
+
+
+ __init__(a: int , b: str ) -> None
+
+
+
+
+ Docstring for `Class.
+
+ init
+
+ .
+
+
+
+
+
+
+ method1
+
+
+
+ method1(a: int , b: str ) -> None
+
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+
+
+
+
+
+
+
+ module_function
+
+
+
+ module_function(a: int , b: str ) -> None
+
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+
+
+
+
+
diff --git a/tests/test_api.py b/tests/test_api.py
new file mode 100644
index 00000000..3322e2e6
--- /dev/null
+++ b/tests/test_api.py
@@ -0,0 +1,188 @@
+"""Tests for our own API exposition."""
+
+from __future__ import annotations
+
+from collections import defaultdict
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+import griffe
+import pytest
+from mkdocstrings import Inventory
+
+from mkdocstrings_handlers import python
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+
+@pytest.fixture(name="loader", scope="module")
+def _fixture_loader() -> griffe.GriffeLoader:
+ loader = griffe.GriffeLoader()
+ loader.load("mkdocstrings")
+ loader.load("mkdocstrings_handlers.python")
+ loader.resolve_aliases()
+ return loader
+
+
+@pytest.fixture(name="internal_api", scope="module")
+def _fixture_internal_api(loader: griffe.GriffeLoader) -> griffe.Module:
+ return loader.modules_collection["mkdocstrings_handlers.python._internal"]
+
+
+@pytest.fixture(name="public_api", scope="module")
+def _fixture_public_api(loader: griffe.GriffeLoader) -> griffe.Module:
+ return loader.modules_collection["mkdocstrings_handlers.python"]
+
+
+def _yield_public_objects(
+ obj: griffe.Module | griffe.Class,
+ *,
+ modules: bool = False,
+ modulelevel: bool = True,
+ inherited: bool = False,
+ special: bool = False,
+) -> Iterator[griffe.Object | griffe.Alias]:
+ for member in obj.all_members.values() if inherited else obj.members.values():
+ try:
+ if member.is_module:
+ if member.is_alias or not member.is_public:
+ continue
+ if modules:
+ yield member
+ yield from _yield_public_objects(
+ member, # type: ignore[arg-type]
+ modules=modules,
+ modulelevel=modulelevel,
+ inherited=inherited,
+ special=special,
+ )
+ elif member.is_public and (special or not member.is_special):
+ yield member
+ else:
+ continue
+ if member.is_class and not modulelevel:
+ yield from _yield_public_objects(
+ member, # type: ignore[arg-type]
+ modules=modules,
+ modulelevel=False,
+ inherited=inherited,
+ special=special,
+ )
+ except (griffe.AliasResolutionError, griffe.CyclicAliasError):
+ continue
+
+
+@pytest.fixture(name="modulelevel_internal_objects", scope="module")
+def _fixture_modulelevel_internal_objects(internal_api: griffe.Module) -> list[griffe.Object | griffe.Alias]:
+ return list(_yield_public_objects(internal_api, modulelevel=True))
+
+
+@pytest.fixture(name="internal_objects", scope="module")
+def _fixture_internal_objects(internal_api: griffe.Module) -> list[griffe.Object | griffe.Alias]:
+ return list(_yield_public_objects(internal_api, modulelevel=False, special=True))
+
+
+@pytest.fixture(name="public_objects", scope="module")
+def _fixture_public_objects(public_api: griffe.Module) -> list[griffe.Object | griffe.Alias]:
+ return list(_yield_public_objects(public_api, modulelevel=False, inherited=True, special=True))
+
+
+@pytest.fixture(name="inventory", scope="module")
+def _fixture_inventory() -> Inventory:
+ inventory_file = Path(__file__).parent.parent / "site" / "objects.inv"
+ if not inventory_file.exists():
+ pytest.skip("The objects inventory is not available.") # ty: ignore[call-non-callable]
+ with inventory_file.open("rb") as file:
+ return Inventory.parse_sphinx(file)
+
+
+def test_exposed_objects(modulelevel_internal_objects: list[griffe.Object | griffe.Alias]) -> None:
+ """All public objects in the internal API are exposed under `mkdocstrings_handlers.python`."""
+ not_exposed = [
+ obj.path
+ for obj in modulelevel_internal_objects
+ if obj.name not in python.__all__ or not hasattr(python, obj.name)
+ ]
+ assert not not_exposed, "Objects not exposed:\n" + "\n".join(sorted(not_exposed))
+
+
+def test_unique_names(modulelevel_internal_objects: list[griffe.Object | griffe.Alias]) -> None:
+ """All internal objects have unique names."""
+ names_to_paths = defaultdict(list)
+ for obj in modulelevel_internal_objects:
+ names_to_paths[obj.name].append(obj.path)
+ non_unique = [paths for paths in names_to_paths.values() if len(paths) > 1]
+ assert not non_unique, "Non-unique names:\n" + "\n".join(str(paths) for paths in non_unique)
+
+
+def test_single_locations(public_api: griffe.Module) -> None:
+ """All objects have a single public location."""
+
+ def _public_path(obj: griffe.Object | griffe.Alias) -> bool:
+ return obj.is_public and (obj.parent is None or _public_path(obj.parent))
+
+ multiple_locations = {}
+ for obj_name in python.__all__:
+ obj = public_api[obj_name]
+ if obj.aliases and (
+ public_aliases := [path for path, alias in obj.aliases.items() if path != obj.path and _public_path(alias)]
+ ):
+ multiple_locations[obj.path] = public_aliases
+ assert not multiple_locations, "Multiple public locations:\n" + "\n".join(
+ f"{path}: {aliases}" for path, aliases in multiple_locations.items()
+ )
+
+
+def test_api_matches_inventory(inventory: Inventory, public_objects: list[griffe.Object | griffe.Alias]) -> None:
+ """All public objects are added to the inventory."""
+ ignore_names = {"__getattr__", "__init__", "__repr__", "__str__", "__post_init__"}
+ not_in_inventory = [
+ f"{obj.relative_filepath}:{obj.lineno}: {obj.path}"
+ for obj in public_objects
+ if obj.name not in ignore_names and obj.path not in inventory
+ ]
+ msg = "Objects not in the inventory (try running `make run mkdocs build`):\n{paths}"
+ assert not not_in_inventory, msg.format(paths="\n".join(sorted(not_in_inventory)))
+
+
+def _module_or_child(parent: str, name: str) -> bool:
+ parents = [parent[:i] for i, char in enumerate(parent) if char == "."]
+ parents.append(parent)
+ return name in parents or name.startswith(parent + ".")
+
+
+def test_inventory_matches_api(
+ inventory: Inventory,
+ public_objects: list[griffe.Object | griffe.Alias],
+ loader: griffe.GriffeLoader,
+) -> None:
+ """The inventory doesn't contain any additional Python object."""
+ not_in_api = []
+ public_api_paths = {obj.path for obj in public_objects}
+ public_api_paths.add("mkdocstrings_handlers")
+ public_api_paths.add("mkdocstrings_handlers.python")
+
+ for item in inventory.values():
+ if item.domain == "py" and "(" not in item.name and _module_or_child("mkdocstrings_handlers.python", item.name):
+ obj = loader.modules_collection[item.name]
+ if obj.path not in public_api_paths and not any(path in public_api_paths for path in obj.aliases):
+ not_in_api.append(item.name)
+ msg = "Inventory objects not in public API (try running `make run mkdocs build`):\n{paths}"
+ assert not not_in_api, msg.format(paths="\n".join(sorted(not_in_api)))
+
+
+def test_no_module_docstrings_in_internal_api(internal_api: griffe.Module) -> None:
+ """No module docstrings should be written in our internal API.
+
+ The reasoning is that docstrings are addressed to users of the public API,
+ but internal modules are not exposed to users, so they should not have docstrings.
+ """
+
+ def _modules(obj: griffe.Module) -> Iterator[griffe.Module]:
+ for member in obj.modules.values():
+ yield member
+ yield from _modules(member)
+
+ for obj in _modules(internal_api):
+ assert not obj.docstring
diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py
new file mode 100644
index 00000000..3363ebd6
--- /dev/null
+++ b/tests/test_end_to_end.py
@@ -0,0 +1,283 @@
+"""End-to-end tests for every combination of options."""
+
+from __future__ import annotations
+
+import json
+import re
+from typing import TYPE_CHECKING, Any
+
+import bs4
+import pytest
+from griffe import LinesCollection, ModulesCollection, TmpPackage, temporary_pypackage
+from inline_snapshot import external_file, register_format_alias
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+ from mkdocstrings_handlers.python import PythonHandler
+
+
+register_format_alias(".html", ".txt")
+
+
+def _normalize_html(html: str) -> str:
+ soup = bs4.BeautifulSoup(html, features="html.parser")
+ html = soup.prettify()
+ html = re.sub(r"\b(0x)[a-f0-9]+\b", r"\1...", html)
+ html = re.sub(r"^(Build Date UTC ?:).+", r"\1...", html, flags=re.MULTILINE)
+ html = re.sub(r"\b[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\b", r"...", html)
+ html = re.sub(r'(?<=id="cell-id=)\w+(?=")', r"...", html)
+ return html # noqa: RET504
+
+
+def _render(handler: PythonHandler, package: TmpPackage, final_options: dict[str, Any]) -> str:
+ final_options.pop("handler", None)
+ final_options.pop("session_handler", None)
+ handler_options = final_options.copy()
+
+ # Some default options to make snapshots easier to review.
+ handler_options.setdefault("heading_level", 1)
+ handler_options.setdefault("show_root_heading", True)
+ handler_options.setdefault("show_source", False)
+
+ options = handler.get_options(handler_options)
+
+ handler._paths = [str(package.tmpdir)]
+ try:
+ data = handler.collect(package.name, options)
+ finally:
+ # We're using a session handler, so we need to reset its state after each call.
+ # This is not thread-safe, but pytest-xdist uses subprocesses, so it's fine.
+ handler._modules_collection = ModulesCollection()
+ handler._lines_collection = LinesCollection()
+ handler._paths = []
+
+ html = handler.render(data, options)
+ return _normalize_html(html)
+
+
+def _render_options(options: dict[str, Any]) -> str:
+ return f"\n\n"
+
+
+def _snapshot_file(group: str, options: dict[str, Any]) -> str:
+ return f"snapshots/{group}/" + ",".join(f"{k}={v}" for k, v in sorted(options.items())) + ".html"
+
+
+# Signature tests.
+@pytest.fixture(name="signature_package", scope="session")
+def _signature_package() -> Iterator[TmpPackage]:
+ code = """
+ def module_function(a: int, b: str) -> None:
+ '''Docstring for `module_function`.'''
+
+ def _private_function(a: int, b: str) -> None:
+ '''Docstring for `_private_function`.'''
+
+ class Class:
+ '''Docstring for `Class`.'''
+
+ def __init__(self, a: int, b: str) -> None:
+ '''Docstring for `Class.__init__.'''
+
+ def method1(self, a: int, b: str) -> None:
+ '''Docstring for `Class.method1`.'''
+ """
+ with temporary_pypackage("signature_package", {"__init__.py": code}) as tmppkg:
+ yield tmppkg
+
+
+@pytest.mark.parametrize("show_signature_annotations", [True, False])
+@pytest.mark.parametrize("signature_crossrefs", [True, False])
+@pytest.mark.parametrize("separate_signature", [True, False])
+def test_end_to_end_for_signatures(
+ session_handler: PythonHandler,
+ signature_package: TmpPackage,
+ show_signature_annotations: bool,
+ signature_crossrefs: bool,
+ separate_signature: bool,
+) -> None:
+ """Test rendering of a given theme's templates.
+
+ Parameters:
+ identifier: Parametrized identifier.
+ session_handler: Python handler (fixture).
+ """
+ options = {
+ "show_signature_annotations": show_signature_annotations,
+ "signature_crossrefs": signature_crossrefs,
+ "separate_signature": separate_signature,
+ }
+ html = _render_options(options) + _render(session_handler, signature_package, options)
+ assert html == external_file(_snapshot_file("signatures", options), format=".txt")
+
+
+# Signature overloads tests.
+@pytest.fixture(name="overloads_package", scope="session")
+def _overloads_package() -> Iterator[TmpPackage]:
+ code = """
+ from typing_extensions import overload
+
+ @overload
+ def foo(a: int, b: str) -> float: ...
+
+ @overload
+ def foo(a: str, b: int) -> None: ...
+
+ def foo(a: str | int, b: int | str) -> float | None:
+ '''Docstring for `foo`.'''
+
+ def bar(a: str, b: int | str) -> float | None:
+ '''Docstring for `bar`.'''
+
+ class Class:
+ '''Docstring for `Class`.'''
+
+ @overload
+ def foo(self, a: int, b: str) -> float: ...
+
+ @overload
+ def foo(self, a: str, b: int) -> None: ...
+
+ def foo(self, a: str | int, b: int | str) -> float | None:
+ '''Docstring for `Class.foo`.'''
+
+ def bar(self, a: str, b: int | str) -> float | None:
+ '''Docstring for `Class.bar`.'''
+ """
+ with temporary_pypackage("overloads_package", {"__init__.py": code}) as tmppkg:
+ yield tmppkg
+
+
+@pytest.mark.parametrize("separate_signature", [True, False])
+@pytest.mark.parametrize("show_overloads", [True, False])
+@pytest.mark.parametrize("overloads_only", [True, False])
+def test_end_to_end_for_overloads(
+ session_handler: PythonHandler,
+ overloads_package: TmpPackage,
+ separate_signature: bool,
+ show_overloads: bool,
+ overloads_only: bool,
+) -> None:
+ """Test rendering of a given theme's templates.
+
+ Parameters:
+ identifier: Parametrized identifier.
+ session_handler: Python handler (fixture).
+ """
+ options = {
+ "separate_signature": separate_signature,
+ "show_overloads": show_overloads,
+ "overloads_only": overloads_only,
+ }
+ html = _render_options(options) + _render(session_handler, overloads_package, options)
+ assert html == external_file(_snapshot_file("overloads", options), format=".txt")
+
+
+# Member tests.
+@pytest.fixture(name="members_package", scope="session")
+def _members_package() -> Iterator[TmpPackage]:
+ code = """
+ '''Docstring for the package.'''
+
+ def module_function(a: int, b: str) -> None:
+ '''Docstring for `module_function`.'''
+
+ class Class:
+ '''Docstring for `Class`.'''
+
+ class NestedClass:
+ '''Docstring for `NestedClass`.'''
+
+ class_attribute: int = 42
+ '''Docstring for `Class.class_attribute`.'''
+
+ def __init__(self, a: int, b: str) -> None:
+ '''Docstring for `Class.__init__`.'''
+ self.instance_attribute = a + b
+ '''Docstring for `Class.instance_attribute`.'''
+
+ def method1(self, a: int, b: str) -> None:
+ '''Docstring for `Class.method1`.'''
+
+ def method2(self, a: int, b: str) -> None:
+ '''Docstring for `Class.method2`.'''
+
+ module_attribute: int = 42
+ '''Docstring for `module_attribute`.'''
+
+ class Subclass(Class):
+ '''Docstring for `Subclass`.'''
+ """
+ with temporary_pypackage("members_package", {"__init__.py": code}) as tmppkg:
+ yield tmppkg
+
+
+@pytest.mark.parametrize("inherited_members", [(), ("method1",), True, False])
+@pytest.mark.parametrize("members", [(), ("module_attribute",), True, False, None])
+@pytest.mark.parametrize("filters", [(), ("!module_attribute",), ("module_attribute",), "public", None])
+def test_end_to_end_for_members(
+ session_handler: PythonHandler,
+ members_package: TmpPackage,
+ inherited_members: list[str] | bool | None,
+ members: list[str] | bool | None,
+ filters: list[str] | None,
+) -> None:
+ """Test rendering of a given theme's templates.
+
+ Parameters:
+ identifier: Parametrized identifier.
+ session_handler: Python handler (fixture).
+ """
+ options = {
+ "inherited_members": inherited_members,
+ "members": members,
+ "filters": filters,
+ }
+ html = _render_options(options) + _render(session_handler, members_package, options)
+ assert html == external_file(_snapshot_file("members", options), format=".txt")
+
+
+# Heading tests.
+@pytest.fixture(name="headings_package", scope="session")
+def _headings_package() -> Iterator[TmpPackage]:
+ code = """
+ def module_function(a: int, b: str) -> None:
+ pass
+
+ class Class:
+ class_attribute: int = 42
+
+ def __init__(self, a: int, b: str) -> None:
+ self.instance_attribute = a + b
+
+ def method1(self, a: int, b: str) -> None:
+ pass
+
+ module_attribute: int = 42
+ """
+ with temporary_pypackage("headings_package", {"__init__.py": code}) as tmppkg:
+ yield tmppkg
+
+
+@pytest.mark.parametrize("separate_signature", [True, False])
+@pytest.mark.parametrize("heading", ["", "Some heading"])
+def test_end_to_end_for_headings(
+ session_handler: PythonHandler,
+ headings_package: TmpPackage,
+ separate_signature: bool,
+ heading: str,
+) -> None:
+ """Test rendering of a given theme's templates.
+
+ Parameters:
+ identifier: Parametrized identifier.
+ session_handler: Python handler (fixture).
+ """
+ options = {
+ "separate_signature": separate_signature,
+ "heading": heading,
+ }
+ extra = {"show_if_no_docstring": True, "members": False}
+ html = _render_options(options) + _render(session_handler, headings_package, {**options, **extra})
+ assert html == external_file(_snapshot_file("headings", options), format=".txt")
diff --git a/tests/test_handler.py b/tests/test_handler.py
index 0717dc48..1cccd6c6 100644
--- a/tests/test_handler.py
+++ b/tests/test_handler.py
@@ -3,43 +3,52 @@
from __future__ import annotations
import os
+import sys
+from dataclasses import replace
from glob import glob
+from io import BytesIO
+from pathlib import Path
from textwrap import dedent
from typing import TYPE_CHECKING
+import mkdocstrings
import pytest
-from griffe import DocstringSectionExamples, DocstringSectionKind, temporary_visited_module
+from griffe import (
+ Docstring,
+ DocstringSectionExamples,
+ DocstringSectionKind,
+ Module,
+ temporary_inspected_module,
+ temporary_visited_module,
+)
+from mkdocstrings import CollectionError
-from mkdocstrings_handlers.python.handler import CollectionError, PythonHandler, get_handler
+from mkdocstrings_handlers.python import Inventory, PythonConfig, PythonHandler, PythonOptions
if TYPE_CHECKING:
- from pathlib import Path
+ from mkdocstrings import MkdocstringsPlugin
-def test_collect_missing_module() -> None:
+def test_collect_missing_module(handler: PythonHandler) -> None:
"""Assert error is raised for missing modules."""
- handler = get_handler(theme="material")
with pytest.raises(CollectionError):
- handler.collect("aaaaaaaa", {})
+ handler.collect("aaaaaaaa", PythonOptions())
-def test_collect_missing_module_item() -> None:
+def test_collect_missing_module_item(handler: PythonHandler) -> None:
"""Assert error is raised for missing items within existing modules."""
- handler = get_handler(theme="material")
with pytest.raises(CollectionError):
- handler.collect("mkdocstrings.aaaaaaaa", {})
+ handler.collect("mkdocstrings.aaaaaaaa", PythonOptions())
-def test_collect_module() -> None:
+def test_collect_module(handler: PythonHandler) -> None:
"""Assert existing module can be collected."""
- handler = get_handler(theme="material")
- assert handler.collect("mkdocstrings", {})
+ assert handler.collect("mkdocstrings", PythonOptions())
-def test_collect_with_null_parser() -> None:
+def test_collect_with_null_parser(handler: PythonHandler) -> None:
"""Assert we can pass `None` as parser when collecting."""
- handler = get_handler(theme="material")
- assert handler.collect("mkdocstrings", {"docstring_style": None})
+ assert handler.collect("mkdocstrings", PythonOptions(docstring_style=None))
@pytest.mark.parametrize(
@@ -71,7 +80,7 @@ def test_render_docstring_examples_section(handler: PythonHandler) -> None:
assert "Hello" in rendered
-def test_expand_globs(tmp_path: Path) -> None:
+def test_expand_globs(tmp_path: Path, plugin: MkdocstringsPlugin) -> None:
"""Assert globs are correctly expanded.
Parameters:
@@ -86,24 +95,16 @@ def test_expand_globs(tmp_path: Path) -> None:
globbed_paths = [tmp_path.joinpath(globbed_name) for globbed_name in globbed_names]
for path in globbed_paths:
path.touch()
- handler = PythonHandler(
- handler="python",
- theme="material",
- config_file_path=str(tmp_path.joinpath("mkdocs.yml")),
- paths=["*exp*"],
- )
+ plugin.handlers._tool_config.config_file_path = str(tmp_path.joinpath("mkdocs.yml"))
+ handler: PythonHandler = plugin.handlers.get_handler("python", {"paths": ["*exp*"]}) # type: ignore[assignment]
for path in globbed_paths:
assert str(path) in handler._paths
-def test_expand_globs_without_changing_directory() -> None:
+def test_expand_globs_without_changing_directory(plugin: MkdocstringsPlugin) -> None:
"""Assert globs are correctly expanded when we are already in the right directory."""
- handler = PythonHandler(
- handler="python",
- theme="material",
- config_file_path="mkdocs.yml",
- paths=["*.md"],
- )
+ plugin.handlers._tool_config.config_file_path = "mkdocs.yml"
+ handler: PythonHandler = plugin.handlers.get_handler("python", {"paths": ["*.md"]}) # type: ignore[assignment]
for path in list(glob(os.path.abspath(".") + "/*.md")):
assert path in handler._paths
@@ -119,22 +120,26 @@ def test_expand_globs_without_changing_directory() -> None:
(True, {"extension.py:SomeExtension": {"option": "value"}}),
(True, {"path/to/extension.py": {"option": "value"}}),
(True, {"path/to/extension.py:SomeExtension": {"option": "value"}}),
- (False, "/absolute/path/to/extension.py"),
- (False, "/absolute/path/to/extension.py:SomeExtension"),
- (False, {"/absolute/path/to/extension.py": {"option": "value"}}),
- (False, {"/absolute/path/to/extension.py:SomeExtension": {"option": "value"}}),
+ # True because OS path normalization.
+ (True, "/absolute/path/to/extension.py"),
+ (True, "/absolute/path/to/extension.py:SomeExtension"),
+ (True, {"/absolute/path/to/extension.py": {"option": "value"}}),
+ (True, {"/absolute/path/to/extension.py:SomeExtension": {"option": "value"}}),
(False, "dot.notation.path.to.extension"),
(False, "dot.notation.path.to.pyextension"),
(False, {"dot.notation.path.to.extension": {"option": "value"}}),
(False, {"dot.notation.path.to.pyextension": {"option": "value"}}),
],
)
-def test_extension_paths(tmp_path: Path, expect_change: bool, extension: str | dict) -> None:
+def test_extension_paths(
+ tmp_path: Path,
+ expect_change: bool,
+ extension: str | dict,
+ plugin: MkdocstringsPlugin,
+) -> None:
"""Assert extension paths are resolved relative to config file."""
- handler = get_handler(
- theme="material",
- config_file_path=str(tmp_path.joinpath("mkdocs.yml")),
- )
+ plugin.handlers._tool_config.config_file_path = str(tmp_path.joinpath("mkdocs.yml"))
+ handler: PythonHandler = plugin.handlers.get_handler("python") # type: ignore[assignment]
normalized = handler.normalize_extension_paths([extension])[0]
if expect_change:
if isinstance(normalized, str) and isinstance(extension, str):
@@ -165,10 +170,166 @@ def function(self):
""",
)
with temporary_visited_module(code) as module:
- # TODO: Remove once Griffe does that automatically.
- module.lines_collection[module.filepath] = code.splitlines() # type: ignore[index]
-
module["Class"].lineno = None
module["Class.function"].lineno = None
module["attribute"].lineno = None
- assert handler.render(module, {"show_source": True})
+ assert handler.render(module, PythonOptions(show_source=True))
+
+
+def test_give_precedence_to_user_paths() -> None:
+ """Assert user paths take precedence over default paths."""
+ last_sys_path = sys.path[-1]
+ handler = PythonHandler(
+ theme="material",
+ custom_templates=None,
+ base_dir=Path("."),
+ config=PythonConfig.from_data(paths=[last_sys_path]),
+ mdx=[],
+ mdx_config={},
+ )
+ assert handler._paths[0] == last_sys_path
+
+
+@pytest.mark.parametrize(
+ ("section", "code"),
+ [
+ (
+ "Attributes",
+ """
+ class A:
+ '''Summary.
+
+ Attributes:
+ x: X.
+ y: Y.
+ '''
+ x: int = 0
+ '''X.'''
+ y: int = 0
+ '''Y.'''
+ """,
+ ),
+ (
+ "Methods",
+ """
+ class A:
+ '''Summary.
+
+ Methods:
+ x: X.
+ y: Y.
+ '''
+ def x(self): ...
+ '''X.'''
+ def y(self): ...
+ '''Y.'''
+ """,
+ ),
+ (
+ "Functions",
+ """
+ '''Summary.
+
+ Functions:
+ x: X.
+ y: Y.
+ '''
+ def x(): ...
+ '''X.'''
+ def y(): ...
+ '''Y.'''
+ """,
+ ),
+ (
+ "Classes",
+ """
+ '''Summary.
+
+ Classes:
+ A: A.
+ B: B.
+ '''
+ class A: ...
+ '''A.'''
+ class B: ...
+ '''B.'''
+ """,
+ ),
+ (
+ "Modules",
+ """
+ '''Summary.
+
+ Modules:
+ a: A.
+ b: B.
+ '''
+ """,
+ ),
+ ],
+)
+def test_deduplicate_summary_sections(handler: PythonHandler, section: str, code: str) -> None:
+ """Assert summary sections are deduplicated."""
+ summary_section = section.lower()
+ summary_section = "functions" if summary_section == "methods" else summary_section
+ with temporary_visited_module(code, docstring_parser="google") as module:
+ if summary_section == "modules":
+ module.set_member("a", Module("A", docstring=Docstring("A.")))
+ module.set_member("b", Module("B", docstring=Docstring("B.")))
+ html = handler.render(
+ module,
+ handler.get_options(
+ {
+ "summary": {summary_section: True},
+ "show_source": False,
+ "show_submodules": True,
+ },
+ ),
+ )
+ assert html.count(f"{section}:") == 1
+
+
+def test_inheriting_self_from_parent_class(handler: PythonHandler) -> None:
+ """Inspect self only once when inheriting it from parent class."""
+ with temporary_inspected_module(
+ """
+ class A: ...
+ class B(A): ...
+ A.B = B
+ """,
+ ) as module:
+ # Assert no recusrion error.
+ handler.render(
+ module,
+ handler.get_options({"inherited_members": True}),
+ )
+
+
+def test_specifying_inventory_base_url(handler: PythonHandler) -> None:
+ """Assert that the handler renders inventory URLs using the specified base_url."""
+ # Update handler config to include an inventory with a base URL
+ base_url = "https://docs.com/my_library"
+ inventory = Inventory(url="https://example.com/objects.inv", base_url=base_url)
+ handler.config = replace(handler.config, inventories=[inventory])
+
+ # Mock inventory bytes
+ item_name = "my_library.my_module.MyClass"
+ mocked_inventory = mkdocstrings.Inventory()
+ mocked_inventory.register(
+ name=item_name,
+ domain="py",
+ role="class",
+ uri=f"api-reference/#{item_name}",
+ dispname=item_name,
+ )
+ mocked_bytes = BytesIO(mocked_inventory.format_sphinx())
+
+ # Get inventory URL and config
+ url, config = handler.get_inventory_urls()[0]
+
+ # Load the mocked inventory
+ _, item_url = next(handler.load_inventory(mocked_bytes, url, **config))
+
+ # Assert the URL is based on the provided base URL
+ msg = "Expected inventory URL to start with base_url"
+ assert item_url.startswith(base_url), msg
diff --git a/tests/test_rendering.py b/tests/test_rendering.py
index 1bab29d7..2616610f 100644
--- a/tests/test_rendering.py
+++ b/tests/test_rendering.py
@@ -4,12 +4,12 @@
import re
from dataclasses import dataclass
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, Callable
import pytest
from griffe import ModulesCollection, temporary_visited_module
-from mkdocstrings_handlers.python import rendering
+from mkdocstrings_handlers.python._internal import rendering
if TYPE_CHECKING:
from markupsafe import Markup
@@ -22,14 +22,22 @@
"aaaaa(bbbbb, ccccc=1) + ddddd.eeeee[ffff] or {ggggg: hhhhh, iiiii: jjjjj}",
],
)
-def test_format_code(code: str) -> None:
- """Assert code can be Black-formatted.
+@pytest.mark.parametrize(
+ "formatter",
+ [
+ rendering._get_black_formatter(),
+ rendering._get_ruff_formatter(),
+ rendering._get_formatter(),
+ ],
+)
+def test_format_code(code: str, formatter: Callable[[str, int], str]) -> None:
+ """Assert code can be formatted.
Parameters:
code: Code to format.
"""
for length in (5, 100):
- assert rendering.do_format_code(code, length)
+ assert formatter(code, length)
@pytest.mark.parametrize(
@@ -37,7 +45,7 @@ def test_format_code(code: str) -> None:
[("Class.method", "(param: str = 'hello') -> 'OtherClass'")],
)
def test_format_signature(name: Markup, signature: str) -> None:
- """Assert signatures can be Black-formatted.
+ """Assert signatures can be formatted.
Parameters:
signature: Signature to format.
@@ -50,6 +58,8 @@ def test_format_signature(name: Markup, signature: str) -> None:
class _FakeObject:
name: str
inherited: bool = False
+ parent: None = None
+ is_alias: bool = False
@pytest.mark.parametrize(
@@ -135,14 +145,14 @@ def main(self): ...
@pytest.mark.parametrize(
("order", "members_list", "expected_names"),
[
- (rendering.Order.alphabetical, None, ["a", "b", "c"]),
- (rendering.Order.source, None, ["c", "b", "a"]),
- (rendering.Order.alphabetical, ["c", "b"], ["c", "b"]),
- (rendering.Order.source, ["a", "c"], ["a", "c"]),
- (rendering.Order.alphabetical, [], ["a", "b", "c"]),
- (rendering.Order.source, [], ["c", "b", "a"]),
- (rendering.Order.alphabetical, True, ["a", "b", "c"]),
- (rendering.Order.source, False, ["c", "b", "a"]),
+ ("alphabetical", None, ["a", "b", "c"]),
+ ("source", None, ["c", "b", "a"]),
+ ("alphabetical", ["c", "b"], ["c", "b"]),
+ ("source", ["a", "c"], ["a", "c"]),
+ ("alphabetical", [], ["a", "b", "c"]),
+ ("source", [], ["c", "b", "a"]),
+ ("alphabetical", True, ["a", "b", "c"]),
+ ("source", False, ["c", "b", "a"]),
],
)
def test_ordering_members(order: rendering.Order, members_list: list[str | None], expected_names: list[str]) -> None:
diff --git a/tests/test_themes.py b/tests/test_themes.py
index a4ad0d59..5a7e9038 100644
--- a/tests/test_themes.py
+++ b/tests/test_themes.py
@@ -7,8 +7,7 @@
import pytest
if TYPE_CHECKING:
- from markdown import Markdown
- from mkdocstrings.plugin import MkdocstringsPlugin
+ from mkdocstrings_handlers.python import PythonHandler
@pytest.mark.parametrize(
@@ -23,24 +22,18 @@
@pytest.mark.parametrize(
"identifier",
[
- "mkdocstrings.extension",
- "mkdocstrings.inventory",
- "mkdocstrings.loggers",
- "mkdocstrings.plugin",
- "mkdocstrings.handlers.base",
- "mkdocstrings.handlers.rendering",
- "mkdocstrings_handlers.python",
+ "mkdocstrings_handlers.python._internal.config",
+ "mkdocstrings_handlers.python._internal.handler",
+ "mkdocstrings_handlers.python._internal.rendering",
],
)
-def test_render_themes_templates_python(identifier: str, plugin: MkdocstringsPlugin, ext_markdown: Markdown) -> None:
+def test_render_themes_templates_python(identifier: str, handler: PythonHandler) -> None:
"""Test rendering of a given theme's templates.
Parameters:
identifier: Parametrized identifier.
- plugin: Pytest fixture (see conftest.py).
- ext_markdown: Pytest fixture (see conftest.py).
+ handler: Python handler (fixture).
"""
- handler = plugin.handlers.get_handler("python")
- handler._update_env(ext_markdown, plugin.handlers._config)
- data = handler.collect(identifier, {})
- handler.render(data, {})
+ options = handler.get_options({})
+ data = handler.collect(identifier, options)
+ handler.render(data, options)