Skip to content

Commit

Permalink
refactor: Prepare relative_crossrefs and scoped_crossrefs insider…
Browse files Browse the repository at this point in the history
…s features
  • Loading branch information
pawamoy committed Sep 3, 2024
1 parent 7b11ba8 commit dd8b014
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 2 deletions.
5 changes: 5 additions & 0 deletions docs/insiders/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## mkdocstrings-python Insiders

### 1.9.0 <small>September 03, 2024</small> { id="1.9.0" }

- [Relative cross-references][relative_crossrefs]
- [Scoped cross-references][scoped_crossrefs]

### 1.8.3 <small>June 19, 2024</small> { id="1.8.3" }

- Update code for Griffe 0.46+ to avoid deprecation warnings
Expand Down
5 changes: 5 additions & 0 deletions docs/insiders/goals.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ goals:
name: FusionDrive Ejection Configuration
features:
- name: Relative cross-references
ref: /usage/configuration/docstrings/#relative_crossrefs
since: 2024/09/03
- name: Scoped cross-references
ref: /usage/configuration/docstrings/#scoped_crossrefs
since: 2024/09/03
220 changes: 220 additions & 0 deletions docs/usage/configuration/docstrings.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,226 @@ class Thing:
////
///

## `relative_crossrefs`

[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } &mdash;
[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0)

- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->

Whether to enable the relative-crossref syntax.

The relative-crossref syntax lets you reference the current object or its parent by prefixing a crossref identifier with dots. For example, to cross-reference the current object's `name` member, you can write `[link to name attribute][.name]`. The "current object" is the object containing the docstring being rendered.


```yaml title="in mkdocs.yml (global configuration)"
plugins:
- mkdocstrings:
handlers:
python:
options:
relative_crossrefs: false
```

```md title="or in docs/some_page.md (local configuration)"
::: path.to.module
options:
relative_crossrefs: true
```

/// admonition | Examples
type: preview

```python title="pkg/module.py"
"""Summary.
- Link to [`module`][.].
- Link to [`module_attribute`][.module_attribute].
- Link to [`Class`][.Class].
- Link to [`class_attribute`][.Class.class_attribute].
- Link to [`instance_attribute`][.Class.instance_attribute].
- Link to [`method`][.Class.method].
"""
module_attribute = 0
"""Summary.

- Link to [`module`][..].
- Link to [`module_attribute`][.].
- Link to [`Class`][..Class].
- Link to [`class_attribute`][..Class.class_attribute].
- Link to [`instance_attribute`][..Class.instance_attribute].
- Link to [`method`][..Class.method].
"""
class Class:
"""Summary.

- Link to [`module`][..].
- Link to [`module_attribute`][..module_attribute].
- Link to [`Class`][.].
- Link to [`class_attribute`][.class_attribute].
- Link to [`instance_attribute`][.instance_attribute].
- Link to [`method`][.method].
"""
class_attribute = 0
"""Summary.

- Link to [`module`][...].
- Link to [`module_attribute`][...module_attribute].
- Link to [`Class`][..].
- Link to [`class_attribute`][.].
- Link to [`instance_attribute`][..instance_attribute].
- Link to [`method`][..method].
"""
def __init__(self):
"""Summary.

- Link to [`module`][...].
- Link to [`module_attribute`][...module_attribute].
- Link to [`Class`][..].
- Link to [`class_attribute`][..class_attribute].
- Link to [`instance_attribute`][..instance_attribute].
- Link to [`method`][..method].
"""
self.instance_attribute = 0
"""Summary.

- Link to [`module`][...].
- Link to [`module_attribute`][...module_attribute].
- Link to [`Class`][..].
- Link to [`class_attribute`][..class_attribute].
- Link to [`instance_attribute`][.].
- Link to [`method`][..method].
"""
def method(self):
"""Summary.

- Link to [`module`][...].
- Link to [`module_attribute`][...module_attribute].
- Link to [`Class`][..].
- Link to [`class_attribute`][..class_attribute].
- Link to [`instance_attribute`][..instance_attribute].
- Link to [`method`][.].
"""
```
///
## `scoped_crossrefs`
[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } &mdash;
[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0)
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->

