Skip to content

Commit

Permalink
feat: Hook into autorefs to provide context around cross-ref errors
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Sep 3, 2024
1 parent 2d59cdb commit bb4be5b
Show file tree
Hide file tree
Showing 25 changed files with 138 additions and 77 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"mkdocstrings>=0.25",
"mkdocs-autorefs>=1.0",
"mkdocstrings>=0.26",
"mkdocs-autorefs>=1.2",
"griffe>=0.49",
]

Expand Down
1 change: 1 addition & 0 deletions src/mkdocstrings_handlers/python/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ def update_env(self, md: Markdown, config: dict) -> None:
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)
Expand Down
58 changes: 58 additions & 0 deletions src/mkdocstrings_handlers/python/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
)
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:
Expand Down Expand Up @@ -571,3 +572,60 @@ def do_as_modules_section(
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,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,37 @@ Context:
-#}
{{ log.debug("Rendering docstring") }}
{% endblock logs %}
{% for section in docstring_sections %}
{% if config.show_docstring_description and section.kind.value == "text" %}
{{ section.value|convert_markdown(heading_level, html_id) }}
{% elif config.show_docstring_attributes and section.kind.value == "attributes" %}
{% include "docstring/attributes"|get_template with context %}
{% elif config.show_docstring_functions and section.kind.value == "functions" %}
{% include "docstring/functions"|get_template with context %}
{% elif config.show_docstring_classes and section.kind.value == "classes" %}
{% include "docstring/classes"|get_template with context %}
{% elif config.show_docstring_modules and section.kind.value == "modules" %}
{% include "docstring/modules"|get_template with context %}
{% elif config.show_docstring_parameters and section.kind.value == "parameters" %}
{% include "docstring/parameters"|get_template with context %}
{% elif config.show_docstring_other_parameters and section.kind.value == "other parameters" %}
{% include "docstring/other_parameters"|get_template with context %}
{% elif config.show_docstring_raises and section.kind.value == "raises" %}
{% include "docstring/raises"|get_template with context %}
{% elif config.show_docstring_warns and section.kind.value == "warns" %}
{% include "docstring/warns"|get_template with context %}
{% elif config.show_docstring_yields and section.kind.value == "yields" %}
{% include "docstring/yields"|get_template with context %}
{% elif config.show_docstring_receives and section.kind.value == "receives" %}
{% include "docstring/receives"|get_template with context %}
{% elif config.show_docstring_returns and section.kind.value == "returns" %}
{% include "docstring/returns"|get_template with context %}
{% elif config.show_docstring_examples and section.kind.value == "examples" %}
{% include "docstring/examples"|get_template with context %}
{% elif config.show_docstring_description and section.kind.value == "admonition" %}
{% include "docstring/admonition"|get_template with context %}
{% endif %}
{% endfor %}
{% with autoref_hook = AutorefsHook(obj, config) %}
{% for section in docstring_sections %}
{% 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 %}
{% elif config.show_docstring_functions and section.kind.value == "functions" %}
{% include "docstring/functions"|get_template with context %}
{% elif config.show_docstring_classes and section.kind.value == "classes" %}
{% include "docstring/classes"|get_template with context %}
{% elif config.show_docstring_modules and section.kind.value == "modules" %}
{% include "docstring/modules"|get_template with context %}
{% elif config.show_docstring_parameters and section.kind.value == "parameters" %}
{% include "docstring/parameters"|get_template with context %}
{% elif config.show_docstring_other_parameters and section.kind.value == "other parameters" %}
{% include "docstring/other_parameters"|get_template with context %}
{% elif config.show_docstring_raises and section.kind.value == "raises" %}
{% include "docstring/raises"|get_template with context %}
{% elif config.show_docstring_warns and section.kind.value == "warns" %}
{% include "docstring/warns"|get_template with context %}
{% elif config.show_docstring_yields and section.kind.value == "yields" %}
{% include "docstring/yields"|get_template with context %}
{% elif config.show_docstring_receives and section.kind.value == "receives" %}
{% include "docstring/receives"|get_template with context %}
{% elif config.show_docstring_returns and section.kind.value == "returns" %}
{% include "docstring/returns"|get_template with context %}
{% elif config.show_docstring_examples and section.kind.value == "examples" %}
{% include "docstring/examples"|get_template with context %}
{% elif config.show_docstring_description and section.kind.value == "admonition" %}
{% include "docstring/admonition"|get_template with context %}
{% endif %}
{% endfor %}
{% endwith %}
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ Context:
{% endblock logs %}

<details class="{{ section.value.kind }}" open>
<summary>{{ section.title|convert_markdown(heading_level, html_id, strip_paragraph=True) }}</summary>
{{ section.value.contents|convert_markdown(heading_level, html_id) }}
<summary>{{ section.title|convert_markdown(heading_level, html_id, strip_paragraph=True, autoref_hook=autoref_hook) }}</summary>
{{ section.value.contents|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</details>
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Context:
</td>
<td>
<div class="doc-md-description">
{{ attribute.description|convert_markdown(heading_level, html_id) }}
{{ attribute.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -66,7 +66,7 @@ Context:
{% endif %}
<div class="doc-md-description">
{{ attribute.description|convert_markdown(heading_level, html_id) }}
{{ attribute.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand All @@ -88,7 +88,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ attribute.name }}" optional hover>{{ attribute.name }}</autoref></code></td>
<td class="doc-attribute-details">
<div class="doc-md-description">
{{ attribute.description|convert_markdown(heading_level, html_id) }}
{{ attribute.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
<p>
{% if attribute.annotation %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ class.name }}" optional hover>{{ class.name }}</autoref></code></td>
<td>
<div class="doc-md-description">
{{ class.description|convert_markdown(heading_level, html_id) }}
{{ class.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -53,7 +53,7 @@ Context:
<b><code><autoref identifier="{{ obj.path }}.{{ class.name }}" optional hover>{{ class.name }}</autoref></code></b>
<div class="doc-md-description">
{{ class.description|convert_markdown(heading_level, html_id) }}
{{ class.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand All @@ -75,7 +75,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ class.name }}" optional hover>{{ class.name }}</autoref></code></td>
<td class="doc-class-details">
<div class="doc-md-description">
{{ class.description|convert_markdown(heading_level, html_id) }}
{{ class.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Context:
<p><span class="doc-section-title">{{ section.title or lang.t("Examples:") }}</span></p>
{% for section_type, sub_section in section.value %}
{% if section_type.value == "text" %}
{{ sub_section|convert_markdown(heading_level, html_id) }}
{{ sub_section|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
{% elif section_type.value == "examples" %}
{{ sub_section|highlight(language="pycon", linenums=False) }}
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ function.name }}" optional hover>{{ function.name }}</autoref></code></td>
<td>
<div class="doc-md-description">
{{ function.description|convert_markdown(heading_level, html_id) }}
{{ function.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -56,7 +56,7 @@ Context:
<b><code><autoref identifier="{{ obj.path }}.{{ function.name }}" optional hover>{{ function.name }}</autoref></code></b>
<div class="doc-md-description">
{{ function.description|convert_markdown(heading_level, html_id) }}
{{ function.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endif %}
Expand All @@ -80,7 +80,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ function.name }}" optional hover>{{ function.name }}</autoref></code></td>
<td class="doc-function-details">
<div class="doc-md-description">
{{ function.description|convert_markdown(heading_level, html_id) }}
{{ function.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ module.name }}" optional hover>{{ module.name }}</autoref></code></td>
<td>
<div class="doc-md-description">
{{ module.description|convert_markdown(heading_level, html_id) }}
{{ module.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -53,7 +53,7 @@ Context:
<b><code><autoref identifier="{{ obj.path }}.{{ module.name }}" optional hover>{{ module.name }}</autoref></code></b>
<div class="doc-md-description">
{{ module.description|convert_markdown(heading_level, html_id) }}
{{ module.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand All @@ -75,7 +75,7 @@ Context:
<td><code><autoref identifier="{{ obj.path }}.{{ module.name }}" optional hover>{{ module.name }}</autoref></code></td>
<td class="doc-module-details">
<div class="doc-md-description">
{{ module.description|convert_markdown(heading_level, html_id) }}
{{ module.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Context:
</td>
<td>
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -66,7 +66,7 @@ Context:
{% endif %}
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand All @@ -88,7 +88,7 @@ Context:
<td><code>{{ parameter.name }}</code></td>
<td class="doc-param-details">
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
<p>
{% if parameter.annotation %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Context:
</td>
<td>
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
<td>
Expand Down Expand Up @@ -81,7 +81,7 @@ Context:
{% endif %}
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand All @@ -103,7 +103,7 @@ Context:
<td><code>{{ parameter.name }}</code></td>
<td class="doc-param-details">
<div class="doc-md-description">
{{ parameter.description|convert_markdown(heading_level, html_id) }}
{{ parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
<p>
{% if parameter.annotation %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Context:
</td>
<td>
<div class="doc-md-description">
{{ raises.description|convert_markdown(heading_level, html_id) }}
{{ raises.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -63,7 +63,7 @@ Context:
{% endif %}
<div class="doc-md-description">
{{ raises.description|convert_markdown(heading_level, html_id) }}
{{ raises.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand Down Expand Up @@ -91,7 +91,7 @@ Context:
</td>
<td class="doc-raises-details">
<div class="doc-md-description">
{{ raises.description|convert_markdown(heading_level, html_id) }}
{{ raises.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Context:
</td>
<td>
<div class="doc-md-description">
{{ receives.description|convert_markdown(heading_level, html_id) }}
{{ receives.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</td>
</tr>
Expand All @@ -69,7 +69,7 @@ Context:
{% endif %}
<div class="doc-md-description">
{{ receives.description|convert_markdown(heading_level, html_id) }}
{{ receives.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
</li>
{% endfor %}
Expand Down Expand Up @@ -101,7 +101,7 @@ Context:
</td>
<td class="doc-receives-details">
<div class="doc-md-description">
{{ receives.description|convert_markdown(heading_level, html_id) }}
{{ receives.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
</div>
{% if receives.name and receives.annotation %}
<p>
Expand Down
Loading

0 comments on commit bb4be5b

Please sign in to comment.