Skip to content

Commit dd8b014

Browse files
committed
refactor: Prepare relative_crossrefs and scoped_crossrefs insiders features
1 parent 7b11ba8 commit dd8b014

File tree

5 files changed

+238
-2
lines changed

5 files changed

+238
-2
lines changed

docs/insiders/changelog.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## mkdocstrings-python Insiders
44

5+
### 1.9.0 <small>September 03, 2024</small> { id="1.9.0" }
6+
7+
- [Relative cross-references][relative_crossrefs]
8+
- [Scoped cross-references][scoped_crossrefs]
9+
510
### 1.8.3 <small>June 19, 2024</small> { id="1.8.3" }
611

712
- Update code for Griffe 0.46+ to avoid deprecation warnings

docs/insiders/goals.yml

+5
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ goals:
3737
name: FusionDrive Ejection Configuration
3838
features:
3939
- name: Relative cross-references
40+
ref: /usage/configuration/docstrings/#relative_crossrefs
41+
since: 2024/09/03
42+
- name: Scoped cross-references
43+
ref: /usage/configuration/docstrings/#scoped_crossrefs
44+
since: 2024/09/03

docs/usage/configuration/docstrings.md

+220
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,226 @@ class Thing:
317317
////
318318
///
319319

320+
## `relative_crossrefs`
321+
322+
[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } &mdash;
323+
[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0)
324+
325+
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
326+
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->
327+
328+
Whether to enable the relative-crossref syntax.
329+
330+
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.
331+
332+
333+
```yaml title="in mkdocs.yml (global configuration)"
334+
plugins:
335+
- mkdocstrings:
336+
handlers:
337+
python:
338+
options:
339+
relative_crossrefs: false
340+
```
341+
342+
```md title="or in docs/some_page.md (local configuration)"
343+
::: path.to.module
344+
options:
345+
relative_crossrefs: true
346+
```
347+
348+
/// admonition | Examples
349+
type: preview
350+
351+
```python title="pkg/module.py"
352+
"""Summary.
353+
354+
- Link to [`module`][.].
355+
- Link to [`module_attribute`][.module_attribute].
356+
- Link to [`Class`][.Class].
357+
- Link to [`class_attribute`][.Class.class_attribute].
358+
- Link to [`instance_attribute`][.Class.instance_attribute].
359+
- Link to [`method`][.Class.method].
360+
"""
361+
362+
module_attribute = 0
363+
"""Summary.
364+
365+
- Link to [`module`][..].
366+
- Link to [`module_attribute`][.].
367+
- Link to [`Class`][..Class].
368+
- Link to [`class_attribute`][..Class.class_attribute].
369+
- Link to [`instance_attribute`][..Class.instance_attribute].
370+
- Link to [`method`][..Class.method].
371+
"""
372+
373+
class Class:
374+
"""Summary.
375+
376+
- Link to [`module`][..].
377+
- Link to [`module_attribute`][..module_attribute].
378+
- Link to [`Class`][.].
379+
- Link to [`class_attribute`][.class_attribute].
380+
- Link to [`instance_attribute`][.instance_attribute].
381+
- Link to [`method`][.method].
382+
"""
383+
384+
class_attribute = 0
385+
"""Summary.
386+
387+
- Link to [`module`][...].
388+
- Link to [`module_attribute`][...module_attribute].
389+
- Link to [`Class`][..].
390+
- Link to [`class_attribute`][.].
391+
- Link to [`instance_attribute`][..instance_attribute].
392+
- Link to [`method`][..method].
393+
"""
394+
395+
def __init__(self):
396+
"""Summary.
397+
398+
- Link to [`module`][...].
399+
- Link to [`module_attribute`][...module_attribute].
400+
- Link to [`Class`][..].
401+
- Link to [`class_attribute`][..class_attribute].
402+
- Link to [`instance_attribute`][..instance_attribute].
403+
- Link to [`method`][..method].
404+
"""
405+
self.instance_attribute = 0
406+
"""Summary.
407+
408+
- Link to [`module`][...].
409+
- Link to [`module_attribute`][...module_attribute].
410+
- Link to [`Class`][..].
411+
- Link to [`class_attribute`][..class_attribute].
412+
- Link to [`instance_attribute`][.].
413+
- Link to [`method`][..method].
414+
"""
415+
416+
def method(self):
417+
"""Summary.
418+
419+
- Link to [`module`][...].
420+
- Link to [`module_attribute`][...module_attribute].
421+
- Link to [`Class`][..].
422+
- Link to [`class_attribute`][..class_attribute].
423+
- Link to [`instance_attribute`][..instance_attribute].
424+
- Link to [`method`][.].
425+
"""
426+
```
427+
428+
///
429+
430+
431+
## `scoped_crossrefs`
432+
433+
[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } &mdash;
434+
[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0)
435+
436+
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**
437+
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->
438+
439+
Whether to enable scoped cross-references.
440+
441+
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.`.
442+
443+
The following order is applied when resolving a name in a given scope:
444+
445+
1. member of the current object
446+
2. parent class
447+
3. repeat 1-2 within parent's scope
448+
449+
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.
450+
451+
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.
452+
453+
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.
454+
455+
```yaml title="in mkdocs.yml (global configuration)"
456+
plugins:
457+
- mkdocstrings:
458+
handlers:
459+
python:
460+
options:
461+
scoped_crossrefs: false
462+
```
463+
464+
```md title="or in docs/some_page.md (local configuration)"
465+
::: path.to.module
466+
options:
467+
scoped_crossrefs: true
468+
```
469+
470+
/// admonition | Examples
471+
type: preview
472+
473+
```python title="pkg/module.py"
474+
"""Summary.
475+
476+
- Link to [`module_attribute`][module_attribute].
477+
- Link to [`Class`][Class].
478+
- Link to [`class_attribute`][Class.class_attribute].
479+
- Link to [`instance_attribute`][Class.instance_attribute].
480+
- Link to [`method`][Class.method].
481+
"""
482+
483+
module_attribute = 0
484+
"""Summary.
485+
486+
- Link to [`Class`][Class].
487+
- Link to [`class_attribute`][Class.class_attribute].
488+
- Link to [`instance_attribute`][Class.instance_attribute].
489+
- Link to [`method`][Class.method].
490+
"""
491+
492+
class Class:
493+
"""Summary.
494+
495+
- Link to [`module_attribute`][module_attribute].
496+
- Link to [`class_attribute`][class_attribute].
497+
- Link to [`instance_attribute`][instance_attribute].
498+
- Link to [`method`][method].
499+
"""
500+
501+
class_attribute = 0
502+
"""Summary.
503+
504+
- Link to [`module_attribute`][module_attribute].
505+
- Link to [`Class`][Class].
506+
- Link to [`instance_attribute`][instance_attribute].
507+
- Link to [`method`][method].
508+
"""
509+
510+
def __init__(self):
511+
"""Summary.
512+
513+
- Link to [`module_attribute`][module_attribute].
514+
- Link to [`Class`][Class].
515+
- Link to [`class_attribute`][class_attribute].
516+
- Link to [`instance_attribute`][instance_attribute].
517+
- Link to [`method`][method].
518+
"""
519+
self.instance_attribute = 0
520+
"""Summary.
521+
522+
- Link to [`module_attribute`][module_attribute].
523+
- Link to [`Class`][Class].
524+
- Link to [`class_attribute`][class_attribute].
525+
- Link to [`method`][method].
526+
"""
527+
528+
def method(self):
529+
"""Summary.
530+
531+
- Link to [`module_attribute`][module_attribute].
532+
- Link to [`Class`][Class].
533+
- Link to [`class_attribute`][class_attribute].
534+
- Link to [`instance_attribute`][instance_attribute].
535+
"""
536+
```
537+
538+
///
539+
320540
## `show_if_no_docstring`
321541
322542
- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }**

src/mkdocstrings_handlers/python/handler.py

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class PythonHandler(BaseHandler):
8585
"separate_signature": False,
8686
"line_length": 60,
8787
"merge_init_into_class": False,
88+
"relative_crossrefs": False,
89+
"scoped_crossrefs": False,
8890
"show_docstring_attributes": True,
8991
"show_docstring_functions": True,
9092
"show_docstring_classes": True,
@@ -168,6 +170,8 @@ class PythonHandler(BaseHandler):
168170
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.
169171
docstring_section_style (str): The style used to render docstring sections. Options: `table`, `list`, `spacy`. Default: `"table"`.
170172
merge_init_into_class (bool): Whether to merge the `__init__` method into the class' signature and docstring. Default: `False`.
173+
relative_crossrefs (bool): Whether to enable the relative crossref syntax. Default: `False`.
174+
scoped_crossrefs (bool): Whether to enable the scoped crossref ability. Default: `False`.
171175
show_if_no_docstring (bool): Show the object heading even if it has no docstring or children with docstrings. Default: `False`.
172176
show_docstring_attributes (bool): Whether to display the "Attributes" section in the object's docstring. Default: `True`.
173177
show_docstring_functions (bool): Whether to display the "Functions" or "Methods" sections in the object's docstring. Default: `True`.

src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja

+4-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,10 @@ Context:
133133
{% endwith %}
134134
{% if config.merge_init_into_class %}
135135
{% if "__init__" in class.all_members and class.all_members["__init__"].has_docstring %}
136-
{% with docstring_sections = class.all_members["__init__"].docstring.parsed %}
137-
{% include "docstring"|get_template with context %}
136+
{% with function = class.all_members["__init__"] %}
137+
{% with obj = function, docstring_sections = function.docstring.parsed %}
138+
{% include "docstring"|get_template with context %}
139+
{% endwith %}
138140
{% endwith %}
139141
{% endif %}
140142
{% endif %}

0 commit comments

Comments
 (0)