From bb36fa1fdc9d0fba1211fbfea2d50768b126a282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 20 May 2025 13:02:38 +0200 Subject: [PATCH 01/46] chore: Template upgrade --- .copier-answers.yml | 2 +- docs/css/material.css | 2 +- mkdocs.yml | 9 +++++---- pyproject.toml | 6 +++--- tests/test_api.py | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index b2cee68e..76531124 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier. -_commit: 1.4.0 +_commit: 1.4.5 _src_path: gh:mkdocstrings/handler-template author_email: dev@pawamoy.fr author_fullname: Timothée Mazzucotelli diff --git a/docs/css/material.css b/docs/css/material.css index 19c6b076..235ef946 100644 --- a/docs/css/material.css +++ b/docs/css/material.css @@ -23,4 +23,4 @@ background-color: rgb(220, 139, 240); -webkit-mask-image: var(--md-admonition-icon--preview); mask-image: var(--md-admonition-icon--preview); -} \ No newline at end of file +} diff --git a/mkdocs.yml b/mkdocs.yml index 6fc301b0..0199ea9a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -182,11 +182,12 @@ plugins: summary: true unwrap_annotated: true - llmstxt: - files: - - output: llms-full.txt - inputs: + full_output: llms-full.txt + sections: + Usage: - index.md - - reference/**.md + API: + - reference/api.md - git-revision-date-localized: enabled: !ENV [DEPLOY, false] enable_creation_date: true diff --git a/pyproject.toml b/pyproject.toml index 54f27585..d93cb20c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ includes = ["src/mkdocstrings_handlers"] editable-backend = "editables" # Include as much as possible in the source distribution, to help redistributors. -excludes = ["**/.pytest_cache"] +excludes = ["**/.pytest_cache", "**/.mypy_cache"] source-includes = [ "config", "docs", @@ -105,13 +105,13 @@ ci = [ "mkdocs>=1.6", "mkdocs-coverage>=1.0", "mkdocs-git-revision-date-localized-plugin>=1.2", - "mkdocs-llmstxt>=0.1", + "mkdocs-llmstxt>=0.2", "mkdocs-material>=9.5", - "pydantic>=2.10", "mkdocs-minify-plugin>=0.8", "mkdocs-redirects>=1.2", "mkdocs-section-index>=0.3", "mkdocstrings>=0.29", + "pydantic>=2.10", # YORE: EOL 3.10: Remove line. "tomli>=2.0; python_version < '3.11'", ] diff --git a/tests/test_api.py b/tests/test_api.py index 490bd82d..6d0b8738 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -145,7 +145,7 @@ def test_api_matches_inventory(inventory: Inventory, public_objects: list[griffe def _module_or_child(parent: str, name: str) -> bool: - parents = [parent[: i + 1] for i, char in enumerate(parent) if char == "."] + parents = [parent[:i] for i, char in enumerate(parent) if char == "."] parents.append(parent) return name in parents or name.startswith(parent + ".") From d4e618ab794747b84dced848b1be824639fea2b8 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 May 2025 04:11:46 -0700 Subject: [PATCH 02/46] fix: Render attribute names without full path in ToC Issue-271: https://github.com/mkdocstrings/python/issues/271 PR-272: https://github.com/mkdocstrings/python/pull/272 --- .../python/templates/material/_base/attribute.html.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja index 7894c544..dd258191 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja @@ -39,7 +39,7 @@ Context: role="data" if attribute.parent.kind.value == "module" else "attr", id=html_id, class="doc doc-heading", - toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute_name), + toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute.name), ) %} {% block heading scoped %} From 096960abd79831d6fd45e2a7962dfd2bd49e4edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 20 May 2025 14:37:42 +0200 Subject: [PATCH 03/46] fix: Use configured heading even when signature is not separated Issue-mkdocstrings-767: https://github.com/mkdocstrings/mkdocstrings/issues/767 PR-278: https://github.com/mkdocstrings/python/pull/278 --- .../material/_base/attribute.html.jinja | 6 ++- .../templates/material/_base/class.html.jinja | 6 ++- .../material/_base/function.html.jinja | 6 ++- .../material/_base/module.html.jinja | 6 ++- tests/snapshots/__init__.py | 18 +++++++ ...b25994087bc836868f63da18557a6094a00ee.html | 20 ++++++++ ...45132d578af0e1df1219c08bc9ea0bea1f39c.html | 18 +++++++ ...6d547a80dfbb41a311dabd94b96fd968b83bc.html | 18 +++++++ ...2a8236f43cade477f95e4ce4c9a60248f0a10.html | 20 ++++++++ tests/test_end_to_end.py | 51 ++++++++++++++++++- 10 files changed, 159 insertions(+), 10 deletions(-) create mode 100644 tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html create mode 100644 tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html create mode 100644 tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html create mode 100644 tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja index dd258191..519590e5 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja @@ -48,8 +48,10 @@ Context: This block renders the heading for the attribute. -#} {% if config.show_symbol_type_heading %}{% endif %} - {% if config.separate_signature %} - {{ config.heading if config.heading and root else attribute_name }} + {% if config.heading and root %} + {{ config.heading }} + {% elif config.separate_signature %} + {{ attribute_name }} {% else %} {%+ filter highlight(language="python", inline=True) %} {{ attribute_name }}{% if attribute.annotation and config.show_signature_annotations %}: {{ attribute.annotation }}{% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index ae2f8de5..8a54dd1b 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -47,8 +47,10 @@ Context: This block renders the heading for the class. -#} {% if config.show_symbol_type_heading %}{% endif %} - {% if config.separate_signature %} - {{ config.heading if config.heading and root else class_name }} + {% if config.heading and root %} + {{ config.heading }} + {% elif config.separate_signature %} + {{ class_name }} {% elif config.merge_init_into_class and "__init__" in all_members %} {% with function = all_members["__init__"] %} {%+ filter highlight(language="python", inline=True) -%} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja index e56bc7e4..21888939 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja @@ -54,8 +54,10 @@ Context: This block renders the heading for the function. -#} {% if config.show_symbol_type_heading %}{% endif %} - {% if config.separate_signature %} - {{ config.heading if config.heading and root else function_name }} + {% if config.heading and root %} + {{ config.heading }} + {% elif config.separate_signature %} + {{ function_name }} {% else %} {%+ filter highlight(language="python", inline=True) -%} {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja index d2b5516d..283f2654 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja @@ -47,8 +47,10 @@ Context: This block renders the heading for the module. -#} {% if config.show_symbol_type_heading %}{% endif %} - {% if config.separate_signature %} - {{ config.heading if config.heading and root else module_name }} + {% if config.heading and root %} + {{ config.heading }} + {% elif config.separate_signature %} + {{ module_name }} {% else %} {{ module_name }} {% endif %} diff --git a/tests/snapshots/__init__.py b/tests/snapshots/__init__.py index e411bfa8..556133ac 100644 --- a/tests/snapshots/__init__.py +++ b/tests/snapshots/__init__.py @@ -383,5 +383,23 @@ (("filters", "public"), ("inherited_members", False), ("members", ("module_attribute",))): external( "80399c502938*.html", ), + (("heading", ""), ("members", False), ("separate_signature", False), ("show_if_no_docstring", True)): external( + "d1dd339f9260*.html", + ), + ( + ("heading", "Some heading"), + ("members", False), + ("separate_signature", True), + ("show_if_no_docstring", True), + ): external("480324b25439*.html"), + (("heading", ""), ("members", False), ("separate_signature", True), ("show_if_no_docstring", True)): external( + "2eef87791b97*.html", + ), + ( + ("heading", "Some heading"), + ("members", False), + ("separate_signature", False), + ("show_if_no_docstring", True), + ): external("51deee0f00f3*.html"), }, ) diff --git a/tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html b/tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html new file mode 100644 index 00000000..f0242792 --- /dev/null +++ b/tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html @@ -0,0 +1,20 @@ + + +
+

+ + headings_package + +

+
+
+
+
+
diff --git a/tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html b/tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html new file mode 100644 index 00000000..fd1f953b --- /dev/null +++ b/tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html @@ -0,0 +1,18 @@ + + +
+

+ Some heading +

+
+
+
+
+
diff --git a/tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html b/tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html new file mode 100644 index 00000000..8601ee01 --- /dev/null +++ b/tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html @@ -0,0 +1,18 @@ + + +
+

+ Some heading +

+
+
+
+
+
diff --git a/tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html b/tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html new file mode 100644 index 00000000..a9dd1e61 --- /dev/null +++ b/tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html @@ -0,0 +1,20 @@ + + +
+

+ + headings_package + +

+
+
+
+
+
diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index 7a26cb53..3a96f803 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -59,7 +59,7 @@ def _render_options(options: dict[str, Any]) -> str: return f"\n\n" -# Signature options +# Signature tests. @pytest.fixture(name="signature_package", scope="session") def _signature_package() -> Iterator[TmpPackage]: code = """ @@ -108,7 +108,7 @@ def test_end_to_end_for_signatures( assert outsource(html, suffix=".html") == snapshots_signatures[snapshot_key] -# Members options. +# Member tests. @pytest.fixture(name="members_package", scope="session") def _members_package() -> Iterator[TmpPackage]: code = """ @@ -171,3 +171,50 @@ def test_end_to_end_for_members( html = _render_options(final_options) + _render(session_handler, members_package, final_options) snapshot_key = tuple(sorted(final_options.items())) assert outsource(html, suffix=".html") == snapshots_members[snapshot_key] + + +# Heading tests. +@pytest.fixture(name="headings_package", scope="session") +def _headings_package() -> Iterator[TmpPackage]: + code = """ + def module_function(a: int, b: str) -> None: + pass + + class Class: + class_attribute: int = 42 + + def __init__(self, a: int, b: str) -> None: + self.instance_attribute = a + b + + def method1(self, a: int, b: str) -> None: + pass + + module_attribute: int = 42 + """ + with temporary_pypackage("headings_package", {"__init__.py": code}) as tmppkg: + yield tmppkg + + +@pytest.mark.parametrize("separate_signature", [True, False]) +@pytest.mark.parametrize("heading", ["", "Some heading"]) +def test_end_to_end_for_headings( + session_handler: PythonHandler, + headings_package: TmpPackage, + separate_signature: bool, + heading: str, +) -> None: + """Test rendering of a given theme's templates. + + Parameters: + identifier: Parametrized identifier. + session_handler: Python handler (fixture). + """ + final_options = { + "separate_signature": separate_signature, + "heading": heading, + "show_if_no_docstring": True, + "members": False, + } + html = _render_options(final_options) + _render(session_handler, headings_package, final_options) + snapshot_key = tuple(sorted(final_options.items())) + assert outsource(html, suffix=".html") == snapshots_members[snapshot_key] From ba669697daad5067ea5db3fdf8a2d5ba2f966b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 20 May 2025 14:50:03 +0200 Subject: [PATCH 04/46] fix: Prevent uppercasing H5 titles (by Material for MkDocs) Issue-mkdocstrings-697: https://github.com/mkdocstrings/mkdocstrings/issues/697 Issue-276: https://github.com/mkdocstrings/python/issues/276 --- .../python/templates/material/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css index e5e150ec..33f63042 100644 --- a/src/mkdocstrings_handlers/python/templates/material/style.css +++ b/src/mkdocstrings_handlers/python/templates/material/style.css @@ -9,6 +9,11 @@ display: inline; } +/* No text transformation from Material for MkDocs for H5 headings. */ +.md-typeset h5 .doc-object-name { + text-transform: none; +} + /* Max width for docstring sections tables. */ .doc .md-typeset__table, .doc .md-typeset__table table { From 0a35b20a6050a28ba8492d93e5f9940a69462ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 20 May 2025 14:50:31 +0200 Subject: [PATCH 05/46] fix: Use default font-size for parameter headings Issue-mkdocstrings-697: https://github.com/mkdocstrings/mkdocstrings/issues/697 --- .../python/templates/material/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css index 33f63042..b8c3e639 100644 --- a/src/mkdocstrings_handlers/python/templates/material/style.css +++ b/src/mkdocstrings_handlers/python/templates/material/style.css @@ -35,6 +35,11 @@ display: inline; } +/* Default font size for parameter headings. */ +.md-typeset .doc-heading-parameter { + font-size: inherit; +} + /* Prefer space on the right, not the left of parameter permalinks. */ .doc-heading-parameter .headerlink { margin-left: 0 !important; From 7f956868f93a766346455fedb296c26787894d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 23 May 2025 15:10:20 +0200 Subject: [PATCH 06/46] fix: Fix highlighting for signature with known special names like `__init__` Issue-mkdocstrings-757: https://github.com/mkdocstrings/mkdocstrings/issues/757 --- .../python/_internal/rendering.py | 10 ++++++---- tests/snapshots/__init__.py | 8 ++++---- ...1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html} | 2 +- ...3050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html} | 2 +- ...8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html} | 2 +- ...2264400a83a1e693c146feec7c359855c676c4a586392.html} | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) rename tests/snapshots/external/{9c0bfc0ee40732505dc3dab8c95ad4ed6582d10df2449c7d92f1e43a91610666.html => 4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html} (93%) rename tests/snapshots/external/{f5ce06acbb7a31658cc6367db31caaf7a210c0a31e71de950e791c5eb33a6258.html => 74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html} (89%) rename tests/snapshots/external/{4370d843cc76138927502402ac39c80414c8441a962f6466afdb280dc022af26.html => d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html} (93%) rename tests/snapshots/external/{261a38d7a86b5e959b6d1c165108301963d0170c2189d5aa18bb7c7eade84ea4.html => e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html} (85%) diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 8f544014..902d794e 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -185,10 +185,12 @@ def do_format_signature( # Pygments sees it as a function call and not a function definition. # The result is that the function name is not parsed as such, # but instead as a regular name: `n` CSS class instead of `nf`. - # To fix it, we replace the first occurrence of an `n` CSS class - # with an `nf` one, unless we found `nf` already. - if signature.find('class="nf"') == -1: - signature = signature.replace('class="n"', 'class="nf"', 1) + # When the function name is a known special name like `__exit__`, + # Pygments will set an `fm` (function -> magic) CSS class. + # To fix this, we replace the CSS class in the first span with `nf`, + # unless we already found an `nf` span. + if not re.search(r'', signature): + signature = re.sub(r'', '', signature, count=1) if stash := env.filters["stash_crossref"].stash: for key, value in stash.items(): diff --git a/tests/snapshots/__init__.py b/tests/snapshots/__init__.py index 556133ac..36eb97b7 100644 --- a/tests/snapshots/__init__.py +++ b/tests/snapshots/__init__.py @@ -8,12 +8,12 @@ ("separate_signature", True), ("show_signature_annotations", False), ("signature_crossrefs", False), - ): external("4370d843cc76*.html"), + ): external("d03d16d1919a*.html"), ( ("separate_signature", True), ("show_signature_annotations", True), ("signature_crossrefs", True), - ): external("261a38d7a86b*.html"), + ): external("e412376be64f*.html"), ( ("separate_signature", False), ("show_signature_annotations", True), @@ -33,12 +33,12 @@ ("separate_signature", True), ("show_signature_annotations", True), ("signature_crossrefs", False), - ): external("f5ce06acbb7a*.html"), + ): external("74ee37cd1e94*.html"), ( ("separate_signature", True), ("show_signature_annotations", False), ("signature_crossrefs", True), - ): external("9c0bfc0ee407*.html"), + ): external("4041a38e355f*.html"), ( ("separate_signature", False), ("show_signature_annotations", True), diff --git a/tests/snapshots/external/9c0bfc0ee40732505dc3dab8c95ad4ed6582d10df2449c7d92f1e43a91610666.html b/tests/snapshots/external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html similarity index 93% rename from tests/snapshots/external/9c0bfc0ee40732505dc3dab8c95ad4ed6582d10df2449c7d92f1e43a91610666.html rename to tests/snapshots/external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html index 6dd48d30..8454da6d 100644 --- a/tests/snapshots/external/9c0bfc0ee40732505dc3dab8c95ad4ed6582d10df2449c7d92f1e43a91610666.html +++ b/tests/snapshots/external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html @@ -36,7 +36,7 @@

-
__init__(a, b)
+        
__init__(a, b)
 
diff --git a/tests/snapshots/external/f5ce06acbb7a31658cc6367db31caaf7a210c0a31e71de950e791c5eb33a6258.html b/tests/snapshots/external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html similarity index 89% rename from tests/snapshots/external/f5ce06acbb7a31658cc6367db31caaf7a210c0a31e71de950e791c5eb33a6258.html rename to tests/snapshots/external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html index 08ae8776..9edcf4c5 100644 --- a/tests/snapshots/external/f5ce06acbb7a31658cc6367db31caaf7a210c0a31e71de950e791c5eb33a6258.html +++ b/tests/snapshots/external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html @@ -36,7 +36,7 @@

-
__init__(a: int, b: str) -> None
+        
__init__(a: int, b: str) -> None
 
diff --git a/tests/snapshots/external/4370d843cc76138927502402ac39c80414c8441a962f6466afdb280dc022af26.html b/tests/snapshots/external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html similarity index 93% rename from tests/snapshots/external/4370d843cc76138927502402ac39c80414c8441a962f6466afdb280dc022af26.html rename to tests/snapshots/external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html index c70d8ae8..03d9e14d 100644 --- a/tests/snapshots/external/4370d843cc76138927502402ac39c80414c8441a962f6466afdb280dc022af26.html +++ b/tests/snapshots/external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html @@ -36,7 +36,7 @@

-
__init__(a, b)
+        
__init__(a, b)
 
diff --git a/tests/snapshots/external/261a38d7a86b5e959b6d1c165108301963d0170c2189d5aa18bb7c7eade84ea4.html b/tests/snapshots/external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html similarity index 85% rename from tests/snapshots/external/261a38d7a86b5e959b6d1c165108301963d0170c2189d5aa18bb7c7eade84ea4.html rename to tests/snapshots/external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html index 2170787f..e9ac18ce 100644 --- a/tests/snapshots/external/261a38d7a86b5e959b6d1c165108301963d0170c2189d5aa18bb7c7eade84ea4.html +++ b/tests/snapshots/external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html @@ -36,7 +36,7 @@

-
__init__(a: int, b: str) -> None
+        
__init__(a: int, b: str) -> None
 
From 5d2ba0aa557f683c3f7338d61810034c9af4ab11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sat, 24 May 2025 12:35:37 +0200 Subject: [PATCH 07/46] chore: Prepare release 1.16.11 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8798a05a..b01d34c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.16.11](https://github.com/mkdocstrings/python/releases/tag/1.16.11) - 2025-05-24 + +[Compare with 1.16.10](https://github.com/mkdocstrings/python/compare/1.16.10...1.16.11) + +### Bug Fixes + +- Fix highlighting for signature with known special names like `__init__` ([7f95686](https://github.com/mkdocstrings/python/commit/7f956868f93a766346455fedb296c26787894d5c) by Timothée Mazzucotelli). [Issue-mkdocstrings-757](https://github.com/mkdocstrings/mkdocstrings/issues/757) +- Use default font-size for parameter headings ([0a35b20](https://github.com/mkdocstrings/python/commit/0a35b20a6050a28ba8492d93e5f9940a69462ce3) by Timothée Mazzucotelli). [Issue-mkdocstrings-697](https://github.com/mkdocstrings/mkdocstrings/issues/697) +- Prevent uppercasing H5 titles (by Material for MkDocs) ([ba66969](https://github.com/mkdocstrings/python/commit/ba669697daad5067ea5db3fdf8a2d5ba2f966b25) by Timothée Mazzucotelli). [Issue-mkdocstrings-697](https://github.com/mkdocstrings/mkdocstrings/issues/697), [Issue-276](https://github.com/mkdocstrings/python/issues/276) +- Use configured heading even when signature is not separated ([096960a](https://github.com/mkdocstrings/python/commit/096960abd79831d6fd45e2a7962dfd2bd49e4edd) by Timothée Mazzucotelli). [Issue-mkdocstrings-767](https://github.com/mkdocstrings/mkdocstrings/issues/767), [PR-278](https://github.com/mkdocstrings/python/pull/278) +- Render attribute names without full path in ToC ([d4e618a](https://github.com/mkdocstrings/python/commit/d4e618ab794747b84dced848b1be824639fea2b8) by David Lee). [Issue-271](https://github.com/mkdocstrings/python/issues/271), [PR-272](https://github.com/mkdocstrings/python/pull/272) + ## [1.16.10](https://github.com/mkdocstrings/python/releases/tag/1.16.10) - 2025-04-03 [Compare with 1.16.9](https://github.com/mkdocstrings/python/compare/1.16.9...1.16.10) From d57740f874f056fb3ba1c6013ad04227df0f0af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 2 Jun 2025 13:38:20 +0200 Subject: [PATCH 08/46] fix: Only replace CSS class in first *highlighting* span When `pymdownx.highlight` sets `auto_title: true`, another span is rendered before the highlighted code. If we replace its CSS class, we mess its final display. Our solution is not very robust: we only look for spans with CSS classes of 1 or 2 characters instead of 1 or more characters. Issue-281: https://github.com/mkdocstrings/python/issues/281 --- src/mkdocstrings_handlers/python/_internal/rendering.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 902d794e..897b6572 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -190,7 +190,7 @@ def do_format_signature( # To fix this, we replace the CSS class in the first span with `nf`, # unless we already found an `nf` span. if not re.search(r'', signature): - signature = re.sub(r'', '', signature, count=1) + signature = re.sub(r'', '', signature, count=1) if stash := env.filters["stash_crossref"].stash: for key, value in stash.items(): From 3c4424d4ff63dacb6e4bf4e7a8c462ea377fb1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 3 Jun 2025 14:52:03 +0200 Subject: [PATCH 09/46] chore: Prepare release 1.16.12 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b01d34c8..ea4f1cf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.16.12](https://github.com/mkdocstrings/python/releases/tag/1.16.12) - 2025-06-03 + +[Compare with 1.16.11](https://github.com/mkdocstrings/python/compare/1.16.11...1.16.12) + +### Bug Fixes + +- Only replace CSS class in first *highlighting* span ([d57740f](https://github.com/mkdocstrings/python/commit/d57740f874f056fb3ba1c6013ad04227df0f0af8) by Timothée Mazzucotelli). [Issue-281](https://github.com/mkdocstrings/python/issues/281) + ## [1.16.11](https://github.com/mkdocstrings/python/releases/tag/1.16.11) - 2025-05-24 [Compare with 1.16.10](https://github.com/mkdocstrings/python/compare/1.16.10...1.16.11) From bac553d8bd87c2ca9a1cd67fc473e2686a4eedc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 3 Jun 2025 15:09:00 +0200 Subject: [PATCH 10/46] ci: Type variable to satisfy Mypy --- src/mkdocstrings_handlers/python/_internal/handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index 896a70e3..158d7ddc 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -360,7 +360,7 @@ def get_aliases(self, identifier: str) -> tuple[str, ...]: return tuple(f"{alias}({parameter})" for alias in aliases) return tuple(aliases) - def normalize_extension_paths(self, extensions: Sequence) -> Sequence: + def normalize_extension_paths(self, extensions: Sequence) -> list[str | dict[str, Any]]: """Resolve extension paths relative to config file. Parameters: @@ -369,7 +369,7 @@ def normalize_extension_paths(self, extensions: Sequence) -> Sequence: Returns: The normalized extensions. """ - normalized = [] + normalized: list[str | dict[str, Any]] = [] for ext in extensions: if isinstance(ext, dict): From f2b3bb07c52c967ad93452015f2dbdc54383ecaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 1 Jul 2025 19:05:53 +0200 Subject: [PATCH 11/46] ci: Fix Ruff warnings --- duties.py | 2 +- src/mkdocstrings_handlers/python/_internal/rendering.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/duties.py b/duties.py index 18282747..2f09340f 100644 --- a/duties.py +++ b/duties.py @@ -240,7 +240,7 @@ def coverage(ctx: Context) -> None: @duty -def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report") -> None: +def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report") -> None: # noqa: PT028 """Run the test suite. Parameters: diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 897b6572..ce701114 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -261,7 +261,7 @@ def do_format_attribute( def do_order_members( members: Sequence[Object | Alias], order: Order | list[Order], - members_list: bool | list[str] | None, + members_list: bool | list[str] | None, # noqa: FBT001 ) -> Sequence[Object | Alias]: """Order members given an ordering method. @@ -522,7 +522,7 @@ def _get_formatter() -> Callable[[str, int], str]: def _get_ruff_formatter() -> Callable[[str, int], str] | None: try: - from ruff.__main__ import find_ruff_bin + from ruff.__main__ import find_ruff_bin # noqa: PLC0415 except ImportError: return None @@ -558,7 +558,7 @@ def formatter(code: str, line_length: int) -> str: def _get_black_formatter() -> Callable[[str, int], str] | None: try: - from black import InvalidInput, Mode, format_str + from black import InvalidInput, Mode, format_str # noqa: PLC0415 except ModuleNotFoundError: return None From d3b35e17384901e7280b8b6926f10fb033480358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Thu, 3 Jul 2025 16:31:31 +0200 Subject: [PATCH 12/46] feat: Support hiding implementation signature (showing overload only) Issue-213: https://github.com/mkdocstrings/python/issues/213 PR-286: https://github.com/mkdocstrings/python/pull/286 --- docs/usage/configuration/signatures.md | 50 +++++ .../python/_internal/config.py | 8 + .../material/_base/function.html.jinja | 2 +- tests/snapshots/__init__.py | 24 +++ ...805c6c2488b30461055f427156fa1567e51c1.html | 169 ++++++++++++++++ ...90888add55a0ff86d8932191bb726ebe1c443.html | 137 +++++++++++++ ...69808d0f3b67e28b1677f04ab965d1da2e6b3.html | 189 ++++++++++++++++++ ...dad2b07086db09c903a750af2f6be914fffb4.html | 189 ++++++++++++++++++ ...310b459b913f30b1bce149d805322d136c711.html | 169 ++++++++++++++++ ...260beecc355aaf82cd133e082e37883837002.html | 117 +++++++++++ ...7d37c09ec0b0294020d9337f34887d02590b5.html | 117 +++++++++++ ...1ab6f69201b959d606633320c9d53d2b3298b.html | 129 ++++++++++++ tests/test_end_to_end.py | 63 ++++++ 13 files changed, 1362 insertions(+), 1 deletion(-) create mode 100644 tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html create mode 100644 tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html create mode 100644 tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html create mode 100644 tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html create mode 100644 tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html create mode 100644 tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html create mode 100644 tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html create mode 100644 tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md index 98c865e5..225be0b8 100644 --- a/docs/usage/configuration/signatures.md +++ b/docs/usage/configuration/signatures.md @@ -286,6 +286,56 @@ plugins: /// +[](){#option-overloads_only} +## `overloads_only` + +Whether to hide the implementation signature if the overloads are shown with [`show_overloads`][]. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + overloads_only: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + overloads_only: true +``` + +/// admonition | Preview + type: preview +//// tab | With overloads only +

function

+ +```python +@overload +function(param1: int): ... +@overload +function(param1: str): ... +``` +Function docstring. + +//// +//// tab | Without overloads only +

function

+ +```python +@overload +function(param1: int): ... +@overload +function(param1: str): ... +function(param1: str | int) +``` +Function docstring. + +//// + +/// + [](){#option-show_signature} ## `show_signature` diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 210f8fe2..5c754088 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -554,6 +554,14 @@ class PythonInputOptions: ), ] = False + overloads_only: Annotated[ + bool, + _Field( + group="signatures", + description="Whether to hide the implementation signature if the overloads are shown.", + ), + ] = False + parameter_headings: Annotated[ bool, _Field( diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja index 21888939..cd97c8db 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja @@ -94,7 +94,7 @@ Context: {% endfor %}
{% endif %} - {% if config.separate_signature %} + {% if config.separate_signature and not (config.show_overloads and function.overloads and config.overloads_only) %} {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %} {{ function.name }} {% endfilter %} diff --git a/tests/snapshots/__init__.py b/tests/snapshots/__init__.py index 36eb97b7..f79db237 100644 --- a/tests/snapshots/__init__.py +++ b/tests/snapshots/__init__.py @@ -44,6 +44,30 @@ ("show_signature_annotations", True), ("signature_crossrefs", False), ): external("d1216ebf8e30*.html"), + (("overloads_only", False), ("separate_signature", True), ("show_overloads", True)): external( + "19a1066a31c4*.html", + ), + (("overloads_only", False), ("separate_signature", True), ("show_overloads", False)): external( + "728ef9e28d86*.html", + ), + (("overloads_only", True), ("separate_signature", False), ("show_overloads", True)): external( + "30b2733496a8*.html", + ), + (("overloads_only", False), ("separate_signature", False), ("show_overloads", True)): external( + "35c8879435c0*.html", + ), + (("overloads_only", False), ("separate_signature", False), ("show_overloads", False)): external( + "45fa32980cab*.html", + ), + (("overloads_only", True), ("separate_signature", True), ("show_overloads", False)): external( + "90ca219874af*.html", + ), + (("overloads_only", True), ("separate_signature", True), ("show_overloads", True)): external( + "fca9fb3aa9f5*.html", + ), + (("overloads_only", True), ("separate_signature", False), ("show_overloads", False)): external( + "17e520187500*.html", + ), }, ) diff --git a/tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html b/tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html new file mode 100644 index 00000000..23a1a9c5 --- /dev/null +++ b/tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html @@ -0,0 +1,169 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html b/tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html new file mode 100644 index 00000000..3f231581 --- /dev/null +++ b/tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html @@ -0,0 +1,137 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + foo + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+
foo(a, b)
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + foo + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+
foo(a, b)
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html b/tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html new file mode 100644 index 00000000..79b078af --- /dev/null +++ b/tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html @@ -0,0 +1,189 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html b/tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html new file mode 100644 index 00000000..afa94fae --- /dev/null +++ b/tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html @@ -0,0 +1,189 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html b/tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html new file mode 100644 index 00000000..76234631 --- /dev/null +++ b/tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html @@ -0,0 +1,169 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + + bar + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + + foo + + + ( + + + a + + + , + + + b + + + ) + + +

+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html b/tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html new file mode 100644 index 00000000..96629ba3 --- /dev/null +++ b/tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html @@ -0,0 +1,117 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + foo + +

+
+
foo(a, b)
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + foo + +

+
+
foo(a, b)
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html b/tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html new file mode 100644 index 00000000..1f1c5822 --- /dev/null +++ b/tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html @@ -0,0 +1,117 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + foo + +

+
+
foo(a, b)
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + foo + +

+
+
foo(a, b)
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html b/tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html new file mode 100644 index 00000000..7d4b3416 --- /dev/null +++ b/tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html @@ -0,0 +1,129 @@ + + +
+

+ + overloads_package + +

+
+
+
+

+ + Class + +

+
+

+ Docstring for + + Class + + . +

+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + Class.bar + + . +

+
+
+
+

+ + foo + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + Class.foo + + . +

+
+
+
+
+
+
+

+ + bar + +

+
+
bar(a, b)
+
+
+
+

+ Docstring for + + bar + + . +

+
+
+
+

+ + foo + +

+
+
+
foo(a: int, b: str) -> float
+
+
+
+
foo(a: str, b: int) -> None
+
+
+
+
+

+ Docstring for + + foo + + . +