Whether to enable scoped cross-references.

With scoped cross-references, you can write identifiers as if you wanted to access them from the current object's scope. The scoping rules do not exactly match Python's: you can reference members and siblings too, without prefixing with `self.` or `cls.`.

The following order is applied when resolving a name in a given scope:

1. member of the current object
2. parent class
3. repeat 1-2 within parent's scope

In practice, it means that the name is first looked up in members, then it is compared against the parent name (only if it's a class), then it is looked up in siblings. It continues climbing up the object tree until there's no parent, in which case it raises a name resolution error.

Cross-referencing an imported object will directly link to this object if the objects inventory of the project it comes from was [loaded][import]. You won't be able to cross-reference it within your own documentation with scoped references, if you happen to be rendering this external object too. In that case, you can use an absolute reference or a [relative][relative_crossrefs] one instead.

Another limitation is that you won't be able to reference an external package if its name can be resolved in the current object's scope.

```yaml title="in mkdocs.yml (global configuration)"
plugins:
- mkdocstrings:
handlers:
python:
options:
scoped_crossrefs: false
```

```md title="or in docs/some_page.md (local configuration)"
::: path.to.module
options:
scoped_crossrefs: true
```

/// admonition | Examples
type: preview

```python title="pkg/module.py"
"""Summary.
- Link to [`module_attribute`][module_attribute].
- Link to [`Class`][Class].
- Link to [`class_attribute`][Class.class_attribute].
- Link to [`instance_attribute`][Class.instance_attribute].
- Link to [`method`][Class.method].
"""
module_attribute = 0
"""Summary.

- Link to [`Class`][Class].
- Link to [`class_attribute`][Class.class_attribute].
- Link to [`instance_attribute`][Class.instance_attribute].
- Link to [`method`][Class.method].
"""
class Class:
"""Summary.

- Link to [`module_attribute`][module_attribute].
- Link to [`class_attribute`][class_attribute].
- Link to [`instance_attribute`][instance_attribute].
- Link to [`method`][method].
"""
class_attribute = 0
"""Summary.

- Link to [`module_attribute`][module_attribute].
- Link to [`Class`][Class].
- Link to [`instance_attribute`][instance_attribute].
- Link to [`method`][method].
"""
def __init__(self):
"""Summary.

- Link to [`module_attribute`][module_attribute].
- Link to [`Class`][Class].
- Link to [`class_attribute`][class_attribute].
- Link to [`instance_attribute`][instance_attribute].
- Link to [`method`][method].
"""
self.instance_attribute = 0
"""Summary.

- Link to [`module_attribute`][module_attribute].
- Link to [`Class`][Class].
- Link to [`class_attribute`][class_attribute].
- Link to [`method`][method].
"""
def method(self):
"""Summary.

- Link to [`module_attribute`][module_attribute].
- Link to [`Class`][Class].
- Link to [`class_attribute`][class_attribute].
- Link to [`instance_attribute`][instance_attribute].
"""
```
///
## `show_if_no_docstring`
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
Expand Down
4 changes: 4 additions & 0 deletions src/mkdocstrings_handlers/python/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class PythonHandler(BaseHandler):
"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,
Expand Down Expand Up @@ -168,6 +170,8 @@ class PythonHandler(BaseHandler):
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`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ Context:
{% endwith %}
{% if config.merge_init_into_class %}
{% if "__init__" in class.all_members and class.all_members["__init__"].has_docstring %}
{% with docstring_sections = class.all_members["__init__"].docstring.parsed %}
{% include "docstring"|get_template with context %}
{% with function = class.all_members["__init__"] %}
{% with obj = function, docstring_sections = function.docstring.parsed %}
{% include "docstring"|get_template with context %}
{% endwith %}
{% endwith %}
{% endif %}
{% endif %}
Expand Down

0 comments on commit dd8b014

Please sign in to comment.