Skip to content

Commit 752949b

Browse files
Merge pull request #61 from analog-garage/compatibility-checks
Compatibility checks
2 parents 4ffe287 + 8500f4a commit 752949b

11 files changed

Lines changed: 754 additions & 36 deletions

File tree

.github/copilot-instructions.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copilot Instructions
2+
3+
## Project Overview
4+
5+
mkdocstrings-python-xref is an mkdocstrings handler that extends the standard
6+
`mkdocstrings-python` handler to support relative cross-reference syntax in Python
7+
docstrings. It also reports source locations for bad references.
8+
9+
## Build, Test, and Lint
10+
11+
All tasks use [pixi](https://pixi.sh/). Run `pixi task list` to see all available tasks.
12+
13+
```bash
14+
# Run tests with verbose output
15+
pixi run pytest
16+
17+
# Run a single test file
18+
pixi run pytest -sv -ra tests/test_crossref.py
19+
20+
# Run a single test by name
21+
pixi run pytest -sv -ra tests/test_crossref.py -k "test_name"
22+
23+
# Lint (ruff + mypy)
24+
pixi run lint
25+
26+
# Type checking only
27+
pixi run mypy
28+
29+
# Ruff linting only
30+
pixi run ruff
31+
32+
# Build docs
33+
pixi run doc
34+
35+
# Serve docs locally
36+
pixi run show-doc
37+
```
38+
39+
## Architecture
40+
41+
- **Namespace package**: `src/mkdocstrings_handlers/` is an implicit namespace package
42+
(no `__init__.py`). The handler lives under `python_xref/`.
43+
- **Handler registration**: `get_handler()` factory in `__init__.py` returns a
44+
`PythonRelXRefHandler` instance. mkdocstrings discovers it via the `python_xref`
45+
handler name.
46+
- **Core classes**:
47+
- `PythonRelXRefHandler` (handler.py) — extends `PythonHandler`, overrides `render()`
48+
to process relative cross-references before rendering.
49+
- `_RelativeCrossrefProcessor` (crossref.py) — visitor-style processor that walks
50+
Griffe docstring objects and substitutes relative refs using compiled regex patterns.
51+
- **Version**: stored as plain text in `src/mkdocstrings_handlers/python_xref/VERSION`.
52+
Hatchling reads it at build time. Versioning tracks the upstream mkdocstrings-python
53+
version.
54+
55+
## Conventions
56+
57+
- **Build system**: Hatchling. The wheel includes `src/mkdocstrings_handlers`.
58+
- **Docstring style**: Google style (enforced by ruff `D` rules and mypy).
59+
- **Formatting**: Use `black` for code formatting.
60+
- **Type annotations**: Required on all function definitions (`disallow_untyped_defs`
61+
and `disallow_incomplete_defs` in mypy config).
62+
- **Test organization**: Tests are in `tests/`. `tests/project/` contains a sample
63+
Python package used by integration tests. There is no `conftest.py`; fixtures come
64+
from pytest builtins.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
*Note that versions roughly correspond to the version of mkdocstrings-python that they
44
are compatible with.*
55

6+
## 2.1.0
7+
8+
* Added `compatibility_check` option to warn or error on cross-reference syntax that
9+
is not supported by the standard mkdocstrings-python handler (#60)
10+
* Added `compatibility_patch` option to generate a patch file converting incompatible
11+
cross-references to standard form (#60)
12+
613
## 2.0.1
714

815
* Fix extended template configuration (#56)

docs/config.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ that the handler name should be `python_xref` instead of `python`. Because
33
this handler extends the standard [mkdocstrings-python][] handler, the same options are
44
available.
55

6-
Additional options are added by this extension. Currently, there are three:
6+
Additional options are added by this extension:
77

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

22+
* **compatibility_check**: `false`, `"warn"`, or `"error"` - when set, reports cross-references
23+
that use syntax not supported by the standard [mkdocstrings-python][] handler. This is
24+
useful when planning to migrate away from this extension. The incompatible syntax elements
25+
are: leading `^`, `(c)`, `(m)`, `(p)` specifiers; trailing `.` after a name (which
26+
appends the title); and leading `?` (which suppresses reference checking).
27+
28+
* **compatibility_patch**: `false` or a file path string - when set to a file path, generates
29+
a unified diff patch file that converts incompatible cross-references to the standard
30+
dot-prefix form. The patch file is overwritten on each build. If no incompatibilities are
31+
found, any existing patch file is removed. The generated patch can be applied with
32+
`git apply <patch-file>` or `patch -p1 -i <patch-file>`.
33+
2234
!!! Example "mkdocs.yml plugins specifications using this handler"
2335

2436
=== "Always check"
@@ -80,6 +92,56 @@ Additional options are added by this extension. Currently, there are three:
8092
check_crossrefs: no
8193
```
8294

95+
!!! Example "Compatibility checking for migration"
96+
97+
To check for incompatible syntax before migrating to the standard handler:
98+
99+
=== "Warn on incompatibilities"
100+
101+
```yaml
102+
plugins:
103+
- mkdocstrings:
104+
default_handler: python_xref
105+
handlers:
106+
python_xref:
107+
options:
108+
relative_crossrefs: yes
109+
compatibility_check: warn
110+
```
111+
112+
=== "Error on incompatibilities"
113+
114+
```yaml
115+
plugins:
116+
- mkdocstrings:
117+
default_handler: python_xref
118+
handlers:
119+
python_xref:
120+
options:
121+
relative_crossrefs: yes
122+
compatibility_check: error
123+
```
124+
125+
=== "Generate a patch file"
126+
127+
```yaml
128+
plugins:
129+
- mkdocstrings:
130+
default_handler: python_xref
131+
handlers:
132+
python_xref:
133+
options:
134+
relative_crossrefs: yes
135+
compatibility_check: warn
136+
compatibility_patch: xref-compat.patch
137+
```
138+
139+
Then apply the patch:
140+
141+
```bash
142+
git apply xref-compat.patch
143+
```
144+
83145

84146

85147
[mkdocstrings-python]: https://mkdocstrings.github.io/python/

docs/index.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,31 @@ reference expression with a `?`, for example:
126126
This function returns a [Path][?pathlib.] instance.
127127
```
128128

129+
## Migrating to standard mkdocstrings-python
130+
131+
If you want to migrate from this extension to the standard [mkdocstrings-python][mkdocstrings_python]
132+
handler, or just want to maintain compatibility with it, then
133+
you can use the `compatibility_check` and `compatibility_patch` options to help
134+
identify and convert incompatible cross-reference syntax.
135+
136+
The following syntax elements are specific to this extension and not supported by the
137+
standard handler:
138+
139+
| Syntax | Description | Standard equivalent |
140+
|--------|-------------|-------------------|
141+
| `^`, `^^`, ... | Caret parent specifier | `..`, `...`, ... (dot prefix) |
142+
| `(c)` | Class specifier | Equivalent number of leading dots |
143+
| `(m)` | Module specifier | Equivalent number of leading dots |
144+
| `(p)` | Package specifier | Equivalent number of leading dots |
145+
| Trailing `.` after a name | Append title to reference | Expand title inline, e.g. `[foo][bar.]``[foo][bar.foo]` |
146+
| Leading `?` | Suppress reference checking | Remove the `?` |
147+
148+
To check for incompatibilities, set `compatibility_check` to `"warn"` or `"error"` in your
149+
handler options. To generate a patch file that converts all incompatible references to
150+
standard form, set `compatibility_patch` to a file path. See the [configuration](config.md)
151+
page for examples. Setting `compatibility_patch` implies a `compatibility_check` of
152+
`"warn"` if not set explicitly.
153+
129154
[mkdocstrings]: https://mkdocstrings.github.io/
130155
[mkdocstrings_python]: https://mkdocstrings.github.io/python/
131156
[relative-crossref-issue]: https://github.com/mkdocstrings/python/issues/27

pixi.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ env = {VERSION = "$(cat src/mkdocstrings_handlers/python_xref/VERSION)"}
311311
cmd = "whl2conda convert dist/mkdocstrings_python_xref-$VERSION-py3-none-any.whl -w dist --overwrite"
312312
depends-on = ["build-wheel"]
313313
inputs = ["dist/mkdocstrings_python_xref-*-none-any.whl"]
314+
outputs = ["dist/mkdocstrings_python_xref-*-py_0.conda"]
314315

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

369370
[tool.pixi.tasks.show-version]
370371
env = {VERSION = "$(cat src/mkdocstrings_handlers/python_xref/VERSION)"}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.1
1+
2.1.0

0 commit comments

Comments
 (0)