+
+
+
+
+
diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index 3a96f803..4e749432 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -108,6 +108,69 @@ def test_end_to_end_for_signatures( assert outsource(html, suffix=".html") == snapshots_signatures[snapshot_key] +# Signature overloads tests. +@pytest.fixture(name="overloads_package", scope="session") +def _overloads_package() -> Iterator[TmpPackage]: + code = """ + from typing_extensions import overload + + @overload + def foo(a: int, b: str) -> float: ... + + @overload + def foo(a: str, b: int) -> None: ... + + def foo(a: str | int, b: int | str) -> float | None: + '''Docstring for `foo`.''' + + def bar(a: str, b: int | str) -> float | None: + '''Docstring for `bar`.''' + + class Class: + '''Docstring for `Class`.''' + + @overload + def foo(self, a: int, b: str) -> float: ... + + @overload + def foo(self, a: str, b: int) -> None: ... + + def foo(self, a: str | int, b: int | str) -> float | None: + '''Docstring for `Class.foo`.''' + + def bar(self, a: str, b: int | str) -> float | None: + '''Docstring for `Class.bar`.''' + """ + with temporary_pypackage("overloads_package", {"__init__.py": code}) as tmppkg: + yield tmppkg + + +@pytest.mark.parametrize("separate_signature", [True, False]) +@pytest.mark.parametrize("show_overloads", [True, False]) +@pytest.mark.parametrize("overloads_only", [True, False]) +def test_end_to_end_for_overloads( + session_handler: PythonHandler, + overloads_package: TmpPackage, + separate_signature: bool, + show_overloads: bool, + overloads_only: bool, +) -> None: + """Test rendering of a given theme's templates. + + Parameters: + identifier: Parametrized identifier. + session_handler: Python handler (fixture). + """ + final_options = { + "separate_signature": separate_signature, + "show_overloads": show_overloads, + "overloads_only": overloads_only, + } + html = _render_options(final_options) + _render(session_handler, overloads_package, final_options) + snapshot_key = tuple(sorted(final_options.items())) + assert outsource(html, suffix=".html") == snapshots_signatures[snapshot_key] + + # Member tests. @pytest.fixture(name="members_package", scope="session") def _members_package() -> Iterator[TmpPackage]: From 6cf34b9882e20d9147a6481e672ae09989a27796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Wed, 9 Jul 2025 22:21:20 +0200 Subject: [PATCH 13/46] feat: Support hiding attribute values Issue-292: #292 PR-293: #293 --- docs/usage/configuration/members.md | 44 +++++++++++++++++++ .../python/_internal/config.py | 8 ++++ .../python/_internal/rendering.py | 3 +- .../material/_base/attribute.html.jinja | 4 +- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/docs/usage/configuration/members.md b/docs/usage/configuration/members.md index 7a5069a1..4afdd310 100644 --- a/docs/usage/configuration/members.md +++ b/docs/usage/configuration/members.md @@ -519,6 +519,50 @@ def function_d(): //// /// + +[](){#option-show_attribute_values} +## `show_attribute_values` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + + +Show initial values of attributes in classes. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + show_attribute_values: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.object + options: + show_attribute_values: true +``` + +```python title="package/module.py" +class SomeClass: + def __init__(self): + self.some_attr = 1 +``` + +/// admonition | Preview + type: preview + +//// tab | With attribute values visible +

SomeClass

+

some_attr = 1

+//// + +//// tab | With attribute values hidden +

SomeClass

+

some_attr

+//// +/// + [](){#option-show_submodules} ## `show_submodules` diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 5c754088..5565e9b0 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -622,6 +622,14 @@ class PythonInputOptions: ), ] = False + show_attribute_values: Annotated[ + bool, + _Field( + group="members", + description="Show initial values of attributes in classes.", + ), + ] = True + show_bases: Annotated[ bool, _Field( diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index ce701114..70eacb36 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -208,6 +208,7 @@ def do_format_attribute( line_length: int, *, crossrefs: bool = False, # noqa: ARG001 + show_value: bool = True, ) -> str: """Format an attribute. @@ -235,7 +236,7 @@ def do_format_attribute( backlink_type="returned-by", ) signature += f": {annotation}" - if attribute.value: + if show_value and attribute.value: value = template.render(context.parent, expression=attribute.value, signature=True, backlink_type="used-by") signature += f" = {value}" diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja index 519590e5..5832c8bd 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja @@ -55,7 +55,7 @@ Context: {% else %} {%+ filter highlight(language="python", inline=True) %} {{ attribute_name }}{% if attribute.annotation and config.show_signature_annotations %}: {{ attribute.annotation }}{% endif %} - {% if attribute.value %} = {{ attribute.value }}{% endif %} + {% if config.show_attribute_values and attribute.value %} = {{ attribute.value }}{% endif %} {% endfilter %} {% endif %} {% endblock heading %} @@ -79,7 +79,7 @@ Context: This block renders the signature for the attribute. -#} {% if config.separate_signature %} - {% filter format_attribute(attribute, config.line_length, crossrefs=config.signature_crossrefs) %} + {% filter format_attribute(attribute, config.line_length, crossrefs=config.signature_crossrefs, show_value=config.show_attribute_values) %} {{ attribute.name }} {% endfilter %} {% endif %} From a1bce97bd3edc75b19174f6132e9320fd1ab286a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 14 Jul 2025 13:30:41 +0200 Subject: [PATCH 14/46] docs: Move `show_attribute_values` option into "signatures" group --- docs/usage/configuration/members.md | 44 ------------------- docs/usage/configuration/signatures.md | 43 ++++++++++++++++++ .../python/_internal/config.py | 2 +- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/docs/usage/configuration/members.md b/docs/usage/configuration/members.md index 4afdd310..7a5069a1 100644 --- a/docs/usage/configuration/members.md +++ b/docs/usage/configuration/members.md @@ -519,50 +519,6 @@ def function_d(): //// /// - -[](){#option-show_attribute_values} -## `show_attribute_values` - -- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** - - -Show initial values of attributes in classes. - -```yaml title="in mkdocs.yml (global configuration)" -plugins: -- mkdocstrings: - handlers: - python: - options: - show_attribute_values: true -``` - -```md title="or in docs/some_page.md (local configuration)" -::: path.to.object - options: - show_attribute_values: true -``` - -```python title="package/module.py" -class SomeClass: - def __init__(self): - self.some_attr = 1 -``` - -/// admonition | Preview - type: preview - -//// tab | With attribute values visible -

SomeClass

-

some_attr = 1

-//// - -//// tab | With attribute values hidden -

SomeClass

-

some_attr

-//// -/// - [](){#option-show_submodules} ## `show_submodules` diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md index 225be0b8..c49cd181 100644 --- a/docs/usage/configuration/signatures.md +++ b/docs/usage/configuration/signatures.md @@ -483,6 +483,49 @@ function(param1, param2=None) //// /// +[](){#option-show_attribute_values} +## `show_attribute_values` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + + +Show initial values of attributes in classes. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + show_attribute_values: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.object + options: + show_attribute_values: true +``` + +```python title="package/module.py" +class SomeClass: + def __init__(self): + self.some_attr = 1 +``` + +/// admonition | Preview + type: preview + +//// tab | With attribute values visible +

SomeClass

+

some_attr = 1

+//// + +//// tab | With attribute values hidden +

SomeClass

+

some_attr

+//// +/// + [](){#option-show_overloads} ## `show_overloads` diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 5565e9b0..c0f9b79e 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -625,7 +625,7 @@ class PythonInputOptions: show_attribute_values: Annotated[ bool, _Field( - group="members", + group="signatures", description="Show initial values of attributes in classes.", ), ] = True From 17f71babf11081869478b21b2bde1a33fc97be41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 23 Jul 2025 19:57:18 +0200 Subject: [PATCH 15/46] refactor: Deprecate `locale` option in favor of mkdocstrings' PR-288: https://github.com/mkdocstrings/python/pull/288 --- docs/usage/index.md | 6 ++++-- src/mkdocstrings_handlers/python/_internal/config.py | 4 +++- src/mkdocstrings_handlers/python/_internal/handler.py | 7 +++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/usage/index.md b/docs/usage/index.md index b2a00955..e1fa457f 100644 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -150,9 +150,11 @@ plugins: [__all__]: https://docs.python.org/3/tutorial/modules.html#importing-from-a-package [](){#setting-locale} -#### `locale` +#### ~~`locale`~~ -The locale to use when translating template strings. The translation system is not fully ready yet, so we don't recommend setting the option for now. +**Deprecated.** Use mkdocstrings' own `locale` setting. + +~~The locale to use when translating template strings.~~ [](){#setting-paths} #### `paths` diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index c0f9b79e..6a68e353 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -1035,7 +1035,9 @@ class PythonInputConfig: locale: Annotated[ str | None, - _Field(description="The locale to use when translating template strings."), + _Field( + description="Deprecated. Use mkdocstrings' own `locale` setting instead. The locale to use when translating template strings.", + ), ] = None @classmethod diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index 158d7ddc..8bc40d27 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -278,12 +278,13 @@ def collect(self, identifier: str, options: PythonOptions) -> CollectorItem: return doc_object - def render(self, data: CollectorItem, options: PythonOptions) -> str: + def render(self, data: CollectorItem, options: PythonOptions, locale: str | None = None) -> str: """Render the collected data. Parameters: data: The collected data. options: The options to use for rendering. + locale: The locale to use for rendering (default is "en"). Returns: The rendered data (HTML). @@ -300,7 +301,8 @@ def render(self, data: CollectorItem, options: PythonOptions) -> str: # than as an item in a dictionary. "heading_level": options.heading_level, "root": True, - "locale": self.config.locale, + # YORE: Bump 2: Regex-replace ` or .+` with ` or "en",` within line. + "locale": locale or self.config.locale, }, ) @@ -401,6 +403,7 @@ def get_handler( Parameters: handler_config: The handler configuration. tool_config: The tool (SSG) configuration. + **kwargs: Additional arguments to pass to the handler. Returns: An instance of `PythonHandler`. From 864e52800c6c95a8c9d159f2b120fd13f09762e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 23 Jul 2025 20:32:24 +0200 Subject: [PATCH 16/46] tests: Fix usage of new inline-snapshot version --- pyproject.toml | 2 +- tests/test_end_to_end.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d93cb20c..8adc2a30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ ci = [ "pytest-randomly>=3.15", "pytest-xdist>=3.6", "beautifulsoup4>=4.12.3", - "inline-snapshot>=0.18", + "inline-snapshot>=0.25", "mypy>=1.10", "types-markdown>=3.6", "types-pyyaml>=6.0", diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index 4e749432..f9cd1244 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -9,7 +9,7 @@ import bs4 import pytest from griffe import LinesCollection, ModulesCollection, TmpPackage, temporary_pypackage -from inline_snapshot import outsource +from inline_snapshot import outsource, register_format_alias from tests.snapshots import snapshots_members, snapshots_signatures @@ -19,6 +19,9 @@ from mkdocstrings_handlers.python import PythonHandler +register_format_alias(".html", ".txt") + + def _normalize_html(html: str) -> str: soup = bs4.BeautifulSoup(html, features="html.parser") html = soup.prettify() # type: ignore[assignment] From b3decd4f49cd6ffeb9c7e3c72d9c86122e79afa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 23 Jul 2025 22:19:50 +0200 Subject: [PATCH 17/46] tests: Use new `external_file` helper from inline-snapshot --- tests/snapshots/__init__.py | 429 ------------------ tests/snapshots/external/.gitignore | 2 - .../heading=,separate_signature=False.html} | 4 +- .../heading=,separate_signature=True.html} | 4 +- ...ome heading,separate_signature=False.html} | 4 +- ...Some heading,separate_signature=True.html} | 4 +- ...od1',),members=('module_attribute',).html} | 0 ...ited_members=('method1',),members=().html} | 0 ...d_members=('method1',),members=False.html} | 0 ...ed_members=('method1',),members=None.html} | 0 ...ed_members=('method1',),members=True.html} | 0 ...ers=(),members=('module_attribute',).html} | 0 ...e',),inherited_members=(),members=().html} | 0 ...),inherited_members=(),members=False.html} | 0 ...,),inherited_members=(),members=None.html} | 0 ...,),inherited_members=(),members=True.html} | 0 ...=False,members=('module_attribute',).html} | 0 ...),inherited_members=False,members=().html} | 0 ...nherited_members=False,members=False.html} | 0 ...inherited_members=False,members=None.html} | 0 ...inherited_members=False,members=True.html} | 0 ...s=True,members=('module_attribute',).html} | 0 ...,),inherited_members=True,members=().html} | 0 ...inherited_members=True,members=False.html} | 0 ...,inherited_members=True,members=None.html} | 0 ...,inherited_members=True,members=True.html} | 0 ...od1',),members=('module_attribute',).html} | 0 ...ited_members=('method1',),members=().html} | 0 ...d_members=('method1',),members=False.html} | 0 ...ed_members=('method1',),members=None.html} | 0 ...ed_members=('method1',),members=True.html} | 0 ...ers=(),members=('module_attribute',).html} | 0 ...e',),inherited_members=(),members=().html} | 0 ...),inherited_members=(),members=False.html} | 0 ...,),inherited_members=(),members=None.html} | 0 ...,),inherited_members=(),members=True.html} | 0 ...=False,members=('module_attribute',).html} | 0 ...),inherited_members=False,members=().html} | 0 ...nherited_members=False,members=False.html} | 0 ...inherited_members=False,members=None.html} | 0 ...inherited_members=False,members=True.html} | 0 ...s=True,members=('module_attribute',).html} | 0 ...,),inherited_members=True,members=().html} | 0 ...inherited_members=True,members=False.html} | 0 ...,inherited_members=True,members=None.html} | 0 ...,inherited_members=True,members=True.html} | 0 ...od1',),members=('module_attribute',).html} | 0 ...ited_members=('method1',),members=().html} | 0 ...d_members=('method1',),members=False.html} | 0 ...ed_members=('method1',),members=None.html} | 0 ...ed_members=('method1',),members=True.html} | 0 ...ers=(),members=('module_attribute',).html} | 0 ...s=(),inherited_members=(),members=().html} | 0 ...),inherited_members=(),members=False.html} | 0 ...(),inherited_members=(),members=None.html} | 0 ...(),inherited_members=(),members=True.html} | 0 ...=False,members=('module_attribute',).html} | 0 ...),inherited_members=False,members=().html} | 0 ...nherited_members=False,members=False.html} | 0 ...inherited_members=False,members=None.html} | 0 ...inherited_members=False,members=True.html} | 0 ...s=True,members=('module_attribute',).html} | 0 ...(),inherited_members=True,members=().html} | 0 ...inherited_members=True,members=False.html} | 0 ...,inherited_members=True,members=None.html} | 0 ...,inherited_members=True,members=True.html} | 0 ...od1',),members=('module_attribute',).html} | 0 ...ited_members=('method1',),members=().html} | 0 ...d_members=('method1',),members=False.html} | 0 ...ed_members=('method1',),members=None.html} | 0 ...ed_members=('method1',),members=True.html} | 0 ...ers=(),members=('module_attribute',).html} | 0 ...None,inherited_members=(),members=().html} | 0 ...e,inherited_members=(),members=False.html} | 0 ...ne,inherited_members=(),members=None.html} | 0 ...ne,inherited_members=(),members=True.html} | 0 ...=False,members=('module_attribute',).html} | 0 ...e,inherited_members=False,members=().html} | 0 ...nherited_members=False,members=False.html} | 0 ...inherited_members=False,members=None.html} | 0 ...inherited_members=False,members=True.html} | 0 ...s=True,members=('module_attribute',).html} | 0 ...ne,inherited_members=True,members=().html} | 0 ...inherited_members=True,members=False.html} | 0 ...,inherited_members=True,members=None.html} | 0 ...,inherited_members=True,members=True.html} | 0 ...od1',),members=('module_attribute',).html} | 0 ...ited_members=('method1',),members=().html} | 0 ...d_members=('method1',),members=False.html} | 0 ...ed_members=('method1',),members=None.html} | 0 ...ed_members=('method1',),members=True.html} | 0 ...ers=(),members=('module_attribute',).html} | 0 ...blic,inherited_members=(),members=().html} | 0 ...c,inherited_members=(),members=False.html} | 0 ...ic,inherited_members=(),members=None.html} | 0 ...ic,inherited_members=(),members=True.html} | 0 ...=False,members=('module_attribute',).html} | 0 ...c,inherited_members=False,members=().html} | 0 ...nherited_members=False,members=False.html} | 0 ...inherited_members=False,members=None.html} | 0 ...inherited_members=False,members=True.html} | 0 ...s=True,members=('module_attribute',).html} | 0 ...ic,inherited_members=True,members=().html} | 0 ...inherited_members=True,members=False.html} | 0 ...,inherited_members=True,members=None.html} | 0 ...,inherited_members=True,members=True.html} | 0 ...signature=False,show_overloads=False.html} | 0 ..._signature=False,show_overloads=True.html} | 0 ..._signature=True,show_overloads=False.html} | 0 ...e_signature=True,show_overloads=True.html} | 0 ...signature=False,show_overloads=False.html} | 0 ..._signature=False,show_overloads=True.html} | 0 ..._signature=True,show_overloads=False.html} | 0 ...e_signature=True,show_overloads=True.html} | 0 ...ions=False,signature_crossrefs=False.html} | 0 ...tions=False,signature_crossrefs=True.html} | 0 ...tions=True,signature_crossrefs=False.html} | 0 ...ations=True,signature_crossrefs=True.html} | 0 ...ions=False,signature_crossrefs=False.html} | 0 ...tions=False,signature_crossrefs=True.html} | 0 ...tions=True,signature_crossrefs=False.html} | 0 ...ations=True,signature_crossrefs=True.html} | 0 tests/test_end_to_end.py | 39 +- 123 files changed, 22 insertions(+), 464 deletions(-) delete mode 100644 tests/snapshots/__init__.py delete mode 100644 tests/snapshots/external/.gitignore rename tests/snapshots/{external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html => headings/heading=,separate_signature=False.html} (76%) rename tests/snapshots/{external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html => headings/heading=,separate_signature=True.html} (79%) rename tests/snapshots/{external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html => headings/heading=Some heading,separate_signature=False.html} (75%) rename tests/snapshots/{external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html => headings/heading=Some heading,separate_signature=True.html} (75%) rename tests/snapshots/{external/26bc66c2ba29feddfbd06c2490eca42ec5a8f62db8d650231b0748ddce8c85f1.html => members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/42c053a5e567a777dfde62cd0d061112dc8098f90e71f71d5aceba8be188fcf7.html => members/filters=('!module_attribute',),inherited_members=('method1',),members=().html} (100%) rename tests/snapshots/{external/c6e7ef9564cdc8449a98c0ef790d652dee02c47b1339f858fc1d7a54aae9ed46.html => members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html} (100%) rename tests/snapshots/{external/fe1cd23642d405d0b2a4d29ec4a2125f55b54f90c2440ee2d856540415e77745.html => members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html} (100%) rename tests/snapshots/{external/9720526cf5e4c44f27695c59764bb1e05e428834744442f43527ebf2b8acfb35.html => members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html} (100%) rename tests/snapshots/{external/6d12192d6b4dc0633bad697a683a3cdf3b2b9ceeb839044c72c63b469914f0a1.html => members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/c260e7f4ef3b8b228bb25879d3adcf6610f1c2c971c9c46b5665d276716b8821.html => members/filters=('!module_attribute',),inherited_members=(),members=().html} (100%) rename tests/snapshots/{external/74bfab19cbd4ba02673f6b9ee736a3b6727936de92f73f299ba238491f619937.html => members/filters=('!module_attribute',),inherited_members=(),members=False.html} (100%) rename tests/snapshots/{external/3935bcf6d71b58daa0e4512cbf3f53e19516885fb65d0bd760c12aadd021507f.html => members/filters=('!module_attribute',),inherited_members=(),members=None.html} (100%) rename tests/snapshots/{external/84193b3c9f5d84fef33daa61fb61aa9a3e66171d312de8d7f836c69f0bc069b0.html => members/filters=('!module_attribute',),inherited_members=(),members=True.html} (100%) rename tests/snapshots/{external/247a6063b698c285bfef7addfd972ddf797f6a90dfd5a3e649e6e4c127b86562.html => members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/fb5ebb7546d8d63744d7e6713ab5317b8c3d00d1108d28d7ef2949994b41dcbd.html => members/filters=('!module_attribute',),inherited_members=False,members=().html} (100%) rename tests/snapshots/{external/eee65d3705a655eec6512c4aa09d55f5d2e7c62dd245fed4b3f002a5e9a4d646.html => members/filters=('!module_attribute',),inherited_members=False,members=False.html} (100%) rename tests/snapshots/{external/d556527026068280df9b77db277472320842cb1ae6099ac3cf558031afda6d2e.html => members/filters=('!module_attribute',),inherited_members=False,members=None.html} (100%) rename tests/snapshots/{external/fe25ab7600392b4fd3a1438fb54337041719faac884123527bab9a92e3a51be5.html => members/filters=('!module_attribute',),inherited_members=False,members=True.html} (100%) rename tests/snapshots/{external/96cf94f4822a5cf5d72407eab5a5dddda972f16623f7710f738ffe2bcf9130d9.html => members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/28d8862dd086c7d523516dd4091b57e5babd34165edccf619b62a06fc1936cd5.html => members/filters=('!module_attribute',),inherited_members=True,members=().html} (100%) rename tests/snapshots/{external/d726cb8367d95b67ce78e718e88ee528d3abc2fbd04413d1c11916a243d7567a.html => members/filters=('!module_attribute',),inherited_members=True,members=False.html} (100%) rename tests/snapshots/{external/8733f7fb7b6d28b15bbe736f29c7fd030467c0ccfa2cbc6a68616e06c6dc6a9b.html => members/filters=('!module_attribute',),inherited_members=True,members=None.html} (100%) rename tests/snapshots/{external/34b16654e7baa8e16315cef2919f2eafa51ba39ec28c4c970fe7ea8e2c79f9d2.html => members/filters=('!module_attribute',),inherited_members=True,members=True.html} (100%) rename tests/snapshots/{external/8b097c69ac2fd52857f33e1b008f4d99a53ed21894c51517b3d79da445b0a705.html => members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/f8f32ea6a0c80a63854f8c8d78b3706797feb3042ac88c8fcf0a6da277eddb9d.html => members/filters=('module_attribute',),inherited_members=('method1',),members=().html} (100%) rename tests/snapshots/{external/f0014d9505eceb38ba1e36c380a97ebe4d43669929ec1cdedba4d418899aecc7.html => members/filters=('module_attribute',),inherited_members=('method1',),members=False.html} (100%) rename tests/snapshots/{external/cfcd41685591bcc497f9d1e9fd20006fc3acd857f068e78e6d1c2461bbd4063f.html => members/filters=('module_attribute',),inherited_members=('method1',),members=None.html} (100%) rename tests/snapshots/{external/e8608b0de174402ca18f88ed58849312158c22f5bfdc845d2da02055fe14853c.html => members/filters=('module_attribute',),inherited_members=('method1',),members=True.html} (100%) rename tests/snapshots/{external/f6e292b8358a04e3471ba11c8820307076be3cf83b0a9ec2fb5c949324b7e172.html => members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/a185e216dc7b7ebb31b46ea0e7ed446cf9da94eee8db306f08bae1ca0db0ca1d.html => members/filters=('module_attribute',),inherited_members=(),members=().html} (100%) rename tests/snapshots/{external/76ee8e01e1c0b94de84d79da8443bc24f601f89cab70eae1b2af5ee21cfb1f3a.html => members/filters=('module_attribute',),inherited_members=(),members=False.html} (100%) rename tests/snapshots/{external/c9a15552eed32a233795c2086a7c766ad95e05197d30d881540fbe52cdc07ff8.html => members/filters=('module_attribute',),inherited_members=(),members=None.html} (100%) rename tests/snapshots/{external/13334b5b4fcf7267539b9eb99ca2ab79c66766ec6f35383f4bfcb6a8d9e2a116.html => members/filters=('module_attribute',),inherited_members=(),members=True.html} (100%) rename tests/snapshots/{external/5a9c10410801aa75b33878971b939da701df9a7ce8006dc7781c148d27a89756.html => members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/d5a6bf59c663338bef9fdc2391f482aee444228e86e23357c11881498e711bb2.html => members/filters=('module_attribute',),inherited_members=False,members=().html} (100%) rename tests/snapshots/{external/7107066872137b807b3f9d897e75eff78f5783b14d3c88e71c6477eaa8493113.html => members/filters=('module_attribute',),inherited_members=False,members=False.html} (100%) rename tests/snapshots/{external/62e18d3e57777d911c7fdee1fcc032a9c23ffe82913060e3b66f29bf81a6a585.html => members/filters=('module_attribute',),inherited_members=False,members=None.html} (100%) rename tests/snapshots/{external/cd3e458517147c43c360525140aa1b9a81682634aaf2674ffd4cceb7fc44aba6.html => members/filters=('module_attribute',),inherited_members=False,members=True.html} (100%) rename tests/snapshots/{external/8d4e1f9af9971bd21234c7c45dfbd59a1aee444bfa0cd3b9cfb6d052d378a041.html => members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/95f8e480937f7a2b956392ed4d8058052d9748874cdd911feacdd31d1abe5d97.html => members/filters=('module_attribute',),inherited_members=True,members=().html} (100%) rename tests/snapshots/{external/f3f3acb6b51ba98f5a06e7c62e85b791b6521504f19a8d7496592dee59c7f199.html => members/filters=('module_attribute',),inherited_members=True,members=False.html} (100%) rename tests/snapshots/{external/2bf34b4dd82e753b21200ec980cb197c530710fe8c150c4dd3fbbfb7d38928cc.html => members/filters=('module_attribute',),inherited_members=True,members=None.html} (100%) rename tests/snapshots/{external/3c21330afd6529769164afe388e9385a9fddb3ae628124965e0c7b81932a0c63.html => members/filters=('module_attribute',),inherited_members=True,members=True.html} (100%) rename tests/snapshots/{external/e90c3e0c85ddaa068f3d063c6a1ef718bb3ae2092760b707e838fb73164b3720.html => members/filters=(),inherited_members=('method1',),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/4892e0fe1920c0bb22fa4787b6e76cccaa968163b35641d705f288c04fe4937e.html => members/filters=(),inherited_members=('method1',),members=().html} (100%) rename tests/snapshots/{external/ab0ddac637b536c06014746a4a8f8e0921b074015ae19680abf5df995c233ba1.html => members/filters=(),inherited_members=('method1',),members=False.html} (100%) rename tests/snapshots/{external/e5dc372374af6f90a5d456d8683aacdf81104137ce91bd6d4121827f8d989d96.html => members/filters=(),inherited_members=('method1',),members=None.html} (100%) rename tests/snapshots/{external/cd51e40cc0ddf1d42b7c6bf7560ead2501370ee9d67499b74afc83e258caff8e.html => members/filters=(),inherited_members=('method1',),members=True.html} (100%) rename tests/snapshots/{external/388a13d71284b1a4b0c457e9c8d1ec60dfefb8871c69ceb1d7a035bd3bdadab8.html => members/filters=(),inherited_members=(),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/11598fec2d07bb675dfa8a57e49136f18a94eedec6bc5a036dcecc005e70dc80.html => members/filters=(),inherited_members=(),members=().html} (100%) rename tests/snapshots/{external/366b0537fe0625a10d55203a3532de5c360e49fb403078a82ec408d829afcb72.html => members/filters=(),inherited_members=(),members=False.html} (100%) rename tests/snapshots/{external/19f98a747c015a074f3d3362d03ed72f9da9db3aefe969a0d78c4052e7594372.html => members/filters=(),inherited_members=(),members=None.html} (100%) rename tests/snapshots/{external/027ef7afeffc56219a09298c7db30f473c4dfdda12d99a171e9c76098c316067.html => members/filters=(),inherited_members=(),members=True.html} (100%) rename tests/snapshots/{external/09d96d69d9dcbc54c8189fb885e8e06269c51be673389f29fa8b2d90cff54eb2.html => members/filters=(),inherited_members=False,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/fba0d78ae23e4f52b5e6f0fe003ea3edf681a937f647b11925e9932006648a11.html => members/filters=(),inherited_members=False,members=().html} (100%) rename tests/snapshots/{external/5cf0130e3b4fdd536b1c99ee66c66ec4245e286bf75b989cf50979ce187e1a16.html => members/filters=(),inherited_members=False,members=False.html} (100%) rename tests/snapshots/{external/eac5bee59a9ee0a64602fd6bb8f4f54cb5f3543aa321169921326288a61f556c.html => members/filters=(),inherited_members=False,members=None.html} (100%) rename tests/snapshots/{external/fca72854c849dc68c3ad072a41c32f926f95c6e88775f3e2eeaa63138d99837c.html => members/filters=(),inherited_members=False,members=True.html} (100%) rename tests/snapshots/{external/9d03089a46fab9a86b0836444cabb6225798eaf25be6fd4171bd73b7354509b6.html => members/filters=(),inherited_members=True,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/c915eb92fd5dcc4e2c9da41ca72c726e65fcd85804942be0c67b4f05f452a549.html => members/filters=(),inherited_members=True,members=().html} (100%) rename tests/snapshots/{external/b0a9b08f1f721721c4dd110cb8f85ffda5caf1f1479851275bc227857fb01400.html => members/filters=(),inherited_members=True,members=False.html} (100%) rename tests/snapshots/{external/14bca0e5703be9cab876200d88cccd1d728d1bdfef7cbfac751af212e00a8663.html => members/filters=(),inherited_members=True,members=None.html} (100%) rename tests/snapshots/{external/722165bce3ada19df43b169ea982ab4908d94cd1bf19b777e1e6bc22e8aa02a5.html => members/filters=(),inherited_members=True,members=True.html} (100%) rename tests/snapshots/{external/afd5c166367dd47e4f9843d906b3a1ad12398888fdad84bfbda3de8b19072611.html => members/filters=None,inherited_members=('method1',),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/4f60da13e2d45e803f73ed41746d8b3570f0dac7e132efb1bf0cdbf77e9e2c59.html => members/filters=None,inherited_members=('method1',),members=().html} (100%) rename tests/snapshots/{external/e3defc3620e5fee20f9400c33b7b541fde66297f257d9baf1b0f94b3ea49e6e0.html => members/filters=None,inherited_members=('method1',),members=False.html} (100%) rename tests/snapshots/{external/43d819f94dc7cafe9ed60ce604bab9a938f42a115dc534cb72d12e15e998e96d.html => members/filters=None,inherited_members=('method1',),members=None.html} (100%) rename tests/snapshots/{external/75b69b702f3b5fa3bc0d30091297b0a09a8915eb7f0e1f7be1ce99f5d59d9514.html => members/filters=None,inherited_members=('method1',),members=True.html} (100%) rename tests/snapshots/{external/166b8dfab738b90f2ff0df84a048df96539455d9cad42b09b248ab65b5c742e2.html => members/filters=None,inherited_members=(),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/f77f1c850398f972a7ae2229f918ba497874115be6c5e9431838b4bb6931b2f4.html => members/filters=None,inherited_members=(),members=().html} (100%) rename tests/snapshots/{external/44e42f27bfe3d3b5ec14700c247c83195b1c6eea319d1a0679b2baa797d9859c.html => members/filters=None,inherited_members=(),members=False.html} (100%) rename tests/snapshots/{external/fd291f98ca28b8f15b5a8ed6a2608bacf5b5322599bcbf0544ef8e9c0a27870b.html => members/filters=None,inherited_members=(),members=None.html} (100%) rename tests/snapshots/{external/dcf34c2f72697f7a4700e4a1f048d601f374eab35eea68c9beb8bab8fc269aed.html => members/filters=None,inherited_members=(),members=True.html} (100%) rename tests/snapshots/{external/a200913d9a7d51c52ab58f6fc4e9ea7be278d7890c46cf28ecc3cfd35a36fb46.html => members/filters=None,inherited_members=False,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/fb770e6537bc1b98c0de03db7810404967562a2ffd1700ca35c9788949ca55c0.html => members/filters=None,inherited_members=False,members=().html} (100%) rename tests/snapshots/{external/9bd282a6f2fe82f3ffe66b175bf90ab3e808e3a67f3c15a9f9e3e143d7956e49.html => members/filters=None,inherited_members=False,members=False.html} (100%) rename tests/snapshots/{external/0f046dea611f6c9e90b8eaed720f22af372394971808e2a5d1b3a12286f1ec76.html => members/filters=None,inherited_members=False,members=None.html} (100%) rename tests/snapshots/{external/f4150843096a1371b097478f8d67062e3d45ab9f6a8f97e79ae62d32abc5e22a.html => members/filters=None,inherited_members=False,members=True.html} (100%) rename tests/snapshots/{external/bd6594ae3b516bf84cd0b0e6605087f430f62d787c32225ac8b4039c92e20b76.html => members/filters=None,inherited_members=True,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/ce06da7f07b34e4f9071c5c001a8626f2d5fd8eed9a3ba81abebd76f8afc6861.html => members/filters=None,inherited_members=True,members=().html} (100%) rename tests/snapshots/{external/3f5d794823a451ec9d4ed8c7e16d1354d39b74380402b255ee60741e97c9960c.html => members/filters=None,inherited_members=True,members=False.html} (100%) rename tests/snapshots/{external/ea914f1afa9de4b5eddc9792c2b6a5d8de367274278976092bb824e99e523ca5.html => members/filters=None,inherited_members=True,members=None.html} (100%) rename tests/snapshots/{external/c0f102dbd7d4de76de40c06a8205a642465f5fde9a37b4b969aa01f161ef25a4.html => members/filters=None,inherited_members=True,members=True.html} (100%) rename tests/snapshots/{external/408244423577f9b2598b319118c5f4a0a495116b06ebb2877a0964d526ec18e0.html => members/filters=public,inherited_members=('method1',),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/51d73351dc5546cefc8087b8409ebb7841c879fb48c875ff4cba6fbadee64014.html => members/filters=public,inherited_members=('method1',),members=().html} (100%) rename tests/snapshots/{external/6abf5ddd819b832a1593ece448c90e63e13faa4376cca76b4fddc4d52a47f8b0.html => members/filters=public,inherited_members=('method1',),members=False.html} (100%) rename tests/snapshots/{external/6af55596d9c42d2634baadf77df6060caba2bd9c2d634576378cc18131c0efba.html => members/filters=public,inherited_members=('method1',),members=None.html} (100%) rename tests/snapshots/{external/6c0b7207df0351e1d5232859a5c13b72533fb8c87e5dc0e971b185f8dfe38c84.html => members/filters=public,inherited_members=('method1',),members=True.html} (100%) rename tests/snapshots/{external/d56d3aeae22be9b2494a085b812f0a3a5fabdbef184198de0462a0b944393891.html => members/filters=public,inherited_members=(),members=('module_attribute',).html} (100%) rename tests/snapshots/{external/2e866eca9a45f82cd1e16bb55bbc2a03bb19548457598bca83141cb375fb1aa3.html => members/filters=public,inherited_members=(),members=().html} (100%) rename tests/snapshots/{external/46daa7e60b98815685904dd397f0de19cf1a94397d2165418a4f9fec02c7b560.html => members/filters=public,inherited_members=(),members=False.html} (100%) rename tests/snapshots/{external/6d72c524b827a2e4fd84a17b2aecfffca0d05bfa3fc38815f89836607e5a6c92.html => members/filters=public,inherited_members=(),members=None.html} (100%) rename tests/snapshots/{external/74e2496015e194b88a30c9d0a4d9309bf74c122d1d24aecaa4d9c9c392057d1a.html => members/filters=public,inherited_members=(),members=True.html} (100%) rename tests/snapshots/{external/80399c502938940d34e928b35648146970dc524534fe2e7f7127ccb32e3067d0.html => members/filters=public,inherited_members=False,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html => members/filters=public,inherited_members=False,members=().html} (100%) rename tests/snapshots/{external/9dab67183389335dadba724875c80c49909904aa135e65c6c411c3a903d458da.html => members/filters=public,inherited_members=False,members=False.html} (100%) rename tests/snapshots/{external/b4e20d5cd52e746cc7473537a2318a9ad886c5d8d8654c8d4f85fe209b04d86b.html => members/filters=public,inherited_members=False,members=None.html} (100%) rename tests/snapshots/{external/a255ee80bf7a569ab3aa55ea94af24ce6671dace3d6075df5d14a3ff428ceb8b.html => members/filters=public,inherited_members=False,members=True.html} (100%) rename tests/snapshots/{external/e254ae60f9af14754001bc63b74a3c473f5198cf2a58f4d30ad6d5a4c196e67c.html => members/filters=public,inherited_members=True,members=('module_attribute',).html} (100%) rename tests/snapshots/{external/f48d651b3f1a2ce91910e05f4c3f7a7ec95e7d0e88d4503f101610d74029ce23.html => members/filters=public,inherited_members=True,members=().html} (100%) rename tests/snapshots/{external/ed5d07bcdbaa3f295c0cb1544d54b196728ed6c70f4d6c902991baca6f16193c.html => members/filters=public,inherited_members=True,members=False.html} (100%) rename tests/snapshots/{external/16295fa51a2c3a60d1461a9a14093603333f836326a007d8eb061f78ab38a712.html => members/filters=public,inherited_members=True,members=None.html} (100%) rename tests/snapshots/{external/37232379c426474cc962db72ded419e39c3e416c30e367c8745f3be4e86557a4.html => members/filters=public,inherited_members=True,members=True.html} (100%) rename tests/snapshots/{external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html => overloads/overloads_only=False,separate_signature=False,show_overloads=False.html} (100%) rename tests/snapshots/{external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html => overloads/overloads_only=False,separate_signature=False,show_overloads=True.html} (100%) rename tests/snapshots/{external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html => overloads/overloads_only=False,separate_signature=True,show_overloads=False.html} (100%) rename tests/snapshots/{external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html => overloads/overloads_only=False,separate_signature=True,show_overloads=True.html} (100%) rename tests/snapshots/{external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html => overloads/overloads_only=True,separate_signature=False,show_overloads=False.html} (100%) rename tests/snapshots/{external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html => overloads/overloads_only=True,separate_signature=False,show_overloads=True.html} (100%) rename tests/snapshots/{external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html => overloads/overloads_only=True,separate_signature=True,show_overloads=False.html} (100%) rename tests/snapshots/{external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html => overloads/overloads_only=True,separate_signature=True,show_overloads=True.html} (100%) rename tests/snapshots/{external/b060b701543e5503dc848538a164e80480ab25f8885aa83b97776e6b0cc6b570.html => signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html} (100%) rename tests/snapshots/{external/6a02b544c12c68b75d9bf3b85b1800830fd980daabff9df8c3760eb6edea7915.html => signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html} (100%) rename tests/snapshots/{external/d1216ebf8e30ec559861678318efb45bef54a847517e5d90e130818c2a06b163.html => signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html} (100%) rename tests/snapshots/{external/735fc6ffdb82ce35cdab2aed2389a630e4d2c7ad95308bc5c7a56a8a8930b37f.html => signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html} (100%) rename tests/snapshots/{external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html => signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html} (100%) rename tests/snapshots/{external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html => signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html} (100%) rename tests/snapshots/{external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html => signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html} (100%) rename tests/snapshots/{external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html => signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html} (100%) diff --git a/tests/snapshots/__init__.py b/tests/snapshots/__init__.py deleted file mode 100644 index f79db237..00000000 --- a/tests/snapshots/__init__.py +++ /dev/null @@ -1,429 +0,0 @@ -"""Snaphots for the inline-snapshot pytest plugin.""" - -from inline_snapshot import external, snapshot - -snapshots_signatures = snapshot( - { - ( - ("separate_signature", True), - ("show_signature_annotations", False), - ("signature_crossrefs", False), - ): external("d03d16d1919a*.html"), - ( - ("separate_signature", True), - ("show_signature_annotations", True), - ("signature_crossrefs", True), - ): external("e412376be64f*.html"), - ( - ("separate_signature", False), - ("show_signature_annotations", True), - ("signature_crossrefs", True), - ): external("735fc6ffdb82*.html"), - ( - ("separate_signature", False), - ("show_signature_annotations", False), - ("signature_crossrefs", True), - ): external("6a02b544c12c*.html"), - ( - ("separate_signature", False), - ("show_signature_annotations", False), - ("signature_crossrefs", False), - ): external("b060b701543e*.html"), - ( - ("separate_signature", True), - ("show_signature_annotations", True), - ("signature_crossrefs", False), - ): external("74ee37cd1e94*.html"), - ( - ("separate_signature", True), - ("show_signature_annotations", False), - ("signature_crossrefs", True), - ): external("4041a38e355f*.html"), - ( - ("separate_signature", False), - ("show_signature_annotations", True), - ("signature_crossrefs", False), - ): external("d1216ebf8e30*.html"), - (("overloads_only", False), ("separate_signature", True), ("show_overloads", True)): external( - "19a1066a31c4*.html", - ), - (("overloads_only", False), ("separate_signature", True), ("show_overloads", False)): external( - "728ef9e28d86*.html", - ), - (("overloads_only", True), ("separate_signature", False), ("show_overloads", True)): external( - "30b2733496a8*.html", - ), - (("overloads_only", False), ("separate_signature", False), ("show_overloads", True)): external( - "35c8879435c0*.html", - ), - (("overloads_only", False), ("separate_signature", False), ("show_overloads", False)): external( - "45fa32980cab*.html", - ), - (("overloads_only", True), ("separate_signature", True), ("show_overloads", False)): external( - "90ca219874af*.html", - ), - (("overloads_only", True), ("separate_signature", True), ("show_overloads", True)): external( - "fca9fb3aa9f5*.html", - ), - (("overloads_only", True), ("separate_signature", False), ("show_overloads", False)): external( - "17e520187500*.html", - ), - }, -) - -snapshots_members = snapshot( - { - ( - ("filters", ()), - ("inherited_members", ("method1",)), - ("members", False), - ): external("ab0ddac637b5*.html"), - (("filters", None), ("inherited_members", True), ("members", True)): external("c0f102dbd7d4*.html"), - (("filters", ()), ("inherited_members", False), ("members", True)): external("fca72854c849*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ()), - ("members", ("module_attribute",)), - ): external("6d12192d6b4d*.html"), - (("filters", ()), ("inherited_members", ()), ("members", False)): external("366b0537fe06*.html"), - ( - ("filters", ()), - ("inherited_members", ("method1",)), - ("members", ("module_attribute",)), - ): external("e90c3e0c85dd*.html"), - (("filters", ()), ("inherited_members", True), ("members", True)): external("722165bce3ad*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ("method1",)), - ("members", ()), - ): external("f8f32ea6a0c8*.html"), - ( - ("filters", ()), - ("inherited_members", ("method1",)), - ("members", True), - ): external("cd51e40cc0dd*.html"), - (("filters", ()), ("inherited_members", False), ("members", False)): external("5cf0130e3b4f*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", True), - ("members", True), - ): external("34b16654e7ba*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", False), - ("members", ()), - ): external("fb5ebb7546d8*.html"), - ( - ("filters", None), - ("inherited_members", ("method1",)), - ("members", ("module_attribute",)), - ): external("afd5c166367d*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ("method1",)), - ("members", ("module_attribute",)), - ): external("26bc66c2ba29*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", False), - ("members", ("module_attribute",)), - ): external("247a6063b698*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", False), - ("members", ("module_attribute",)), - ): external("5a9c10410801*.html"), - (("filters", ()), ("inherited_members", False), ("members", ())): external("fba0d78ae23e*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ("method1",)), - ("members", None), - ): external("cfcd41685591*.html"), - (("filters", ()), ("inherited_members", False), ("members", None)): external("eac5bee59a9e*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ()), - ("members", False), - ): external("76ee8e01e1c0*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ("method1",)), - ("members", ()), - ): external("42c053a5e567*.html"), - ( - ("filters", None), - ("inherited_members", ("method1",)), - ("members", ()), - ): external("4f60da13e2d4*.html"), - (("filters", ()), ("inherited_members", True), ("members", ())): external("c915eb92fd5d*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ()), - ("members", None), - ): external("c9a15552eed3*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ("method1",)), - ("members", None), - ): external("fe1cd23642d4*.html"), - (("filters", None), ("inherited_members", False), ("members", False)): external("9bd282a6f2fe*.html"), - ( - ("filters", None), - ("inherited_members", ()), - ("members", ("module_attribute",)), - ): external("166b8dfab738*.html"), - (("filters", None), ("inherited_members", ()), ("members", False)): external("44e42f27bfe3*.html"), - (("filters", None), ("inherited_members", False), ("members", None)): external("0f046dea611f*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", True), - ("members", ()), - ): external("28d8862dd086*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", True), - ("members", False), - ): external("f3f3acb6b51b*.html"), - (("filters", None), ("inherited_members", ()), ("members", True)): external("dcf34c2f7269*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", True), - ("members", None), - ): external("8733f7fb7b6d*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", False), - ("members", False), - ): external("eee65d3705a6*.html"), - ( - ("filters", None), - ("inherited_members", False), - ("members", ("module_attribute",)), - ): external("a200913d9a7d*.html"), - ( - ("filters", None), - ("inherited_members", True), - ("members", ("module_attribute",)), - ): external("bd6594ae3b51*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", True), - ("members", ("module_attribute",)), - ): external("8d4e1f9af997*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", False), - ("members", ()), - ): external("d5a6bf59c663*.html"), - (("filters", None), ("inherited_members", ()), ("members", None)): external("fd291f98ca28*.html"), - (("filters", ()), ("inherited_members", True), ("members", None)): external("14bca0e5703b*.html"), - ( - ("filters", ()), - ("inherited_members", False), - ("members", ("module_attribute",)), - ): external("09d96d69d9dc*.html"), - ( - ("filters", None), - ("inherited_members", ("method1",)), - ("members", None), - ): external("43d819f94dc7*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", True), - ("members", ()), - ): external("95f8e480937f*.html"), - (("filters", None), ("inherited_members", False), ("members", True)): external("f4150843096a*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", True), - ("members", True), - ): external("3c21330afd65*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", False), - ("members", None), - ): external("d55652702606*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ("method1",)), - ("members", False), - ): external("f0014d9505ec*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", True), - ("members", ("module_attribute",)), - ): external("96cf94f4822a*.html"), - (("filters", None), ("inherited_members", True), ("members", ())): external("ce06da7f07b3*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ()), - ("members", False), - ): external("74bfab19cbd4*.html"), - ( - ("filters", None), - ("inherited_members", ("method1",)), - ("members", True), - ): external("75b69b702f3b*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", True), - ("members", False), - ): external("d726cb8367d9*.html"), - (("filters", None), ("inherited_members", False), ("members", ())): external("fb770e6537bc*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", True), - ("members", None), - ): external("2bf34b4dd82e*.html"), - ( - ("filters", ()), - ("inherited_members", ("method1",)), - ("members", ()), - ): external("4892e0fe1920*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ()), - ("members", True), - ): external("13334b5b4fcf*.html"), - ( - ("filters", ()), - ("inherited_members", ()), - ("members", ("module_attribute",)), - ): external("388a13d71284*.html"), - (("filters", None), ("inherited_members", True), ("members", False)): external("3f5d794823a4*.html"), - ( - ("filters", ()), - ("inherited_members", True), - ("members", ("module_attribute",)), - ): external("9d03089a46fa*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ("method1",)), - ("members", ("module_attribute",)), - ): external("8b097c69ac2f*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", False), - ("members", True), - ): external("cd3e45851714*.html"), - ( - ("filters", None), - ("inherited_members", ("method1",)), - ("members", False), - ): external("e3defc3620e5*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ()), - ("members", True), - ): external("84193b3c9f5d*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ("method1",)), - ("members", False), - ): external("c6e7ef9564cd*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", False), - ("members", None), - ): external("62e18d3e5777*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ()), - ("members", None), - ): external("3935bcf6d71b*.html"), - (("filters", None), ("inherited_members", ()), ("members", ())): external("f77f1c850398*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", False), - ("members", True), - ): external("fe25ab760039*.html"), - (("filters", None), ("inherited_members", True), ("members", None)): external("ea914f1afa9d*.html"), - (("filters", ()), ("inherited_members", ()), ("members", None)): external("19f98a747c01*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ()), - ("members", ()), - ): external("c260e7f4ef3b*.html"), - ( - ("filters", ("!module_attribute",)), - ("inherited_members", ("method1",)), - ("members", True), - ): external("9720526cf5e4*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ()), - ("members", ("module_attribute",)), - ): external("f6e292b8358a*.html"), - (("filters", ()), ("inherited_members", True), ("members", False)): external("b0a9b08f1f72*.html"), - (("filters", ()), ("inherited_members", ()), ("members", True)): external("027ef7afeffc*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", False), - ("members", False), - ): external("710706687213*.html"), - (("filters", ()), ("inherited_members", ()), ("members", ())): external("11598fec2d07*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ("method1",)), - ("members", True), - ): external("e8608b0de174*.html"), - ( - ("filters", ()), - ("inherited_members", ("method1",)), - ("members", None), - ): external("e5dc372374af*.html"), - ( - ("filters", ("module_attribute",)), - ("inherited_members", ()), - ("members", ()), - ): external("a185e216dc7b*.html"), - (("filters", "public"), ("inherited_members", ("method1",)), ("members", None)): external("6af55596d9c4*.html"), - (("filters", "public"), ("inherited_members", ("method1",)), ("members", False)): external( - "6abf5ddd819b*.html", - ), - (("filters", "public"), ("inherited_members", ()), ("members", None)): external("6d72c524b827*.html"), - (("filters", "public"), ("inherited_members", False), ("members", False)): external("9dab67183389*.html"), - (("filters", "public"), ("inherited_members", ("method1",)), ("members", True)): external("6c0b7207df03*.html"), - (("filters", "public"), ("inherited_members", True), ("members", ())): external("f48d651b3f1a*.html"), - (("filters", "public"), ("inherited_members", ("method1",)), ("members", ("module_attribute",))): external( - "408244423577*.html", - ), - (("filters", "public"), ("inherited_members", True), ("members", None)): external("16295fa51a2c*.html"), - (("filters", "public"), ("inherited_members", True), ("members", True)): external("37232379c426*.html"), - (("filters", "public"), ("inherited_members", ()), ("members", ())): external("2e866eca9a45*.html"), - (("filters", "public"), ("inherited_members", True), ("members", False)): external("ed5d07bcdbaa*.html"), - (("filters", "public"), ("inherited_members", False), ("members", ())): external("135f57223e00*.html"), - (("filters", "public"), ("inherited_members", False), ("members", None)): external("b4e20d5cd52e*.html"), - (("filters", "public"), ("inherited_members", ()), ("members", False)): external("46daa7e60b98*.html"), - (("filters", "public"), ("inherited_members", False), ("members", True)): external("a255ee80bf7a*.html"), - (("filters", "public"), ("inherited_members", ()), ("members", True)): external("74e2496015e1*.html"), - (("filters", "public"), ("inherited_members", True), ("members", ("module_attribute",))): external( - "e254ae60f9af*.html", - ), - (("filters", "public"), ("inherited_members", ("method1",)), ("members", ())): external("51d73351dc55*.html"), - (("filters", "public"), ("inherited_members", ()), ("members", ("module_attribute",))): external( - "d56d3aeae22b*.html", - ), - (("filters", "public"), ("inherited_members", False), ("members", ("module_attribute",))): external( - "80399c502938*.html", - ), - (("heading", ""), ("members", False), ("separate_signature", False), ("show_if_no_docstring", True)): external( - "d1dd339f9260*.html", - ), - ( - ("heading", "Some heading"), - ("members", False), - ("separate_signature", True), - ("show_if_no_docstring", True), - ): external("480324b25439*.html"), - (("heading", ""), ("members", False), ("separate_signature", True), ("show_if_no_docstring", True)): external( - "2eef87791b97*.html", - ), - ( - ("heading", "Some heading"), - ("members", False), - ("separate_signature", False), - ("show_if_no_docstring", True), - ): external("51deee0f00f3*.html"), - }, -) diff --git a/tests/snapshots/external/.gitignore b/tests/snapshots/external/.gitignore deleted file mode 100644 index 45bef68b..00000000 --- a/tests/snapshots/external/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# ignore all snapshots which are not refered in the source -*-new.* diff --git a/tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html b/tests/snapshots/headings/heading=,separate_signature=False.html similarity index 76% rename from tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html rename to tests/snapshots/headings/heading=,separate_signature=False.html index a9dd1e61..2be154b9 100644 --- a/tests/snapshots/external/d1dd339f926026210ea46cc75922a8236f43cade477f95e4ce4c9a60248f0a10.html +++ b/tests/snapshots/headings/heading=,separate_signature=False.html @@ -1,9 +1,7 @@ diff --git a/tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html b/tests/snapshots/headings/heading=,separate_signature=True.html similarity index 79% rename from tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html rename to tests/snapshots/headings/heading=,separate_signature=True.html index f0242792..c73f0184 100644 --- a/tests/snapshots/external/2eef87791b974c724d2cd98e40bb25994087bc836868f63da18557a6094a00ee.html +++ b/tests/snapshots/headings/heading=,separate_signature=True.html @@ -1,9 +1,7 @@ diff --git a/tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html b/tests/snapshots/headings/heading=Some heading,separate_signature=False.html similarity index 75% rename from tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html rename to tests/snapshots/headings/heading=Some heading,separate_signature=False.html index fd1f953b..b000bf14 100644 --- a/tests/snapshots/external/480324b25439ea41507fdda100045132d578af0e1df1219c08bc9ea0bea1f39c.html +++ b/tests/snapshots/headings/heading=Some heading,separate_signature=False.html @@ -1,9 +1,7 @@ diff --git a/tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html b/tests/snapshots/headings/heading=Some heading,separate_signature=True.html similarity index 75% rename from tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html rename to tests/snapshots/headings/heading=Some heading,separate_signature=True.html index 8601ee01..852b7487 100644 --- a/tests/snapshots/external/51deee0f00f35b0902f82fb96a36d547a80dfbb41a311dabd94b96fd968b83bc.html +++ b/tests/snapshots/headings/heading=Some heading,separate_signature=True.html @@ -1,9 +1,7 @@ diff --git a/tests/snapshots/external/26bc66c2ba29feddfbd06c2490eca42ec5a8f62db8d650231b0748ddce8c85f1.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/26bc66c2ba29feddfbd06c2490eca42ec5a8f62db8d650231b0748ddce8c85f1.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=('module_attribute',).html diff --git a/tests/snapshots/external/42c053a5e567a777dfde62cd0d061112dc8098f90e71f71d5aceba8be188fcf7.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=().html similarity index 100% rename from tests/snapshots/external/42c053a5e567a777dfde62cd0d061112dc8098f90e71f71d5aceba8be188fcf7.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=().html diff --git a/tests/snapshots/external/c6e7ef9564cdc8449a98c0ef790d652dee02c47b1339f858fc1d7a54aae9ed46.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html similarity index 100% rename from tests/snapshots/external/c6e7ef9564cdc8449a98c0ef790d652dee02c47b1339f858fc1d7a54aae9ed46.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=False.html diff --git a/tests/snapshots/external/fe1cd23642d405d0b2a4d29ec4a2125f55b54f90c2440ee2d856540415e77745.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html similarity index 100% rename from tests/snapshots/external/fe1cd23642d405d0b2a4d29ec4a2125f55b54f90c2440ee2d856540415e77745.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=None.html diff --git a/tests/snapshots/external/9720526cf5e4c44f27695c59764bb1e05e428834744442f43527ebf2b8acfb35.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html similarity index 100% rename from tests/snapshots/external/9720526cf5e4c44f27695c59764bb1e05e428834744442f43527ebf2b8acfb35.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=('method1',),members=True.html diff --git a/tests/snapshots/external/6d12192d6b4dc0633bad697a683a3cdf3b2b9ceeb839044c72c63b469914f0a1.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/6d12192d6b4dc0633bad697a683a3cdf3b2b9ceeb839044c72c63b469914f0a1.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=('module_attribute',).html diff --git a/tests/snapshots/external/c260e7f4ef3b8b228bb25879d3adcf6610f1c2c971c9c46b5665d276716b8821.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=().html similarity index 100% rename from tests/snapshots/external/c260e7f4ef3b8b228bb25879d3adcf6610f1c2c971c9c46b5665d276716b8821.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=().html diff --git a/tests/snapshots/external/74bfab19cbd4ba02673f6b9ee736a3b6727936de92f73f299ba238491f619937.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=False.html similarity index 100% rename from tests/snapshots/external/74bfab19cbd4ba02673f6b9ee736a3b6727936de92f73f299ba238491f619937.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=False.html diff --git a/tests/snapshots/external/3935bcf6d71b58daa0e4512cbf3f53e19516885fb65d0bd760c12aadd021507f.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=None.html similarity index 100% rename from tests/snapshots/external/3935bcf6d71b58daa0e4512cbf3f53e19516885fb65d0bd760c12aadd021507f.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=None.html diff --git a/tests/snapshots/external/84193b3c9f5d84fef33daa61fb61aa9a3e66171d312de8d7f836c69f0bc069b0.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=True.html similarity index 100% rename from tests/snapshots/external/84193b3c9f5d84fef33daa61fb61aa9a3e66171d312de8d7f836c69f0bc069b0.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=(),members=True.html diff --git a/tests/snapshots/external/247a6063b698c285bfef7addfd972ddf797f6a90dfd5a3e649e6e4c127b86562.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/247a6063b698c285bfef7addfd972ddf797f6a90dfd5a3e649e6e4c127b86562.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=('module_attribute',).html diff --git a/tests/snapshots/external/fb5ebb7546d8d63744d7e6713ab5317b8c3d00d1108d28d7ef2949994b41dcbd.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=().html similarity index 100% rename from tests/snapshots/external/fb5ebb7546d8d63744d7e6713ab5317b8c3d00d1108d28d7ef2949994b41dcbd.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=().html diff --git a/tests/snapshots/external/eee65d3705a655eec6512c4aa09d55f5d2e7c62dd245fed4b3f002a5e9a4d646.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=False.html similarity index 100% rename from tests/snapshots/external/eee65d3705a655eec6512c4aa09d55f5d2e7c62dd245fed4b3f002a5e9a4d646.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=False.html diff --git a/tests/snapshots/external/d556527026068280df9b77db277472320842cb1ae6099ac3cf558031afda6d2e.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=None.html similarity index 100% rename from tests/snapshots/external/d556527026068280df9b77db277472320842cb1ae6099ac3cf558031afda6d2e.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=None.html diff --git a/tests/snapshots/external/fe25ab7600392b4fd3a1438fb54337041719faac884123527bab9a92e3a51be5.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=True.html similarity index 100% rename from tests/snapshots/external/fe25ab7600392b4fd3a1438fb54337041719faac884123527bab9a92e3a51be5.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=False,members=True.html diff --git a/tests/snapshots/external/96cf94f4822a5cf5d72407eab5a5dddda972f16623f7710f738ffe2bcf9130d9.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/96cf94f4822a5cf5d72407eab5a5dddda972f16623f7710f738ffe2bcf9130d9.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=('module_attribute',).html diff --git a/tests/snapshots/external/28d8862dd086c7d523516dd4091b57e5babd34165edccf619b62a06fc1936cd5.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=().html similarity index 100% rename from tests/snapshots/external/28d8862dd086c7d523516dd4091b57e5babd34165edccf619b62a06fc1936cd5.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=().html diff --git a/tests/snapshots/external/d726cb8367d95b67ce78e718e88ee528d3abc2fbd04413d1c11916a243d7567a.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=False.html similarity index 100% rename from tests/snapshots/external/d726cb8367d95b67ce78e718e88ee528d3abc2fbd04413d1c11916a243d7567a.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=False.html diff --git a/tests/snapshots/external/8733f7fb7b6d28b15bbe736f29c7fd030467c0ccfa2cbc6a68616e06c6dc6a9b.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=None.html similarity index 100% rename from tests/snapshots/external/8733f7fb7b6d28b15bbe736f29c7fd030467c0ccfa2cbc6a68616e06c6dc6a9b.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=None.html diff --git a/tests/snapshots/external/34b16654e7baa8e16315cef2919f2eafa51ba39ec28c4c970fe7ea8e2c79f9d2.html b/tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=True.html similarity index 100% rename from tests/snapshots/external/34b16654e7baa8e16315cef2919f2eafa51ba39ec28c4c970fe7ea8e2c79f9d2.html rename to tests/snapshots/members/filters=('!module_attribute',),inherited_members=True,members=True.html diff --git a/tests/snapshots/external/8b097c69ac2fd52857f33e1b008f4d99a53ed21894c51517b3d79da445b0a705.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/8b097c69ac2fd52857f33e1b008f4d99a53ed21894c51517b3d79da445b0a705.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=('module_attribute',).html diff --git a/tests/snapshots/external/f8f32ea6a0c80a63854f8c8d78b3706797feb3042ac88c8fcf0a6da277eddb9d.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=().html similarity index 100% rename from tests/snapshots/external/f8f32ea6a0c80a63854f8c8d78b3706797feb3042ac88c8fcf0a6da277eddb9d.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=().html diff --git a/tests/snapshots/external/f0014d9505eceb38ba1e36c380a97ebe4d43669929ec1cdedba4d418899aecc7.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=False.html similarity index 100% rename from tests/snapshots/external/f0014d9505eceb38ba1e36c380a97ebe4d43669929ec1cdedba4d418899aecc7.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=False.html diff --git a/tests/snapshots/external/cfcd41685591bcc497f9d1e9fd20006fc3acd857f068e78e6d1c2461bbd4063f.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=None.html similarity index 100% rename from tests/snapshots/external/cfcd41685591bcc497f9d1e9fd20006fc3acd857f068e78e6d1c2461bbd4063f.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=None.html diff --git a/tests/snapshots/external/e8608b0de174402ca18f88ed58849312158c22f5bfdc845d2da02055fe14853c.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=True.html similarity index 100% rename from tests/snapshots/external/e8608b0de174402ca18f88ed58849312158c22f5bfdc845d2da02055fe14853c.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=('method1',),members=True.html diff --git a/tests/snapshots/external/f6e292b8358a04e3471ba11c8820307076be3cf83b0a9ec2fb5c949324b7e172.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/f6e292b8358a04e3471ba11c8820307076be3cf83b0a9ec2fb5c949324b7e172.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=('module_attribute',).html diff --git a/tests/snapshots/external/a185e216dc7b7ebb31b46ea0e7ed446cf9da94eee8db306f08bae1ca0db0ca1d.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=().html similarity index 100% rename from tests/snapshots/external/a185e216dc7b7ebb31b46ea0e7ed446cf9da94eee8db306f08bae1ca0db0ca1d.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=().html diff --git a/tests/snapshots/external/76ee8e01e1c0b94de84d79da8443bc24f601f89cab70eae1b2af5ee21cfb1f3a.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=False.html similarity index 100% rename from tests/snapshots/external/76ee8e01e1c0b94de84d79da8443bc24f601f89cab70eae1b2af5ee21cfb1f3a.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=False.html diff --git a/tests/snapshots/external/c9a15552eed32a233795c2086a7c766ad95e05197d30d881540fbe52cdc07ff8.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=None.html similarity index 100% rename from tests/snapshots/external/c9a15552eed32a233795c2086a7c766ad95e05197d30d881540fbe52cdc07ff8.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=None.html diff --git a/tests/snapshots/external/13334b5b4fcf7267539b9eb99ca2ab79c66766ec6f35383f4bfcb6a8d9e2a116.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=True.html similarity index 100% rename from tests/snapshots/external/13334b5b4fcf7267539b9eb99ca2ab79c66766ec6f35383f4bfcb6a8d9e2a116.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=(),members=True.html diff --git a/tests/snapshots/external/5a9c10410801aa75b33878971b939da701df9a7ce8006dc7781c148d27a89756.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/5a9c10410801aa75b33878971b939da701df9a7ce8006dc7781c148d27a89756.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=('module_attribute',).html diff --git a/tests/snapshots/external/d5a6bf59c663338bef9fdc2391f482aee444228e86e23357c11881498e711bb2.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=().html similarity index 100% rename from tests/snapshots/external/d5a6bf59c663338bef9fdc2391f482aee444228e86e23357c11881498e711bb2.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=().html diff --git a/tests/snapshots/external/7107066872137b807b3f9d897e75eff78f5783b14d3c88e71c6477eaa8493113.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=False.html similarity index 100% rename from tests/snapshots/external/7107066872137b807b3f9d897e75eff78f5783b14d3c88e71c6477eaa8493113.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=False.html diff --git a/tests/snapshots/external/62e18d3e57777d911c7fdee1fcc032a9c23ffe82913060e3b66f29bf81a6a585.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=None.html similarity index 100% rename from tests/snapshots/external/62e18d3e57777d911c7fdee1fcc032a9c23ffe82913060e3b66f29bf81a6a585.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=None.html diff --git a/tests/snapshots/external/cd3e458517147c43c360525140aa1b9a81682634aaf2674ffd4cceb7fc44aba6.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=True.html similarity index 100% rename from tests/snapshots/external/cd3e458517147c43c360525140aa1b9a81682634aaf2674ffd4cceb7fc44aba6.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=False,members=True.html diff --git a/tests/snapshots/external/8d4e1f9af9971bd21234c7c45dfbd59a1aee444bfa0cd3b9cfb6d052d378a041.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/8d4e1f9af9971bd21234c7c45dfbd59a1aee444bfa0cd3b9cfb6d052d378a041.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=('module_attribute',).html diff --git a/tests/snapshots/external/95f8e480937f7a2b956392ed4d8058052d9748874cdd911feacdd31d1abe5d97.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=().html similarity index 100% rename from tests/snapshots/external/95f8e480937f7a2b956392ed4d8058052d9748874cdd911feacdd31d1abe5d97.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=().html diff --git a/tests/snapshots/external/f3f3acb6b51ba98f5a06e7c62e85b791b6521504f19a8d7496592dee59c7f199.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=False.html similarity index 100% rename from tests/snapshots/external/f3f3acb6b51ba98f5a06e7c62e85b791b6521504f19a8d7496592dee59c7f199.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=False.html diff --git a/tests/snapshots/external/2bf34b4dd82e753b21200ec980cb197c530710fe8c150c4dd3fbbfb7d38928cc.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=None.html similarity index 100% rename from tests/snapshots/external/2bf34b4dd82e753b21200ec980cb197c530710fe8c150c4dd3fbbfb7d38928cc.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=None.html diff --git a/tests/snapshots/external/3c21330afd6529769164afe388e9385a9fddb3ae628124965e0c7b81932a0c63.html b/tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=True.html similarity index 100% rename from tests/snapshots/external/3c21330afd6529769164afe388e9385a9fddb3ae628124965e0c7b81932a0c63.html rename to tests/snapshots/members/filters=('module_attribute',),inherited_members=True,members=True.html diff --git a/tests/snapshots/external/e90c3e0c85ddaa068f3d063c6a1ef718bb3ae2092760b707e838fb73164b3720.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/e90c3e0c85ddaa068f3d063c6a1ef718bb3ae2092760b707e838fb73164b3720.html rename to tests/snapshots/members/filters=(),inherited_members=('method1',),members=('module_attribute',).html diff --git a/tests/snapshots/external/4892e0fe1920c0bb22fa4787b6e76cccaa968163b35641d705f288c04fe4937e.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=().html similarity index 100% rename from tests/snapshots/external/4892e0fe1920c0bb22fa4787b6e76cccaa968163b35641d705f288c04fe4937e.html rename to tests/snapshots/members/filters=(),inherited_members=('method1',),members=().html diff --git a/tests/snapshots/external/ab0ddac637b536c06014746a4a8f8e0921b074015ae19680abf5df995c233ba1.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=False.html similarity index 100% rename from tests/snapshots/external/ab0ddac637b536c06014746a4a8f8e0921b074015ae19680abf5df995c233ba1.html rename to tests/snapshots/members/filters=(),inherited_members=('method1',),members=False.html diff --git a/tests/snapshots/external/e5dc372374af6f90a5d456d8683aacdf81104137ce91bd6d4121827f8d989d96.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=None.html similarity index 100% rename from tests/snapshots/external/e5dc372374af6f90a5d456d8683aacdf81104137ce91bd6d4121827f8d989d96.html rename to tests/snapshots/members/filters=(),inherited_members=('method1',),members=None.html diff --git a/tests/snapshots/external/cd51e40cc0ddf1d42b7c6bf7560ead2501370ee9d67499b74afc83e258caff8e.html b/tests/snapshots/members/filters=(),inherited_members=('method1',),members=True.html similarity index 100% rename from tests/snapshots/external/cd51e40cc0ddf1d42b7c6bf7560ead2501370ee9d67499b74afc83e258caff8e.html rename to tests/snapshots/members/filters=(),inherited_members=('method1',),members=True.html diff --git a/tests/snapshots/external/388a13d71284b1a4b0c457e9c8d1ec60dfefb8871c69ceb1d7a035bd3bdadab8.html b/tests/snapshots/members/filters=(),inherited_members=(),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/388a13d71284b1a4b0c457e9c8d1ec60dfefb8871c69ceb1d7a035bd3bdadab8.html rename to tests/snapshots/members/filters=(),inherited_members=(),members=('module_attribute',).html diff --git a/tests/snapshots/external/11598fec2d07bb675dfa8a57e49136f18a94eedec6bc5a036dcecc005e70dc80.html b/tests/snapshots/members/filters=(),inherited_members=(),members=().html similarity index 100% rename from tests/snapshots/external/11598fec2d07bb675dfa8a57e49136f18a94eedec6bc5a036dcecc005e70dc80.html rename to tests/snapshots/members/filters=(),inherited_members=(),members=().html diff --git a/tests/snapshots/external/366b0537fe0625a10d55203a3532de5c360e49fb403078a82ec408d829afcb72.html b/tests/snapshots/members/filters=(),inherited_members=(),members=False.html similarity index 100% rename from tests/snapshots/external/366b0537fe0625a10d55203a3532de5c360e49fb403078a82ec408d829afcb72.html rename to tests/snapshots/members/filters=(),inherited_members=(),members=False.html diff --git a/tests/snapshots/external/19f98a747c015a074f3d3362d03ed72f9da9db3aefe969a0d78c4052e7594372.html b/tests/snapshots/members/filters=(),inherited_members=(),members=None.html similarity index 100% rename from tests/snapshots/external/19f98a747c015a074f3d3362d03ed72f9da9db3aefe969a0d78c4052e7594372.html rename to tests/snapshots/members/filters=(),inherited_members=(),members=None.html diff --git a/tests/snapshots/external/027ef7afeffc56219a09298c7db30f473c4dfdda12d99a171e9c76098c316067.html b/tests/snapshots/members/filters=(),inherited_members=(),members=True.html similarity index 100% rename from tests/snapshots/external/027ef7afeffc56219a09298c7db30f473c4dfdda12d99a171e9c76098c316067.html rename to tests/snapshots/members/filters=(),inherited_members=(),members=True.html diff --git a/tests/snapshots/external/09d96d69d9dcbc54c8189fb885e8e06269c51be673389f29fa8b2d90cff54eb2.html b/tests/snapshots/members/filters=(),inherited_members=False,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/09d96d69d9dcbc54c8189fb885e8e06269c51be673389f29fa8b2d90cff54eb2.html rename to tests/snapshots/members/filters=(),inherited_members=False,members=('module_attribute',).html diff --git a/tests/snapshots/external/fba0d78ae23e4f52b5e6f0fe003ea3edf681a937f647b11925e9932006648a11.html b/tests/snapshots/members/filters=(),inherited_members=False,members=().html similarity index 100% rename from tests/snapshots/external/fba0d78ae23e4f52b5e6f0fe003ea3edf681a937f647b11925e9932006648a11.html rename to tests/snapshots/members/filters=(),inherited_members=False,members=().html diff --git a/tests/snapshots/external/5cf0130e3b4fdd536b1c99ee66c66ec4245e286bf75b989cf50979ce187e1a16.html b/tests/snapshots/members/filters=(),inherited_members=False,members=False.html similarity index 100% rename from tests/snapshots/external/5cf0130e3b4fdd536b1c99ee66c66ec4245e286bf75b989cf50979ce187e1a16.html rename to tests/snapshots/members/filters=(),inherited_members=False,members=False.html diff --git a/tests/snapshots/external/eac5bee59a9ee0a64602fd6bb8f4f54cb5f3543aa321169921326288a61f556c.html b/tests/snapshots/members/filters=(),inherited_members=False,members=None.html similarity index 100% rename from tests/snapshots/external/eac5bee59a9ee0a64602fd6bb8f4f54cb5f3543aa321169921326288a61f556c.html rename to tests/snapshots/members/filters=(),inherited_members=False,members=None.html diff --git a/tests/snapshots/external/fca72854c849dc68c3ad072a41c32f926f95c6e88775f3e2eeaa63138d99837c.html b/tests/snapshots/members/filters=(),inherited_members=False,members=True.html similarity index 100% rename from tests/snapshots/external/fca72854c849dc68c3ad072a41c32f926f95c6e88775f3e2eeaa63138d99837c.html rename to tests/snapshots/members/filters=(),inherited_members=False,members=True.html diff --git a/tests/snapshots/external/9d03089a46fab9a86b0836444cabb6225798eaf25be6fd4171bd73b7354509b6.html b/tests/snapshots/members/filters=(),inherited_members=True,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/9d03089a46fab9a86b0836444cabb6225798eaf25be6fd4171bd73b7354509b6.html rename to tests/snapshots/members/filters=(),inherited_members=True,members=('module_attribute',).html diff --git a/tests/snapshots/external/c915eb92fd5dcc4e2c9da41ca72c726e65fcd85804942be0c67b4f05f452a549.html b/tests/snapshots/members/filters=(),inherited_members=True,members=().html similarity index 100% rename from tests/snapshots/external/c915eb92fd5dcc4e2c9da41ca72c726e65fcd85804942be0c67b4f05f452a549.html rename to tests/snapshots/members/filters=(),inherited_members=True,members=().html diff --git a/tests/snapshots/external/b0a9b08f1f721721c4dd110cb8f85ffda5caf1f1479851275bc227857fb01400.html b/tests/snapshots/members/filters=(),inherited_members=True,members=False.html similarity index 100% rename from tests/snapshots/external/b0a9b08f1f721721c4dd110cb8f85ffda5caf1f1479851275bc227857fb01400.html rename to tests/snapshots/members/filters=(),inherited_members=True,members=False.html diff --git a/tests/snapshots/external/14bca0e5703be9cab876200d88cccd1d728d1bdfef7cbfac751af212e00a8663.html b/tests/snapshots/members/filters=(),inherited_members=True,members=None.html similarity index 100% rename from tests/snapshots/external/14bca0e5703be9cab876200d88cccd1d728d1bdfef7cbfac751af212e00a8663.html rename to tests/snapshots/members/filters=(),inherited_members=True,members=None.html diff --git a/tests/snapshots/external/722165bce3ada19df43b169ea982ab4908d94cd1bf19b777e1e6bc22e8aa02a5.html b/tests/snapshots/members/filters=(),inherited_members=True,members=True.html similarity index 100% rename from tests/snapshots/external/722165bce3ada19df43b169ea982ab4908d94cd1bf19b777e1e6bc22e8aa02a5.html rename to tests/snapshots/members/filters=(),inherited_members=True,members=True.html diff --git a/tests/snapshots/external/afd5c166367dd47e4f9843d906b3a1ad12398888fdad84bfbda3de8b19072611.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/afd5c166367dd47e4f9843d906b3a1ad12398888fdad84bfbda3de8b19072611.html rename to tests/snapshots/members/filters=None,inherited_members=('method1',),members=('module_attribute',).html diff --git a/tests/snapshots/external/4f60da13e2d45e803f73ed41746d8b3570f0dac7e132efb1bf0cdbf77e9e2c59.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=().html similarity index 100% rename from tests/snapshots/external/4f60da13e2d45e803f73ed41746d8b3570f0dac7e132efb1bf0cdbf77e9e2c59.html rename to tests/snapshots/members/filters=None,inherited_members=('method1',),members=().html diff --git a/tests/snapshots/external/e3defc3620e5fee20f9400c33b7b541fde66297f257d9baf1b0f94b3ea49e6e0.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=False.html similarity index 100% rename from tests/snapshots/external/e3defc3620e5fee20f9400c33b7b541fde66297f257d9baf1b0f94b3ea49e6e0.html rename to tests/snapshots/members/filters=None,inherited_members=('method1',),members=False.html diff --git a/tests/snapshots/external/43d819f94dc7cafe9ed60ce604bab9a938f42a115dc534cb72d12e15e998e96d.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=None.html similarity index 100% rename from tests/snapshots/external/43d819f94dc7cafe9ed60ce604bab9a938f42a115dc534cb72d12e15e998e96d.html rename to tests/snapshots/members/filters=None,inherited_members=('method1',),members=None.html diff --git a/tests/snapshots/external/75b69b702f3b5fa3bc0d30091297b0a09a8915eb7f0e1f7be1ce99f5d59d9514.html b/tests/snapshots/members/filters=None,inherited_members=('method1',),members=True.html similarity index 100% rename from tests/snapshots/external/75b69b702f3b5fa3bc0d30091297b0a09a8915eb7f0e1f7be1ce99f5d59d9514.html rename to tests/snapshots/members/filters=None,inherited_members=('method1',),members=True.html diff --git a/tests/snapshots/external/166b8dfab738b90f2ff0df84a048df96539455d9cad42b09b248ab65b5c742e2.html b/tests/snapshots/members/filters=None,inherited_members=(),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/166b8dfab738b90f2ff0df84a048df96539455d9cad42b09b248ab65b5c742e2.html rename to tests/snapshots/members/filters=None,inherited_members=(),members=('module_attribute',).html diff --git a/tests/snapshots/external/f77f1c850398f972a7ae2229f918ba497874115be6c5e9431838b4bb6931b2f4.html b/tests/snapshots/members/filters=None,inherited_members=(),members=().html similarity index 100% rename from tests/snapshots/external/f77f1c850398f972a7ae2229f918ba497874115be6c5e9431838b4bb6931b2f4.html rename to tests/snapshots/members/filters=None,inherited_members=(),members=().html diff --git a/tests/snapshots/external/44e42f27bfe3d3b5ec14700c247c83195b1c6eea319d1a0679b2baa797d9859c.html b/tests/snapshots/members/filters=None,inherited_members=(),members=False.html similarity index 100% rename from tests/snapshots/external/44e42f27bfe3d3b5ec14700c247c83195b1c6eea319d1a0679b2baa797d9859c.html rename to tests/snapshots/members/filters=None,inherited_members=(),members=False.html diff --git a/tests/snapshots/external/fd291f98ca28b8f15b5a8ed6a2608bacf5b5322599bcbf0544ef8e9c0a27870b.html b/tests/snapshots/members/filters=None,inherited_members=(),members=None.html similarity index 100% rename from tests/snapshots/external/fd291f98ca28b8f15b5a8ed6a2608bacf5b5322599bcbf0544ef8e9c0a27870b.html rename to tests/snapshots/members/filters=None,inherited_members=(),members=None.html diff --git a/tests/snapshots/external/dcf34c2f72697f7a4700e4a1f048d601f374eab35eea68c9beb8bab8fc269aed.html b/tests/snapshots/members/filters=None,inherited_members=(),members=True.html similarity index 100% rename from tests/snapshots/external/dcf34c2f72697f7a4700e4a1f048d601f374eab35eea68c9beb8bab8fc269aed.html rename to tests/snapshots/members/filters=None,inherited_members=(),members=True.html diff --git a/tests/snapshots/external/a200913d9a7d51c52ab58f6fc4e9ea7be278d7890c46cf28ecc3cfd35a36fb46.html b/tests/snapshots/members/filters=None,inherited_members=False,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/a200913d9a7d51c52ab58f6fc4e9ea7be278d7890c46cf28ecc3cfd35a36fb46.html rename to tests/snapshots/members/filters=None,inherited_members=False,members=('module_attribute',).html diff --git a/tests/snapshots/external/fb770e6537bc1b98c0de03db7810404967562a2ffd1700ca35c9788949ca55c0.html b/tests/snapshots/members/filters=None,inherited_members=False,members=().html similarity index 100% rename from tests/snapshots/external/fb770e6537bc1b98c0de03db7810404967562a2ffd1700ca35c9788949ca55c0.html rename to tests/snapshots/members/filters=None,inherited_members=False,members=().html diff --git a/tests/snapshots/external/9bd282a6f2fe82f3ffe66b175bf90ab3e808e3a67f3c15a9f9e3e143d7956e49.html b/tests/snapshots/members/filters=None,inherited_members=False,members=False.html similarity index 100% rename from tests/snapshots/external/9bd282a6f2fe82f3ffe66b175bf90ab3e808e3a67f3c15a9f9e3e143d7956e49.html rename to tests/snapshots/members/filters=None,inherited_members=False,members=False.html diff --git a/tests/snapshots/external/0f046dea611f6c9e90b8eaed720f22af372394971808e2a5d1b3a12286f1ec76.html b/tests/snapshots/members/filters=None,inherited_members=False,members=None.html similarity index 100% rename from tests/snapshots/external/0f046dea611f6c9e90b8eaed720f22af372394971808e2a5d1b3a12286f1ec76.html rename to tests/snapshots/members/filters=None,inherited_members=False,members=None.html diff --git a/tests/snapshots/external/f4150843096a1371b097478f8d67062e3d45ab9f6a8f97e79ae62d32abc5e22a.html b/tests/snapshots/members/filters=None,inherited_members=False,members=True.html similarity index 100% rename from tests/snapshots/external/f4150843096a1371b097478f8d67062e3d45ab9f6a8f97e79ae62d32abc5e22a.html rename to tests/snapshots/members/filters=None,inherited_members=False,members=True.html diff --git a/tests/snapshots/external/bd6594ae3b516bf84cd0b0e6605087f430f62d787c32225ac8b4039c92e20b76.html b/tests/snapshots/members/filters=None,inherited_members=True,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/bd6594ae3b516bf84cd0b0e6605087f430f62d787c32225ac8b4039c92e20b76.html rename to tests/snapshots/members/filters=None,inherited_members=True,members=('module_attribute',).html diff --git a/tests/snapshots/external/ce06da7f07b34e4f9071c5c001a8626f2d5fd8eed9a3ba81abebd76f8afc6861.html b/tests/snapshots/members/filters=None,inherited_members=True,members=().html similarity index 100% rename from tests/snapshots/external/ce06da7f07b34e4f9071c5c001a8626f2d5fd8eed9a3ba81abebd76f8afc6861.html rename to tests/snapshots/members/filters=None,inherited_members=True,members=().html diff --git a/tests/snapshots/external/3f5d794823a451ec9d4ed8c7e16d1354d39b74380402b255ee60741e97c9960c.html b/tests/snapshots/members/filters=None,inherited_members=True,members=False.html similarity index 100% rename from tests/snapshots/external/3f5d794823a451ec9d4ed8c7e16d1354d39b74380402b255ee60741e97c9960c.html rename to tests/snapshots/members/filters=None,inherited_members=True,members=False.html diff --git a/tests/snapshots/external/ea914f1afa9de4b5eddc9792c2b6a5d8de367274278976092bb824e99e523ca5.html b/tests/snapshots/members/filters=None,inherited_members=True,members=None.html similarity index 100% rename from tests/snapshots/external/ea914f1afa9de4b5eddc9792c2b6a5d8de367274278976092bb824e99e523ca5.html rename to tests/snapshots/members/filters=None,inherited_members=True,members=None.html diff --git a/tests/snapshots/external/c0f102dbd7d4de76de40c06a8205a642465f5fde9a37b4b969aa01f161ef25a4.html b/tests/snapshots/members/filters=None,inherited_members=True,members=True.html similarity index 100% rename from tests/snapshots/external/c0f102dbd7d4de76de40c06a8205a642465f5fde9a37b4b969aa01f161ef25a4.html rename to tests/snapshots/members/filters=None,inherited_members=True,members=True.html diff --git a/tests/snapshots/external/408244423577f9b2598b319118c5f4a0a495116b06ebb2877a0964d526ec18e0.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/408244423577f9b2598b319118c5f4a0a495116b06ebb2877a0964d526ec18e0.html rename to tests/snapshots/members/filters=public,inherited_members=('method1',),members=('module_attribute',).html diff --git a/tests/snapshots/external/51d73351dc5546cefc8087b8409ebb7841c879fb48c875ff4cba6fbadee64014.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=().html similarity index 100% rename from tests/snapshots/external/51d73351dc5546cefc8087b8409ebb7841c879fb48c875ff4cba6fbadee64014.html rename to tests/snapshots/members/filters=public,inherited_members=('method1',),members=().html diff --git a/tests/snapshots/external/6abf5ddd819b832a1593ece448c90e63e13faa4376cca76b4fddc4d52a47f8b0.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=False.html similarity index 100% rename from tests/snapshots/external/6abf5ddd819b832a1593ece448c90e63e13faa4376cca76b4fddc4d52a47f8b0.html rename to tests/snapshots/members/filters=public,inherited_members=('method1',),members=False.html diff --git a/tests/snapshots/external/6af55596d9c42d2634baadf77df6060caba2bd9c2d634576378cc18131c0efba.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=None.html similarity index 100% rename from tests/snapshots/external/6af55596d9c42d2634baadf77df6060caba2bd9c2d634576378cc18131c0efba.html rename to tests/snapshots/members/filters=public,inherited_members=('method1',),members=None.html diff --git a/tests/snapshots/external/6c0b7207df0351e1d5232859a5c13b72533fb8c87e5dc0e971b185f8dfe38c84.html b/tests/snapshots/members/filters=public,inherited_members=('method1',),members=True.html similarity index 100% rename from tests/snapshots/external/6c0b7207df0351e1d5232859a5c13b72533fb8c87e5dc0e971b185f8dfe38c84.html rename to tests/snapshots/members/filters=public,inherited_members=('method1',),members=True.html diff --git a/tests/snapshots/external/d56d3aeae22be9b2494a085b812f0a3a5fabdbef184198de0462a0b944393891.html b/tests/snapshots/members/filters=public,inherited_members=(),members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/d56d3aeae22be9b2494a085b812f0a3a5fabdbef184198de0462a0b944393891.html rename to tests/snapshots/members/filters=public,inherited_members=(),members=('module_attribute',).html diff --git a/tests/snapshots/external/2e866eca9a45f82cd1e16bb55bbc2a03bb19548457598bca83141cb375fb1aa3.html b/tests/snapshots/members/filters=public,inherited_members=(),members=().html similarity index 100% rename from tests/snapshots/external/2e866eca9a45f82cd1e16bb55bbc2a03bb19548457598bca83141cb375fb1aa3.html rename to tests/snapshots/members/filters=public,inherited_members=(),members=().html diff --git a/tests/snapshots/external/46daa7e60b98815685904dd397f0de19cf1a94397d2165418a4f9fec02c7b560.html b/tests/snapshots/members/filters=public,inherited_members=(),members=False.html similarity index 100% rename from tests/snapshots/external/46daa7e60b98815685904dd397f0de19cf1a94397d2165418a4f9fec02c7b560.html rename to tests/snapshots/members/filters=public,inherited_members=(),members=False.html diff --git a/tests/snapshots/external/6d72c524b827a2e4fd84a17b2aecfffca0d05bfa3fc38815f89836607e5a6c92.html b/tests/snapshots/members/filters=public,inherited_members=(),members=None.html similarity index 100% rename from tests/snapshots/external/6d72c524b827a2e4fd84a17b2aecfffca0d05bfa3fc38815f89836607e5a6c92.html rename to tests/snapshots/members/filters=public,inherited_members=(),members=None.html diff --git a/tests/snapshots/external/74e2496015e194b88a30c9d0a4d9309bf74c122d1d24aecaa4d9c9c392057d1a.html b/tests/snapshots/members/filters=public,inherited_members=(),members=True.html similarity index 100% rename from tests/snapshots/external/74e2496015e194b88a30c9d0a4d9309bf74c122d1d24aecaa4d9c9c392057d1a.html rename to tests/snapshots/members/filters=public,inherited_members=(),members=True.html diff --git a/tests/snapshots/external/80399c502938940d34e928b35648146970dc524534fe2e7f7127ccb32e3067d0.html b/tests/snapshots/members/filters=public,inherited_members=False,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/80399c502938940d34e928b35648146970dc524534fe2e7f7127ccb32e3067d0.html rename to tests/snapshots/members/filters=public,inherited_members=False,members=('module_attribute',).html diff --git a/tests/snapshots/external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html b/tests/snapshots/members/filters=public,inherited_members=False,members=().html similarity index 100% rename from tests/snapshots/external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html rename to tests/snapshots/members/filters=public,inherited_members=False,members=().html diff --git a/tests/snapshots/external/9dab67183389335dadba724875c80c49909904aa135e65c6c411c3a903d458da.html b/tests/snapshots/members/filters=public,inherited_members=False,members=False.html similarity index 100% rename from tests/snapshots/external/9dab67183389335dadba724875c80c49909904aa135e65c6c411c3a903d458da.html rename to tests/snapshots/members/filters=public,inherited_members=False,members=False.html diff --git a/tests/snapshots/external/b4e20d5cd52e746cc7473537a2318a9ad886c5d8d8654c8d4f85fe209b04d86b.html b/tests/snapshots/members/filters=public,inherited_members=False,members=None.html similarity index 100% rename from tests/snapshots/external/b4e20d5cd52e746cc7473537a2318a9ad886c5d8d8654c8d4f85fe209b04d86b.html rename to tests/snapshots/members/filters=public,inherited_members=False,members=None.html diff --git a/tests/snapshots/external/a255ee80bf7a569ab3aa55ea94af24ce6671dace3d6075df5d14a3ff428ceb8b.html b/tests/snapshots/members/filters=public,inherited_members=False,members=True.html similarity index 100% rename from tests/snapshots/external/a255ee80bf7a569ab3aa55ea94af24ce6671dace3d6075df5d14a3ff428ceb8b.html rename to tests/snapshots/members/filters=public,inherited_members=False,members=True.html diff --git a/tests/snapshots/external/e254ae60f9af14754001bc63b74a3c473f5198cf2a58f4d30ad6d5a4c196e67c.html b/tests/snapshots/members/filters=public,inherited_members=True,members=('module_attribute',).html similarity index 100% rename from tests/snapshots/external/e254ae60f9af14754001bc63b74a3c473f5198cf2a58f4d30ad6d5a4c196e67c.html rename to tests/snapshots/members/filters=public,inherited_members=True,members=('module_attribute',).html diff --git a/tests/snapshots/external/f48d651b3f1a2ce91910e05f4c3f7a7ec95e7d0e88d4503f101610d74029ce23.html b/tests/snapshots/members/filters=public,inherited_members=True,members=().html similarity index 100% rename from tests/snapshots/external/f48d651b3f1a2ce91910e05f4c3f7a7ec95e7d0e88d4503f101610d74029ce23.html rename to tests/snapshots/members/filters=public,inherited_members=True,members=().html diff --git a/tests/snapshots/external/ed5d07bcdbaa3f295c0cb1544d54b196728ed6c70f4d6c902991baca6f16193c.html b/tests/snapshots/members/filters=public,inherited_members=True,members=False.html similarity index 100% rename from tests/snapshots/external/ed5d07bcdbaa3f295c0cb1544d54b196728ed6c70f4d6c902991baca6f16193c.html rename to tests/snapshots/members/filters=public,inherited_members=True,members=False.html diff --git a/tests/snapshots/external/16295fa51a2c3a60d1461a9a14093603333f836326a007d8eb061f78ab38a712.html b/tests/snapshots/members/filters=public,inherited_members=True,members=None.html similarity index 100% rename from tests/snapshots/external/16295fa51a2c3a60d1461a9a14093603333f836326a007d8eb061f78ab38a712.html rename to tests/snapshots/members/filters=public,inherited_members=True,members=None.html diff --git a/tests/snapshots/external/37232379c426474cc962db72ded419e39c3e416c30e367c8745f3be4e86557a4.html b/tests/snapshots/members/filters=public,inherited_members=True,members=True.html similarity index 100% rename from tests/snapshots/external/37232379c426474cc962db72ded419e39c3e416c30e367c8745f3be4e86557a4.html rename to tests/snapshots/members/filters=public,inherited_members=True,members=True.html diff --git a/tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=False.html similarity index 100% rename from tests/snapshots/external/45fa32980cabc490537069f05a1310b459b913f30b1bce149d805322d136c711.html rename to tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=False.html diff --git a/tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=True.html similarity index 100% rename from tests/snapshots/external/35c8879435c018f36b85b8167e3dad2b07086db09c903a750af2f6be914fffb4.html rename to tests/snapshots/overloads/overloads_only=False,separate_signature=False,show_overloads=True.html diff --git a/tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=False.html similarity index 100% rename from tests/snapshots/external/728ef9e28d866a04e6cd10c1c1c260beecc355aaf82cd133e082e37883837002.html rename to tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=False.html diff --git a/tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html b/tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=True.html similarity index 100% rename from tests/snapshots/external/19a1066a31c46587271239553fc90888add55a0ff86d8932191bb726ebe1c443.html rename to tests/snapshots/overloads/overloads_only=False,separate_signature=True,show_overloads=True.html diff --git a/tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=False.html similarity index 100% rename from tests/snapshots/external/17e520187500b8d5538f3bbef11805c6c2488b30461055f427156fa1567e51c1.html rename to tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=False.html diff --git a/tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=True.html similarity index 100% rename from tests/snapshots/external/30b2733496a882fe6d5d71107eb69808d0f3b67e28b1677f04ab965d1da2e6b3.html rename to tests/snapshots/overloads/overloads_only=True,separate_signature=False,show_overloads=True.html diff --git a/tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=False.html similarity index 100% rename from tests/snapshots/external/90ca219874af369f47b226128197d37c09ec0b0294020d9337f34887d02590b5.html rename to tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=False.html diff --git a/tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html b/tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=True.html similarity index 100% rename from tests/snapshots/external/fca9fb3aa9f566962016f8042811ab6f69201b959d606633320c9d53d2b3298b.html rename to tests/snapshots/overloads/overloads_only=True,separate_signature=True,show_overloads=True.html diff --git a/tests/snapshots/external/b060b701543e5503dc848538a164e80480ab25f8885aa83b97776e6b0cc6b570.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html similarity index 100% rename from tests/snapshots/external/b060b701543e5503dc848538a164e80480ab25f8885aa83b97776e6b0cc6b570.html rename to tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=False.html diff --git a/tests/snapshots/external/6a02b544c12c68b75d9bf3b85b1800830fd980daabff9df8c3760eb6edea7915.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html similarity index 100% rename from tests/snapshots/external/6a02b544c12c68b75d9bf3b85b1800830fd980daabff9df8c3760eb6edea7915.html rename to tests/snapshots/signatures/separate_signature=False,show_signature_annotations=False,signature_crossrefs=True.html diff --git a/tests/snapshots/external/d1216ebf8e30ec559861678318efb45bef54a847517e5d90e130818c2a06b163.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html similarity index 100% rename from tests/snapshots/external/d1216ebf8e30ec559861678318efb45bef54a847517e5d90e130818c2a06b163.html rename to tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=False.html diff --git a/tests/snapshots/external/735fc6ffdb82ce35cdab2aed2389a630e4d2c7ad95308bc5c7a56a8a8930b37f.html b/tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html similarity index 100% rename from tests/snapshots/external/735fc6ffdb82ce35cdab2aed2389a630e4d2c7ad95308bc5c7a56a8a8930b37f.html rename to tests/snapshots/signatures/separate_signature=False,show_signature_annotations=True,signature_crossrefs=True.html diff --git a/tests/snapshots/external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html similarity index 100% rename from tests/snapshots/external/d03d16d1919af01db9b8d4e5bf36b007810eb3730a7283624a4d68c6fe2ce652.html rename to tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=False.html diff --git a/tests/snapshots/external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html similarity index 100% rename from tests/snapshots/external/4041a38e355f6585a7e1265509d7c5b499fe3776aeeeb298db7589bb385ca019.html rename to tests/snapshots/signatures/separate_signature=True,show_signature_annotations=False,signature_crossrefs=True.html diff --git a/tests/snapshots/external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html similarity index 100% rename from tests/snapshots/external/74ee37cd1e94250baa33050af088e7341495708d879ab45ee9e8ab1dcac26f2a.html rename to tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=False.html diff --git a/tests/snapshots/external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html b/tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html similarity index 100% rename from tests/snapshots/external/e412376be64f25f3f5d2264400a83a1e693c146feec7c359855c676c4a586392.html rename to tests/snapshots/signatures/separate_signature=True,show_signature_annotations=True,signature_crossrefs=True.html diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index f9cd1244..e442b1a8 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -9,9 +9,7 @@ import bs4 import pytest from griffe import LinesCollection, ModulesCollection, TmpPackage, temporary_pypackage -from inline_snapshot import outsource, register_format_alias - -from tests.snapshots import snapshots_members, snapshots_signatures +from inline_snapshot import external_file, register_format_alias if TYPE_CHECKING: from collections.abc import Iterator @@ -62,6 +60,10 @@ def _render_options(options: dict[str, Any]) -> str: return f"\n\n" +def _snapshot_file(group: str, options: dict[str, Any]) -> str: + return f"snapshots/{group}/" + ",".join(f"{k}={v}" for k, v in sorted(options.items())) + ".html" + + # Signature tests. @pytest.fixture(name="signature_package", scope="session") def _signature_package() -> Iterator[TmpPackage]: @@ -101,14 +103,13 @@ def test_end_to_end_for_signatures( identifier: Parametrized identifier. session_handler: Python handler (fixture). """ - final_options = { + options = { "show_signature_annotations": show_signature_annotations, "signature_crossrefs": signature_crossrefs, "separate_signature": separate_signature, } - html = _render_options(final_options) + _render(session_handler, signature_package, final_options) - snapshot_key = tuple(sorted(final_options.items())) - assert outsource(html, suffix=".html") == snapshots_signatures[snapshot_key] + html = _render_options(options) + _render(session_handler, signature_package, options) + assert html == external_file(_snapshot_file("signatures", options), format=".txt") # Signature overloads tests. @@ -164,14 +165,13 @@ def test_end_to_end_for_overloads( identifier: Parametrized identifier. session_handler: Python handler (fixture). """ - final_options = { + options = { "separate_signature": separate_signature, "show_overloads": show_overloads, "overloads_only": overloads_only, } - html = _render_options(final_options) + _render(session_handler, overloads_package, final_options) - snapshot_key = tuple(sorted(final_options.items())) - assert outsource(html, suffix=".html") == snapshots_signatures[snapshot_key] + html = _render_options(options) + _render(session_handler, overloads_package, options) + assert html == external_file(_snapshot_file("overloads", options), format=".txt") # Member tests. @@ -229,14 +229,13 @@ def test_end_to_end_for_members( identifier: Parametrized identifier. session_handler: Python handler (fixture). """ - final_options = { + options = { "inherited_members": inherited_members, "members": members, "filters": filters, } - html = _render_options(final_options) + _render(session_handler, members_package, final_options) - snapshot_key = tuple(sorted(final_options.items())) - assert outsource(html, suffix=".html") == snapshots_members[snapshot_key] + html = _render_options(options) + _render(session_handler, members_package, options) + assert html == external_file(_snapshot_file("members", options), format=".txt") # Heading tests. @@ -275,12 +274,10 @@ def test_end_to_end_for_headings( identifier: Parametrized identifier. session_handler: Python handler (fixture). """ - final_options = { + options = { "separate_signature": separate_signature, "heading": heading, - "show_if_no_docstring": True, - "members": False, } - html = _render_options(final_options) + _render(session_handler, headings_package, final_options) - snapshot_key = tuple(sorted(final_options.items())) - assert outsource(html, suffix=".html") == snapshots_members[snapshot_key] + extra = {"show_if_no_docstring": True, "members": False} + html = _render_options(options) + _render(session_handler, headings_package, {**options, **extra}) + assert html == external_file(_snapshot_file("headings", options), format=".txt") From baf3facaaf20ba1f3fb0185ee9499ca6dd48a590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 7 Aug 2025 13:54:32 +0200 Subject: [PATCH 18/46] ci: Remove type ignore comment --- src/mkdocstrings_handlers/python/_internal/rendering.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 70eacb36..0e5f3d39 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -639,7 +639,7 @@ def _parse_docstring_summary(attribute: Attribute) -> str: name=attribute.name, description=_parse_docstring_summary(attribute), annotation=attribute.annotation, - value=attribute.value, # type: ignore[arg-type] + value=attribute.value, ) for attribute in attributes if not check_public or attribute.is_public From e82c24f17513fba4cff22e90f0a82c00a01a077d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Thu, 7 Aug 2025 13:57:57 +0200 Subject: [PATCH 19/46] feat: Add `skip_local_inventory` option to prevent objects from being registered in the local objects inventory Issue-296: https://github.com/mkdocstrings/python/issues/296 Issue-mkdocstrings-671: https://github.com/mkdocstrings/mkdocstrings/issues/671 PR-297: https://github.com/mkdocstrings/python/pull/297 --- docs/usage/configuration/general.md | 60 +++++++++++++++++++ docs/usage/configuration/headings.md | 2 +- pyproject.toml | 2 +- .../python/_internal/config.py | 8 +++ .../material/_base/attribute.html.jinja | 2 + .../material/_base/children.html.jinja | 8 +-- .../templates/material/_base/class.html.jinja | 2 + .../_base/docstring/parameters.html.jinja | 3 + .../material/_base/function.html.jinja | 2 + .../material/_base/module.html.jinja | 2 + 10 files changed, 85 insertions(+), 6 deletions(-) diff --git a/docs/usage/configuration/general.md b/docs/usage/configuration/general.md index 973658c1..68899890 100644 --- a/docs/usage/configuration/general.md +++ b/docs/usage/configuration/general.md @@ -494,3 +494,63 @@ def some_function():

Docstring of the function.

//// /// + +[](){#option-skip_local_inventory} +## `skip_local_inventory` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** + + +Whether to skip registering symbols in the objects inventory. + +With this option enabled, re-rendering docstrings for objects from external inventories is possible with their cross-references pointing to the original external inventory, not local. Similarly, it becomes possible to render the same symbol several times in the same documentation, with only one canonical location being used for cross-references (preventing confusion in mkdocs-autorefs). + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + skip_local_inventory: false +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + skip_local_inventory: true +``` + +/// admonition | Preview + type: preview + + +//// tab | Without `skip_local_inventory` + +```md exec="on" +::: bisect.bisect_left + options: + heading_level: 3 + skip_local_inventory: false + show_docstring_description: false +``` + +Notice how [`bisect.bisect_left`][] now points to the section above. + +//// + +//// tab | With `skip_local_inventory` + +```md exec="on" +::: bisect.bisect_right + inventories: + - https://docs.python.org/3/objects.inv + options: + heading_level: 3 + skip_local_inventory: true + show_docstring_description: false +``` + +Notice how [`bisect.bisect_right`][] points to the original Python documentation. + +//// +/// diff --git a/docs/usage/configuration/headings.md b/docs/usage/configuration/headings.md index b4314b77..0c253f1f 100644 --- a/docs/usage/configuration/headings.md +++ b/docs/usage/configuration/headings.md @@ -88,7 +88,7 @@ With this option enabled, each function/method parameter (including parameters of `__init__` methods merged in their parent class with the [`merge_init_into_class`][] option) gets a permalink, an entry in the Table of Contents, -and an entry in the generated objects inventory. +and an entry in the generated objects inventory (unless [`skip_local_inventory`][] is enabled). The permalink and inventory entry allow cross-references from internal and external pages. diff --git a/pyproject.toml b/pyproject.toml index 8adc2a30..9ac5537d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "mkdocstrings>=0.28.3", + "mkdocstrings>=0.30", "mkdocs-autorefs>=1.4", "griffe>=1.6.2", "typing-extensions>=4.0; python_version < '3.11'", diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 6a68e353..49c55813 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -865,6 +865,14 @@ class PythonInputOptions: ), ] = False + skip_local_inventory: Annotated[ + bool, + _Field( + group="general", + description="Whether to prevent objects from being registered in the local objects inventory.", + ), + ] = False + signature_crossrefs: Annotated[ bool, _Field( diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja index 5832c8bd..bad9ad54 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja @@ -40,6 +40,7 @@ Context: id=html_id, class="doc doc-heading", toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute.name), + skip_inventory=config.skip_local_inventory, ) %} {% block heading scoped %} @@ -93,6 +94,7 @@ Context: id=html_id, toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute_name), hidden=True, + skip_inventory=config.skip_local_inventory, ) %} {% endfilter %} {% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja index 0b9fcd64..0538aa9a 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja @@ -45,7 +45,7 @@ Context: ) %} {% if attributes %} {% if config.show_category_heading %} - {% filter heading(heading_level, id=html_id ~ "-attributes") %}Attributes{% endfilter %} + {% filter heading(heading_level, id=html_id ~ "-attributes", skip_inventory=config.skip_local_inventory) %}Attributes{% endfilter %} {% endif %} {% with heading_level = heading_level + extra_level %} {% for attribute in attributes|order_members(config.members_order, members_list) %} @@ -65,7 +65,7 @@ Context: ) %} {% if classes %} {% if config.show_category_heading %} - {% filter heading(heading_level, id=html_id ~ "-classes") %}Classes{% endfilter %} + {% filter heading(heading_level, id=html_id ~ "-classes", skip_inventory=config.skip_local_inventory) %}Classes{% endfilter %} {% endif %} {% with heading_level = heading_level + extra_level %} {% for class in classes|order_members(config.members_order, members_list) %} @@ -85,7 +85,7 @@ Context: ) %} {% if functions %} {% if config.show_category_heading %} - {% filter heading(heading_level, id=html_id ~ "-functions") %}Functions{% endfilter %} + {% filter heading(heading_level, id=html_id ~ "-functions", skip_inventory=config.skip_local_inventory) %}Functions{% endfilter %} {% endif %} {% with heading_level = heading_level + extra_level %} {% for function in functions|order_members(config.members_order, members_list) %} @@ -108,7 +108,7 @@ Context: ) %} {% if modules %} {% if config.show_category_heading %} - {% filter heading(heading_level, id=html_id ~ "-modules") %}Modules{% endfilter %} + {% filter heading(heading_level, id=html_id ~ "-modules", skip_inventory=config.skip_local_inventory) %}Modules{% endfilter %} {% endif %} {% with heading_level = heading_level + extra_level %} {% for module in modules|order_members("alphabetical", members_list) %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index 8a54dd1b..f366f497 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -39,6 +39,7 @@ Context: id=html_id, class="doc doc-heading", toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else class.name), + skip_inventory=config.skip_local_inventory, ) %} {% block heading scoped %} @@ -112,6 +113,7 @@ Context: id=html_id, toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else class.name), hidden=True, + skip_inventory=config.skip_local_inventory, ) %} {% endfilter %} {% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja index 1035ddf7..a3ea5f7f 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja @@ -43,6 +43,7 @@ Context: id=html_id ~ "(" ~ parameter.name ~ ")", class="doc doc-heading doc-heading-parameter", toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name, + skip_inventory=config.skip_local_inventory, ) %} {{ parameter.name }} {% endfilter %} @@ -92,6 +93,7 @@ Context: id=html_id ~ "(" ~ parameter.name ~ ")", class="doc doc-heading doc-heading-parameter", toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name, + skip_inventory=config.skip_local_inventory, ) %} {{ parameter.name }} {% endfilter %} @@ -139,6 +141,7 @@ Context: id=html_id ~ "(" ~ parameter.name ~ ")", class="doc doc-heading doc-heading-parameter", toc_label=(' '|safe if config.show_symbol_type_toc else '') + parameter.name, + skip_inventory=config.skip_local_inventory, ) %} {{ parameter.name }} {% endfilter %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja index cd97c8db..4c84006e 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja @@ -46,6 +46,7 @@ Context: id=html_id, class="doc doc-heading", toc_label=((' ')|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else function.name), + skip_inventory=config.skip_local_inventory, ) %} {% block heading scoped %} @@ -110,6 +111,7 @@ Context: id=html_id, toc_label=((' ')|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else function.name), hidden=True, + skip_inventory=config.skip_local_inventory, ) %} {% endfilter %} {% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja index 283f2654..c5e4a400 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja @@ -39,6 +39,7 @@ Context: id=html_id, class="doc doc-heading", toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else module.name), + skip_inventory=config.skip_local_inventory, ) %} {% block heading scoped %} @@ -76,6 +77,7 @@ Context: id=html_id, toc_label=(' '|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else module.name), hidden=True, + skip_inventory=config.skip_local_inventory, ) %} {% endfilter %} {% endif %} From 0e3bdb857b5ede3e15aa7a9b8b87b33f68889c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Aug 2025 23:17:28 +0200 Subject: [PATCH 20/46] feat: Support new Griffe parsing options `warn_missing_types` and `warnings` Issue-mkdocstrings-437: https://github.com/mkdocstrings/mkdocstrings/issues/437 --- pyproject.toml | 2 +- .../python/_internal/config.py | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9ac5537d..45430d46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ classifiers = [ dependencies = [ "mkdocstrings>=0.30", "mkdocs-autorefs>=1.4", - "griffe>=1.6.2", + "griffe>=1.12.1", "typing-extensions>=4.0; python_version < '3.11'", ] diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 49c55813..952fc159 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -186,6 +186,24 @@ class GoogleStyleOptions: ), ] = True + warn_missing_types: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Warn about missing type/annotation for parameters, return values, etc.", + ), + ] = True + + warnings: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Generally enable/disable warnings when parsing docstrings.", + ), + ] = True + # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. @dataclass(**_dataclass_options) # type: ignore[call-overload] @@ -219,12 +237,57 @@ class NumpyStyleOptions: ), ] = True + warn_missing_types: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Warn about missing type/annotation for parameters, return values, etc.", + ), + ] = True + + warnings: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Generally enable/disable warnings when parsing docstrings.", + ), + ] = True + # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. @dataclass(**_dataclass_options) # type: ignore[call-overload] class SphinxStyleOptions: """Sphinx style docstring options.""" + warn_unknown_params: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Warn about documented parameters not appearing in the signature.", + ), + ] = True + + warn_missing_types: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Warn about missing type/annotation for return values.", + ), + ] = True + + warnings: Annotated[ + bool, + _Field( + group="docstrings", + parent="docstring_options", + description="Generally enable/disable warnings when parsing docstrings.", + ), + ] = True + # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. @dataclass(**_dataclass_options) # type: ignore[call-overload] From 3a0bb1e60b07e47996ced740577c02ade50bf02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Aug 2025 23:18:01 +0200 Subject: [PATCH 21/46] chore: Prepare release 1.17.0 --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea4f1cf3..d7d2a9a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.17.0](https://github.com/mkdocstrings/python/releases/tag/1.17.0) - 2025-08-14 + +[Compare with 1.16.12](https://github.com/mkdocstrings/python/compare/1.16.12...1.17.0) + +### Features + +- Support new Griffe parsing options `warn_missing_types` and `warnings` ([0e3bdb8](https://github.com/mkdocstrings/python/commit/0e3bdb857b5ede3e15aa7a9b8b87b33f68889c9e) by Timothée Mazzucotelli). [Issue-mkdocstrings-437](https://github.com/mkdocstrings/mkdocstrings/issues/437) +- Add `skip_local_inventory` option to prevent objects from being registered in the local objects inventory ([e82c24f](https://github.com/mkdocstrings/python/commit/e82c24f17513fba4cff22e90f0a82c00a01a077d) by Bartosz Sławecki). [Issue-296](https://github.com/mkdocstrings/python/issues/296), [Issue-mkdocstrings-671](https://github.com/mkdocstrings/mkdocstrings/issues/671), [PR-297](https://github.com/mkdocstrings/python/pull/297) +- Support hiding attribute values ([6cf34b9](https://github.com/mkdocstrings/python/commit/6cf34b9882e20d9147a6481e672ae09989a27796) by Bartosz Sławecki). Issue-292: #292, PR-293: #293 +- Support hiding implementation signature (showing overload only) ([d3b35e1](https://github.com/mkdocstrings/python/commit/d3b35e17384901e7280b8b6926f10fb033480358) by Bartosz Sławecki). [Issue-213](https://github.com/mkdocstrings/python/issues/213), [PR-286](https://github.com/mkdocstrings/python/pull/286) + +### Code Refactoring + +- Deprecate `locale` option in favor of mkdocstrings' ([17f71ba](https://github.com/mkdocstrings/python/commit/17f71babf11081869478b21b2bde1a33fc97be41) by Timothée Mazzucotelli). [PR-288](https://github.com/mkdocstrings/python/pull/288) + ## [1.16.12](https://github.com/mkdocstrings/python/releases/tag/1.16.12) - 2025-06-03 [Compare with 1.16.11](https://github.com/mkdocstrings/python/compare/1.16.11...1.16.12) From 6004ccf3576c7a20e21c880bb2235b7b426ba382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 24 Aug 2025 19:28:53 +0200 Subject: [PATCH 22/46] fix: Increase maximum recursion limit in case of deeply nested ASTs (rare occurrence) Issue-griffe-402: https://github.com/mkdocstrings/griffe/issues/402 --- src/mkdocstrings_handlers/python/_internal/handler.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index 8bc40d27..66bee9f3 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -408,6 +408,10 @@ def get_handler( Returns: An instance of `PythonHandler`. """ + # In rare cases, Griffe hits the recursion limit because of deeply-nested ASTs. + # We therefore increase the limit here, once, before Griffe is used to collect or render stuff. + sys.setrecursionlimit(max(sys.getrecursionlimit(), 2000)) + base_dir = Path(tool_config.config_file_path or "./mkdocs.yml").parent if "inventories" not in handler_config and "import" in handler_config: warn("The 'import' key is renamed 'inventories' for the Python handler", FutureWarning, stacklevel=1) From 53507b537e0387624f3b71b099b254c1e4f3b4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 26 Aug 2025 14:10:12 +0200 Subject: [PATCH 23/46] ci: Remove unused type ignore comment --- tests/test_end_to_end.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index e442b1a8..3363ebd6 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -22,7 +22,7 @@ def _normalize_html(html: str) -> str: soup = bs4.BeautifulSoup(html, features="html.parser") - html = soup.prettify() # type: ignore[assignment] + html = soup.prettify() html = re.sub(r"\b(0x)[a-f0-9]+\b", r"\1...", html) html = re.sub(r"^(Build Date UTC ?:).+", r"\1...", html, flags=re.MULTILINE) html = re.sub(r"\b[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\b", r"...", html) From dc8c3adb23b37add6601de9e74085f76e5fc9ee5 Mon Sep 17 00:00:00 2001 From: Victor Westerhuis Date: Tue, 26 Aug 2025 16:01:19 +0200 Subject: [PATCH 24/46] feat: Support PEP 695 generics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-221: https://github.com/mkdocstrings/python/pull/221 Co-authored-by: Timothée Mazzucotelli --- .github/workflows/ci.yml | 2 +- docs/snippets/package/generics.py | 49 +++++ docs/usage/configuration/docstrings.md | 117 +++++++++- docs/usage/configuration/headings.md | 128 +++++++++++ docs/usage/configuration/members.md | 2 +- docs/usage/configuration/signatures.md | 55 +++++ docs/usage/customization.md | 58 ++++- duties.py | 6 +- mkdocs.yml | 2 + pyproject.toml | 2 +- src/mkdocstrings_handlers/python/__init__.py | 4 + .../python/_internal/config.py | 53 ++++- .../python/_internal/handler.py | 2 + .../python/_internal/rendering.py | 102 ++++++++- .../material/_base/children.html.jinja | 25 +++ .../templates/material/_base/class.html.jinja | 54 +++-- .../material/_base/docstring.html.jinja | 6 + .../_base/docstring/type_aliases.html | 10 + .../_base/docstring/type_aliases.html.jinja | 86 ++++++++ .../_base/docstring/type_parameters.html | 10 + .../docstring/type_parameters.html.jinja | 208 ++++++++++++++++++ .../material/_base/expression.html.jinja | 52 ++++- .../material/_base/function.html.jinja | 6 +- .../material/_base/languages/en.html.jinja | 11 + .../material/_base/languages/ja.html.jinja | 13 +- .../material/_base/languages/zh.html.jinja | 13 +- .../material/_base/summary.html.jinja | 5 + .../material/_base/summary/type_aliases.html | 10 + .../_base/summary/type_aliases.html.jinja | 24 ++ .../templates/material/_base/type_alias.html | 10 + .../material/_base/type_alias.html.jinja | 120 ++++++++++ .../material/_base/type_parameters.html | 10 + .../material/_base/type_parameters.html.jinja | 89 ++++++++ .../material/docstring/type_aliases.html | 1 + .../docstring/type_aliases.html.jinja | 1 + .../material/docstring/type_parameters.html | 1 + .../docstring/type_parameters.html.jinja | 1 + .../python/templates/material/style.css | 38 +++- .../material/summary/type_aliases.html | 1 + .../material/summary/type_aliases.html.jinja | 1 + .../python/templates/material/type_alias.html | 1 + .../templates/material/type_alias.html.jinja | 1 + .../templates/material/type_parameters.html | 1 + .../material/type_parameters.html.jinja | 1 + 44 files changed, 1344 insertions(+), 48 deletions(-) create mode 100644 docs/snippets/package/generics.py create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/type_alias.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/material/type_parameters.html create mode 100644 src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32767fde..cf37ef60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Setup uv uses: astral-sh/setup-uv@v5 diff --git a/docs/snippets/package/generics.py b/docs/snippets/package/generics.py new file mode 100644 index 00000000..0aef12d4 --- /dev/null +++ b/docs/snippets/package/generics.py @@ -0,0 +1,49 @@ +"""Some module showing generics. + +Type Aliases: + SomeType: Some type alias. +""" + +type SomeType[Z] = int | list[Z] +"""Some type alias. + +Type parameters: + Z: Some type parameter. +""" + + +class MagicBag[T: (str, bytes) = str](list[T]): + """A magic bag of items. + + Type parameters: + T: Some type. + """ + + def __init__[U: (int, bool)](self, *args: T, flag1: U | None = None, flag2: U | None = None) -> None: + """Initialize bag. + + Type parameters: + U: Some flag type. + + Parameters: + flag1: Some flag. + flag2: Some flag. + """ + super().__init__(args) + self.flag1 = flag1 + self.flag2 = flag2 + + def mutate[K](self, item: T, into: K) -> K: + """Shake the bag to mutate an item into something else (and eject it). + + Type parameters: + K: Some other type. + + Parameters: + item: The item to mutate. + into: Mutate the item into something like this. + + Returns: + The mutated item. + """ + ... diff --git a/docs/usage/configuration/docstrings.md b/docs/usage/configuration/docstrings.md index ae925f23..f864d102 100644 --- a/docs/usage/configuration/docstrings.md +++ b/docs/usage/configuration/docstrings.md @@ -623,7 +623,7 @@ class ClassWithoutDocstring: - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** -Whether to render the "Attributes" sections of docstrings. +Whether to render the "Attributes" section of docstrings. ```yaml title="in mkdocs.yml (global configuration)" plugins: @@ -676,7 +676,7 @@ class Class: - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** -Whether to render the "Functions" or "Methods" sections of docstrings. +Whether to render the "Functions" or "Methods" section of docstrings. ```yaml title="in mkdocs.yml (global configuration)" plugins: @@ -751,7 +751,7 @@ class Class: - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** -Whether to render the "Classes" sections of docstrings. +Whether to render the "Classes" section of docstrings. ```yaml title="in mkdocs.yml (global configuration)" plugins: @@ -804,13 +804,71 @@ class Class: //// /// +[](){#option-show_docstring_type_aliases} +## `show_docstring_type_aliases` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + +Whether to render the "Type Aliases" section of docstrings. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + show_docstring_type_aliases: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + show_docstring_type_aliases: false +``` + +```python +"""Summary. + +Type Aliases: + TypeAlias: Some type alias. +""" + + +type TypeAlias = int +"""Summary.""" +``` + +/// admonition | Preview + type: preview + +//// tab | With type_aliases +

module

+

Summary.

+

Type Aliases:

+ +**Name** | **Description** +------------ | ---------------- +`TypeAlias` | Some type alias. + +

TypeAlias

+

Summary.

+//// + +//// tab | Without classes +

module

+

Summary.

+

TypeAlias

+

Summary.

+//// +/// + [](){#option-show_docstring_modules} ## `show_docstring_modules` - **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** -Whether to render the "Modules" sections of docstrings. +Whether to render the "Modules" section of docstrings. ```yaml title="in mkdocs.yml (global configuration)" plugins: @@ -1245,6 +1303,57 @@ def rand() -> int: //// /// +[](){#option-show_docstring_type_parameters} +## `show_docstring_type_parameters` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + + +Whether to render the "Type Parameters" section of docstrings. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + show_docstring_type_parameters: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + show_docstring_type_parameters: false +``` + +```python +class AClass[X: (int, str) = str]: + """Represents something. + + Type Parameters: + X: Something. + """ +``` + +/// admonition | Preview + type: preview + +//// tab | With parameters +

AClass

+

Represents something.

+

Type Parameters:

+ +**Name** | **Bound or Constraints** | **Description** | **Default** +---------- | ------------------------ | --------------- | ----------- +`whatever` | `(int, str)` | Something. | `str` +//// + +//// tab | Without parameters +

AClass

+

Represents something.

+//// +/// + [](){#option-show_docstring_warns} ## `show_docstring_warns` diff --git a/docs/usage/configuration/headings.md b/docs/usage/configuration/headings.md index 0c253f1f..ee10e381 100644 --- a/docs/usage/configuration/headings.md +++ b/docs/usage/configuration/headings.md @@ -682,3 +682,131 @@ NOTE: **Use with/without `heading`.** If you use this option without specifying heading: "My fancy module" toc_label: "My fancy module" ``` + +[](){#option-type_parameter_headings} +## `type_parameter_headings` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** + +Whether to render headings for generic class, function/method and type alias +type parameters. + +With this option enabled, each type parameter of a generic object (including +type parameters of `__init__` methods merged in their parent class with the +[`merge_init_into_class`][] option) gets a permalink, an entry in the Table of +Contents, and an entry in the generated objects inventory. The permalink and +inventory entry allow cross-references from internal and external pages. + + + +Enabling this option along with [`signature_crossrefs`][] will automatically +render cross-references to type parameters in class/function/method/type alias +signatures. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + type_parameter_headings: false +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + type_parameter_headings: true +``` + +/// admonition | Preview: Cross-references + type: preview + +```md exec="on" +::: package.generics + options: + show_root_heading: false + heading_level: 3 + docstring_section_style: list + show_bases: true + summary: false + separate_signature: true + show_signature_type_parameters: true + type_parameter_headings: true +``` + +/// + +/// admonition | Preview: Type parameter sections + type: preview + +//// tab | Table style +```md exec="on" +::: package.generics.MagicBag + options: + members: false + heading_level: 3 + show_root_heading: false + show_root_toc_entry: false + parameter_headings: true + docstring_section_style: table + show_docstring_description: false + show_docstring_parameters: false + show_docstring_returns: false +``` +//// + +//// tab | List style +```md exec="on" +::: package.generics.MagicBag + options: + members: false + heading_level: 3 + show_root_heading: false + show_root_toc_entry: false + parameter_headings: true + docstring_section_style: list + show_docstring_description: false + show_docstring_parameters: false + show_docstring_returns: false +``` +//// + +//// tab | Spacy style +```md exec="on" +::: package.generics.MagicBag + options: + members: false + heading_level: 3 + show_root_heading: false + show_root_toc_entry: false + parameter_headings: true + docstring_section_style: spacy + show_docstring_description: false + show_docstring_parameters: false + show_docstring_returns: false +``` +//// +/// + +/// admonition | Preview: Table of contents (with symbol types) + type: preview + + mutate
+ U + +To customize symbols, see [Customizing symbol types](../customization.md/#symbol-types). + +/// diff --git a/docs/usage/configuration/members.md b/docs/usage/configuration/members.md index 7a5069a1..3c344221 100644 --- a/docs/usage/configuration/members.md +++ b/docs/usage/configuration/members.md @@ -585,7 +585,7 @@ package Whether to render summaries of modules, classes, functions (methods) and attributes. This option accepts a boolean (`yes`, `true`, `no`, `false` in YAML) -or a dictionary with one or more of the following keys: `attributes`, `functions`, `classes`, `modules`, +or a dictionary with one or more of the following keys: `attributes`, `functions`, `classes`, `modules`, `type_aliases`, with booleans as values. Class methods summary is (de)activated with the `functions` key. By default, `summary` is false, and by extension all values are false. diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md index c49cd181..0dabf74f 100644 --- a/docs/usage/configuration/signatures.md +++ b/docs/usage/configuration/signatures.md @@ -430,6 +430,61 @@ function(param1, param2=None) //// /// +[](){#option-show_signature_type_parameters} +## `show_signature_type_parameters` + +- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** + + +Show the type parameters in generic classes, methods, functions and type aliases +signatures. + +Since the heading can become quite long when type parameters are rendered, it is +usually best to [separate the signature][separate_signature] from the heading. + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + separate_signature: true + show_signature_annotations: true + show_signature_type_parameters: true +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.module + options: + separate_signature: true + show_signature_annotations: true + show_signature_type_parameters: false +``` + +/// admonition | Preview + type: preview + +//// tab | With signature type parameters +

function

+ +```python +function[T, *R](param: T) -> tuple[*R] +``` + +

Function docstring.

+//// + +//// tab | Without signature type parameters +

function

+ +```python +function(param: T) -> tuple[*R] +``` + +

Function docstring.

+//// +/// + [](){#option-separate_signature} ## `separate_signature` diff --git a/docs/usage/customization.md b/docs/usage/customization.md index 8239c2e9..d1e66b31 100644 --- a/docs/usage/customization.md +++ b/docs/usage/customization.md @@ -34,9 +34,10 @@ The following CSS classes are used in the generated HTML: - `doc-class`: on `div`s containing a class - `doc-function`: on `div`s containing a function - `doc-module`: on `div`s containing a module + - `doc-type_alias`: on `div`s containing a type alias - `doc-heading`: on objects headings - `doc-object-name`: on `span`s wrapping objects names/paths in the heading - - `doc-KIND-name`: as above, specific to the kind of object (module, class, function, attribute) + - `doc-KIND-name`: as above, specific to the kind of object (module, class, function, attribute, type_alias) - `doc-contents`: on `div`s wrapping the docstring then the children (if any) - `first`: same, but only on the root object's contents `div` - `doc-labels`: on `span`s wrapping the object's labels @@ -48,7 +49,7 @@ The following CSS classes are used in the generated HTML: - `doc-symbol`: on `code` tags of symbol types - `doc-symbol-heading`: on symbol types in headings - `doc-symbol-toc`: on symbol types in the ToC - - `doc-symbol-KIND`: specific to the kind of object (`module`, `class`, `function`, `method`, `attribute`) + - `doc-symbol-KIND`: specific to the kind of object (`module`, `class`, `function`, `method`, `attribute`, `type_alias`) /// admonition | Example with colorful labels type: example @@ -90,33 +91,41 @@ by overriding the values of our CSS variables, for example: ```css title="docs/css/mkdocstrings.css" [data-md-color-scheme="default"] { --doc-symbol-parameter-fg-color: #df50af; + --doc-symbol-type_parameter-fg-color: #df50af; --doc-symbol-attribute-fg-color: #0079ff; --doc-symbol-function-fg-color: #00dfa2; --doc-symbol-method-fg-color: #00dfa2; --doc-symbol-class-fg-color: #d1b619; + --doc-symbol-type_alias-fg-color: #d1b619; --doc-symbol-module-fg-color: #ff0060; --doc-symbol-parameter-bg-color: #df50af1a; + --doc-symbol-type_parameter-bg-color: #df50af1a; --doc-symbol-attribute-bg-color: #0079ff1a; --doc-symbol-function-bg-color: #00dfa21a; --doc-symbol-method-bg-color: #00dfa21a; --doc-symbol-class-bg-color: #d1b6191a; + --doc-symbol-type_alias-bg-color: #d1b6191a; --doc-symbol-module-bg-color: #ff00601a; } [data-md-color-scheme="slate"] { --doc-symbol-parameter-fg-color: #ffa8cc; + --doc-symbol-type_parameter-fg-color: #ffa8cc; --doc-symbol-attribute-fg-color: #963fb8; --doc-symbol-function-fg-color: #6d67e4; --doc-symbol-method-fg-color: #6d67e4; --doc-symbol-class-fg-color: #46c2cb; + --doc-symbol-type_alias-fg-color: #46c2cb; --doc-symbol-module-fg-color: #f2f7a1; --doc-symbol-parameter-bg-color: #ffa8cc1a; + --doc-symbol-type_parameter-bg-color: #ffa8cc1a; --doc-symbol-attribute-bg-color: #963fb81a; --doc-symbol-function-bg-color: #6d67e41a; --doc-symbol-method-bg-color: #6d67e41a; --doc-symbol-class-bg-color: #46c2cb1a; + --doc-symbol-type_alias-bg-color: #46c2cb1a; --doc-symbol-module-bg-color: #f2f7a11a; } ``` @@ -129,17 +138,21 @@ otherwise just override the variables at root level: ```css title="docs/css/mkdocstrings.css" :root { --doc-symbol-parameter-fg-color: #df50af; + --doc-symbol-type_parameter-fg-color: #df50af; --doc-symbol-attribute-fg-color: #0079ff; --doc-symbol-function-fg-color: #00dfa2; --doc-symbol-method-fg-color: #00dfa2; --doc-symbol-class-fg-color: #d1b619; + --doc-symbol-type_alias-fg-color: #d1b619; --doc-symbol-module-fg-color: #ff0060; --doc-symbol-parameter-bg-color: #df50af1a; + --doc-symbol-type_parameter-bg-color: #df50af1a; --doc-symbol-attribute-bg-color: #0079ff1a; --doc-symbol-function-bg-color: #00dfa21a; --doc-symbol-method-bg-color: #00dfa21a; --doc-symbol-class-bg-color: #d1b6191a; + --doc-symbol-type_alias-bg-color: #d1b6191a; --doc-symbol-module-bg-color: #ff00601a; } ``` @@ -151,33 +164,41 @@ otherwise just override the variables at root level: @@ -204,6 +225,10 @@ For example, to use single letters instead of truncated types: content: "P"; } +.doc-symbol-type_parameter::after { + content: "P"; +} + .doc-symbol-attribute::after { content: "A"; } @@ -220,6 +245,10 @@ For example, to use single letters instead of truncated types: content: "C"; } +.doc-symbol-type_alias::after { + content: "T"; +} + .doc-symbol-module::after { content: "M"; } @@ -234,6 +263,10 @@ For example, to use single letters instead of truncated types: content: "P"; } + #preview-symbol-names .doc-symbol-type_parameter::after { + content: "P"; + } + #preview-symbol-names .doc-symbol-attribute::after { content: "A"; } @@ -250,16 +283,22 @@ For example, to use single letters instead of truncated types: content: "C"; } + #preview-symbol-names .doc-symbol-type_alias::after { + content: "T"; + } + #preview-symbol-names .doc-symbol-module::after { content: "M"; }
  • Parameter:
  • +
  • Type Parameter:
  • Attribute:
  • Function:
  • Method:
  • Class:
  • +
  • Type Alias:
  • Module:
@@ -324,6 +363,19 @@ Available context: - `config`: The handler configuration (dictionary). - `module`: The [Module][griffe.Module] instance. +#### `type_alias.html` + +- `heading`: The class heading. +- `labels`: The class labels. +- `signature`: The class signature. +- `contents`: The class contents: bases, docstring, source and children blocks. +- `docstring`: The class docstring. + +Available context: + +- `config`: The handler configuration (dictionary). +- `type_alias`: The [TypeAlias][griffe.TypeAlias] instance. + #### `class.html` - `heading`: The class heading. @@ -379,6 +431,8 @@ In `docstring/attributes.html`, `docstring/raises.html`, `docstring/receives.html`, `docstring/returns.html`, +`docstring/type_aliases.html`, +`docstring/type_parameters.html`, `docstring/warns.html`, and `docstring/yields.html`: diff --git a/duties.py b/duties.py index 2f09340f..0fa73ea0 100644 --- a/duties.py +++ b/duties.py @@ -93,7 +93,7 @@ def check_quality(ctx: Context) -> None: ) -@duty +@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) def check_docs(ctx: Context) -> None: """Check if the documentation builds correctly.""" Path("htmlcov").mkdir(parents=True, exist_ok=True) @@ -128,7 +128,7 @@ def check_api(ctx: Context, *cli_args: str) -> None: ) -@duty +@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) def docs(ctx: Context, *cli_args: str, host: str = "127.0.0.1", port: int = 8000) -> None: """Serve the documentation (localhost:8000). @@ -144,7 +144,7 @@ def docs(ctx: Context, *cli_args: str, host: str = "127.0.0.1", port: int = 8000 ) -@duty +@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) def docs_deploy(ctx: Context, *, force: bool = False) -> None: """Deploy the documentation to GitHub pages. diff --git a/mkdocs.yml b/mkdocs.yml index 0199ea9a..0796e003 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -166,6 +166,7 @@ plugins: line_length: 88 merge_init_into_class: true parameter_headings: true + type_parameter_headings: true preload_modules: [mkdocstrings] relative_crossrefs: true scoped_crossrefs: true @@ -175,6 +176,7 @@ plugins: show_root_heading: true show_root_full_path: false show_signature_annotations: true + show_signature_type_parameters: true show_source: false show_symbol_type_heading: true show_symbol_type_toc: true diff --git a/pyproject.toml b/pyproject.toml index 45430d46..ad0c852c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ classifiers = [ dependencies = [ "mkdocstrings>=0.30", "mkdocs-autorefs>=1.4", - "griffe>=1.12.1", + "griffe>=1.13", "typing-extensions>=4.0; python_version < '3.11'", ] diff --git a/src/mkdocstrings_handlers/python/__init__.py b/src/mkdocstrings_handlers/python/__init__.py index faa9b9f4..7e12fa73 100644 --- a/src/mkdocstrings_handlers/python/__init__.py +++ b/src/mkdocstrings_handlers/python/__init__.py @@ -22,12 +22,14 @@ do_as_classes_section, do_as_functions_section, do_as_modules_section, + do_as_type_aliases_section, do_backlink_tree, do_crossref, do_filter_objects, do_format_attribute, do_format_code, do_format_signature, + do_format_type_alias, do_get_template, do_multi_crossref, do_order_members, @@ -55,12 +57,14 @@ "do_as_classes_section", "do_as_functions_section", "do_as_modules_section", + "do_as_type_aliases_section", "do_backlink_tree", "do_crossref", "do_filter_objects", "do_format_attribute", "do_format_code", "do_format_signature", + "do_format_type_alias", "do_get_template", "do_multi_crossref", "do_order_members", diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 952fc159..62c124ba 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -423,6 +423,15 @@ class SummaryOption: ), ] = False + type_aliases: Annotated[ + bool, + _Field( + group="members", + parent="summary", + description="Whether to render summaries of type aliases.", + ), + ] = False + # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. @dataclass(**_dataclass_options) # type: ignore[call-overload] @@ -797,6 +806,22 @@ class PythonInputOptions: ), ] = True + show_docstring_type_aliases: Annotated[ + bool, + _Field( + group="docstrings", + description="Whether to display the 'Type Aliases' section in the object's docstring.", + ), + ] = True + + show_docstring_type_parameters: Annotated[ + bool, + _Field( + group="docstrings", + description="Whether to display the 'Type Parameters' section in the object's docstring.", + ), + ] = True + show_docstring_warns: Annotated[ bool, _Field( @@ -888,6 +913,14 @@ class PythonInputOptions: ), ] = False + show_signature_type_parameters: Annotated[ + bool, + _Field( + group="signatures", + description="Show the type parameters in generic classes, methods, functions and type aliases signatures.", + ), + ] = False + show_signature: Annotated[ bool, _Field( @@ -960,6 +993,14 @@ class PythonInputOptions: ), ] = "" + type_parameter_headings: Annotated[ + bool, + _Field( + group="headings", + description="Whether to render headings for type parameters (therefore showing type parameters in the ToC).", + ), + ] = False + unwrap_annotated: Annotated[ bool, _Field( @@ -1001,9 +1042,15 @@ def coerce(cls, **data: Any) -> MutableMapping[str, Any]: if "summary" in data: summary = data["summary"] if summary is True: - summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True) + summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True, type_aliases=True) elif summary is False: - summary = SummaryOption(attributes=False, functions=False, classes=False, modules=False) + summary = SummaryOption( + attributes=False, + functions=False, + classes=False, + modules=False, + type_aliases=False, + ) else: summary = SummaryOption(**summary) data["summary"] = summary @@ -1028,7 +1075,7 @@ class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore] """A list of filters, or `"public"`.""" summary: SummaryOption = field(default_factory=SummaryOption) - """Whether to render summaries of modules, classes, functions (methods) and attributes.""" + """Whether to render summaries of modules, classes, functions (methods), attributes and type aliases.""" @classmethod def coerce(cls, **data: Any) -> MutableMapping[str, Any]: diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index 66bee9f3..c62088b3 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -322,12 +322,14 @@ def update_env(self, config: Any) -> None: # noqa: ARG002 self.env.filters["format_code"] = rendering.do_format_code self.env.filters["format_signature"] = rendering.do_format_signature self.env.filters["format_attribute"] = rendering.do_format_attribute + self.env.filters["format_type_alias"] = rendering.do_format_type_alias self.env.filters["filter_objects"] = rendering.do_filter_objects self.env.filters["stash_crossref"] = rendering.do_stash_crossref self.env.filters["get_template"] = rendering.do_get_template self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section 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_type_aliases_section"] = rendering.do_as_type_aliases_section self.env.filters["as_modules_section"] = rendering.do_as_modules_section self.env.filters["backlink_tree"] = rendering.do_backlink_tree self.env.globals["AutorefsHook"] = rendering.AutorefsHook diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 0e5f3d39..99aeb014 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -28,7 +28,10 @@ DocstringSectionClasses, DocstringSectionFunctions, DocstringSectionModules, + DocstringSectionTypeAliases, + DocstringTypeAlias, Object, + TypeAlias, ) from jinja2 import TemplateNotFound, pass_context, pass_environment from markupsafe import Markup @@ -160,8 +163,10 @@ def do_format_signature( The same code, formatted. """ env = context.environment + # YORE: Bump 2: Replace `do_get_template(env, "type_parameters")` with `"type_parameters.html.jinja"` within line. + type_params_template = env.get_template(do_get_template(env, "type_parameters")) # YORE: Bump 2: Replace `do_get_template(env, "signature")` with `"signature.html.jinja"` within line. - template = env.get_template(do_get_template(env, "signature")) + signature_template = env.get_template(do_get_template(env, "signature")) if annotations is None: new_context = context.parent @@ -169,7 +174,9 @@ def do_format_signature( new_context = dict(context.parent) new_context["config"] = replace(new_context["config"], show_signature_annotations=annotations) - signature = template.render(new_context, function=function, signature=True) + signature = type_params_template.render(context.parent, obj=function, signature=True) + signature += signature_template.render(new_context, function=function, signature=True) + signature = _format_signature(callable_path, signature, line_length) signature = str( env.filters["highlight"]( @@ -259,6 +266,67 @@ def do_format_attribute( return signature +@pass_context +def do_format_type_alias( + context: Context, + type_alias_path: Markup, + type_alias: TypeAlias, + line_length: int, + *, + crossrefs: bool = False, # noqa: ARG001 +) -> str: + """Format a type alias. + + Parameters: + context: Jinja context, passed automatically. + type_alias_path: The path of the type alias we render the signature of. + type_alias: The type alias we render the signature of. + line_length: The line length. + crossrefs: Whether to cross-reference types in the signature. + + Returns: + The same code, formatted. + """ + env = context.environment + # YORE: Bump 2: Replace `do_get_template(env, "type_parameters")` with `"type_parameters.html.jinja"` within line. + type_params_template = env.get_template(do_get_template(env, "type_parameters")) + # YORE: Bump 2: Replace `do_get_template(env, "expression")` with `"expression.html.jinja"` within line. + expr_template = env.get_template(do_get_template(env, "expression")) + + signature = str(type_alias_path).strip() + signature += type_params_template.render(context.parent, obj=type_alias, signature=True) + value = expr_template.render(context.parent, expression=type_alias.value, signature=True) + signature += f" = {value}" + + signature = do_format_code(signature, line_length) + signature = str( + env.filters["highlight"]( + Markup.escape(signature), + language="python", + inline=False, + classes=["doc-signature"], + linenums=False, + ), + ) + + # Since we highlight the signature without `type`, + # Pygments sees only an assignment, not a type alias definition + # (at the moment it does not understand type alias definitions anyway). + # The result is that the type alias name is not parsed as such, + # but instead as a regular name: `n` CSS class instead of `nc`. + # To fix it, we replace the first occurrence of an `n` CSS class + # with an `nc` one, unless we found `nc` already. + if not re.search(r'', signature): + signature = re.sub(r'', '', signature, count=1) + + if stash := env.filters["stash_crossref"].stash: + for key, value in stash.items(): + signature = re.sub(rf"\b{key}\b", value, signature) + stash.clear() + + return signature + + def do_order_members( members: Sequence[Object | Alias], order: Order | list[Order], @@ -592,7 +660,7 @@ def do_get_template(env: Environment, obj: str | Object) -> str: extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {}) if name := extra_data.get("template", ""): return name - name = obj.kind.value + name = obj.kind.value.replace(" ", "_") # YORE: Bump 2: Replace block with `return f"{name}.html.jinja"`. try: template = env.get_template(f"{name}.html") @@ -732,6 +800,34 @@ def do_as_modules_section( ) +@pass_context +def do_as_type_aliases_section( + context: Context, # noqa: ARG001 + type_aliases: Sequence[TypeAlias], + *, + check_public: bool = True, +) -> DocstringSectionTypeAliases: + """Build a type aliases section from a list of type aliases. + + Parameters: + type_aliases: The type aliases to build the section from. + check_public: Whether to check if the type_alias is public. + + Returns: + A type aliases docstring section. + """ + return DocstringSectionTypeAliases( + [ + DocstringTypeAlias( + name=type_alias.name, + description=type_alias.docstring.value.split("\n", 1)[0] if type_alias.docstring else "", + ) + for type_alias in type_aliases + if not check_public or type_alias.is_public + ], + ) + + class AutorefsHook(AutorefsHookInterface): """Autorefs hook. diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja index 0538aa9a..3be0a33a 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja @@ -57,6 +57,26 @@ Context: {% endif %} {% endwith %} + {% with type_aliases = obj.type_aliases|filter_objects( + filters=config.filters, + members_list=members_list, + inherited_members=config.inherited_members, + keep_no_docstrings=config.show_if_no_docstring, + ) %} + {% if type_aliases %} + {% if config.show_category_heading %} + {% filter heading(heading_level, id=html_id ~ "-type_aliases") %}Type Aliases{% endfilter %} + {% endif %} + {% with heading_level = heading_level + extra_level %} + {% for type_alias in type_aliases|order_members(config.members_order, members_list) %} + {% if config.filters == "public" or members_list is not none or (not type_alias.is_imported or type_alias.is_public) %} + {% include type_alias|get_template with context %} + {% endif %} + {% endfor %} + {% endwith %} + {% endif %} + {% endwith %} + {% with classes = obj.classes|filter_objects( filters=config.filters, members_list=members_list, @@ -143,6 +163,11 @@ Context: {% include attribute|get_template with context %} {% endwith %} + {% elif child.is_type_alias %} + {% with type_alias = child %} + {% include type_alias|get_template with context %} + {% endwith %} + {% elif child.is_class %} {% with class = child %} {% include class|get_template with context %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index f366f497..50385f41 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -54,12 +54,18 @@ Context: {{ class_name }} {% elif config.merge_init_into_class and "__init__" in all_members %} {% with function = all_members["__init__"] %} - {%+ filter highlight(language="python", inline=True) -%} + {%+ filter highlight(language="python", inline=True) %} + {{ class_name -}} + {%- with obj = function -%} + {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} + {%- include "type_parameters"|get_template with context -%} + {%- endwith -%} {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} - {{ class_name }}{% include "signature"|get_template with context %} - {%- endfilter %} + {%- include "signature"|get_template with context -%} + {% endfilter %} {% endwith %} {% else %} + {# TODO: Maybe render type parameters here. #} {{ class_name }} {% endif %} {% endblock heading %} @@ -83,26 +89,30 @@ Context: This block renders the signature for the class. Overloads of the `__init__` method are rendered if `merge_init_into_class` is enabled. The actual `__init__` method signature is only rendered if `separate_signature` is also enabled. + + If the class is generic, but the `__init__` method isn't or `merge_init_into_class` is disabled, + the class signature is rendered if `separate_signature` and `show_signature_type_parameters` are enabled. + + If the `__init__` method or any overloads are generic, they are rendered as methods if + `merge_init_into_class`, `separate_signature` and `show_signature_type_parameters` are enabled. -#} - {% if config.merge_init_into_class %} - {% if "__init__" in all_members %} - {% with function = all_members["__init__"] %} - {% if function.overloads and config.show_overloads %} -
- {% for overload in function.overloads %} - {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %} - {{ class.name }} - {% endfilter %} - {% endfor %} -
- {% endif %} - {% if config.separate_signature %} - {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %} - {{ class.name }} - {% endfilter %} - {% endif %} - {% endwith %} - {% endif %} + {% if config.merge_init_into_class and "__init__" in all_members %} + {% with function = all_members["__init__"] %} + {% if function.overloads and config.show_overloads %} +
+ {% for overload in function.overloads %} + {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %} + {{ class.name }} + {% endfilter %} + {% endfor %} +
+ {% endif %} + {% if config.separate_signature %} + {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %} + {{ class.name }} + {% endfilter %} + {% endif %} + {% endwith %} {% endif %} {% endblock signature %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja index c560668e..cae4f50f 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja @@ -32,9 +32,15 @@ Context: {% elif config.show_docstring_classes and section.kind.value == "classes" %} {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} {% include "docstring/classes"|get_template with context %} + {% elif config.show_docstring_type_aliases and section.kind.value == "type aliases" %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% include "docstring/type_aliases"|get_template with context %} {% elif config.show_docstring_modules and section.kind.value == "modules" %} {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} {% include "docstring/modules"|get_template with context %} + {% elif config.show_docstring_type_parameters and section.kind.value == "type parameters" %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% include "docstring/type_parameters"|get_template with context %} {% elif config.show_docstring_parameters and section.kind.value == "parameters" %} {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} {% include "docstring/parameters"|get_template with context %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html new file mode 100644 index 00000000..e9a99d1b --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html @@ -0,0 +1,10 @@ +{# YORE: Bump 2: Remove file. #} +{% extends "_base/docstring/type_aliases.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {{ log.warning( + "DeprecationWarning: Extending '_base/docstring/type_aliases.html' is deprecated, extend '_base/docstring/type_aliases.html.jinja' instead. ", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja new file mode 100644 index 00000000..ceaa520c --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja @@ -0,0 +1,86 @@ +{#- Template for "Type Aliases" sections in docstrings. + +This template renders a list of documented type aliases in the format +specified with the [`docstring_section_style`][] configuration option. + +Context: + section (griffe.DocstringSectionTypeAliases): The section to render. +-#} + +{% block logs scoped %} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} + {{ log.debug("Rendering type aliases section") }} +{% endblock logs %} + +{% import "language"|get_template as lang with context %} +{#- Language module providing the `t` translation method. -#} + +{% if config.docstring_section_style == "table" %} + {% block table_style scoped %} + {#- Block for the `table` section style. -#} +

{{ section.title or lang.t("Type Aliases:") }}

+ + + + + + + + + {% for type_alias in section.value %} + + + + + {% endfor %} + +
{{ lang.t("Name") }}{{ lang.t("Description") }}
{{ type_alias.name }} +
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
+
+ {% endblock table_style %} +{% elif config.docstring_section_style == "list" %} + {% block list_style scoped %} + {#- Block for the `list` section style. -#} +

{{ section.title or lang.t("Type Aliases:") }}

+
    + {% for type_alias in section.value %} +
  • + {{ type_alias.name }} + – +
    + {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
    +
  • + {% endfor %} +
+ {% endblock list_style %} +{% elif config.docstring_section_style == "spacy" %} + {% block spacy_style scoped %} + {#- Block for the `spacy` section style. -#} + + + + + + + + + {% for type_alias in section.value %} + + + + + {% endfor %} + +
{{ (section.title or lang.t("TYPE ALIAS")).rstrip(":").upper() }}{{ lang.t("DESCRIPTION") }}
{{ type_alias.name }} +
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
+
+ {% endblock spacy_style %} +{% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html new file mode 100644 index 00000000..90a1af38 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html @@ -0,0 +1,10 @@ +{# YORE: Bump 2: Remove file. #} +{% extends "_base/docstring/type_parameters.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {{ log.warning( + "DeprecationWarning: Extending '_base/docstring/type_parameters.html' is deprecated, extend '_base/docstring/type_parameters.html.jinja' instead. ", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja new file mode 100644 index 00000000..8e83e8be --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja @@ -0,0 +1,208 @@ +{#- Template for "Parameters" sections in docstrings. + +This template renders a list of documented type parameters in the format +specified with the [`docstring_section_style`][] configuration option. + +Context: + section (griffe.DocstringSectionTypeParameters): The section to render. +-#} + +{% block logs scoped %} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} + {{ log.debug("Rendering type parameters section") }} +{% endblock logs %} + +{% import "language"|get_template as lang with context %} +{#- Language module providing the `t` translation method. -#} + +{% if config.docstring_section_style == "table" %} + {% block table_style scoped %} + {#- Block for the `table` section style. -#} +

+ + {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }} + +

+ + + + + + + + + + + {% for type_parameter in section.value %} + + + + + + + {% endfor %} + +
{{ lang.t("Name") }}{{ lang.t("Bound or Constraints") }}{{ lang.t("Description") }}{{ lang.t("Default") }}
+ {% if config.type_parameter_headings %} + {% filter heading( + heading_level + 1, + role="typeparam", + id=obj.path ~ "[" ~ type_parameter.name ~ "]", + class="doc doc-heading doc-heading-type_parameter", + toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name, + ) %} + {{ type_parameter.name }} + {% endfilter %} + {% else %} + {{ type_parameter.name }} + {% endif %} + + {% if type_parameter.annotation %} + {% with expression = type_parameter.annotation %} + {% include "expression"|get_template with context %} + {% endwith %} + {% endif %} + +
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
+
+ {% if type_parameter.default %} + {% with expression = type_parameter.default %} + {% include "expression"|get_template with context %} + {% endwith %} + {% else %} + {{ lang.t("required") }} + {% endif %} +
+ {% endblock table_style %} +{% elif config.docstring_section_style == "list" %} + {% block list_style scoped %} + {#- Block for the `list` section style. -#} +

+ + {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }} + +

+
    + {% for type_parameter in section.value %} +
  • + {% if config.type_parameter_headings %} + {% filter heading( + heading_level + 1, + role="typeparam", + id=obj.path ~ "[" ~ type_parameter.name ~ "]", + class="doc doc-heading doc-heading-type_parameter", + toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name, + ) %} + {{ type_parameter.name }} + {% endfilter %} + {% else %} + {{ type_parameter.name }} + {% endif %} + {%- if type_parameter.bound or type_parameter.constraints or type_parameter.default -%} + ( + {%- endif -%} + {%- if type_parameter.bound -%} + {%- with expression = type_parameter.bound -%} + {% include "expression"|get_template with context %} + {%- endwith -%} + {%- if type_parameter.default %}, {% endif -%} + {%- elif type_parameter.constraints -%} + {%- for expression in type_parameter.constraints -%} + {% include "expression"|get_template with context %} + {%- if not loop.last %}, {% endif -%} + {%- endfor -%} + {%- if type_parameter.default %}, {% endif -%} + {%- endif -%} + {%- if type_parameter.default -%} + {{ lang.t("default:") }} + {% with expression = type_parameter.default %} + {% include "expression"|get_template with context %} + {%- endwith -%} + {%- endif -%} + {%- if type_parameter.constraints or type_parameter.default -%} + ) + {% endif -%} + – +
    + {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
    +
  • + {% endfor %} +
+ {% endblock list_style %} +{% elif config.docstring_section_style == "spacy" %} + {% block spacy_style scoped %} + {#- Block for the `spacy` section style. -#} + + + + + + + + + {% for type_parameter in section.value %} + + + + + {% endfor %} + +
+ + {{ (section.title or lang.t(("CLASS " if obj.is_class else "INIT " if obj.is_init_method else "") ~ "TYPE PARAMETER")).rstrip(":").upper() }} + + {{ lang.t("DESCRIPTION") }}
+ {% if config.type_parameter_headings %} + {% filter heading( + heading_level + 1, + role="typeparam", + id=obj.path ~ "[" ~ type_parameter.name ~ "]", + class="doc doc-heading doc-heading-type_parameter", + toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name, + ) %} + {{ type_parameter.name }} + {% endfilter %} + {% else %} + {{ type_parameter.name }} + {% endif %} + +
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }} +
+

+ {% if type_parameter.constraints %} + + {{ lang.t("CONSTRAINTS:") }} + {% for constraint in type_parameter.constraints -%} + {%- with expression = constraint -%} + {% include "expression"|get_template with context %} + {%- endwith -%} + {%- if not loop.last %}, {% endif -%} + {% endfor %} + + {% elif type_parameter.bound %} + + {{ lang.t("BOUND:") }} + {% with expression = type_parameter.bound %} + {% include "expression"|get_template with context %} + {% endwith %} + + {% endif %} + {% if type_parameter.default %} + + {{ lang.t("DEFAULT:") }} + {% with expression = type_parameter.default %} + {% include "expression"|get_template with context %} + {% endwith %} + + {% endif %} +

+
+ {% endblock spacy_style %} +{% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja index d49e43be..54781739 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja @@ -2,6 +2,10 @@ This template renders a Griffe expression, which is a tree-like structure representing a Python expression. + +Context: + expression (griffe.Expr): The expression to render. + config (dict): The configuration options. -#} {% block logs scoped %} @@ -16,6 +20,25 @@ which is a tree-like structure representing a Python expression. This macro outputs a cross-reference to the given name. + Parameters: + name (griffe.ExprName): The name to cross-reference. + annotation_path (str): Either "brief", "source", or "full". + + Returns: + Either a cross-reference (using an autoref element) or the name itself. + -#} + {%- if name.classname == "ExprName" and name.is_type_parameter -%} + {{ type_param_crossref(name) }} + {%- else -%} + {{ object_crossref(name, annotation_path) }} + {%- endif -%} +{%- endmacro -%} + +{%- macro object_crossref(name, annotation_path) -%} + {#- Output a cross-reference to a Griffe object. + + This macro outputs a cross-reference to the given name. + Parameters: name (griffe.ExprName): The name to cross-reference. annotation_path (str): Either "brief", "source", or "full". @@ -50,6 +73,26 @@ which is a tree-like structure representing a Python expression. {%- endwith -%} {%- endmacro -%} +{%- macro type_param_crossref(name) -%} + {#- Render a cross-reference to a type parameter heading. + + Parameters: + name (griffe.ExprName): The name to cross-reference. + + Returns: + The autorefs cross-reference, or the type parameter name. + -#} + {%- if not signature -%} + {{ name.name }} + {%- elif config.signature_crossrefs -%} + {%- filter stash_crossref(length=name.name|length) -%} + {{ name.name }} + {%- endfilter -%} + {%- else -%} + {{ name.name }} + {%- endif -%} +{%- endmacro -%} + {%- macro param_crossref(expression) -%} {#- Render a cross-reference to a parameter heading. @@ -89,7 +132,14 @@ which is a tree-like structure representing a Python expression. {%- elif config.unwrap_annotated and expression.classname == "ExprSubscript" and expression.canonical_path in ("typing.Annotated", "typing_extensions.Annotated") -%} {{ render(expression.slice.elements[0], annotations_path) }} {%- elif expression.classname == "ExprAttribute" -%} - {%- if annotations_path == "brief" -%} + {%- if expression.first.is_type_parameter -%} + {{ type_param_crossref(expression.first) }} + {%- for element in expression -%} + {%- if not loop.first -%} + {{ render(element, "brief") }} + {%- endif -%} + {%- endfor -%} + {%- elif annotations_path == "brief" -%} {%- if expression.last.is_enum_value -%} {{ crossref(expression.last.parent, "brief", backlink_type) }}.value {%- else -%} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja index 4c84006e..708fde68 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja @@ -61,8 +61,10 @@ Context: {{ function_name }} {% else %} {%+ filter highlight(language="python", inline=True) -%} - {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} - {{ function_name }}{% include "signature"|get_template with context %} + {{ function_name }} + {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within block. -#} + {%- include "type_parameters"|get_template with context -%} + {%- include "signature"|get_template with context -%} {%- endfilter %} {% endif %} {% endblock heading %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja index bcdcce2d..a2e38b7c 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja @@ -10,8 +10,13 @@ {% macro t(key) %}{{ { "ATTRIBUTE": "ATTRIBUTE", "Attributes:": "Attributes:", + "BOUND:": "BOUND:", + "Bound or Constraints": "Bound or Constraints", "Classes:": "Classes:", + "Class Type Parameters:": "Class Type Parameters:", + "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER", "CLASS": "CLASS", + "CONSTRAINTS:": "CONSTRAINTS:", "DEFAULT:": "DEFAULT:", "Default": "Default", "default:": "default:", @@ -20,6 +25,8 @@ "Examples:": "Examples:", "Functions:": "Functions:", "FUNCTION": "FUNCTION", + "Init Type Parameters:": "Init Type Parameters:", + "INIT TYPE PARAMETER": "INIT TYPE PARAMETER", "Methods:": "Methods:", "METHOD": "METHOD", "Modules:": "Modules:", @@ -38,6 +45,10 @@ "Source code in": "Source code in", "TYPE:": "TYPE:", "Type": "Type", + "Type Aliases:": "Type Aliases:", + "TYPE ALIAS": "TYPE ALIAS", + "Type Parameters:": "Type Parameters:", + "TYPE PARAMETER": "TYPE PARAMETER", "WARNS": "WARNS", "Warns:": "Warns:", "YIELDS": "YIELDS", diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja index 0393ca03..be0dd62b 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja @@ -10,8 +10,13 @@ {% macro t(key) %}{{ { "ATTRIBUTE": "属性", "Attributes:": "属性:", + "BOUND:": "BOUND:", + "Bound or Constraints": "Bound or Constraints", "Classes:": "クラス:", - "CLASS": "クラス", + "Class Type Parameters:": "Class Type Parameters:", + "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER", + "CLASS": "CLASS", + "CONSTRAINTS:": "CONSTRAINTS:", "DEFAULT:": "デフォルト:", "Default": "デフォルト", "default:": "デフォルト:", @@ -20,6 +25,8 @@ "Examples:": "例:", "Functions:": "関数:", "FUNCTION": "関数", + "Init Type Parameters:": "Init Type Parameters:", + "INIT TYPE PARAMETER": "INIT TYPE PARAMETER", "Methods:": "メソッド:", "METHOD": "メソッド", "Modules:": "モジュール:", @@ -38,6 +45,10 @@ "Source code in": "ソースコード位置:", "TYPE:": "タイプ:", "Type": "タイプ", + "Type Aliases:": "Type Aliases:", + "TYPE ALIAS": "TYPE ALIAS", + "Type Parameters:": "Type Parameters:", + "TYPE PARAMETER": "TYPE PARAMETER", "WARNS": "警告", "Warns:": "警告:", "YIELDS": "返す", diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja index e57169ad..3f1e3481 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja @@ -10,8 +10,13 @@ {% macro t(key) %}{{ { "ATTRIBUTE": "属性", "Attributes:": "属性:", + "BOUND:": "BOUND:", + "Bound or Constraints": "Bound or Constraints", "Classes:": "类:", - "CLASS": "类", + "Class Type Parameters:": "Class Type Parameters:", + "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER", + "CLASS": "CLASS", + "CONSTRAINTS:": "CONSTRAINTS:", "DEFAULT:": "默认:", "Default": "默认", "default:": "默认:", @@ -20,6 +25,8 @@ "Examples:": "示例:", "Functions:": "函数:", "FUNCTION": "函数", + "Init Type Parameters:": "Init Type Parameters:", + "INIT TYPE PARAMETER": "INIT TYPE PARAMETER", "Methods:": "方法:", "METHOD": "方法", "Modules:": "模块:", @@ -38,6 +45,10 @@ "Source code in": "源代码位于:", "TYPE:": "类型:", "Type": "类型", + "Type Aliases:": "Type Aliases:", + "TYPE ALIAS": "TYPE ALIAS", + "Type Parameters:": "Type Parameters:", + "TYPE PARAMETER": "TYPE PARAMETER", "Warns:": "警告:", "WARNS": "警告", "YIELDS": "产生", diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja index 78b0b9d7..477d0b0d 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja @@ -13,6 +13,11 @@ {% include "summary/modules"|get_template with context %} {% endif %} + {% if config.summary.type_aliases %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% include "summary/type_aliases"|get_template with context %} + {% endif %} + {% if config.summary.classes %} {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} {% include "summary/classes"|get_template with context %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html new file mode 100644 index 00000000..68554b8c --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html @@ -0,0 +1,10 @@ +{# YORE: Bump 2: Remove file. #} +{% extends "_base/summary/type_aliases.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {{ log.warning( + "DeprecationWarning: Extending '_base/type_aliases/classes.html' is deprecated, extend '_base/type_aliases/classes.html.jinja' instead.", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja new file mode 100644 index 00000000..9ebc2b23 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja @@ -0,0 +1,24 @@ +{#- Summary of type aliases. -#} + +{% block logs scoped %} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} +{% endblock logs %} + +{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "type aliases") | list %} + {% with section = obj.type_aliases + |filter_objects( + filters=config.filters, + members_list=members_list, + inherited_members=config.inherited_members, + keep_no_docstrings=config.show_if_no_docstring, + ) + |order_members("alphabetical", members_list) + |as_type_aliases_section(check_public=not members_list) + %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% if section %}{% include "docstring/type_aliases"|get_template with context %}{% endif %} + {% endwith %} +{% endif %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html new file mode 100644 index 00000000..d811f7f3 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html @@ -0,0 +1,10 @@ +{# YORE: Bump 2: Remove file. #} +{% extends "_base/type_alias.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {{ log.warning( + "DeprecationWarning: Extending '_base/type_alias.html' is deprecated, extend '_base/type_alias.html.jinja' instead. ", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja new file mode 100644 index 00000000..bb7d4d71 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja @@ -0,0 +1,120 @@ +{#- Template for Python type aliases. + +This template renders a Python type alias. + +Context: + type_alias (griffe.TypeAlias): The type alias to render. + root (bool): Whether this is the root object, injected with `:::` in a Markdown page. + heading_level (int): The HTML heading level to use. + config (dict): The configuration options. +-#} + +{% block logs scoped %} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} + {{ log.debug("Rendering " + type_alias.path) }} +{% endblock logs %} + +
+ {% with obj = type_alias, html_id = type_alias.path %} + + {% if root %} + {% set show_full_path = config.show_root_full_path %} + {% set root_members = True %} + {% elif root_members %} + {% set show_full_path = config.show_root_members_full_path or config.show_object_full_path %} + {% set root_members = False %} + {% else %} + {% set show_full_path = config.show_object_full_path %} + {% endif %} + + {% set type_alias_name = type_alias.path if show_full_path else type_alias.name %} + + {% if not root or config.show_root_heading %} + {% filter heading( + heading_level, + role="typealias", + id=html_id, + class="doc doc-heading", + toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_alias.name, + ) %} + + {% block heading scoped %} + {#- Heading block. + + This block renders the heading for the type alias. + -#} + {% if config.show_symbol_type_heading %}{% endif %} + {% if config.separate_signature %} + {{ type_alias_name }} + {% else %} + {%+ filter highlight(language="python", inline=True) %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {{ type_alias_name }}{% include "type_parameters"|get_template with context %} = {{ type_alias.value }} + {% endfilter %} + {% endif %} + {% endblock heading %} + + {% block labels scoped %} + {#- Labels block. + + This block renders the labels for the type alias. + -#} + {% with labels = type_alias.labels %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% include "labels"|get_template with context %} + {% endwith %} + {% endblock labels %} + + {% endfilter %} + + {% block signature scoped %} + {#- Signature block. + + This block renders the signature for the type alias. + -#} + {% if config.separate_signature %} + {% filter format_type_alias(type_alias, config.line_length, crossrefs=config.signature_crossrefs) %} + {{ type_alias.name }} + {% endfilter %} + {% endif %} + {% endblock signature %} + + {% else %} + {% if config.show_root_toc_entry %} + {% filter heading(heading_level, + role="typealias", + id=html_id, + toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_alias.name, + hidden=True, + ) %} + {% endfilter %} + {% endif %} + {% set heading_level = heading_level - 1 %} + {% endif %} + +
+ {% block contents scoped %} + {#- Contents block. + + This block renders the contents of the type alias. + It contains other blocks that users can override. + Overriding the contents block allows to rearrange the order of the blocks. + -#} + {% block docstring scoped %} + {#- Docstring block. + + This block renders the docstring for the type alias. + -#} + {% with docstring_sections = type_alias.docstring.parsed %} + {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #} + {% include "docstring"|get_template with context %} + {% endwith %} + {% endblock docstring %} + {% endblock contents %} +
+ + {% endwith %} +
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html new file mode 100644 index 00000000..782b1e8b --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html @@ -0,0 +1,10 @@ +{# YORE: Bump 2: Remove file. #} +{% extends "_base/type_parameters.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {{ log.warning( + "DeprecationWarning: Extending '_base/type_parameters.html' is deprecated, extend '_base/type_parameters.html.jinja' instead.", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja new file mode 100644 index 00000000..59fad354 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja @@ -0,0 +1,89 @@ +{#- Template for type parameters. + +This template renders the type parameters of a generic obj. +It iterates over the type parameters of the object to rebuild the signature. +The signature is the list of type parameters of a generic object, including their names, default values, and bound or constraints. + +Context: + obj (griffe.Object): The object to render. + config (dict): The configuration options. +-#} + +{%- if config.show_signature_type_parameters -%} + {%- block logs scoped -%} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} + {{ log.debug("Rendering type parameters") }} + {%- endblock logs -%} + + {%- with ns = namespace(annotation="", equal="=", default=False) -%} + {%- if obj.is_generic -%} + [ + {%- for type_parameter in obj.type_parameters -%} + {#- Prepare type bound or constraints. -#} + {%- if config.show_signature_annotations and type_parameter.annotation is not none -%} + {%- set ns.equal = " = " -%} + {%- if config.separate_signature and config.signature_crossrefs -%} + {%- with expression = type_parameter.annotation -%} + {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} + {%- set ns.annotation -%}: {% include "expression"|get_template with context %}{%- endset -%} + {%- endwith -%} + {%- else -%} + {%- set ns.annotation = ": " + type_parameter.annotation|safe -%} + {%- endif -%} + {%- else -%} + {%- set ns.equal = "=" -%} + {%- set ns.annotation = "" -%} + {%- endif -%} + + {#- Prepare default value. -#} + {%- if type_parameter.default is not none -%} + {%- set ns.default = True -%} + {%- else -%} + {%- set ns.default = False -%} + {%- endif -%} + + {#- Prepare name. -#} + {%- set type_param_prefix -%} + {%- if type_parameter.kind == "type-var-tuple" -%} + * + {%- elif type_parameter.kind == "param-spec" -%} + ** + {%- endif -%} + {%- endset -%} + + {#- Render type parameter name with optional cross-reference to its heading. -#} + {{ type_param_prefix }} + {%- if config.separate_signature and config.type_parameter_headings and config.signature_crossrefs -%} + {%- filter stash_crossref(length=type_parameter.name|length) -%} + {{ type_parameter.name }} + {%- endfilter -%} + {%- else -%} + {{ type_parameter.name }} + {%- endif -%} + + {#- Render type parameter bound or constraints. -#} + {{ ns.annotation }} + + {#- Render type parameter default value. -#} + {%- if ns.default -%} + {{ ns.equal }} + {%- if config.signature_crossrefs and config.separate_signature -%} + {%- with expression = type_parameter.default -%} + {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#} + {%- include "expression"|get_template with context -%} + {%- endwith -%} + {%- else -%} + {{ type_parameter.default|safe }} + {%- endif -%} + {%- endif -%} + + {%- if not loop.last %}, {% endif -%} + {%- endfor -%} + ] + {%- endif -%} + + {%- endwith -%} +{%- endif -%} diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html new file mode 100644 index 00000000..78bd497a --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html @@ -0,0 +1 @@ +{% extends "_base/docstring/type_aliases.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja new file mode 100644 index 00000000..78bd497a --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja @@ -0,0 +1 @@ +{% extends "_base/docstring/type_aliases.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html new file mode 100644 index 00000000..223fbb04 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html @@ -0,0 +1 @@ +{% extends "_base/docstring/type_parameters.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja new file mode 100644 index 00000000..223fbb04 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja @@ -0,0 +1 @@ +{% extends "_base/docstring/type_parameters.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css index b8c3e639..7475f5cd 100644 --- a/src/mkdocstrings_handlers/python/templates/material/style.css +++ b/src/mkdocstrings_handlers/python/templates/material/style.css @@ -26,12 +26,14 @@ } /* Defaults in Spacy table style. */ -.doc-param-default { +.doc-param-default, +.doc-type_param-default { float: right; } /* Parameter headings must be inline, not blocks. */ -.doc-heading-parameter { +.doc-heading-parameter, +.doc-heading-type_parameter { display: inline; } @@ -41,7 +43,8 @@ } /* Prefer space on the right, not the left of parameter permalinks. */ -.doc-heading-parameter .headerlink { +.doc-heading-parameter .headerlink, +.doc-heading-type_parameter .headerlink { margin-left: 0 !important; margin-right: 0.2rem; } @@ -77,33 +80,41 @@ :root, :host, [data-md-color-scheme="default"] { --doc-symbol-parameter-fg-color: #df50af; + --doc-symbol-type_parameter-fg-color: #df50af; --doc-symbol-attribute-fg-color: #953800; --doc-symbol-function-fg-color: #8250df; --doc-symbol-method-fg-color: #8250df; --doc-symbol-class-fg-color: #0550ae; + --doc-symbol-type_alias-fg-color: #0550ae; --doc-symbol-module-fg-color: #5cad0f; --doc-symbol-parameter-bg-color: #df50af1a; + --doc-symbol-type_parameter-bg-color: #df50af1a; --doc-symbol-attribute-bg-color: #9538001a; --doc-symbol-function-bg-color: #8250df1a; --doc-symbol-method-bg-color: #8250df1a; --doc-symbol-class-bg-color: #0550ae1a; + --doc-symbol-type_alias-bg-color: #0550ae1a; --doc-symbol-module-bg-color: #5cad0f1a; } [data-md-color-scheme="slate"] { --doc-symbol-parameter-fg-color: #ffa8cc; + --doc-symbol-type_parameter-fg-color: #ffa8cc; --doc-symbol-attribute-fg-color: #ffa657; --doc-symbol-function-fg-color: #d2a8ff; --doc-symbol-method-fg-color: #d2a8ff; --doc-symbol-class-fg-color: #79c0ff; + --doc-symbol-type_alias-fg-color: #79c0ff; --doc-symbol-module-fg-color: #baff79; --doc-symbol-parameter-bg-color: #ffa8cc1a; + --doc-symbol-type_parameter-bg-color: #ffa8cc1a; --doc-symbol-attribute-bg-color: #ffa6571a; --doc-symbol-function-bg-color: #d2a8ff1a; --doc-symbol-method-bg-color: #d2a8ff1a; --doc-symbol-class-bg-color: #79c0ff1a; + --doc-symbol-type_alias-bg-color: #79c0ff1a; --doc-symbol-module-bg-color: #baff791a; } @@ -124,6 +135,16 @@ code.doc-symbol-parameter::after { content: "param"; } +code.doc-symbol-type_parameter, +a code.doc-symbol-type_parameter { + color: var(--doc-symbol-type_parameter-fg-color); + background-color: var(--doc-symbol-type_parameter-bg-color); +} + +code.doc-symbol-type_parameter::after { + content: "type-param"; +} + code.doc-symbol-attribute, a code.doc-symbol-attribute { color: var(--doc-symbol-attribute-fg-color); @@ -164,6 +185,17 @@ code.doc-symbol-class::after { content: "class"; } + +code.doc-symbol-type_alias, +a code.doc-symbol-type_alias { + color: var(--doc-symbol-type_alias-fg-color); + background-color: var(--doc-symbol-type_alias-bg-color); +} + +code.doc-symbol-type_alias::after { + content: "type"; +} + code.doc-symbol-module, a code.doc-symbol-module { color: var(--doc-symbol-module-fg-color); diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html new file mode 100644 index 00000000..ca10bc88 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html @@ -0,0 +1 @@ +{% extends "_base/summary/type_aliases.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja new file mode 100644 index 00000000..ca10bc88 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja @@ -0,0 +1 @@ +{% extends "_base/summary/type_aliases.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html b/src/mkdocstrings_handlers/python/templates/material/type_alias.html new file mode 100644 index 00000000..5139a2db --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html @@ -0,0 +1 @@ +{% extends "_base/type_alias.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja new file mode 100644 index 00000000..5139a2db --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja @@ -0,0 +1 @@ +{% extends "_base/type_alias.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html new file mode 100644 index 00000000..c39ca528 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html @@ -0,0 +1 @@ +{% extends "_base/type_parameters.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja new file mode 100644 index 00000000..c39ca528 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja @@ -0,0 +1 @@ +{% extends "_base/type_parameters.html.jinja" %} From 2d3f75ac4eff8cbc9bd7f747f975af7d70013062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 26 Aug 2025 16:02:17 +0200 Subject: [PATCH 25/46] chore: Prepare release 1.18.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d2a9a9..a639b706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.18.0](https://github.com/mkdocstrings/python/releases/tag/1.18.0) - 2025-08-26 + +[Compare with 1.17.0](https://github.com/mkdocstrings/python/compare/1.17.0...1.18.0) + +### Features + +- Support PEP 695 generics ([dc8c3ad](https://github.com/mkdocstrings/python/commit/dc8c3adb23b37add6601de9e74085f76e5fc9ee5) by Victor Westerhuis). [PR-221](https://github.com/mkdocstrings/python/pull/221), Co-authored-by: Timothée Mazzucotelli + +### Bug Fixes + +- Increase maximum recursion limit in case of deeply nested ASTs (rare occurrence) ([6004ccf](https://github.com/mkdocstrings/python/commit/6004ccf3576c7a20e21c880bb2235b7b426ba382) by Timothée Mazzucotelli). [Issue-griffe-402](https://github.com/mkdocstrings/griffe/issues/402) + ## [1.17.0](https://github.com/mkdocstrings/python/releases/tag/1.17.0) - 2025-08-14 [Compare with 1.16.12](https://github.com/mkdocstrings/python/compare/1.16.12...1.17.0) From 9ef620f2b1ae80b3711a2e84ab12d7d2c4a2dbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 28 Aug 2025 12:44:35 +0200 Subject: [PATCH 26/46] fix: Don't show implementation signature of `__init__` method when `overloads_only` is true and it is merged into the class Issue-308: https://github.com/mkdocstrings/python/issues/308 --- .../python/templates/material/_base/class.html.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index 50385f41..23b3f458 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -107,7 +107,7 @@ Context: {% endfor %}
{% endif %} - {% if config.separate_signature %} + {% if config.separate_signature and not (config.show_overloads and function.overloads and config.overloads_only) %} {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %} {{ class.name }} {% endfilter %} From 913358955a90b4faac32b3903a8531a835713e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 28 Aug 2025 12:45:55 +0200 Subject: [PATCH 27/46] chore: Prepare release 1.18.1 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a639b706..4faea5fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.18.1](https://github.com/mkdocstrings/python/releases/tag/1.18.1) - 2025-08-28 + +[Compare with 1.18.0](https://github.com/mkdocstrings/python/compare/1.18.0...1.18.1) + +### Bug Fixes + +- Don't show implementation signature of `__init__` method when `overloads_only` is true and it is merged into the class ([9ef620f](https://github.com/mkdocstrings/python/commit/9ef620f2b1ae80b3711a2e84ab12d7d2c4a2dbdd) by Timothée Mazzucotelli). [Issue-308](https://github.com/mkdocstrings/python/issues/308) + ## [1.18.0](https://github.com/mkdocstrings/python/releases/tag/1.18.0) - 2025-08-26 [Compare with 1.17.0](https://github.com/mkdocstrings/python/compare/1.17.0...1.18.0) From 30d4ba23e4402a63ee27a37135c38918bdcbeca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 28 Aug 2025 15:48:11 +0200 Subject: [PATCH 28/46] docs: Fix docs for type parameter headings --- docs/usage/configuration/headings.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/usage/configuration/headings.md b/docs/usage/configuration/headings.md index ee10e381..8e904e5f 100644 --- a/docs/usage/configuration/headings.md +++ b/docs/usage/configuration/headings.md @@ -744,6 +744,7 @@ plugins: summary: false separate_signature: true show_signature_type_parameters: true + show_inheritance_diagram: false type_parameter_headings: true ``` @@ -765,6 +766,7 @@ plugins: show_docstring_description: false show_docstring_parameters: false show_docstring_returns: false + show_inheritance_diagram: false ``` //// @@ -781,6 +783,7 @@ plugins: show_docstring_description: false show_docstring_parameters: false show_docstring_returns: false + show_inheritance_diagram: false ``` //// @@ -797,6 +800,7 @@ plugins: show_docstring_description: false show_docstring_parameters: false show_docstring_returns: false + show_inheritance_diagram: false ``` //// /// From 6f79be0ea83522021e16e5d401209e58576ef93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 28 Aug 2025 18:10:49 +0200 Subject: [PATCH 29/46] fix: Normalize spaces to underscores when passing object to rendering context using its kind as key Issue-mkdocstrings-791: https://github.com/mkdocstrings/mkdocstrings/issues/791 --- src/mkdocstrings_handlers/python/_internal/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index c62088b3..fbed2b8e 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -295,7 +295,7 @@ def render(self, data: CollectorItem, options: PythonOptions, locale: str | None return template.render( **{ "config": options, - data.kind.value: data, + data.kind.value.replace(" ", "_"): data, # Heading level is a "state" variable, that will change at each step # of the rendering recursion. Therefore, it's easier to use it as a plain value # than as an item in a dictionary. From 754b481471ebc032e6dafe7efe4193b73ef2d8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 28 Aug 2025 18:11:08 +0200 Subject: [PATCH 30/46] chore: Prepare release 1.18.2 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4faea5fa..1ac6e8ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.18.2](https://github.com/mkdocstrings/python/releases/tag/1.18.2) - 2025-08-28 + +[Compare with 1.18.1](https://github.com/mkdocstrings/python/compare/1.18.1...1.18.2) + +### Bug Fixes + +- Normalize spaces to underscores when passing object to rendering context using its kind as key ([6f79be0](https://github.com/mkdocstrings/python/commit/6f79be0ea83522021e16e5d401209e58576ef93a) by Timothée Mazzucotelli). [Issue-mkdocstrings-791](https://github.com/mkdocstrings/mkdocstrings/issues/791) + ## [1.18.1](https://github.com/mkdocstrings/python/releases/tag/1.18.1) - 2025-08-28 [Compare with 1.18.0](https://github.com/mkdocstrings/python/compare/1.18.0...1.18.1) From f25b2ecf73f30ac0ea836bec1aa60e87a360e23a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 9 Sep 2025 14:07:57 +0200 Subject: [PATCH 31/46] docs: Add recommended settings section in usage page Issue-199: https://github.com/mkdocstrings/python/issues/199 --- docs/usage/index.md | 104 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/docs/usage/index.md b/docs/usage/index.md index e1fa457f..3348a627 100644 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -380,3 +380,107 @@ poetry install poetry run mkdocs build ``` /// + +## Recommended settings + +If you're in a hurry, here is the configuration we recommend for the Python handler. + +```yaml +- mkdocstrings: + handlers: + python: + + # Where to find your sources, see "Finding modules". + paths: [src] + + # Load object inventories to enable cross-references to other projects. + inventories: + - https://docs.python.org/3/objects.inv + # Also load inventories of your dependencies, generally served at + # https://docs-url-for-your-dependency/objects.inv. + + options: + + # DOCSTRINGS ------------------------------------------------------------- + docstring_options: + # Discard first line of `__init__` method docstrings, + # useful when merging such docstrings into their parent class'. + ignore_init_summary: true + + # Tables are generally too large, lists will fix this. + docstring_section_style: list + + # CROSS-REFERENCES ------------------------------------------------------- + # Enable relative crossrefs and scoped crossrefs, see Docstrings options. + relative_crossrefs: true # Sponsors only! + scoped_crossrefs: true # Sponsors only! + + # Enable cross-references in signatures. + signature_crossrefs: true + + # Unwrap actual types from `Annotated` type annotations. + unwrap_annotated: true + + # MEMBERS ---------------------------------------------------------------- + # Only render pulic symbols. + filters: public # Sponsors only! + # Comment the option otherwise to get the default filters. + + # Show class inherited members. + inherited_members: true + + # Render auto-generated summaries of attributes, functions, etc. + # at the start of each symbol's documentation. + summary: true + + # HEADINGS --------------------------------------------------------------- + # For auto-generated pages, one module per page, + # make the module heading be the H1 heading of the page. + heading_level: 1 + + # Render headings for parameters, making them linkable. + parameter_headings: true + + # Render headings for type parameters too. + type_parameter_headings: true + + # Always show the heading for the symbol you render with `::: id`. + show_root_heading: true + + # Only show the name of the symbols you inject render `::: id`. + show_root_full_path: false + + # Show the type of symbol (class, function, etc.) in the heading. + show_symbol_type_heading: true + + # Show the type of symbol (class, function, etc.) in the table of contents. + show_symbol_type_toc: true + + # SIGNATURES ------------------------------------------------------------- + # Format code to 80 + 10% margin (Black and Ruff defaults) + # in signatures and attribute value code blocks. + # Needs Black/Ruff installed. + line_length: 88 + + # Merge signature and docstring of `__init__` methods + # into their parent class signature and docstring. + merge_init_into_class: true + + # Render signatures and attribute values in a separate code block, + # below the symbol heading. + separate_signature: true + + # Show type annotations in signatures. + show_signature_annotations: true + + # Show type parameters in signatures. + show_signature_type_parameters: true + + # OTHER ------------------------------------------------------------------ + # Show backlinks to other documentation sections within each symbol. + backlinks: tree # Sponsors only! + + # Show base classes OR inheritance diagram. + show_bases: false + show_inheritance_diagram: true # Sponsors only! +``` From be7d65da939b88997935a3ecfdce1e5052817795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 9 Oct 2025 13:10:07 +0200 Subject: [PATCH 32/46] docs: Show default value for `show_overloads` and `overloads_only` options Issue-312: https://github.com/mkdocstrings/python/issues/312 Issue-313: https://github.com/mkdocstrings/python/issues/313 --- docs/usage/configuration/signatures.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md index 0dabf74f..16ac218b 100644 --- a/docs/usage/configuration/signatures.md +++ b/docs/usage/configuration/signatures.md @@ -289,6 +289,8 @@ plugins: [](){#option-overloads_only} ## `overloads_only` +- **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** + Whether to hide the implementation signature if the overloads are shown with [`show_overloads`][]. ```yaml title="in mkdocs.yml (global configuration)" @@ -297,7 +299,7 @@ plugins: handlers: python: options: - overloads_only: true + overloads_only: false ``` ```md title="or in docs/some_page.md (local configuration)" @@ -584,6 +586,8 @@ class SomeClass: [](){#option-show_overloads} ## `show_overloads` +- **:octicons-package-24: Type [`bool`][] :material-equal: `True`{ title="default value" }** + Whether to render function / method overloads. ```yaml title="in mkdocs.yml (global configuration)" From 6d600238c631bca29d95df711b6c788d978fbe98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 9 Oct 2025 13:34:58 +0200 Subject: [PATCH 33/46] chore: Template upgrade --- .copier-answers.yml | 2 +- .github/pull_request_template.md | 15 +++++ .github/workflows/ci.yml | 30 ++++++++- Makefile | 7 +++ README.md | 2 +- config/pytest.ini | 2 + config/pytest_39.ini | 17 ++++++ docs/js/insiders.js | 13 ++-- duties.py | 24 +++++--- scripts/get_version.py | 7 ++- scripts/make.py | 61 +++++++++++++++---- .../python/_internal/debug.py | 2 +- tests/test_api.py | 6 +- 13 files changed, 153 insertions(+), 35 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 config/pytest_39.ini diff --git a/.copier-answers.yml b/.copier-answers.yml index 76531124..0d9a98c3 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier. -_commit: 1.4.5 +_commit: 1.5.1 _src_path: gh:mkdocstrings/handler-template author_email: dev@pawamoy.fr author_fullname: Timothée Mazzucotelli diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..6f0f2faf --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,15 @@ +### For reviewers + + +- [ ] I did not use AI +- [ ] I used AI and thoroughly reviewed every code/docs change + +### Description of the change + + +### Relevant resources + + +- +- +- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf37ef60..2399abb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,10 +2,17 @@ name: ci on: push: + branches: + - main + - test-me-* pull_request: branches: - main +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + defaults: run: shell: bash @@ -14,13 +21,30 @@ env: LANG: en_US.utf-8 LC_ALL: en_US.utf-8 PYTHONIOENCODING: UTF-8 + PYTHONWARNDEFAULTENCODING: "1" PYTHON_VERSIONS: "" jobs: quality: + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + - windows-latest + python-version: + - "3.9" + - "3.13" + include: + - os: ubuntu-latest + python-version: "3.10" + - os: ubuntu-latest + python-version: "3.11" + - os: ubuntu-latest + python-version: "3.12" - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -32,7 +56,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.13" + python-version: ${{ matrix.python-version }} - name: Setup uv uses: astral-sh/setup-uv@v5 @@ -109,7 +133,7 @@ jobs: - lowest-direct exclude: ${{ fromJSON(needs.exclude-test-jobs.outputs.jobs) }} runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.python-version == '3.14' }} + continue-on-error: true steps: - name: Checkout diff --git a/Makefile b/Makefile index 5e88121d..1b3391da 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,13 @@ # the `make` command will point at the `scripts/make` shell script. # This Makefile is just here to allow auto-completion in the terminal. +default: help + @echo + @echo 'Enable direnv in your shell to use the `make` command: `direnv allow`' + @echo 'Or use `python scripts/make ARGS` to run the commands/tasks directly.' + +.DEFAULT_GOAL: default + actions = \ allrun \ changelog \ diff --git a/README.md b/README.md index 937a3a84..44507e72 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![ci](https://github.com/mkdocstrings/python/workflows/ci/badge.svg)](https://github.com/mkdocstrings/python/actions?query=workflow%3Aci) [![documentation](https://img.shields.io/badge/docs-mkdocs-708FCC.svg?style=flat)](https://mkdocstrings.github.io/python/) [![pypi version](https://img.shields.io/pypi/v/mkdocstrings-python.svg)](https://pypi.org/project/mkdocstrings-python/) -[![gitter](https://badges.gitter.im/join%20chat.svg)](https://app.gitter.im/#/room/#python:gitter.im) +[![gitter](https://img.shields.io/badge/matrix-chat-4DB798.svg?style=flat)](https://app.gitter.im/#/room/#mkdocstrings_python:gitter.im) --- diff --git a/config/pytest.ini b/config/pytest.ini index 4f43c18e..39ee3a3c 100644 --- a/config/pytest.ini +++ b/config/pytest.ini @@ -10,6 +10,8 @@ testpaths = # action:message_regex:warning_class:module_regex:line filterwarnings = error + default::EncodingWarning + error::EncodingWarning:python # TODO: Remove once pytest-xdist 4 is released. ignore:.*rsyncdir:DeprecationWarning:xdist # TODO: Remove once mkdocstrings stops setting fallback function. diff --git a/config/pytest_39.ini b/config/pytest_39.ini new file mode 100644 index 00000000..a876e994 --- /dev/null +++ b/config/pytest_39.ini @@ -0,0 +1,17 @@ +# YORE: EOL 3.9: Remove file. +# This file is used on 3.9 due to forward compatibility issue with filterwarnings. +# See https://github.com/pytest-dev/pytest/issues/11101. +[pytest] +python_files = + test_*.py +addopts = + --cov + --cov-config config/coverage.ini +testpaths = + tests + +# action:message_regex:warning_class:module_regex:line +filterwarnings = + error + # TODO: remove once pytest-xdist 4 is released + ignore:.*rsyncdir:DeprecationWarning:xdist diff --git a/docs/js/insiders.js b/docs/js/insiders.js index 8bb68485..a86a0918 100644 --- a/docs/js/insiders.js +++ b/docs/js/insiders.js @@ -29,11 +29,14 @@ function updatePremiumSponsors(dataURL, rank) { let html = ''; html += `${capRank} sponsors

` sponsors.forEach(function (sponsor) { - html += ` - - ${sponsor.name} - - ` + html += `` + if (sponsor.image) { + html += `${sponsor.name}` + } else if (sponsor.imageLight && sponsor.imageDark) { + html += `${sponsor.name}` + html += `${sponsor.name}` + } + html += ''; }); html += '

' sponsorsDiv.innerHTML = html; diff --git a/duties.py b/duties.py index 0fa73ea0..41df37b6 100644 --- a/duties.py +++ b/duties.py @@ -26,6 +26,8 @@ WINDOWS = os.name == "nt" PTY = not WINDOWS and not CI MULTIRUN = os.environ.get("MULTIRUN", "0") == "1" +PY_VERSION = f"{sys.version_info.major}{sys.version_info.minor}" +PY_DEV = "314" def pyprefix(title: str) -> str: @@ -84,7 +86,7 @@ def check(ctx: Context) -> None: """Check it all!""" -@duty +@duty(nofail=PY_VERSION == PY_DEV) def check_quality(ctx: Context) -> None: """Check the code quality.""" ctx.run( @@ -93,7 +95,7 @@ def check_quality(ctx: Context) -> None: ) -@duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) +@duty(nofail=PY_VERSION == PY_DEV, skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) def check_docs(ctx: Context) -> None: """Check if the documentation builds correctly.""" Path("htmlcov").mkdir(parents=True, exist_ok=True) @@ -105,7 +107,7 @@ def check_docs(ctx: Context) -> None: ) -@duty +@duty(nofail=PY_VERSION == PY_DEV) def check_types(ctx: Context) -> None: """Check that the code is correctly typed.""" os.environ["MYPYPATH"] = "src" @@ -118,7 +120,7 @@ def check_types(ctx: Context) -> None: ) -@duty +@duty(nofail=PY_VERSION == PY_DEV) def check_api(ctx: Context, *cli_args: str) -> None: """Check for API breaking changes.""" ctx.run( @@ -239,7 +241,7 @@ def coverage(ctx: Context) -> None: ctx.run(tools.coverage.html(rcfile="config/coverage.ini")) -@duty +@duty(nofail=PY_VERSION == PY_DEV) def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report") -> None: # noqa: PT028 """Run the test suite. @@ -247,17 +249,23 @@ def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report" match: A pytest expression to filter selected tests. snapshot: Whether to "create", "fix", "trim", or "update" snapshots. """ - py_version = f"{sys.version_info.major}{sys.version_info.minor}" - os.environ["COVERAGE_FILE"] = f".coverage.{py_version}" + os.environ["COVERAGE_FILE"] = f".coverage.{PY_VERSION}" + os.environ["PYTHONWARNDEFAULTENCODING"] = "1" args = list(cli_args) if snapshot == "disable" or not snapshot: args = ["-n", "auto", "--inline-snapshot=disable"] else: args = [f"--inline-snapshot={snapshot}"] + + config_file = "config/pytest.ini" + # YORE: EOL 3.9: Remove block. + if sys.version_info[:2] < (3, 10): + config_file = "config/pytest_39.ini" + ctx.run( tools.pytest( "tests", - config_file="config/pytest.ini", + config_file=config_file, select=match, color="yes", ).add_args(*args), diff --git a/scripts/get_version.py b/scripts/get_version.py index 6734e5b6..3c425a73 100644 --- a/scripts/get_version.py +++ b/scripts/get_version.py @@ -4,7 +4,12 @@ from contextlib import suppress from pathlib import Path -from pdm.backend.hooks.version import SCMVersion, Version, default_version_formatter, get_version_from_scm +from pdm.backend.hooks.version import ( # ty: ignore[unresolved-import] + SCMVersion, + Version, + default_version_formatter, + get_version_from_scm, +) _root = Path(__file__).parent.parent _changelog = _root / "CHANGELOG.md" diff --git a/scripts/make.py b/scripts/make.py index 5a7fb4c2..1e697bcc 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -14,7 +14,8 @@ from collections.abc import Iterator -PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.9 3.10 3.11 3.12 3.13").split() +PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.9 3.10 3.11 3.12 3.13 3.14").split() +PYTHON_DEV = "3.14" def shell(cmd: str, *, capture_output: bool = False, **kwargs: Any) -> str | None: @@ -67,16 +68,31 @@ def setup() -> None: uv_install(venv_path) +class _RunError(subprocess.CalledProcessError): + def __init__(self, *args: Any, python_version: str, **kwargs: Any): + super().__init__(*args, **kwargs) + self.python_version = python_version + + def run(version: str, cmd: str, *args: str, **kwargs: Any) -> None: """Run a command in a virtual environment.""" kwargs = {"check": True, **kwargs} uv_run = ["uv", "run", "--no-sync"] - if version == "default": - with environ(UV_PROJECT_ENVIRONMENT=".venv"): - subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510 - else: - with environ(UV_PROJECT_ENVIRONMENT=f".venvs/{version}", MULTIRUN="1"): - subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510 + try: + if version == "default": + with environ(UV_PROJECT_ENVIRONMENT=".venv"): + subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510 + else: + with environ(UV_PROJECT_ENVIRONMENT=f".venvs/{version}", MULTIRUN="1"): + subprocess.run([*uv_run, cmd, *args], **kwargs) # noqa: S603, PLW1510 + except subprocess.CalledProcessError as process: + raise _RunError( + returncode=process.returncode, + python_version=version, + cmd=process.cmd, + output=process.output, + stderr=process.stderr, + ) from process def multirun(cmd: str, *args: str, **kwargs: Any) -> None: @@ -144,19 +160,31 @@ def main() -> int: cmd = args.pop(0) if cmd == "run": - run("default", *args) + if not args: + print("make: run: missing command", file=sys.stderr) + return 1 + run("default", *args) # ty: ignore[missing-argument] return 0 if cmd == "multirun": - multirun(*args) + if not args: + print("make: run: missing command", file=sys.stderr) + return 1 + multirun(*args) # ty: ignore[missing-argument] return 0 if cmd == "allrun": - allrun(*args) + if not args: + print("make: run: missing command", file=sys.stderr) + return 1 + allrun(*args) # ty: ignore[missing-argument] return 0 if cmd.startswith("3."): - run(cmd, *args) + if not args: + print("make: run: missing command", file=sys.stderr) + return 1 + run(cmd, *args) # ty: ignore[missing-argument] return 0 opts = [] @@ -183,7 +211,14 @@ def main() -> int: if __name__ == "__main__": try: sys.exit(main()) - except subprocess.CalledProcessError as process: + except _RunError as process: if process.output: print(process.output, file=sys.stderr) - sys.exit(process.returncode) + if (code := process.returncode) == 139: # noqa: PLR2004 + print( + f"✗ (python{process.python_version}) '{' '.join(process.cmd)}' failed with return code {code} (segfault)", + file=sys.stderr, + ) + if process.python_version == PYTHON_DEV: + code = 0 + sys.exit(code) diff --git a/src/mkdocstrings_handlers/python/_internal/debug.py b/src/mkdocstrings_handlers/python/_internal/debug.py index 5fff669f..a3c99d75 100644 --- a/src/mkdocstrings_handlers/python/_internal/debug.py +++ b/src/mkdocstrings_handlers/python/_internal/debug.py @@ -85,7 +85,7 @@ def _get_debug_info() -> _Environment: interpreter_version=py_version, interpreter_path=sys.executable, platform=platform.platform(), - variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))], + variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))], # ty: ignore[invalid-argument-type] packages=[_Package(pkg, _get_version(pkg)) for pkg in packages], ) diff --git a/tests/test_api.py b/tests/test_api.py index 6d0b8738..099e2058 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -92,7 +92,7 @@ def _fixture_public_objects(public_api: griffe.Module) -> list[griffe.Object | g def _fixture_inventory() -> Inventory: inventory_file = Path(__file__).parent.parent / "site" / "objects.inv" if not inventory_file.exists(): - raise pytest.skip("The objects inventory is not available.") + pytest.skip("The objects inventory is not available.") # ty: ignore[call-non-callable] with inventory_file.open("rb") as file: return Inventory.parse_sphinx(file) @@ -138,7 +138,9 @@ def test_api_matches_inventory(inventory: Inventory, public_objects: list[griffe """All public objects are added to the inventory.""" ignore_names = {"__getattr__", "__init__", "__repr__", "__str__", "__post_init__"} not_in_inventory = [ - obj.path for obj in public_objects if obj.name not in ignore_names and obj.path not in inventory + f"{obj.relative_filepath}:{obj.lineno}: {obj.path}" + for obj in public_objects + if obj.name not in ignore_names and obj.path not in inventory ] msg = "Objects not in the inventory (try running `make run mkdocs build`):\n{paths}" assert not not_in_inventory, msg.format(paths="\n".join(sorted(not_in_inventory))) From 669b42ebd7c154c81764fa98c052cf857f7aa406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:49:13 +0100 Subject: [PATCH 34/46] feat: Release inheritance diagram features --- docs/usage/configuration/general.md | 137 ++++++++++ .../python/_internal/config.py | 8 + .../templates/material/_base/class.html.jinja | 48 ++++ .../templates/readthedocs/_base/class.html | 11 + .../readthedocs/_base/class.html.jinja | 251 ++++++++++++++++++ .../python/templates/readthedocs/class.html | 1 + .../templates/readthedocs/class.html.jinja | 1 + 7 files changed, 457 insertions(+) create mode 100644 src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html create mode 100644 src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja create mode 100644 src/mkdocstrings_handlers/python/templates/readthedocs/class.html create mode 100644 src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja diff --git a/docs/usage/configuration/general.md b/docs/usage/configuration/general.md index 68899890..7d7b71e1 100644 --- a/docs/usage/configuration/general.md +++ b/docs/usage/configuration/general.md @@ -269,6 +269,143 @@ plugins: WARNING: **Packages are loaded only once.** When mkdocstrings-python collects data from a Python package (thanks to [Griffe](https://mkdocstrings.github.io/griffe/)), it collects *the entire package* and *caches it*. Next time an object from the same package is rendered, the package is retrieved from the cache and not collected again. The `force_inspection` option will therefore only have an effect the first time a package is collected, and will do nothing for objects rendered afterwards. +[](){#option-inheritance_diagram_direction} +## `inheritance_diagram_direction` + +The direction of the Mermaid chart presenting the inheritance diagram of a class, `TD` by default. + +```yaml title="mkdocs.yml" +extra_javascript: +- https://unpkg.com/mermaid@10.9.0/dist/mermaid.min.js +``` + +```yaml title="in mkdocs.yml (global configuration)" +plugins: +- mkdocstrings: + handlers: + python: + options: + inheritance_diagram_direction: TD +``` + +```md title="or in docs/some_page.md (local configuration)" +::: path.to.object + options: + inheritance_diagram_direction: TD +``` + +/// admonition | Preview + type: preview + + +With the following classes: + +```python +class SuperAbstract: + """Super abstract class.""" +class Mixin1: + """Mixin 1.""" +class Abstract(SuperAbstract, Mixin1): + """Abstract class.""" +class Mixin2A: + """Mixin 2A.""" +class Mixin2B(Mixin2A): + """Mixin 2B.""" +class Concrete(Abstract, Mixin2B): + """Concrete class.""" +class SuperConcrete(Concrete): + """Super concrete class.""" +``` + +//// tab | `TD` (or `TB`) + +```mermaid +flowchart TD +SuperConcrete[SuperConcrete] +Concrete[Concrete] +Abstract[Abstract] +SuperAbstract[SuperAbstract] +Mixin1[Mixin1] +Mixin2B[Mixin2B] +Mixin2A[Mixin2A] + +Concrete --> SuperConcrete +Abstract --> Concrete +SuperAbstract --> Abstract +Mixin1 --> Abstract +Mixin2B --> Concrete +Mixin2A --> Mixin2B +``` + +//// + +//// tab | `BT` + +```mermaid +flowchart BT +SuperConcrete[SuperConcrete] +Concrete[Concrete] +Abstract[Abstract] +SuperAbstract[SuperAbstract] +Mixin1[Mixin1] +Mixin2B[Mixin2B] +Mixin2A[Mixin2A] + +Concrete --> SuperConcrete +Abstract --> Concrete +SuperAbstract --> Abstract +Mixin1 --> Abstract +Mixin2B --> Concrete +Mixin2A --> Mixin2B +``` + +//// + +//// tab | `RL` + +```mermaid +flowchart RL +SuperConcrete[SuperConcrete] +Concrete[Concrete] +Abstract[Abstract] +SuperAbstract[SuperAbstract] +Mixin1[Mixin1] +Mixin2B[Mixin2B] +Mixin2A[Mixin2A] + +Concrete --> SuperConcrete +Abstract --> Concrete +SuperAbstract --> Abstract +Mixin1 --> Abstract +Mixin2B --> Concrete +Mixin2A --> Mixin2B +``` + +//// + +//// tab | `LR` + +```mermaid +flowchart LR +SuperConcrete[SuperConcrete] +Concrete[Concrete] +Abstract[Abstract] +SuperAbstract[SuperAbstract] +Mixin1[Mixin1] +Mixin2B[Mixin2B] +Mixin2A[Mixin2A] + +Concrete --> SuperConcrete +Abstract --> Concrete +SuperAbstract --> Abstract +Mixin1 --> Abstract +Mixin2B --> Concrete +Mixin2A --> Mixin2B +``` + +//// +/// + [](){#option-preload_modules} ## `preload_modules` diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index 62c124ba..e02d2fe1 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -560,6 +560,14 @@ class PythonInputOptions: ), ] = 2 + inheritance_diagram_direction: Annotated[ + Literal["TB", "TD", "BT", "RL", "LR"], + _Field( + group="docstrings", + description="The direction of the Mermaid chart presenting the inheritance diagram of a class.", + ), + ] = "TD" + inherited_members: Annotated[ bool | list[str], _Field( diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index 23b3f458..0cd4ab4b 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -157,6 +157,54 @@ Context: {% endif %} {% endblock bases %} + {% block inheritance_diagram scoped %} + {#- Inheritance diagram block. + + This block renders the inheritance diagram for the class, + using Mermaid syntax and a bit of JavaScript to make the nodes clickable, + linking to the corresponding class documentation. + -#} + {% if config.show_inheritance_diagram and class.bases %} + {% macro edges(class) %} + {% for base in class.resolved_bases %} + {{ base.path }} --> {{ class.path }} + {{ edges(base) }} + {% endfor %} + {% endmacro %} +
+ + {% for base in class.mro() %} + + {% endfor %} +
+

+              flowchart {{ config.inheritance_diagram_direction }}
+              {{ class.path }}[{{ class.name }}]
+              {% for base in class.mro() %}
+              {{ base.path }}[{{ base.name }}]
+              {% endfor %}
+
+              {{ edges(class) | safe }}
+
+              click {{ class.path }} href "" "{{ class.path }}"
+              {% for base in class.mro() %}
+              click {{ base.path }} href "" "{{ base.path }}"
+              {% endfor %}
+            
+ + {% endif %} + {% endblock inheritance_diagram %} + {% block docstring scoped %} {#- Docstring block. diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html new file mode 100644 index 00000000..ac3e421e --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html @@ -0,0 +1,11 @@ +{% extends "_base/class.html.jinja" %} + +{% block logs scoped %} + {{ super() }} + {# TODO: Switch to a warning after some time. #} + {{ log.info( + "DeprecationWarning: Extending '_base/class.html' is deprecated, extend '_base/class.html.jinja' instead. " ~ + "After some time, this message will be logged as a warning, causing strict builds to fail.", + once=True, + ) }} +{% endblock logs %} diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja new file mode 100644 index 00000000..554485d7 --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja @@ -0,0 +1,251 @@ +{#- Template for Python classes. + +This template renders a Python class. + +Context: + class (griffe.Class): The class to render. + root (bool): Whether this is the root object, injected with `:::` in a Markdown page. + heading_level (int): The HTML heading level to use. + config (dict): The configuration options. +-#} + +{% block logs scoped %} + {#- Logging block. + + This block can be used to log debug messages, deprecation messages, warnings, etc. + -#} + {{ log.debug("Rendering " + class.path) }} +{% endblock logs %} + +
+ {% with obj = class, html_id = class.path %} + + {% if root %} + {% set show_full_path = config.show_root_full_path %} + {% set root_members = True %} + {% elif root_members %} + {% set show_full_path = config.show_root_members_full_path or config.show_object_full_path %} + {% set root_members = False %} + {% else %} + {% set show_full_path = config.show_object_full_path %} + {% endif %} + + {% set class_name = class.path if show_full_path else class.name %} + + {% if not root or config.show_root_heading %} + {% filter heading( + heading_level, + role="class", + id=html_id, + class="doc doc-heading", + toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name, + ) %} + + {% block heading scoped %} + {#- Heading block. + + This block renders the heading for the class. + -#} + {% if config.show_symbol_type_heading %}{% endif %} + {% if config.separate_signature %} + {{ class_name }} + {% elif config.merge_init_into_class and "__init__" in class.all_members %} + {% with function = class.all_members["__init__"] %} + {%+ filter highlight(language="python", inline=True) %} + {{ class_name }}{% include "signature"|get_template with context %} + {% endfilter %} + {% endwith %} + {% else %} + {{ class_name }} + {% endif %} + {% endblock heading %} + + {% block labels scoped %} + {#- Labels block. + + This block renders the labels for the class. + -#} + {% with labels = class.labels %} + {% include "labels"|get_template with context %} + {% endwith %} + {% endblock labels %} + + {% endfilter %} + + {% block signature scoped %} + {#- Signature block. + + This block renders the signature for the class. + -#} + {% if config.separate_signature and config.merge_init_into_class %} + {% if "__init__" in class.all_members %} + {% with function = class.all_members["__init__"] %} + {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %} + {{ class.name }} + {% endfilter %} + {% endwith %} + {% endif %} + {% endif %} + {% endblock signature %} + + {% else %} + {% if config.show_root_toc_entry %} + {% filter heading(heading_level, + role="class", + id=html_id, + toc_label=(' '|safe if config.show_symbol_type_toc else '') + class.name, + hidden=True, + ) %} + {% endfilter %} + {% endif %} + {% set heading_level = heading_level - 1 %} + {% endif %} + +
+ {% block contents scoped %} + {#- Contents block. + + This block renders the contents of the class. + It contains other blocks that users can override. + Overriding the contents block allows to rearrange the order of the blocks. + -#} + {% block bases scoped %} + {#- Class bases block. + + This block renders the bases for the class. + -#} + {% if config.show_bases and class.bases %} +

+ Bases: {% for expression in class.bases -%} + {% include "expression"|get_template with context %}{% if not loop.last %}, {% endif %} + {% endfor -%} +

+ {% endif %} + {% endblock bases %} + + {% block inheritance_diagram scoped %} + {#- Inheritance diagram block. + + This block renders the inheritance diagram for the class, + using Mermaid syntax and a bit of JavaScript to make the nodes clickable, + linking to the corresponding class documentation. + -#} + {% if config.show_inheritance_diagram and class.bases %} + {% macro edges(class) %} + {% for base in class.resolved_bases %} + {{ base.path }} --> {{ class.path }} + {{ edges(base) }} + {% endfor %} + {% endmacro %} +
+ + {% for base in class.mro() %} + + {% endfor %} +
+
+ flowchart {{ config.inheritance_diagram_direction }} + {{ class.path }}[{{ class.name }}] + {% for base in class.mro() %} + {{ base.path }}[{{ base.name }}] + {% endfor %} + + {{ edges(class) | safe }} + + click {{ class.path }} href "" "{{ class.path }}" + {% for base in class.mro() %} + click {{ base.path }} href "" "{{ base.path }}" + {% endfor %} +
+ + {% endif %} + {% endblock inheritance_diagram %} + + {% block docstring scoped %} + {#- Docstring block. + + This block renders the docstring for the class. + -#} + {% with docstring_sections = class.docstring.parsed %} + {% include "docstring"|get_template with context %} + {% endwith %} + {% if config.merge_init_into_class %} + {% if "__init__" in class.all_members and class.all_members["__init__"].has_docstring %} + {% with function = class.all_members["__init__"] %} + {% with obj = function, docstring_sections = function.docstring.parsed %} + {% include "docstring"|get_template with context %} + {% endwith %} + {% endwith %} + {% endif %} + {% endif %} + {% endblock docstring %} + + {% block summary scoped %} + {#- Summary block. + + This block renders auto-summaries for classes, methods, and attributes. + -#} + {% include "summary"|get_template with context %} + {% endblock summary %} + + {% block source scoped %} + {#- Source block. + + This block renders the source code for the class. + -#} + {% if config.show_source %} + {% if config.merge_init_into_class %} + {% if "__init__" in class.all_members and class.all_members["__init__"].source %} + {% with init = class.all_members["__init__"] %} +
+ Source code in + {%- if init.relative_filepath.is_absolute() -%} + {{ init.relative_package_filepath }} + {%- else -%} + {{ init.relative_filepath }} + {%- endif -%} + + {{ init.source|highlight(language="python", linestart=init.lineno or 0, linenums=True) }} +
+ {% endwith %} + {% endif %} + {% elif class.source %} +
+ Source code in + {%- if class.relative_filepath.is_absolute() -%} + {{ class.relative_package_filepath }} + {%- else -%} + {{ class.relative_filepath }} + {%- endif -%} + + {{ class.source|highlight(language="python", linestart=class.lineno or 0, linenums=True) }} +
+ {% endif %} + {% endif %} + {% endblock source %} + + {% block children scoped %} + {#- Children block. + + This block renders the children (members) of the class. + -#} + {% set root = False %} + {% set heading_level = heading_level + 1 %} + {% include "children"|get_template with context %} + {% endblock children %} + {% endblock contents %} +
+ + {% endwith %} + +
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/class.html b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html new file mode 100644 index 00000000..5e7329df --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html @@ -0,0 +1 @@ +{% extends "_base/class.html.jinja" %} diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja new file mode 100644 index 00000000..5e7329df --- /dev/null +++ b/src/mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja @@ -0,0 +1 @@ +{% extends "_base/class.html.jinja" %} From fdaeb48a0f2208bafd14f2f7ead42bca37bea665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:50:30 +0100 Subject: [PATCH 35/46] feat: Release visually-lighter admonitions for source code blocks --- docs/insiders/changelog.md | 11 ++++++++- docs/insiders/goals.yml | 4 +++- .../templates/material/_base/class.html.jinja | 4 ++-- .../material/_base/function.html.jinja | 2 +- .../python/templates/material/style.css | 24 +++++++++++++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/docs/insiders/changelog.md b/docs/insiders/changelog.md index b5717892..7898983c 100644 --- a/docs/insiders/changelog.md +++ b/docs/insiders/changelog.md @@ -2,7 +2,11 @@ ## mkdocstrings-python Insiders -### 1.12.0 March 22, 2025 { id="1.12.0" } +### 1.12.1 May 24, 2025 { id="1.12.1" } + +- Visually-lighter admonitions for source code blocks + +### 1.12.0 March 24, 2025 { id="1.12.0" } - [Ordering method: `__all__`][option-members_order] @@ -14,6 +18,11 @@ - [Backlinks][backlinks] +### 1.9.1 December 26, 2024 { id="1.9.1" } + +- Re-add class template for RTD theme +- Make inheritance diagrams rendering more robust + ### 1.9.0 September 03, 2024 { id="1.9.0" } - [Relative cross-references][relative_crossrefs] diff --git a/docs/insiders/goals.yml b/docs/insiders/goals.yml index 71128361..313322fd 100644 --- a/docs/insiders/goals.yml +++ b/docs/insiders/goals.yml @@ -50,4 +50,6 @@ goals: since: 2025/03/20 - name: "Ordering method: `__all__`" ref: /usage/configuration/members/#option-members_order - since: 2025/03/22 \ No newline at end of file + since: 2025/03/24 + - name: "Visually-lighter source code blocks" + since: 2025/05/24 diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja index 0cd4ab4b..417afe41 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja @@ -252,7 +252,7 @@ Context: {% if config.merge_init_into_class %} {% if "__init__" in all_members and all_members["__init__"].source %} {% with init = all_members["__init__"] %} -
+
Source code in {%- if init.relative_filepath.is_absolute() -%} {{ init.relative_package_filepath }} @@ -265,7 +265,7 @@ Context: {% endwith %} {% endif %} {% elif class.source %} -
+
Source code in {%- if class.relative_filepath.is_absolute() -%} {{ class.relative_package_filepath }} diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja index 708fde68..f296c214 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja @@ -149,7 +149,7 @@ Context: This block renders the source code for the function. -#} {% if config.show_source and function.source %} -
+
{{ lang.t("Source code in") }} {%- if function.relative_filepath.is_absolute() -%} {{ function.relative_package_filepath }} diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css index 7475f5cd..7bb97041 100644 --- a/src/mkdocstrings_handlers/python/templates/material/style.css +++ b/src/mkdocstrings_handlers/python/templates/material/style.css @@ -210,3 +210,27 @@ code.doc-symbol-module::after { color: inherit; border-bottom: 1px dotted currentcolor; } + +/* Source code blocks (admonitions). */ +:root { + --md-admonition-icon--mkdocstrings-source: url('data:image/svg+xml;charset=utf-8,') +} +.md-typeset .admonition.mkdocstrings-source, +.md-typeset details.mkdocstrings-source { + border: none; + padding: 0; +} +.md-typeset .admonition.mkdocstrings-source:focus-within, +.md-typeset details.mkdocstrings-source:focus-within { + box-shadow: none; +} +.md-typeset .mkdocstrings-source > .admonition-title, +.md-typeset .mkdocstrings-source > summary { + background-color: inherit; +} +.md-typeset .mkdocstrings-source > .admonition-title::before, +.md-typeset .mkdocstrings-source > summary::before { + background-color: var(--md-default-fg-color); + -webkit-mask-image: var(--md-admonition-icon--mkdocstrings-source); + mask-image: var(--md-admonition-icon--mkdocstrings-source); +} From dbadd1e898bb2e67515077d152890bdbbf0b3eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:50:52 +0100 Subject: [PATCH 36/46] feat: Release expression modernization feature --- .../python/templates/material/_base/expression.html.jinja | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja index 54781739..4f44ae00 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja @@ -166,4 +166,7 @@ Context: {%- endif -%} {%- endmacro -%} +{%- if config.modernize_annotations and expression is not string -%} + {%- set expression = expression.modernize() -%} +{%- endif -%} {{ render(expression, config.annotations_path, backlink_type|default("")) }} From ae7cc2d7d8ea5711d8ce06620edd534a3e2b47aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:51:19 +0100 Subject: [PATCH 37/46] feat: Release backlinks feature --- .../python/_internal/handler.py | 22 ++++++++- .../material/_base/backlinks.html.jinja | 49 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py index fbed2b8e..5945455d 100644 --- a/src/mkdocstrings_handlers/python/_internal/handler.py +++ b/src/mkdocstrings_handlers/python/_internal/handler.py @@ -22,15 +22,17 @@ patch_loggers, ) from mkdocs.exceptions import PluginError +from mkdocs_autorefs import BacklinkCrumb from mkdocstrings import BaseHandler, CollectionError, CollectorItem, HandlerOptions, Inventory, get_logger from mkdocstrings_handlers.python._internal import rendering from mkdocstrings_handlers.python._internal.config import PythonConfig, PythonOptions if TYPE_CHECKING: - from collections.abc import Iterator, Mapping, MutableMapping, Sequence + from collections.abc import Iterable, Iterator, Mapping, MutableMapping, Sequence from mkdocs.config.defaults import MkDocsConfig + from mkdocs_autorefs import Backlink # YORE: EOL 3.10: Replace block with line 2. @@ -306,6 +308,24 @@ def render(self, data: CollectorItem, options: PythonOptions, locale: str | None }, ) + def render_backlinks(self, backlinks: Mapping[str, Iterable[Backlink]], *, locale: str | None = None) -> str: # noqa: ARG002 + """Render the backlinks. + + Parameters: + backlinks: The backlinks to render. + + Returns: + The rendered backlinks (HTML). + """ + template = self.env.get_template("backlinks.html.jinja") + verbose_type = {key: key.capitalize().replace("-by", " by") for key in backlinks.keys()} # noqa: SIM118 + return template.render( + backlinks=backlinks, + config=self.get_options({}), + verbose_type=verbose_type, + default_crumb=BacklinkCrumb(title="", url=""), + ) + def update_env(self, config: Any) -> None: # noqa: ARG002 """Update the Jinja environment with custom filters and tests. diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja index 2ab16038..930da3e8 100644 --- a/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja +++ b/src/mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja @@ -15,3 +15,52 @@ Context: This block can be used to log debug messages, deprecation messages, warnings, etc. -#} {% endblock logs %} + +{% macro render_crumb(crumb, last=false) %} + + {% if crumb.url and crumb.title %} + {{ crumb.title | safe }} + {% elif crumb.title %} + {{ crumb.title | safe }} + {% endif %} + +{% endmacro %} + +{% macro render_tree(tree) %} + +{% endmacro %} + +{% if config.backlinks %} + +{% endif %} From 3be14cc07bc9429d7ce01c748d825e2db1559212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:51:55 +0100 Subject: [PATCH 38/46] feat: Release public filter feature --- src/mkdocstrings_handlers/python/_internal/config.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index e02d2fe1..d3588e2d 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -1088,11 +1088,7 @@ class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore] @classmethod def coerce(cls, **data: Any) -> MutableMapping[str, Any]: """Create an instance from a dictionary.""" - if "filters" in data: - # Non-insiders: transform back to default filters. - # Next: `if "filters" in data and not isinstance(data["filters"], str):`. - if data["filters"] == "public": - data["filters"] = _DEFAULT_FILTERS + if "filters" in data and not isinstance(data["filters"], str): # Filters are `None` or a sequence of strings (tests use tuples). data["filters"] = [ (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or () From 84aaebcb4991c0245bf7ca8d7024c9d04942b0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:52:34 +0100 Subject: [PATCH 39/46] feat: Release `__all__` ordering feature --- .../python/_internal/rendering.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index 99aeb014..d95a55e4 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -62,8 +62,15 @@ def _sort_key_source(item: CollectorItem) -> float: return item.lineno if item.lineno is not None else float("inf") -def _sort__all__(item: CollectorItem) -> float: # noqa: ARG001 - raise ValueError("Not implemented in public version of mkdocstrings-python") +def _sort__all__(item: CollectorItem) -> float: + if item.parent.exports is not None: + try: + return item.parent.exports.index(item.name) + except ValueError: + # If the item is not in `__all__`, it will go to the end of the list. + return float("inf") + # No exports declared, refuse to sort (try other methods or return members as they are). + raise ValueError(f"Parent object {item.parent.path} doesn't declare exports") Order = Literal["__all__", "alphabetical", "source"] From 872afc584f33f50a133472afdc9355734a5e51ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 13:52:50 +0100 Subject: [PATCH 40/46] feat: Release scoped and relative cross-references --- .../python/_internal/rendering.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py index d95a55e4..ba51fcac 100644 --- a/src/mkdocstrings_handlers/python/_internal/rendering.py +++ b/src/mkdocstrings_handlers/python/_internal/rendering.py @@ -863,6 +863,33 @@ def expand_identifier(self, identifier: str) -> str: Returns: The expanded identifier. """ + # Handle leading dots in the identifier: + # - `.name` is a reference to the current object's `name` member. + # - `..name` is a reference to the parent object's `name` member. + # - etc. + # TODO: We should update the protocol to allow modifying the title too. + # In this case it would likely be better to strip dots from the title, + # when it's not explicitly specified. + if self.config.relative_crossrefs and identifier.startswith("."): # type: ignore[attr-defined] + identifier = identifier[1:] + obj = self.current_object + while identifier and identifier[0] == ".": + identifier = identifier[1:] + obj = obj.parent # type: ignore[assignment] + identifier = f"{obj.path}.{identifier}" if identifier else obj.path + + # We resolve the identifier to its full path. + # For this we take out the first name, resolve it, and then append the rest. + if self.config.scoped_crossrefs: # type: ignore[attr-defined] + if "." in identifier: + identifier, remaining = identifier.split(".", 1) + else: + remaining = "" + with suppress(Exception): + identifier = self.current_object.resolve(identifier) + if remaining: + identifier = f"{identifier}.{remaining}" + return identifier def get_context(self) -> AutorefsHookInterface.Context: From a99a5266ff3233dbca6e682805a0c4e0bb3fc5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:07:14 +0100 Subject: [PATCH 41/46] chore: Template upgrade --- .copier-answers.yml | 6 +- .github/workflows/ci.yml | 46 +++------ .github/workflows/release.yml | 21 +--- .github/workflows/sponsors.yml | 26 +++++ README.md | 5 + config/pytest_39.ini | 17 ---- docs/.overrides/main.html | 12 +-- docs/css/insiders.css | 124 ----------------------- docs/insiders/changelog.md | 103 -------------------- docs/insiders/goals.yml | 55 ----------- docs/insiders/index.md | 161 ------------------------------ docs/insiders/installation.md | 67 ------------- docs/js/insiders.js | 77 --------------- duties.py | 72 ++------------ mkdocs.yml | 12 +-- pyproject.toml | 3 +- scripts/insiders.py | 173 --------------------------------- scripts/make.py | 4 +- 18 files changed, 67 insertions(+), 917 deletions(-) create mode 100644 .github/workflows/sponsors.yml delete mode 100644 config/pytest_39.ini delete mode 100644 docs/css/insiders.css delete mode 100644 docs/insiders/changelog.md delete mode 100644 docs/insiders/goals.yml delete mode 100644 docs/insiders/index.md delete mode 100644 docs/insiders/installation.md delete mode 100644 docs/js/insiders.js delete mode 100644 scripts/insiders.py diff --git a/.copier-answers.yml b/.copier-answers.yml index 0d9a98c3..39641f11 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier. -_commit: 1.5.1 +_commit: 1.6.0 _src_path: gh:mkdocstrings/handler-template author_email: dev@pawamoy.fr author_fullname: Timothée Mazzucotelli @@ -8,13 +8,9 @@ copyright_date: '2021' copyright_holder: Timothée Mazzucotelli copyright_holder_email: dev@pawamoy.fr copyright_license: ISC -insiders: true -insiders_email: insiders@pawamoy.fr -insiders_repository_name: mkdocstrings-python language: Python project_description: A Python handler for mkdocstrings. project_name: mkdocstrings-python -public_release: true python_package_distribution_name: mkdocstrings-python python_package_import_name: python repository_name: python diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2399abb9..cde0a41b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,15 +34,15 @@ jobs: - macos-latest - windows-latest python-version: - - "3.9" - - "3.13" + - "3.10" + - "3.14" include: - - os: ubuntu-latest - python-version: "3.10" - os: ubuntu-latest python-version: "3.11" - os: ubuntu-latest python-version: "3.12" + - os: ubuntu-latest + python-version: "3.13" runs-on: ${{ matrix.os }} @@ -54,7 +54,7 @@ jobs: fetch-tags: true - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} @@ -81,39 +81,15 @@ jobs: - name: Store objects inventory for tests uses: actions/upload-artifact@v4 + if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13' }} with: name: objects.inv path: site/objects.inv - exclude-test-jobs: - runs-on: ubuntu-latest - outputs: - jobs: ${{ steps.exclude-jobs.outputs.jobs }} - steps: - - id: exclude-jobs - run: | - if ${{ github.repository_owner == 'pawamoy-insiders' }}; then - echo 'jobs=[ - {"os": "macos-latest"}, - {"os": "windows-latest"}, - {"python-version": "3.10"}, - {"python-version": "3.11"}, - {"python-version": "3.12"}, - {"python-version": "3.13"}, - {"python-version": "3.14"} - ]' | tr -d '[:space:]' >> $GITHUB_OUTPUT - else - echo 'jobs=[ - {"os": "macos-latest", "resolution": "lowest-direct"}, - {"os": "windows-latest", "resolution": "lowest-direct"} - ]' | tr -d '[:space:]' >> $GITHUB_OUTPUT - fi - tests: needs: - quality - - exclude-test-jobs strategy: max-parallel: 4 matrix: @@ -122,16 +98,20 @@ jobs: - macos-latest - windows-latest python-version: - - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" + - "3.15" resolution: - highest - lowest-direct - exclude: ${{ fromJSON(needs.exclude-test-jobs.outputs.jobs) }} + exclude: + - os: macos-latest + resolution: lowest-direct + - os: windows-latest + resolution: lowest-direct runs-on: ${{ matrix.os }} continue-on-error: true @@ -143,7 +123,7 @@ jobs: fetch-tags: true - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} allow-prereleases: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ef68f27..1c7cda36 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,30 +15,15 @@ jobs: fetch-depth: 0 fetch-tags: true - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: "3.12" + python-version: "3.13" - name: Setup uv uses: astral-sh/setup-uv@v5 - - name: Build dists - if: github.repository_owner == 'pawamoy-insiders' - run: uv tool run --from build pyproject-build - - name: Upload dists artifact - uses: actions/upload-artifact@v4 - if: github.repository_owner == 'pawamoy-insiders' - with: - name: python-insiders - path: ./dist/* - name: Prepare release notes - if: github.repository_owner != 'pawamoy-insiders' run: uv tool run git-changelog --release-notes > release-notes.md - - name: Create release with assets - uses: softprops/action-gh-release@v2 - if: github.repository_owner == 'pawamoy-insiders' - with: - files: ./dist/* - name: Create release uses: softprops/action-gh-release@v2 - if: github.repository_owner != 'pawamoy-insiders' with: body_path: release-notes.md + diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml new file mode 100644 index 00000000..8dd9150f --- /dev/null +++ b/.github/workflows/sponsors.yml @@ -0,0 +1,26 @@ +name: Update sponsors + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-readme: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Update README and create PR + uses: pawamoy/readme-insert@main + with: + markup-url: https://pawamoy.github.io/sponsors.txt + start-marker: '' + end-marker: '' + commit-message: 'chore: Update sponsors section in README' + pr-title: 'chore: Update sponsors section in README' + pr-body: 'This PR updates the sponsors section in the README file.' diff --git a/README.md b/README.md index 44507e72..485a1c0d 100644 --- a/README.md +++ b/README.md @@ -77,3 +77,8 @@ dependencies = [ - **Source code display:** *mkdocstrings* can add a collapsible div containing the highlighted source code of the Python object. + +## Sponsors + + + diff --git a/config/pytest_39.ini b/config/pytest_39.ini deleted file mode 100644 index a876e994..00000000 --- a/config/pytest_39.ini +++ /dev/null @@ -1,17 +0,0 @@ -# YORE: EOL 3.9: Remove file. -# This file is used on 3.9 due to forward compatibility issue with filterwarnings. -# See https://github.com/pytest-dev/pytest/issues/11101. -[pytest] -python_files = - test_*.py -addopts = - --cov - --cov-config config/coverage.ini -testpaths = - tests - -# action:message_regex:warning_class:module_regex:line -filterwarnings = - error - # TODO: remove once pytest-xdist 4 is released - ignore:.*rsyncdir:DeprecationWarning:xdist diff --git a/docs/.overrides/main.html b/docs/.overrides/main.html index 5bedfd03..c702362f 100644 --- a/docs/.overrides/main.html +++ b/docs/.overrides/main.html @@ -1,13 +1,11 @@ {% extends "base.html" %} {% block announce %} - - Fund this project through - sponsorship - - {% include ".icons/octicons/heart-fill-16.svg" %} - — - + Fund this project through + sponsorship + + {% include ".icons/octicons/heart-fill-16.svg" %} + — Follow @pawamoy on diff --git a/docs/css/insiders.css b/docs/css/insiders.css deleted file mode 100644 index e7b9c74f..00000000 --- a/docs/css/insiders.css +++ /dev/null @@ -1,124 +0,0 @@ -@keyframes heart { - - 0%, - 40%, - 80%, - 100% { - transform: scale(1); - } - - 20%, - 60% { - transform: scale(1.15); - } -} - -@keyframes vibrate { - 0%, 2%, 4%, 6%, 8%, 10%, 12%, 14%, 16%, 18% { - -webkit-transform: translate3d(-2px, 0, 0); - transform: translate3d(-2px, 0, 0); - } - 1%, 3%, 5%, 7%, 9%, 11%, 13%, 15%, 17%, 19% { - -webkit-transform: translate3d(2px, 0, 0); - transform: translate3d(2px, 0, 0); - } - 20%, 100% { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.heart { - color: #e91e63; -} - -.pulse { - animation: heart 1000ms infinite; -} - -.vibrate { - animation: vibrate 2000ms infinite; -} - -.new-feature svg { - fill: var(--md-accent-fg-color) !important; -} - -a.insiders { - color: #e91e63; -} - -.sponsorship-list { - width: 100%; -} - -.sponsorship-item { - border-radius: 100%; - display: inline-block; - height: 1.6rem; - margin: 0.1rem; - overflow: hidden; - width: 1.6rem; -} - -.sponsorship-item:focus, .sponsorship-item:hover { - transform: scale(1.1); -} - -.sponsorship-item img { - filter: grayscale(100%) opacity(75%); - height: auto; - width: 100%; -} - -.sponsorship-item:focus img, .sponsorship-item:hover img { - filter: grayscale(0); -} - -.sponsorship-item.private { - background: var(--md-default-fg-color--lightest); - color: var(--md-default-fg-color); - font-size: .6rem; - font-weight: 700; - line-height: 1.6rem; - text-align: center; -} - -.mastodon { - color: #897ff8; - border-radius: 100%; - box-shadow: inset 0 0 0 .05rem currentcolor; - display: inline-block; - height: 1.2rem !important; - padding: .25rem; - transition: all .25s; - vertical-align: bottom !important; - width: 1.2rem; -} - -.premium-sponsors { - text-align: center; -} - -#silver-sponsors img { - height: 140px; -} - -#bronze-sponsors img { - height: 140px; -} - -#bronze-sponsors p { - display: flex; - flex-wrap: wrap; - justify-content: center; -} - -#bronze-sponsors a { - display: block; - flex-shrink: 0; -} - -.sponsors-total { - font-weight: bold; -} \ No newline at end of file diff --git a/docs/insiders/changelog.md b/docs/insiders/changelog.md deleted file mode 100644 index 7898983c..00000000 --- a/docs/insiders/changelog.md +++ /dev/null @@ -1,103 +0,0 @@ -# Changelog - -## mkdocstrings-python Insiders - -### 1.12.1 May 24, 2025 { id="1.12.1" } - -- Visually-lighter admonitions for source code blocks - -### 1.12.0 March 24, 2025 { id="1.12.0" } - -- [Ordering method: `__all__`][option-members_order] - -### 1.11.0 March 20, 2025 { id="1.11.0" } - -- [Filtering method: `public`][option-filters-public] - -### 1.10.0 March 10, 2025 { id="1.10.0" } - -- [Backlinks][backlinks] - -### 1.9.1 December 26, 2024 { id="1.9.1" } - -- Re-add class template for RTD theme -- Make inheritance diagrams rendering more robust - -### 1.9.0 September 03, 2024 { id="1.9.0" } - -- [Relative cross-references][relative_crossrefs] -- [Scoped cross-references][scoped_crossrefs] - -### 1.8.3 June 19, 2024 { id="1.8.3" } - -- Update code for Griffe 0.46+ to avoid deprecation warnings - -### 1.8.2 May 09, 2024 { id="1.8.2" } - -- Don't render cross-refs for default values when signatures aren't separated - -### 1.8.1 April 19, 2024 { id="1.8.1" } - -- Render enumeration instance name instead of just "value", allowing proper cross-reference - -### 1.8.0 March 24, 2024 { id="1.8.0" } - -- [Annotations modernization][modernize_annotations] - -### 1.7.0 March 24, 2024 { id="1.7.0" } - -- [Class inheritance diagrams with Mermaid][show_inheritance_diagram] - -### 1.6.0 January 30, 2024 { id="1.6.0" } - -- Render cross-references to parameters documentation in signatures and attribute values. -- Add [`parameter_headings`][parameter_headings] option to render headings for parameters (enabling permalinks and ToC/inventory entries). -- Render cross-references for default parameter values in signatures. - -### 1.5.1 September 12, 2023 { id="1.5.1" } - -- Prevent empty auto-summarized Methods section. - -### 1.5.0 September 05, 2023 { id="1.5.0" } - -- Render function signature overloads. - -### 1.4.0 August 27, 2023 { id="1.4.0" } - -- Render cross-references in attribute signatures. - -### 1.3.0 August 24, 2023 { id="1.3.0" } - -- Add "method" symbol type. - -### 1.2.0 August 20, 2023 { id="1.2.0" } - -- Add [member auto-summaries](../usage/configuration/members.md#summary). - -### 1.1.4 July 17, 2023 { id="1.1.4" } - -- Fix heading level increment for class members. - -### 1.1.3 July 17, 2023 { id="1.1.3" } - -- Fix heading level (avoid with clause preventing to decrease it). - -### 1.1.2 July 15, 2023 { id="1.1.2" } - -- Use non-breaking spaces after symbol types. - -### 1.1.1 June 27, 2023 { id="1.1.1" } - -- Correctly escape expressions in signatures and other rendered types. - -### 1.1.0 June 4, 2023 { id="1.1.0" } - -- Add [Symbol types in headings and table of contents](../usage/configuration/headings.md#show_symbol_type_toc). - -### 1.0.0 May 10, 2023 { id="1.0.0" } - -- Add [cross-references for type annotations in signatures](../usage/configuration/signatures.md#signature_crossrefs). - Make sure to update your local templates as the signature of the - [`format_signature` filter][mkdocstrings_handlers.python.do_format_signature] - has changed. The templates that must be updated: - `class.html`, `expression.html`, `function.html` and `signature.html`. diff --git a/docs/insiders/goals.yml b/docs/insiders/goals.yml deleted file mode 100644 index 313322fd..00000000 --- a/docs/insiders/goals.yml +++ /dev/null @@ -1,55 +0,0 @@ -goals: - 500: - name: PlasmaVac User Guide - features: - - name: Cross-references for type annotations in signatures - ref: /usage/configuration/signatures/#signature_crossrefs - since: 2023/05/10 - - name: Symbol types in headings and table of contents - ref: /usage/configuration/headings/#show_symbol_type_toc - since: 2023/06/04 - 1000: - name: GraviFridge Fluid Renewal - features: - - name: Auto-summary of object members - ref: /usage/configuration/members/#summary - since: 2023/08/20 - - name: Automatic rendering of function signature overloads - since: 2023/09/05 - - name: Parameter headings - ref: /usage/configuration/headings/#parameter_headings - since: 2024/01/30 - - name: Automatic cross-references to parameters - ref: /usage/configuration/headings/#parameter_headings - since: 2024/01/30 - - name: Automatic cross-references for default parameter values in signatures - since: 2024/01/30 - 1500: - name: HyperLamp Navigation Tips - features: - - name: Class inheritance diagrams with Mermaid - ref: /usage/configuration/general/#show_inheritance_diagram - since: 2024/03/24 - - name: Annotations modernization - ref: /usage/configuration/signatures/#modernize_annotations - since: 2024/03/24 - 2000: - 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 - - name: Backlinks - ref: /usage/configuration/general/#backlinks - since: 2025/03/10 - - name: "Filtering method: `public`" - ref: /usage/configuration/members/#option-filters-public - since: 2025/03/20 - - name: "Ordering method: `__all__`" - ref: /usage/configuration/members/#option-members_order - since: 2025/03/24 - - name: "Visually-lighter source code blocks" - since: 2025/05/24 diff --git a/docs/insiders/index.md b/docs/insiders/index.md deleted file mode 100644 index f184961f..00000000 --- a/docs/insiders/index.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: Insiders ---- - -# Insiders - -*mkdocstrings-python* follows the **sponsorware** release strategy, which means that new features are first exclusively released to sponsors as part of [Insiders][]. Read on to learn [what sponsorships achieve][sponsorship], [how to become a sponsor][sponsors] to get access to Insiders, and [what's in it for you][features]! - -## What is Insiders? - -*mkdocstrings-python Insiders* is a private fork of *mkdocstrings-python*, hosted as a private GitHub repository. Almost[^1] [all new features][features] are developed as part of this fork, which means that they are immediately available to all eligible sponsors, as they are granted access to this private repository. - -[^1]: In general, every new feature is first exclusively released to sponsors, but sometimes upstream dependencies enhance existing features that must be supported by *mkdocstrings-python*. - -Every feature is tied to a [funding goal][funding] in monthly subscriptions. When a funding goal is hit, the features that are tied to it are merged back into *mkdocstrings-python* and released for general availability, making them available to all users. Bugfixes are always released in tandem. - -Sponsorships start as low as [**$10 a month**][sponsors].[^2] - -[^2]: Note that $10 a month is the minimum amount to become eligible for Insiders. While GitHub Sponsors also allows to sponsor lower amounts or one-time amounts, those can't be granted access to Insiders due to technical reasons. Such contributions are still very much welcome as they help ensuring the project's sustainability. - -## What sponsorships achieve - -Sponsorships make this project sustainable, as they buy the maintainers of this project time – a very scarce resource – which is spent on the development of new features, bug fixing, stability improvement, issue triage and general support. The biggest bottleneck in Open Source is time.[^3] - -[^3]: Making an Open Source project sustainable is exceptionally hard: maintainers burn out, projects are abandoned. That's not great and very unpredictable. The sponsorware model ensures that if you decide to use *mkdocstrings-python*, you can be sure that bugs are fixed quickly and new features are added regularly. - -If you're unsure if you should sponsor this project, check out the list of [completed funding goals][goals completed] to learn whether you're already using features that were developed with the help of sponsorships. You're most likely using at least a handful of them, [thanks to our awesome sponsors][sponsors]! - -## What's in it for me? - -```python exec="1" session="insiders" -data_source = [ - "docs/insiders/goals.yml", - ("griffe-inherited-docstrings", "https://mkdocstrings.github.io/griffe-inherited-docstrings/", "insiders/goals.yml"), - ("griffe-pydantic", "https://mkdocstrings.github.io/griffe-pydantic/", "insiders/goals.yml"), - ("griffe-warnings-deprecated", "https://mkdocstrings.github.io/griffe-warnings-deprecated/", "insiders/goals.yml"), -] -``` - - -```python exec="1" session="insiders" idprefix="" ---8<-- "scripts/insiders.py" - -if unreleased_features: - print( - "The moment you [become a sponsor](#how-to-become-a-sponsor), you'll get **immediate " - f"access to {len(unreleased_features)} additional features** that you can start using right away, and " - "which are currently exclusively available to sponsors:\n" - ) - - for feature in unreleased_features: - feature.render(badge=True) - - print( - "\n\nThese are just the features related to this project. " - "[See the complete feature list on the author's main Insiders page](https://pawamoy.github.io/insiders/#whats-in-it-for-me)." - ) -else: - print( - "The moment you [become a sponsor](#how-to-become-a-sponsor), you'll get immediate " - "access to all released features that you can start using right away, and " - "which are exclusively available to sponsors. At this moment, there are no " - "Insiders features for this project, but checkout the [next funding goals](#goals) " - "to see what's coming, as well as **[the feature list for all Insiders projects](https://pawamoy.github.io/insiders/#whats-in-it-for-me).**" - ) -``` - - -Additionally, your sponsorship will give more weight to your upvotes on issues, helping us prioritize work items in our backlog. For more information on how we prioritize work, see this page: [Backlog management][backlog]. - -## How to become a sponsor - -Thanks for your interest in sponsoring! In order to become an eligible sponsor with your GitHub account, visit [pawamoy's sponsor profile][github sponsor profile], and complete a sponsorship of **$10 a month or more**. You can use your individual or organization GitHub account for sponsoring. - -Sponsorships lower than $10 a month are also very much appreciated, and useful. They won't grant you access to Insiders, but they will be counted towards reaching sponsorship goals. Every sponsorship helps us implementing new features and releasing them to the public. - -**Important:** By default, when you're sponsoring **[@pawamoy][github sponsor profile]** through a GitHub organization, all the publicly visible members of the organization will be invited to join our private repositories. If you wish to only grant access to a subset of users, please send a short email to insiders@pawamoy.fr with the name of your organization and the GitHub accounts of the users that should be granted access. - -**Tip:** to ensure that access is not tied to a particular individual GitHub account, you can create a bot account (i.e. a GitHub account that is not tied to a specific individual), and use this account for the sponsoring. After being granted access to our private repositories, the bot account can create private forks of our private repositories into your own organization, which all members of your organization will have access to. - -You can cancel your sponsorship anytime.[^5] - -[^5]: If you cancel your sponsorship, GitHub schedules a cancellation request which will become effective at the end of the billing cycle. This means that even though you cancel your sponsorship, you will keep your access to Insiders as long as your cancellation isn't effective. All charges are processed by GitHub through Stripe. As we don't receive any information regarding your payment, and GitHub doesn't offer refunds, sponsorships are non-refundable. - -[:octicons-heart-fill-24:{ .pulse }   Join our awesome sponsors][github sponsor profile]{ .md-button .md-button--primary } - -
-
-
-
-
-
-
- -
- - - If you sponsor publicly, you're automatically added here with a link to your profile and avatar to show your support for *mkdocstrings-python*. Alternatively, if you wish to keep your sponsorship private, you'll be a silent +1. You can select visibility during checkout and change it afterwards. - - -## Funding - -### Goals - -The following section lists all funding goals. Each goal contains a list of features prefixed with a checkmark symbol, denoting whether a feature is :octicons-check-circle-fill-24:{ style="color: #00e676" } already available or :octicons-check-circle-fill-24:{ style="color: var(--md-default-fg-color--lightest)" } planned, but not yet implemented. When the funding goal is hit, the features are released for general availability. - -```python exec="1" session="insiders" idprefix="" -for goal in goals.values(): - if not goal.complete: - goal.render() -``` - -### Goals completed - -This section lists all funding goals that were previously completed, which means that those features were part of Insiders, but are now generally available and can be used by all users. - -```python exec="1" session="insiders" idprefix="" -for goal in goals.values(): - if goal.complete: - goal.render() -``` - -## Frequently asked questions - -### Compatibility - -> We're building an open source project and want to allow outside collaborators to use *mkdocstrings-python* locally without having access to Insiders. Is this still possible? - -Yes. Insiders is compatible with *mkdocstrings-python*. Almost all new features and configuration options are either backward-compatible or implemented behind feature flags. Most Insiders features enhance the overall experience, though while these features add value for the users of your project, they shouldn't be necessary for previewing when making changes to content. - -### Payment - -> We don't want to pay for sponsorship every month. Are there any other options? - -Yes. You can sponsor on a yearly basis by [switching your GitHub account to a yearly billing cycle][billing cycle]. If for some reason you cannot do that, you could also create a dedicated GitHub account with a yearly billing cycle, which you only use for sponsoring (some sponsors already do that). - -If you have any problems or further questions, please reach out to insiders@pawamoy.fr. - -### Terms - -> Are we allowed to use Insiders under the same terms and conditions as *mkdocstrings-python*? - -Yes. Whether you're an individual or a company, you may use *mkdocstrings-python Insiders* precisely under the same terms as *mkdocstrings-python*, which are given by the [ISC license][license]. However, we kindly ask you to respect our **fair use policy**: - -- Please **don't distribute the source code** of Insiders. You may freely use it for public, private or commercial projects, privately fork or mirror it, but please don't make the source code public, as it would counteract the sponsorware strategy. -- If you cancel your subscription, your access to the private repository is revoked, and you will miss out on all future updates of Insiders. However, you may **use the latest version** that's available to you **as long as you like**. Just remember that [GitHub deletes private forks][private forks]. - -[backlog]: https://pawamoy.github.io/backlog/ -[insiders]: #what-is-insiders -[sponsorship]: #what-sponsorships-achieve -[sponsors]: #how-to-become-a-sponsor -[features]: #whats-in-it-for-me -[funding]: #funding -[goals completed]: #goals-completed -[github sponsor profile]: https://github.com/sponsors/pawamoy -[billing cycle]: https://docs.github.com/en/github/setting-up-and-managing-billing-and-payments-on-github/changing-the-duration-of-your-billing-cycle -[license]: ../license.md -[private forks]: https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/removing-a-collaborator-from-a-personal-repository - - - diff --git a/docs/insiders/installation.md b/docs/insiders/installation.md deleted file mode 100644 index 3e20e5d7..00000000 --- a/docs/insiders/installation.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Getting started with Insiders ---- - -# Getting started with Insiders - -*mkdocstrings-python Insiders* is a compatible drop-in replacement for *mkdocstrings-python*, and can be installed similarly using `pip` or `git`. Note that in order to access the Insiders repository, you need to [become an eligible sponsor][] of @pawamoy on GitHub. - -## Installation - -### with the `insiders` tool - -[`insiders`][insiders-tool] is a tool that helps you keep up-to-date versions of Insiders projects in the PyPI index of your choice (self-hosted, Google registry, Artifactory, etc.). - -**We kindly ask that you do not upload the distributions to public registries, as it is against our [Terms of use][].** - -### with pip (ssh/https) - -*mkdocstrings-python Insiders* can be installed with `pip` [using SSH][install-pip-ssh]: - -```bash -pip install git+ssh://git@github.com/pawamoy-insiders/mkdocstrings-python.git -``` - -Or using HTTPS: - -```bash -pip install git+https://${GH_TOKEN}@github.com/pawamoy-insiders/mkdocstrings-python.git -``` - ->? NOTE: **How to get a GitHub personal access token?** The `GH_TOKEN` environment variable is a GitHub token. It can be obtained by creating a [personal access token][github-pat] for your GitHub account. It will give you access to the Insiders repository, programmatically, from the command line or GitHub Actions workflows: -> -> 1. Go to https://github.com/settings/tokens -> 2. Click on [Generate a new token][github-pat-new] -> 3. Enter a name and select the [`repo`][scopes] scope -> 4. Generate the token and store it in a safe place -> -> Note that the personal access token must be kept secret at all times, as it allows the owner to access your private repositories. - -### with Git - -Of course, you can use *mkdocstrings-python Insiders* directly using Git: - -``` -git clone git@github.com:pawamoy-insiders/mkdocstrings-python -``` - -When cloning with Git, the package must be installed: - -``` -pip install -e mkdocstrings-python -``` - -## Upgrading - -When upgrading Insiders, you should always check the version of *mkdocstrings-python* which makes up the first part of the version qualifier. For example, a version like `8.x.x.4.x.x` means that Insiders `4.x.x` is currently based on `8.x.x`. - -If the major version increased, it's a good idea to consult the [changelog][] and go through the steps to ensure your configuration is up to date and all necessary changes have been made. - -[become an eligible sponsor]: ./index.md#how-to-become-a-sponsor -[changelog]: ./changelog.md -[github-pat]: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token -[github-pat-new]: https://github.com/settings/tokens/new -[insiders-tool]: https://pawamoy.github.io/insiders-project/ -[install-pip-ssh]: https://docs.github.com/en/authentication/connecting-to-github-with-ssh -[scopes]: https://docs.github.com/en/developers/apps/scopes-for-oauth-apps#available-scopes -[terms of use]: ./index.md#terms diff --git a/docs/js/insiders.js b/docs/js/insiders.js deleted file mode 100644 index a86a0918..00000000 --- a/docs/js/insiders.js +++ /dev/null @@ -1,77 +0,0 @@ -function humanReadableAmount(amount) { - const strAmount = String(amount); - if (strAmount.length >= 4) { - return `${strAmount.slice(0, strAmount.length - 3)},${strAmount.slice(-3)}`; - } - return strAmount; -} - -function getJSON(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'json'; - xhr.onload = function () { - var status = xhr.status; - if (status === 200) { - callback(null, xhr.response); - } else { - callback(status, xhr.response); - } - }; - xhr.send(); -} - -function updatePremiumSponsors(dataURL, rank) { - let capRank = rank.charAt(0).toUpperCase() + rank.slice(1); - getJSON(dataURL + `/sponsors${capRank}.json`, function (err, sponsors) { - const sponsorsDiv = document.getElementById(`${rank}-sponsors`); - if (sponsors.length > 0) { - let html = ''; - html += `${capRank} sponsors

` - sponsors.forEach(function (sponsor) { - html += `` - if (sponsor.image) { - html += `${sponsor.name}` - } else if (sponsor.imageLight && sponsor.imageDark) { - html += `${sponsor.name}` - html += `${sponsor.name}` - } - html += ''; - }); - html += '

' - sponsorsDiv.innerHTML = html; - } - }); -} - -function updateInsidersPage(author_username) { - const sponsorURL = `https://github.com/sponsors/${author_username}` - const dataURL = `https://raw.githubusercontent.com/${author_username}/sponsors/main`; - getJSON(dataURL + '/numbers.json', function (err, numbers) { - document.getElementById('sponsors-count').innerHTML = numbers.count; - Array.from(document.getElementsByClassName('sponsors-total')).forEach(function (element) { - element.innerHTML = '$ ' + humanReadableAmount(numbers.total); - }); - getJSON(dataURL + '/sponsors.json', function (err, sponsors) { - const sponsorsElem = document.getElementById('sponsors'); - const privateSponsors = numbers.count - sponsors.length; - sponsors.forEach(function (sponsor) { - sponsorsElem.innerHTML += ` - - - - `; - }); - if (privateSponsors > 0) { - sponsorsElem.innerHTML += ` - - +${privateSponsors} - - `; - } - }); - }); - updatePremiumSponsors(dataURL, "gold"); - updatePremiumSponsors(dataURL, "silver"); - updatePremiumSponsors(dataURL, "bronze"); -} diff --git a/duties.py b/duties.py index 41df37b6..a21c3b8e 100644 --- a/duties.py +++ b/duties.py @@ -6,10 +6,9 @@ import re import sys from contextlib import contextmanager -from functools import wraps from importlib.metadata import version as pkgversion from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable +from typing import TYPE_CHECKING from duty import duty, tools @@ -37,21 +36,6 @@ def pyprefix(title: str) -> str: return title -def not_from_insiders(func: Callable) -> Callable: - @wraps(func) - def wrapper(ctx: Context, *args: Any, **kwargs: Any) -> None: - origin = ctx.run("git config --get remote.origin.url", silent=True) - if "pawamoy-insiders/griffe" in origin: - ctx.run( - lambda: False, - title="Not running this task from insiders repository (do that from public repo instead!)", - ) - return - func(ctx, *args, **kwargs) - - return wrapper - - @contextmanager def material_insiders() -> Iterator[bool]: if "+insiders" in pkgversion("mkdocs-material"): @@ -147,39 +131,13 @@ def docs(ctx: Context, *cli_args: str, host: str = "127.0.0.1", port: int = 8000 @duty(skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) -def docs_deploy(ctx: Context, *, force: bool = False) -> None: - """Deploy the documentation to GitHub pages. - - Parameters: - force: Whether to force deployment, even from non-Insiders version. - """ +def docs_deploy(ctx: Context) -> None: + """Deploy the documentation to GitHub pages.""" os.environ["DEPLOY"] = "true" with material_insiders() as insiders: if not insiders: ctx.run(lambda: False, title="Not deploying docs without Material for MkDocs Insiders!") - origin = ctx.run("git config --get remote.origin.url", silent=True, allow_overrides=False) - if "pawamoy-insiders/mkdocstrings-python" in origin: - ctx.run( - "git remote add upstream git@github.com:mkdocstrings/python", - silent=True, - nofail=True, - allow_overrides=False, - ) - ctx.run( - tools.mkdocs.gh_deploy(remote_name="upstream", force=True), - title="Deploying documentation", - ) - elif force: - ctx.run( - tools.mkdocs.gh_deploy(force=True), - title="Deploying documentation", - ) - else: - ctx.run( - lambda: False, - title="Not deploying docs from public repository (do that from insiders instead!)", - nofail=True, - ) + ctx.run(tools.mkdocs.gh_deploy(force=True), title="Deploying documentation") @duty @@ -203,7 +161,6 @@ def build(ctx: Context) -> None: @duty -@not_from_insiders def publish(ctx: Context) -> None: """Publish source and wheel distributions to PyPI.""" if not Path("dist").exists(): @@ -217,7 +174,6 @@ def publish(ctx: Context) -> None: @duty(post=["build", "publish", "docs-deploy"]) -@not_from_insiders def release(ctx: Context, version: str = "") -> None: """Release a new Python package. @@ -228,7 +184,7 @@ def release(ctx: Context, version: str = "") -> None: ctx.run("false", title="A version must be provided") ctx.run("git add pyproject.toml CHANGELOG.md", title="Staging files", pty=PTY) ctx.run(["git", "commit", "-m", f"chore: Prepare release {version}"], title="Committing changes", pty=PTY) - ctx.run(f"git tag {version}", title="Tagging commit", pty=PTY) + ctx.run(f"git tag -m '' -a {version}", title="Tagging commit", pty=PTY) ctx.run("git push", title="Pushing commits", pty=False) ctx.run("git push --tags", title="Pushing tags", pty=False) @@ -242,13 +198,8 @@ def coverage(ctx: Context) -> None: @duty(nofail=PY_VERSION == PY_DEV) -def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report") -> None: # noqa: PT028 - """Run the test suite. - - Parameters: - match: A pytest expression to filter selected tests. - snapshot: Whether to "create", "fix", "trim", or "update" snapshots. - """ +def test(ctx: Context, *cli_args: str, snapshot: str = "report") -> None: + """Run the test suite.""" os.environ["COVERAGE_FILE"] = f".coverage.{PY_VERSION}" os.environ["PYTHONWARNDEFAULTENCODING"] = "1" args = list(cli_args) @@ -256,17 +207,10 @@ def test(ctx: Context, *cli_args: str, match: str = "", snapshot: str = "report" args = ["-n", "auto", "--inline-snapshot=disable"] else: args = [f"--inline-snapshot={snapshot}"] - - config_file = "config/pytest.ini" - # YORE: EOL 3.9: Remove block. - if sys.version_info[:2] < (3, 10): - config_file = "config/pytest_39.ini" - ctx.run( tools.pytest( "tests", - config_file=config_file, - select=match, + config_file="config/pytest.ini", color="yes", ).add_args(*args), title=pyprefix("Running tests"), diff --git a/mkdocs.yml b/mkdocs.yml index 0796e003..f7b3b7a2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,13 +41,8 @@ nav: - Development: - Contributing: contributing.md - Code of Conduct: code_of_conduct.md - # - Coverage report: coverage.md -- Insiders: - - insiders/index.md - - Getting started: - - Installation: insiders/installation.md - - Changelog: insiders/changelog.md -- mkdocstrings: https://mkdocstrings.github.io/ + - Coverage report: coverage.md + - mkdocstrings: https://mkdocstrings.github.io/ theme: name: material @@ -93,7 +88,6 @@ theme: extra_css: - css/material.css - css/mkdocstrings.css -- css/insiders.css extra_javascript: - js/feedback.js @@ -177,7 +171,7 @@ plugins: show_root_full_path: false show_signature_annotations: true show_signature_type_parameters: true - show_source: false + show_source: true show_symbol_type_heading: true show_symbol_type_toc: true signature_crossrefs: true diff --git a/pyproject.toml b/pyproject.toml index ad0c852c..2d6c7188 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ authors = [{name = "Timothée Mazzucotelli", email = "dev@pawamoy.fr"}] license = "ISC" license-files = ["LICENSE"] readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" keywords = [] dynamic = ["version"] classifiers = [ @@ -18,7 +18,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/scripts/insiders.py b/scripts/insiders.py deleted file mode 100644 index 4cd438d4..00000000 --- a/scripts/insiders.py +++ /dev/null @@ -1,173 +0,0 @@ -# Functions related to Insiders funding goals. - -from __future__ import annotations - -import json -import logging -import os -import posixpath -from dataclasses import dataclass -from datetime import date, datetime, timedelta -from itertools import chain -from pathlib import Path -from typing import TYPE_CHECKING, cast -from urllib.error import HTTPError -from urllib.parse import urljoin -from urllib.request import urlopen - -import yaml - -if TYPE_CHECKING: - from collections.abc import Iterable - -logger = logging.getLogger(f"mkdocs.logs.{__name__}") - - -def human_readable_amount(amount: int) -> str: - str_amount = str(amount) - if len(str_amount) >= 4: # noqa: PLR2004 - return f"{str_amount[: len(str_amount) - 3]},{str_amount[-3:]}" - return str_amount - - -@dataclass -class Project: - name: str - url: str - - -@dataclass -class Feature: - name: str - ref: str | None - since: date | None - project: Project | None - - def url(self, rel_base: str = "..") -> str | None: # noqa: D102 - if not self.ref: - return None - if self.project: - rel_base = self.project.url - return posixpath.join(rel_base, self.ref.lstrip("/")) - - def render(self, rel_base: str = "..", *, badge: bool = False) -> None: # noqa: D102 - new = "" - if badge: - recent = self.since and date.today() - self.since <= timedelta(days=60) # noqa: DTZ011 - if recent: - ft_date = self.since.strftime("%B %d, %Y") # type: ignore[union-attr] - new = f' :material-alert-decagram:{{ .new-feature .vibrate title="Added on {ft_date}" }}' - project = f"[{self.project.name}]({self.project.url}) — " if self.project else "" - feature = f"[{self.name}]({self.url(rel_base)})" if self.ref else self.name - print(f"- [{'x' if self.since else ' '}] {project}{feature}{new}") - - -@dataclass -class Goal: - name: str - amount: int - features: list[Feature] - complete: bool = False - - @property - def human_readable_amount(self) -> str: # noqa: D102 - return human_readable_amount(self.amount) - - def render(self, rel_base: str = "..") -> None: # noqa: D102 - print(f"#### $ {self.human_readable_amount} — {self.name}\n") - if self.features: - for feature in self.features: - feature.render(rel_base) - print("") - else: - print("There are no features in this goal for this project. ") - print( - "[See the features in this goal **for all Insiders projects.**]" - f"(https://pawamoy.github.io/insiders/#{self.amount}-{self.name.lower().replace(' ', '-')})", - ) - - -def load_goals(data: str, funding: int = 0, project: Project | None = None) -> dict[int, Goal]: - goals_data = yaml.safe_load(data)["goals"] - return { - amount: Goal( - name=goal_data["name"], - amount=amount, - complete=funding >= amount, - features=[ - Feature( - name=feature_data["name"], - ref=feature_data.get("ref"), - since=feature_data.get("since") and datetime.strptime(feature_data["since"], "%Y/%m/%d").date(), # noqa: DTZ007 - project=project, - ) - for feature_data in goal_data["features"] - ], - ) - for amount, goal_data in goals_data.items() - } - - -def _load_goals_from_disk(path: str, funding: int = 0) -> dict[int, Goal]: - project_dir = os.getenv("MKDOCS_CONFIG_DIR", ".") - try: - data = Path(project_dir, path).read_text() - except OSError as error: - raise RuntimeError(f"Could not load data from disk: {path}") from error - return load_goals(data, funding) - - -def _load_goals_from_url(source_data: tuple[str, str, str], funding: int = 0) -> dict[int, Goal]: - project_name, project_url, data_fragment = source_data - data_url = urljoin(project_url, data_fragment) - try: - with urlopen(data_url) as response: # noqa: S310 - data = response.read() - except HTTPError as error: - raise RuntimeError(f"Could not load data from network: {data_url}") from error - return load_goals(data, funding, project=Project(name=project_name, url=project_url)) - - -def _load_goals(source: str | tuple[str, str, str], funding: int = 0) -> dict[int, Goal]: - if isinstance(source, str): - return _load_goals_from_disk(source, funding) - return _load_goals_from_url(source, funding) - - -def funding_goals(source: str | list[str | tuple[str, str, str]], funding: int = 0) -> dict[int, Goal]: - if isinstance(source, str): - return _load_goals_from_disk(source, funding) - goals = {} - for src in source: - source_goals = _load_goals(src, funding) - for amount, goal in source_goals.items(): - if amount not in goals: - goals[amount] = goal - else: - goals[amount].features.extend(goal.features) - return {amount: goals[amount] for amount in sorted(goals)} - - -def feature_list(goals: Iterable[Goal]) -> list[Feature]: - return list(chain.from_iterable(goal.features for goal in goals)) - - -def load_json(url: str) -> str | list | dict: - with urlopen(url) as response: # noqa: S310 - return json.loads(response.read().decode()) - - -data_source = globals()["data_source"] -sponsor_url = "https://github.com/sponsors/pawamoy" -data_url = "https://raw.githubusercontent.com/pawamoy/sponsors/main" -numbers: dict[str, int] = load_json(f"{data_url}/numbers.json") # type: ignore[assignment] -sponsors: list[dict] = load_json(f"{data_url}/sponsors.json") # type: ignore[assignment] -current_funding = numbers["total"] -sponsors_count = numbers["count"] -goals = funding_goals(data_source, funding=current_funding) -ongoing_goals = [goal for goal in goals.values() if not goal.complete] -unreleased_features = sorted( - (ft for ft in feature_list(ongoing_goals) if ft.since), - key=lambda ft: cast("date", ft.since), - reverse=True, -) diff --git a/scripts/make.py b/scripts/make.py index 1e697bcc..b741a366 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -14,8 +14,8 @@ from collections.abc import Iterator -PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.9 3.10 3.11 3.12 3.13 3.14").split() -PYTHON_DEV = "3.14" +PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.10 3.11 3.12 3.13 3.14 3.15").split() +PYTHON_DEV = "3.15" def shell(cmd: str, *, capture_output: bool = False, **kwargs: Any) -> str | None: From 3bc2d7b0c59f687434e6daba4ccf0b755509dcb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:09:38 +0100 Subject: [PATCH 42/46] style: Format --- duties.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/duties.py b/duties.py index a21c3b8e..21f7c7dc 100644 --- a/duties.py +++ b/duties.py @@ -79,7 +79,11 @@ def check_quality(ctx: Context) -> None: ) -@duty(nofail=PY_VERSION == PY_DEV, skip_if=sys.version_info < (3, 13), skip_reason=pyprefix("Skipped: docs require modern generics syntax")) +@duty( + nofail=PY_VERSION == PY_DEV, + skip_if=sys.version_info < (3, 13), + skip_reason=pyprefix("Skipped: docs require modern generics syntax"), +) def check_docs(ctx: Context) -> None: """Check if the documentation builds correctly.""" Path("htmlcov").mkdir(parents=True, exist_ok=True) From c086b036f7900578a13a56cc77228b442b5a3359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:10:51 +0100 Subject: [PATCH 43/46] chore: Ignore lint --- duties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/duties.py b/duties.py index 21f7c7dc..a48e743f 100644 --- a/duties.py +++ b/duties.py @@ -202,7 +202,7 @@ def coverage(ctx: Context) -> None: @duty(nofail=PY_VERSION == PY_DEV) -def test(ctx: Context, *cli_args: str, snapshot: str = "report") -> None: +def test(ctx: Context, *cli_args: str, snapshot: str = "report") -> None: # noqa: PT028 """Run the test suite.""" os.environ["COVERAGE_FILE"] = f".coverage.{PY_VERSION}" os.environ["PYTHONWARNDEFAULTENCODING"] = "1" From 63546221bd5e4b7127c9745774d10a55176a4ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:19:55 +0100 Subject: [PATCH 44/46] docs: Remove Insiders links --- CHANGELOG.md | 3 --- docs/usage/configuration/docstrings.md | 6 ------ docs/usage/configuration/general.md | 6 ------ docs/usage/configuration/headings.md | 6 ------ docs/usage/configuration/members.md | 7 +------ docs/usage/configuration/signatures.md | 8 -------- mkdocs.yml | 2 +- src/mkdocstrings_handlers/python/_internal/config.py | 3 --- 8 files changed, 2 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac6e8ec..e398e9ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -487,9 +487,6 @@ Importing from submodules is now deprecated: the public API is fully exposed und - [`griffe-inherited-docstrings`](https://mkdocstrings.github.io/griffe-inherited-docstrings/), a Griffe extension for inheriting docstrings - [`griffe2md`](https://mkdocstrings.github.io/griffe2md/), a tool to output API docs to Markdown using Griffe - See the complete list of features and projects here: - https://pawamoy.github.io/insiders/#500-plasmavac-user-guide. - ## [1.7.5](https://github.com/mkdocstrings/python/releases/tag/1.7.5) - 2023-11-21 [Compare with 1.7.4](https://github.com/mkdocstrings/python/compare/1.7.4...1.7.5) diff --git a/docs/usage/configuration/docstrings.md b/docs/usage/configuration/docstrings.md index f864d102..95f9032f 100644 --- a/docs/usage/configuration/docstrings.md +++ b/docs/usage/configuration/docstrings.md @@ -327,9 +327,6 @@ class Thing: [](){#option-relative_crossrefs} ## `relative_crossrefs` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** @@ -440,9 +437,6 @@ INFO: **There is an alternative, third-party Python handler that handles relativ [](){#option-scoped_crossrefs} ## `scoped_crossrefs` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.9.0](../../insiders/changelog.md#1.9.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** diff --git a/docs/usage/configuration/general.md b/docs/usage/configuration/general.md index 7d7b71e1..921f3b27 100644 --- a/docs/usage/configuration/general.md +++ b/docs/usage/configuration/general.md @@ -63,9 +63,6 @@ plugins: [](){#option-backlinks} ## `backlinks` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.10.0](../../insiders/changelog.md#1.10.0) - - **:octicons-package-24: Type Literal["flat", "tree", False] :material-equal: `False`{ title="default value" }** The `backlinks` option enables rendering of backlinks within your API documentation. @@ -503,9 +500,6 @@ plugins: [](){#option-show_inheritance_diagram} ## `show_inheritance_diagram` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.7.0](../../insiders/changelog.md#1.7.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** diff --git a/docs/usage/configuration/headings.md b/docs/usage/configuration/headings.md index 8e904e5f..593b6fb0 100644 --- a/docs/usage/configuration/headings.md +++ b/docs/usage/configuration/headings.md @@ -77,8 +77,6 @@ plugins: [](){#option-parameter_headings} ## `parameter_headings` -[:octicons-tag-24: Insiders 1.6.0](../../insiders/changelog.md#1.6.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** @@ -537,8 +535,6 @@ plugins: [](){#option-show_symbol_type_heading} ## `show_symbol_type_heading` -[:octicons-tag-24: Insiders 1.1.0](../../insiders/changelog.md#1.1.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** @@ -602,8 +598,6 @@ plugins: [](){#option-show_symbol_type_toc} ## `show_symbol_type_toc` -[:octicons-tag-24: Insiders 1.1.0](../../insiders/changelog.md#1.1.0) - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** diff --git a/docs/usage/configuration/members.md b/docs/usage/configuration/members.md index 3c344221..53d955fa 100644 --- a/docs/usage/configuration/members.md +++ b/docs/usage/configuration/members.md @@ -269,7 +269,7 @@ class Main(Base): The members ordering to use. Possible values: -- `__all__` ([:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — [:octicons-tag-24: Insiders 1.12.0](../../insiders/changelog.md#1.12.0)): Order according to `__all__` attributes. Since classes do not define `__all__` attributes, you can specify a second ordering method by using a list. +- `__all__`: Order according to `__all__` attributes. Since classes do not define `__all__` attributes, you can specify a second ordering method by using a list. - `alphabetical`: Order by the members names. - `source`: Order members as they appear in the source file. @@ -351,9 +351,6 @@ A list of filters, or `"public"`. [](){#option-filters-public} -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.11.0](../../insiders/changelog.md#1.11.0) - The `public` filtering method will include only public objects: those added to the `__all__` attribute of modules, or not starting with a single underscore. Special methods and attributes ("dunder" methods/attributes, starting and ending with two underscores), like `__init__`, `__call__`, `__mult__`, etc., are always considered public. **List of filters** @@ -577,8 +574,6 @@ package [](){#option-summary} ## `summary` -[:octicons-tag-24: Insiders 1.2.0](../../insiders/changelog.md#1.2.0) - - **:octicons-package-24: Type bool | dict[str, bool] :material-equal: `False`{ title="default value" }** diff --git a/docs/usage/configuration/signatures.md b/docs/usage/configuration/signatures.md index 16ac218b..109362e3 100644 --- a/docs/usage/configuration/signatures.md +++ b/docs/usage/configuration/signatures.md @@ -203,12 +203,6 @@ plugins: [](){#option-modernize_annotations} ## `modernize_annotations` -[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } — -[:octicons-tag-24: Insiders 1.8.0](../../insiders/changelog.md#1.8.0) — -**This feature also requires -[Griffe Insiders](https://mkdocstrings.github.io/griffe/insiders/) -to be installed.** - - **:octicons-package-24: Type [`bool`][] :material-equal: `False`{ title="default value" }** @@ -637,8 +631,6 @@ Function docstring. [](){#option-signature_crossrefs} ## `signature_crossrefs` -[:octicons-tag-24: Insiders 1.0.0](../../insiders/changelog.md#1.0.0) - Whether to render cross-references for type annotations in signatures. When signatures are separated from headings with the [`separate_signature`][] option diff --git a/mkdocs.yml b/mkdocs.yml index f7b3b7a2..30a806d1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -137,7 +137,7 @@ plugins: - autorefs - markdown-exec - section-index -# - coverage +- coverage - mkdocstrings: handlers: python: diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index d3588e2d..ad461c42 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -519,9 +519,6 @@ class PythonInputOptions: **Filtering methods** - [:octicons-heart-fill-24:{ .pulse } Sponsors only](../insiders/index.md){ .insiders } — - [:octicons-tag-24: Insiders 1.11.0](../insiders/changelog.md#1.11.0) - The `public` method will include only public objects: those added to `__all__` or not starting with an underscore (except for special methods/attributes). """, From b696ed2224756472a3617fa3cc18b69d0418ed71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:21:55 +0100 Subject: [PATCH 45/46] refactor: Update code base for Python 3.10 --- .../python/_internal/config.py | 51 ++++--------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py index ad461c42..79ba87f9 100644 --- a/src/mkdocstrings_handlers/python/_internal/config.py +++ b/src/mkdocstrings_handlers/python/_internal/config.py @@ -39,18 +39,6 @@ if getattr(pydantic, "__version__", "1.").startswith("1."): raise ImportError # noqa: TRY301 - # YORE: EOL 3.9: Remove block. - if sys.version_info < (3, 10): - try: - import eval_type_backport # noqa: F401 - except ImportError: - _logger.debug( - "Pydantic needs the `eval-type-backport` package to be installed " - "for modern type syntax to work on Python 3.9. " - "Deactivating Pydantic validation for Python handler options.", - ) - raise - from inspect import cleandoc from pydantic import Field as BaseField @@ -87,14 +75,7 @@ def _Field(*args: Any, **kwargs: Any) -> None: # type: ignore[misc] # noqa: N8 from collections.abc import MutableMapping -# YORE: EOL 3.9: Remove block. -_dataclass_options = {"frozen": True} -if sys.version_info >= (3, 10): - _dataclass_options["kw_only"] = True - - -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class GoogleStyleOptions: """Google style docstring options.""" @@ -205,8 +186,7 @@ class GoogleStyleOptions: ] = True -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class NumpyStyleOptions: """Numpy style docstring options.""" @@ -256,8 +236,7 @@ class NumpyStyleOptions: ] = True -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class SphinxStyleOptions: """Sphinx style docstring options.""" @@ -289,8 +268,7 @@ class SphinxStyleOptions: ] = True -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class PerStyleOptions: """Per style options.""" @@ -333,8 +311,7 @@ def from_data(cls, **data: Any) -> Self: return cls(**data) -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class AutoStyleOptions: """Auto style docstring options.""" @@ -382,8 +359,7 @@ def from_data(cls, **data: Any) -> Self: return cls(**data) -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class SummaryOption: """Summary option.""" @@ -433,8 +409,7 @@ class SummaryOption: ] = False -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class PythonInputOptions: """Accepted input options.""" @@ -1067,8 +1042,7 @@ def from_data(cls, **data: Any) -> Self: return cls(**cls.coerce(**data)) -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore] """Final options passed as template context.""" @@ -1093,8 +1067,7 @@ def coerce(cls, **data: Any) -> MutableMapping[str, Any]: return super().coerce(**data) -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class Inventory: """An inventory.""" @@ -1127,8 +1100,7 @@ def _config(self) -> dict[str, Any]: return {"base_url": self.base_url, "domains": self.domains} -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class PythonInputConfig: """Python handler configuration.""" @@ -1170,8 +1142,7 @@ def from_data(cls, **data: Any) -> Self: return cls(**cls.coerce(**data)) -# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line. -@dataclass(**_dataclass_options) # type: ignore[call-overload] +@dataclass(frozen=True, kw_only=True) class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore] """Python handler configuration.""" From e07c882ac52494ea7689df2605355eef869491e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 10 Nov 2025 14:30:15 +0100 Subject: [PATCH 46/46] chore: Prepare release 1.19.0 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e398e9ae..179b9a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.19.0](https://github.com/mkdocstrings/python/releases/tag/1.19.0) - 2025-11-10 + +[Compare with 1.18.2](https://github.com/mkdocstrings/python/compare/1.18.2...1.19.0) + +### Features + +- Release scoped and relative cross-references ([872afc5](https://github.com/mkdocstrings/python/commit/872afc584f33f50a133472afdc9355734a5e51ec) by Timothée Mazzucotelli). +- Release `__all__` ordering feature ([84aaebc](https://github.com/mkdocstrings/python/commit/84aaebcb4991c0245bf7ca8d7024c9d04942b0c1) by Timothée Mazzucotelli). +- Release public filter feature ([3be14cc](https://github.com/mkdocstrings/python/commit/3be14cc07bc9429d7ce01c748d825e2db1559212) by Timothée Mazzucotelli). +- Release backlinks feature ([ae7cc2d](https://github.com/mkdocstrings/python/commit/ae7cc2d7d8ea5711d8ce06620edd534a3e2b47aa) by Timothée Mazzucotelli). +- Release expression modernization feature ([dbadd1e](https://github.com/mkdocstrings/python/commit/dbadd1e898bb2e67515077d152890bdbbf0b3eb1) by Timothée Mazzucotelli). +- Release visually-lighter admonitions for source code blocks ([fdaeb48](https://github.com/mkdocstrings/python/commit/fdaeb48a0f2208bafd14f2f7ead42bca37bea665) by Timothée Mazzucotelli). +- Release inheritance diagram features ([669b42e](https://github.com/mkdocstrings/python/commit/669b42ebd7c154c81764fa98c052cf857f7aa406) by Timothée Mazzucotelli). + +### Code Refactoring + +- Update code base for Python 3.10 ([b696ed2](https://github.com/mkdocstrings/python/commit/b696ed2224756472a3617fa3cc18b69d0418ed71) by Timothée Mazzucotelli). + ## [1.18.2](https://github.com/mkdocstrings/python/releases/tag/1.18.2) - 2025-08-28 [Compare with 1.18.1](https://github.com/mkdocstrings/python/compare/1.18.1...1.18.2)