Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copilot Instructions

## Project Overview

mkdocstrings-python-xref is an mkdocstrings handler that extends the standard
`mkdocstrings-python` handler to support relative cross-reference syntax in Python
docstrings. It also reports source locations for bad references.

## Build, Test, and Lint

All tasks use [pixi](https://pixi.sh/). Run `pixi task list` to see all available tasks.

```bash
# Run tests with verbose output
pixi run pytest

# Run a single test file
pixi run pytest -sv -ra tests/test_crossref.py

# Run a single test by name
pixi run pytest -sv -ra tests/test_crossref.py -k "test_name"

# Lint (ruff + mypy)
pixi run lint

# Type checking only
pixi run mypy

# Ruff linting only
pixi run ruff

# Build docs
pixi run doc

# Serve docs locally
pixi run show-doc
```

## Architecture

- **Namespace package**: `src/mkdocstrings_handlers/` is an implicit namespace package
(no `__init__.py`). The handler lives under `python_xref/`.
- **Handler registration**: `get_handler()` factory in `__init__.py` returns a
`PythonRelXRefHandler` instance. mkdocstrings discovers it via the `python_xref`
handler name.
- **Core classes**:
- `PythonRelXRefHandler` (handler.py) — extends `PythonHandler`, overrides `render()`
to process relative cross-references before rendering.
- `_RelativeCrossrefProcessor` (crossref.py) — visitor-style processor that walks
Griffe docstring objects and substitutes relative refs using compiled regex patterns.
- **Version**: stored as plain text in `src/mkdocstrings_handlers/python_xref/VERSION`.
Hatchling reads it at build time. Versioning tracks the upstream mkdocstrings-python
version.

## Conventions

- **Build system**: Hatchling. The wheel includes `src/mkdocstrings_handlers`.
- **Docstring style**: Google style (enforced by ruff `D` rules and mypy).
- **Formatting**: Use `black` for code formatting.
- **Type annotations**: Required on all function definitions (`disallow_untyped_defs`
and `disallow_incomplete_defs` in mypy config).
- **Test organization**: Tests are in `tests/`. `tests/project/` contains a sample
Python package used by integration tests. There is no `conftest.py`; fixtures come
from pytest builtins.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
*Note that versions roughly correspond to the version of mkdocstrings-python that they
are compatible with.*

## 2.1.0

* Added `compatibility_check` option to warn or error on cross-reference syntax that
is not supported by the standard mkdocstrings-python handler (#60)
* Added `compatibility_patch` option to generate a patch file converting incompatible
cross-references to standard form (#60)

## 2.0.1

* Fix extended template configuration (#56)
Expand Down
64 changes: 63 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ that the handler name should be `python_xref` instead of `python`. Because
this handler extends the standard [mkdocstrings-python][] handler, the same options are
available.

Additional options are added by this extension. Currently, there are three:
Additional options are added by this extension:

* **relative_crossrefs**: `bool` - if set to true enables use of relative path syntax in
cross-references.
Expand All @@ -19,6 +19,18 @@ Additional options are added by this extension. Currently, there are three:
libraries which are very expensive to import without having to disable checking for all
cross-references.

* **compatibility_check**: `false`, `"warn"`, or `"error"` - when set, reports cross-references
that use syntax not supported by the standard [mkdocstrings-python][] handler. This is
useful when planning to migrate away from this extension. The incompatible syntax elements
are: leading `^`, `(c)`, `(m)`, `(p)` specifiers; trailing `.` after a name (which
appends the title); and leading `?` (which suppresses reference checking).

* **compatibility_patch**: `false` or a file path string - when set to a file path, generates
a unified diff patch file that converts incompatible cross-references to the standard
dot-prefix form. The patch file is overwritten on each build. If no incompatibilities are
found, any existing patch file is removed. The generated patch can be applied with
`git apply <patch-file>` or `patch -p1 -i <patch-file>`.

!!! Example "mkdocs.yml plugins specifications using this handler"

=== "Always check"
Expand Down Expand Up @@ -80,6 +92,56 @@ Additional options are added by this extension. Currently, there are three:
check_crossrefs: no
```

!!! Example "Compatibility checking for migration"

To check for incompatible syntax before migrating to the standard handler:

=== "Warn on incompatibilities"

```yaml
plugins:
- mkdocstrings:
default_handler: python_xref
handlers:
python_xref:
options:
relative_crossrefs: yes
compatibility_check: warn
```

=== "Error on incompatibilities"

```yaml
plugins:
- mkdocstrings:
default_handler: python_xref
handlers:
python_xref:
options:
relative_crossrefs: yes
compatibility_check: error
```

=== "Generate a patch file"

```yaml
plugins:
- mkdocstrings:
default_handler: python_xref
handlers:
python_xref:
options:
relative_crossrefs: yes
compatibility_check: warn
compatibility_patch: xref-compat.patch
```

Then apply the patch:

```bash
git apply xref-compat.patch
```



[mkdocstrings-python]: https://mkdocstrings.github.io/python/
25 changes: 25 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,31 @@ reference expression with a `?`, for example:
This function returns a [Path][?pathlib.] instance.
```

## Migrating to standard mkdocstrings-python

If you want to migrate from this extension to the standard [mkdocstrings-python][mkdocstrings_python]
handler, or just want to maintain compatibility with it, then
you can use the `compatibility_check` and `compatibility_patch` options to help
identify and convert incompatible cross-reference syntax.

The following syntax elements are specific to this extension and not supported by the
standard handler:

| Syntax | Description | Standard equivalent |
|--------|-------------|-------------------|
| `^`, `^^`, ... | Caret parent specifier | `..`, `...`, ... (dot prefix) |
| `(c)` | Class specifier | Equivalent number of leading dots |
| `(m)` | Module specifier | Equivalent number of leading dots |
| `(p)` | Package specifier | Equivalent number of leading dots |
| Trailing `.` after a name | Append title to reference | Expand title inline, e.g. `[foo][bar.]` → `[foo][bar.foo]` |
| Leading `?` | Suppress reference checking | Remove the `?` |

To check for incompatibilities, set `compatibility_check` to `"warn"` or `"error"` in your
handler options. To generate a patch file that converts all incompatible references to
standard form, set `compatibility_patch` to a file path. See the [configuration](config.md)
page for examples. Setting `compatibility_patch` implies a `compatibility_check` of
`"warn"` if not set explicitly.

[mkdocstrings]: https://mkdocstrings.github.io/
[mkdocstrings_python]: https://mkdocstrings.github.io/python/
[relative-crossref-issue]: https://github.com/mkdocstrings/python/issues/27
4 changes: 2 additions & 2 deletions pixi.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ env = {VERSION = "$(cat src/mkdocstrings_handlers/python_xref/VERSION)"}
cmd = "whl2conda convert dist/mkdocstrings_python_xref-$VERSION-py3-none-any.whl -w dist --overwrite"
depends-on = ["build-wheel"]
inputs = ["dist/mkdocstrings_python_xref-*-none-any.whl"]
outputs = ["dist/mkdocstrings_python_xref-*-py_0.conda"]

# upload tasks
[tool.pixi.tasks.check-upload-wheel]
Expand Down Expand Up @@ -364,7 +365,7 @@ cmd = "mike serve -F mkdocs.yml"
[tool.pixi.tasks.doc-deploy]
env = {VERSION = "$(cat src/mkdocstrings_handlers/python_xref/VERSION)"}
description = "Deploy the current version to the gh-pages branch"
cmd = "mike deploy -F mkdocs.yml -u $VERSION latest & mike set-default -u $VERSION latest"
cmd = "mike deploy -F mkdocs.yml -u $VERSION latest && mike set-default latest"

[tool.pixi.tasks.show-version]
env = {VERSION = "$(cat src/mkdocstrings_handlers/python_xref/VERSION)"}
Expand Down
2 changes: 1 addition & 1 deletion src/mkdocstrings_handlers/python_xref/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.1
2.1.0
Loading
Loading