From 37ab2a3014713b6fc00fb4417cace73430a5e2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Krupi=C5=84ski?= <3732079+rafalkrupinski@users.noreply.github.com> Date: Sun, 13 Jul 2025 15:50:41 +0200 Subject: [PATCH 01/12] feat: Read config from config file or pyproject.toml --- CHANGELOG.md | 6 ++++++ src/griffe2md/cli.py | 5 ++++- src/griffe2md/config.py | 45 +++++++++++++++++++++++++++++++++++++++++ src/griffe2md/main.py | 2 +- tests/test_config.py | 34 +++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 src/griffe2md/config.py create mode 100644 tests/test_config.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b56a4d..4378b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ 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). +## [unreleased] + +### Features + +- Read configuration from a config file or pyproject.toml . + ## [1.1.0](https://github.com/mkdocstrings/griffe2md/releases/tag/1.1.0) - 2025-02-11 [Compare with 1.0.2](https://github.com/mkdocstrings/griffe2md/compare/1.0.2...1.1.0) diff --git a/src/griffe2md/cli.py b/src/griffe2md/cli.py index 8e15217..d34faf4 100644 --- a/src/griffe2md/cli.py +++ b/src/griffe2md/cli.py @@ -18,6 +18,7 @@ from typing import Any from griffe2md import debug +from griffe2md.config import load_config from griffe2md.main import write_package_docs @@ -57,5 +58,7 @@ def main(args: list[str] | None = None) -> int: """ parser = get_parser() opts = parser.parse_args(args=args) - write_package_docs(opts.package, output=opts.output) + config = load_config() + + write_package_docs(opts.package, config, opts.output) return 0 diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py new file mode 100644 index 0000000..a355a9f --- /dev/null +++ b/src/griffe2md/config.py @@ -0,0 +1,45 @@ +"""Load configuration.""" + +import logging +import pathlib +from typing import Optional + +import tomllib + +logger = logging.getLogger(__name__) + +PATHS = ( + ".config/griffe2md.toml", + "config/griffe2md.toml", +) + +PYPROJECT = "pyproject.toml" + + +def _locate_config_file() -> Optional[pathlib.Path]: + for path in PATHS: + path_ = pathlib.Path(path) + if path_.is_file(): + return path_ + + pyproj_path = pathlib.Path(PYPROJECT) + if pyproj_path.is_file(): + return pyproj_path + + return None + + +def load_config() -> Optional[dict]: + """Load the configuration if config file or config entry in pyproject.toml exists. If neither config file was found or pyproject.toml file doesn't have [tool.griffe2md] section, returns None.""" + config_path = _locate_config_file() + if config_path is None: + return None + + logger.debug("Loading config from %s", config_path) + + with open(config_path, "rb") as f: + config = tomllib.load(f) + + if str(config_path) == PYPROJECT: + return (config.get("tool") or {}).get("griffe2md") + return config diff --git a/src/griffe2md/main.py b/src/griffe2md/main.py index a503eb5..864bdea 100644 --- a/src/griffe2md/main.py +++ b/src/griffe2md/main.py @@ -139,7 +139,7 @@ def render_package_docs(package: str, config: dict | None = None) -> str: Returns: Markdown. """ - config = config or dict(rendering.default_config) + config = {**rendering.default_config, **(config or {})} parser = config["docstring_style"] and Parser(config["docstring_style"]) loader = GriffeLoader(docstring_parser=parser) module = loader.load(package) diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..aa5bd9a --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,34 @@ +"""Test config loading.""" +from pathlib import Path +from unittest.mock import Mock, patch + +import pytest + +import griffe2md.cli +from griffe2md.config import PYPROJECT + + +@pytest.mark.parametrize( + "rel_path", + [ + ".config/griffe2md.toml", + "config/griffe2md.toml", + "pyproject.toml", + ], +) +def test_load_config(tmpdir, rel_path: str)->None: # noqa: ANN001 + """Test that config is loaded.""" + expected_config = {"dummy": True} + config_text = "dummy=true" + + mock_write = Mock() + + with tmpdir.as_cwd(), patch("griffe2md.cli.write_package_docs", mock_write): + text = f"[tool.griffe2md]\n{config_text}" if rel_path == PYPROJECT else config_text + config_path = Path(tmpdir) / rel_path + config_path.parent.mkdir(parents=True, exist_ok=True) + config_path.write_text(text, "utf-8") + + griffe2md.cli.main(["griffe2md", "-o/dev/null"]) + + mock_write.assert_called_once_with("griffe2md", expected_config, "/dev/null") From 821a58b0f6a15dfce6c2ed416a1ac430e0e45cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 14 Jul 2025 21:04:57 +0200 Subject: [PATCH 02/12] fixup! feat: Read config from config file or pyproject.toml --- src/griffe2md/config.py | 40 ++++++++++++++++++---------------------- tests/test_config.py | 3 ++- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py index a355a9f..3a50fe6 100644 --- a/src/griffe2md/config.py +++ b/src/griffe2md/config.py @@ -1,45 +1,41 @@ """Load configuration.""" import logging -import pathlib -from typing import Optional +from pathlib import Path +from typing import Any import tomllib logger = logging.getLogger(__name__) PATHS = ( - ".config/griffe2md.toml", - "config/griffe2md.toml", + Path(".config/griffe2md.toml"), + Path("config/griffe2md.toml"), + Path("pyproject.toml"), ) -PYPROJECT = "pyproject.toml" - -def _locate_config_file() -> Optional[pathlib.Path]: +def _locate_config_file() -> Path | None: for path in PATHS: - path_ = pathlib.Path(path) - if path_.is_file(): - return path_ - - pyproj_path = pathlib.Path(PYPROJECT) - if pyproj_path.is_file(): - return pyproj_path - + if path.is_file(): + return path return None -def load_config() -> Optional[dict]: - """Load the configuration if config file or config entry in pyproject.toml exists. If neither config file was found or pyproject.toml file doesn't have [tool.griffe2md] section, returns None.""" - config_path = _locate_config_file() - if config_path is None: +def load_config() -> dict[str, Any] | None: + """Load the configuration if config file or config entry in pyproject.toml exists. + + If neither config file was found or pyproject.toml file doesn't have + a `[tool.griffe2md]` section, None is returned. + """ + if not (config_path := _locate_config_file()): return None logger.debug("Loading config from %s", config_path) - with open(config_path, "rb") as f: + with config_path.open("rb") as f: config = tomllib.load(f) - if str(config_path) == PYPROJECT: - return (config.get("tool") or {}).get("griffe2md") + if config_path.name == "pyproject.toml": + return config.get("tool", {}).get("griffe2md", None) return config diff --git a/tests/test_config.py b/tests/test_config.py index aa5bd9a..89a4d89 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,4 +1,5 @@ """Test config loading.""" + from pathlib import Path from unittest.mock import Mock, patch @@ -16,7 +17,7 @@ "pyproject.toml", ], ) -def test_load_config(tmpdir, rel_path: str)->None: # noqa: ANN001 +def test_load_config(tmpdir, rel_path: str) -> None: # noqa: ANN001 """Test that config is loaded.""" expected_config = {"dummy": True} config_text = "dummy=true" From 2ba0b03c9b9dbd0a3ea831660f094e800bc595ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 14 Jul 2025 21:53:44 +0200 Subject: [PATCH 03/12] fixup! feat: Read config from config file or pyproject.toml --- duties.py | 2 +- pyproject.toml | 2 ++ src/griffe2md/config.py | 13 ++++++++++--- src/griffe2md/rendering.py | 4 ++-- tests/test_config.py | 21 +++++++-------------- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/duties.py b/duties.py index 8152356..7cee833 100644 --- a/duties.py +++ b/duties.py @@ -185,7 +185,7 @@ def coverage(ctx: Context) -> None: @duty -def test(ctx: Context, *cli_args: str, match: str = "") -> None: +def test(ctx: Context, *cli_args: str, match: str = "") -> None: # noqa: PT028 """Run the test suite. Parameters: diff --git a/pyproject.toml b/pyproject.toml index 77fbe4e..c4af0a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,8 @@ dependencies = [ "griffe>=0.49", "jinja2>=3.1.2", "mdformat>=0.7.16", + # YORE: EOL 3.10: Remove line. + "tomli>=2.0; python_version < '3.11'", ] [project.urls] diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py index 3a50fe6..5c140a4 100644 --- a/src/griffe2md/config.py +++ b/src/griffe2md/config.py @@ -1,14 +1,21 @@ """Load configuration.""" +from __future__ import annotations + import logging +import sys from pathlib import Path from typing import Any -import tomllib +# YORE: EOL 3.10: Replace block with line 2. +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib logger = logging.getLogger(__name__) -PATHS = ( +CONFIG_FILE_PATHS = ( Path(".config/griffe2md.toml"), Path("config/griffe2md.toml"), Path("pyproject.toml"), @@ -16,7 +23,7 @@ def _locate_config_file() -> Path | None: - for path in PATHS: + for path in CONFIG_FILE_PATHS: if path.is_file(): return path return None diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index 0207268..65eea7a 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -284,7 +284,7 @@ def do_format_attribute( def do_order_members( members: Sequence[Object | Alias], order: Order, - members_list: bool | list[str] | None, + members_list: bool | list[str] | None, # noqa: FBT001 ) -> Sequence[Object | Alias]: """Order members given an ordering method. @@ -415,7 +415,7 @@ def do_filter_objects( @lru_cache(maxsize=1) def _get_black_formatter() -> Callable[[str, int], str]: try: - from black import InvalidInput, Mode, format_str + from black import InvalidInput, Mode, format_str # noqa: PLC0415 except ModuleNotFoundError: logger.info("Formatting signatures requires Black to be installed.") return lambda text, _: text diff --git a/tests/test_config.py b/tests/test_config.py index 89a4d89..e3e72b3 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,26 +6,19 @@ import pytest import griffe2md.cli -from griffe2md.config import PYPROJECT - - -@pytest.mark.parametrize( - "rel_path", - [ - ".config/griffe2md.toml", - "config/griffe2md.toml", - "pyproject.toml", - ], -) -def test_load_config(tmpdir, rel_path: str) -> None: # noqa: ANN001 +from griffe2md.config import CONFIG_FILE_PATHS + + +@pytest.mark.parametrize("rel_path", CONFIG_FILE_PATHS) +def test_load_config(tmpdir: Path, rel_path: Path) -> None: """Test that config is loaded.""" expected_config = {"dummy": True} config_text = "dummy=true" mock_write = Mock() - with tmpdir.as_cwd(), patch("griffe2md.cli.write_package_docs", mock_write): - text = f"[tool.griffe2md]\n{config_text}" if rel_path == PYPROJECT else config_text + with tmpdir.as_cwd(), patch("griffe2md.cli.write_package_docs", mock_write): # type: ignore[attr-defined] + text = f"[tool.griffe2md]\n{config_text}" if rel_path.name == "pyproject.toml" else config_text config_path = Path(tmpdir) / rel_path config_path.parent.mkdir(parents=True, exist_ok=True) config_path.write_text(text, "utf-8") From 1859cb8e26a036e361c255e917028fd5985e9e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 14 Jul 2025 21:53:58 +0200 Subject: [PATCH 04/12] fixup! feat: Read config from config file or pyproject.toml --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4378b99..8b56a4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,6 @@ 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). -## [unreleased] - -### Features - -- Read configuration from a config file or pyproject.toml . - ## [1.1.0](https://github.com/mkdocstrings/griffe2md/releases/tag/1.1.0) - 2025-02-11 [Compare with 1.0.2](https://github.com/mkdocstrings/griffe2md/compare/1.0.2...1.1.0) From 56a1f31ef47548f33f09414f38f02fc647db5c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 15 Jul 2025 16:11:47 +0200 Subject: [PATCH 05/12] fixup! feat: Read config from config file or pyproject.toml --- CHANGELOG.md | 6 ----- duties.py | 2 +- pyproject.toml | 2 ++ src/griffe2md/config.py | 53 ++++++++++++++++++++------------------ src/griffe2md/rendering.py | 4 +-- tests/test_config.py | 22 ++++++---------- 6 files changed, 41 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4378b99..8b56a4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,6 @@ 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). -## [unreleased] - -### Features - -- Read configuration from a config file or pyproject.toml . - ## [1.1.0](https://github.com/mkdocstrings/griffe2md/releases/tag/1.1.0) - 2025-02-11 [Compare with 1.0.2](https://github.com/mkdocstrings/griffe2md/compare/1.0.2...1.1.0) diff --git a/duties.py b/duties.py index 8152356..7cee833 100644 --- a/duties.py +++ b/duties.py @@ -185,7 +185,7 @@ def coverage(ctx: Context) -> None: @duty -def test(ctx: Context, *cli_args: str, match: str = "") -> None: +def test(ctx: Context, *cli_args: str, match: str = "") -> None: # noqa: PT028 """Run the test suite. Parameters: diff --git a/pyproject.toml b/pyproject.toml index 77fbe4e..c4af0a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,8 @@ dependencies = [ "griffe>=0.49", "jinja2>=3.1.2", "mdformat>=0.7.16", + # YORE: EOL 3.10: Remove line. + "tomli>=2.0; python_version < '3.11'", ] [project.urls] diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py index a355a9f..5c140a4 100644 --- a/src/griffe2md/config.py +++ b/src/griffe2md/config.py @@ -1,45 +1,48 @@ """Load configuration.""" +from __future__ import annotations + import logging -import pathlib -from typing import Optional +import sys +from pathlib import Path +from typing import Any -import tomllib +# YORE: EOL 3.10: Replace block with line 2. +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib logger = logging.getLogger(__name__) -PATHS = ( - ".config/griffe2md.toml", - "config/griffe2md.toml", +CONFIG_FILE_PATHS = ( + Path(".config/griffe2md.toml"), + Path("config/griffe2md.toml"), + Path("pyproject.toml"), ) -PYPROJECT = "pyproject.toml" - - -def _locate_config_file() -> Optional[pathlib.Path]: - for path in PATHS: - path_ = pathlib.Path(path) - if path_.is_file(): - return path_ - - pyproj_path = pathlib.Path(PYPROJECT) - if pyproj_path.is_file(): - return pyproj_path +def _locate_config_file() -> Path | None: + for path in CONFIG_FILE_PATHS: + if path.is_file(): + return path return None -def load_config() -> Optional[dict]: - """Load the configuration if config file or config entry in pyproject.toml exists. If neither config file was found or pyproject.toml file doesn't have [tool.griffe2md] section, returns None.""" - config_path = _locate_config_file() - if config_path is None: +def load_config() -> dict[str, Any] | None: + """Load the configuration if config file or config entry in pyproject.toml exists. + + If neither config file was found or pyproject.toml file doesn't have + a `[tool.griffe2md]` section, None is returned. + """ + if not (config_path := _locate_config_file()): return None logger.debug("Loading config from %s", config_path) - with open(config_path, "rb") as f: + with config_path.open("rb") as f: config = tomllib.load(f) - if str(config_path) == PYPROJECT: - return (config.get("tool") or {}).get("griffe2md") + if config_path.name == "pyproject.toml": + return config.get("tool", {}).get("griffe2md", None) return config diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index 0207268..65eea7a 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -284,7 +284,7 @@ def do_format_attribute( def do_order_members( members: Sequence[Object | Alias], order: Order, - members_list: bool | list[str] | None, + members_list: bool | list[str] | None, # noqa: FBT001 ) -> Sequence[Object | Alias]: """Order members given an ordering method. @@ -415,7 +415,7 @@ def do_filter_objects( @lru_cache(maxsize=1) def _get_black_formatter() -> Callable[[str, int], str]: try: - from black import InvalidInput, Mode, format_str + from black import InvalidInput, Mode, format_str # noqa: PLC0415 except ModuleNotFoundError: logger.info("Formatting signatures requires Black to be installed.") return lambda text, _: text diff --git a/tests/test_config.py b/tests/test_config.py index aa5bd9a..e3e72b3 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,30 +1,24 @@ """Test config loading.""" + from pathlib import Path from unittest.mock import Mock, patch import pytest import griffe2md.cli -from griffe2md.config import PYPROJECT - - -@pytest.mark.parametrize( - "rel_path", - [ - ".config/griffe2md.toml", - "config/griffe2md.toml", - "pyproject.toml", - ], -) -def test_load_config(tmpdir, rel_path: str)->None: # noqa: ANN001 +from griffe2md.config import CONFIG_FILE_PATHS + + +@pytest.mark.parametrize("rel_path", CONFIG_FILE_PATHS) +def test_load_config(tmpdir: Path, rel_path: Path) -> None: """Test that config is loaded.""" expected_config = {"dummy": True} config_text = "dummy=true" mock_write = Mock() - with tmpdir.as_cwd(), patch("griffe2md.cli.write_package_docs", mock_write): - text = f"[tool.griffe2md]\n{config_text}" if rel_path == PYPROJECT else config_text + with tmpdir.as_cwd(), patch("griffe2md.cli.write_package_docs", mock_write): # type: ignore[attr-defined] + text = f"[tool.griffe2md]\n{config_text}" if rel_path.name == "pyproject.toml" else config_text config_path = Path(tmpdir) / rel_path config_path.parent.mkdir(parents=True, exist_ok=True) config_path.write_text(text, "utf-8") From ae8eb4165ab97ece92c34311264c97b29a224001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 15 Jul 2025 16:16:10 +0200 Subject: [PATCH 06/12] fixup! feat: Read config from config file or pyproject.toml --- tests/test_cli.py | 2 +- tests/test_config.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 9ea0691..916a6f8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,7 +27,7 @@ def test_show_help(capsys: pytest.CaptureFixture) -> None: def test_render_self() -> None: """Render docs for itself.""" - cli.main(["griffe2md", "-o/dev/null"]) + cli.main(["griffe2md"]) def test_show_version(capsys: pytest.CaptureFixture) -> None: diff --git a/tests/test_config.py b/tests/test_config.py index e3e72b3..4919d3f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -23,6 +23,6 @@ def test_load_config(tmpdir: Path, rel_path: Path) -> None: config_path.parent.mkdir(parents=True, exist_ok=True) config_path.write_text(text, "utf-8") - griffe2md.cli.main(["griffe2md", "-o/dev/null"]) + griffe2md.cli.main(["griffe2md"]) - mock_write.assert_called_once_with("griffe2md", expected_config, "/dev/null") + mock_write.assert_called_once_with("griffe2md", expected_config, None) From d669c0564810e7b3dbee181bd1df07b0874cc2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Krupi=C5=84ski?= <3732079+rafalkrupinski@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:28:31 +0200 Subject: [PATCH 07/12] doc: document the configuration dict and how to configure the app --- README.md | 15 ++++++++++++ src/griffe2md/config.py | 9 ++++--- src/griffe2md/main.py | 16 ++++++------ src/griffe2md/rendering.py | 50 +++++++++++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 834ab99..dc804d3 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,18 @@ Use the `-o`, `--output` option to write to a file instead of standard output: ```bash griffe2md markdown -o markdown.md ``` + +`griffe2md` can be configured by either 'pyproject.toml' or 'griffe2md.toml' files. The latter can be placed either in '.config' or 'config' directory in the project root. + +'griffe2md.toml' file is structured as a simple key-value dictionary, e.g.: +```toml +docstring_style = "sphinx" +``` + +If you configure it in `pyproject.toml`, the configuration should go under 'tool.griffe2md' key: +```toml +[tool.griffe2md] +docstring_style = "sphinx" +``` + +See [the documentation](https://mkdocstrings.github.io/griffe2md/reference/griffe2md/rendering/#griffe2md.rendering.ConfigDict) for reference. diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py index 5c140a4..70cdf1e 100644 --- a/src/griffe2md/config.py +++ b/src/griffe2md/config.py @@ -4,8 +4,11 @@ import logging import sys +import typing from pathlib import Path -from typing import Any + +if typing.TYPE_CHECKING: + from griffe2md import rendering # YORE: EOL 3.10: Replace block with line 2. if sys.version_info >= (3, 11): @@ -29,7 +32,7 @@ def _locate_config_file() -> Path | None: return None -def load_config() -> dict[str, Any] | None: +def load_config() -> rendering.ConfigDict | None: """Load the configuration if config file or config entry in pyproject.toml exists. If neither config file was found or pyproject.toml file doesn't have @@ -45,4 +48,4 @@ def load_config() -> dict[str, Any] | None: if config_path.name == "pyproject.toml": return config.get("tool", {}).get("griffe2md", None) - return config + return typing.cast("rendering.ConfigDict", config) diff --git a/src/griffe2md/main.py b/src/griffe2md/main.py index 864bdea..0a79636 100644 --- a/src/griffe2md/main.py +++ b/src/griffe2md/main.py @@ -5,7 +5,7 @@ import re import sys from pathlib import Path -from typing import IO, TYPE_CHECKING +from typing import IO, TYPE_CHECKING, cast import mdformat from griffe import GriffeLoader, Parser @@ -27,7 +27,7 @@ def _output(text: str, to: IO | str | None = None) -> None: to.write(text) -def prepare_context(obj: Object, config: dict | None = None) -> dict: +def prepare_context(obj: Object, config: rendering.ConfigDict | None = None) -> dict: """Prepare Jinja context. Parameters: @@ -37,7 +37,7 @@ def prepare_context(obj: Object, config: dict | None = None) -> dict: Returns: The Jinja context. """ - config = dict(rendering.default_config, **(config or {})) + config = cast(rendering.ConfigDict, {**rendering.default_config, **(config or {})}) if config["filters"]: config["filters"] = [(re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in config["filters"]] @@ -113,7 +113,7 @@ def prepare_env(env: Environment | None = None) -> Environment: return env -def render_object_docs(obj: Object, config: dict | None = None) -> str: +def render_object_docs(obj: Object, config: rendering.ConfigDict | None = None) -> str: """Render docs for a given object. Parameters: @@ -129,7 +129,7 @@ def render_object_docs(obj: Object, config: dict | None = None) -> str: return mdformat.text(rendered) -def render_package_docs(package: str, config: dict | None = None) -> str: +def render_package_docs(package: str, config: rendering.ConfigDict | None = None) -> str: """Render docs for a given package. Parameters: @@ -139,15 +139,15 @@ def render_package_docs(package: str, config: dict | None = None) -> str: Returns: Markdown. """ - config = {**rendering.default_config, **(config or {})} + config = cast(rendering.ConfigDict, {**rendering.default_config, **(config or {})}) parser = config["docstring_style"] and Parser(config["docstring_style"]) - loader = GriffeLoader(docstring_parser=parser) + loader = GriffeLoader(docstring_parser=parser) # type; ignore[arg-type] module = loader.load(package) loader.resolve_aliases(external=True) return render_object_docs(module, config) # type: ignore[arg-type] -def write_package_docs(package: str, config: dict | None = None, output: IO | str | None = None) -> None: +def write_package_docs(package: str, config: rendering.ConfigDict | None = None, output: IO | str | None = None) -> None: """Write docs for a given package to a file or stdout. Parameters: diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index 65eea7a..43dd325 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -8,6 +8,7 @@ import re import string import sys +import typing from functools import lru_cache, partial from re import Pattern from typing import TYPE_CHECKING, Any, Callable @@ -46,7 +47,54 @@ class Order(enum.Enum): """Source code order.""" -default_config: dict = { +class ConfigDict(typing.TypedDict): + """Configuration for griffe2md, griffe and mkdocstrings.""" + + allow_inspection: bool + annotations_path: str + docstring_options: dict + """mkdocstring [configuration](https://mkdocstrings.github.io/python/usage/configuration/general/)""" + + docstring_section_style: str + docstring_style: typing.Literal['google', 'numpy', 'sphinx', 'auto'] + """Style of project docstring.""" + + filters: Any + group_by_category: bool + heading_level: int + inherited_members: bool + line_length: int + load_external_modules: bool + members: Any + members_order: Any + merge_init_into_class: bool + preload_modules: Any + separate_signature: bool + show_bases: bool + show_category_heading: bool + show_docstring_attributes: bool + show_docstring_description: bool + show_docstring_examples: bool + show_docstring_other_parameters: bool + show_docstring_parameters: bool + show_docstring_raises: bool + show_docstring_receives: bool + show_docstring_returns: bool + show_docstring_warns: bool + show_docstring_yields: bool + show_if_no_docstring: bool + show_object_full_path: bool + show_root_full_path: bool + show_root_heading: bool + show_root_members_full_path: bool + show_signature: bool + show_signature_annotations: bool + show_submodules: bool + signature_crossrefs: bool + summary: bool | dict + + +default_config: ConfigDict = { "docstring_style": "google", "docstring_options": {"ignore_init_summary": True}, "show_root_heading": True, From 71b6908caff7d6b66b01ba5cb66369e0b1569d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 30 Jul 2025 17:31:57 +0200 Subject: [PATCH 08/12] fixup --- src/griffe2md/main.py | 10 +++++++--- src/griffe2md/rendering.py | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/griffe2md/main.py b/src/griffe2md/main.py index 0a79636..46db030 100644 --- a/src/griffe2md/main.py +++ b/src/griffe2md/main.py @@ -37,7 +37,7 @@ def prepare_context(obj: Object, config: rendering.ConfigDict | None = None) -> Returns: The Jinja context. """ - config = cast(rendering.ConfigDict, {**rendering.default_config, **(config or {})}) + config = cast("rendering.ConfigDict", {**rendering.default_config, **(config or {})}) if config["filters"]: config["filters"] = [(re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in config["filters"]] @@ -139,7 +139,7 @@ def render_package_docs(package: str, config: rendering.ConfigDict | None = None Returns: Markdown. """ - config = cast(rendering.ConfigDict, {**rendering.default_config, **(config or {})}) + config = cast("rendering.ConfigDict", {**rendering.default_config, **(config or {})}) parser = config["docstring_style"] and Parser(config["docstring_style"]) loader = GriffeLoader(docstring_parser=parser) # type; ignore[arg-type] module = loader.load(package) @@ -147,7 +147,11 @@ def render_package_docs(package: str, config: rendering.ConfigDict | None = None return render_object_docs(module, config) # type: ignore[arg-type] -def write_package_docs(package: str, config: rendering.ConfigDict | None = None, output: IO | str | None = None) -> None: +def write_package_docs( + package: str, + config: rendering.ConfigDict | None = None, + output: IO | str | None = None, +) -> None: """Write docs for a given package to a file or stdout. Parameters: diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index 43dd325..cfa5179 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: from collections.abc import Sequence - from griffe.dataclasses import Alias, Attribute, Class, Function, Module, Object + from griffe import Alias, Attribute, Class, Function, Module, Object from jinja2.runtime import Context from markupsafe import Markup @@ -56,7 +56,7 @@ class ConfigDict(typing.TypedDict): """mkdocstring [configuration](https://mkdocstrings.github.io/python/usage/configuration/general/)""" docstring_section_style: str - docstring_style: typing.Literal['google', 'numpy', 'sphinx', 'auto'] + docstring_style: typing.Literal["google", "numpy", "sphinx", "auto"] """Style of project docstring.""" filters: Any @@ -492,7 +492,7 @@ def from_private_package(obj: Object | Alias) -> bool: if not obj.is_alias: return False try: - return obj.target.package.name == f"_{obj.parent.package.name}" + return obj.target.package.name == f"_{obj.parent.package.name}" # type: ignore[union-attr] except (AliasResolutionError, CyclicAliasError): return False @@ -517,7 +517,7 @@ def do_as_attributes_section( name=attribute.name, description=attribute.docstring.value.split("\n", 1)[0] if attribute.docstring else "", annotation=attribute.annotation, - value=attribute.value, + value=str(attribute.value) if attribute.value else None, ) for attribute in attributes if not check_public or attribute.is_public or from_private_package(attribute) From b1a803277602b5737116eb971d251a23a2ef40a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 30 Jul 2025 17:49:50 +0200 Subject: [PATCH 09/12] fixup --- src/griffe2md/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/griffe2md/main.py b/src/griffe2md/main.py index 46db030..341ce48 100644 --- a/src/griffe2md/main.py +++ b/src/griffe2md/main.py @@ -141,7 +141,7 @@ def render_package_docs(package: str, config: rendering.ConfigDict | None = None """ config = cast("rendering.ConfigDict", {**rendering.default_config, **(config or {})}) parser = config["docstring_style"] and Parser(config["docstring_style"]) - loader = GriffeLoader(docstring_parser=parser) # type; ignore[arg-type] + loader = GriffeLoader(docstring_parser=parser) module = loader.load(package) loader.resolve_aliases(external=True) return render_object_docs(module, config) # type: ignore[arg-type] From a83704be811f36b8a67529143ec294a80ef912bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Krupi=C5=84ski?= <3732079+rafalkrupinski@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:15:16 +0200 Subject: [PATCH 10/12] doc: document entries in the configuration dict --- src/griffe2md/rendering.py | 59 +++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index cfa5179..61c31d3 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -47,30 +47,65 @@ class Order(enum.Enum): """Source code order.""" +class SummaryConfig(typing.TypedDict): + attributes: bool + functions: bool + classes: bool + modules: bool + + class ConfigDict(typing.TypedDict): """Configuration for griffe2md, griffe and mkdocstrings.""" - allow_inspection: bool - annotations_path: str docstring_options: dict """mkdocstring [configuration](https://mkdocstrings.github.io/python/usage/configuration/general/)""" - docstring_section_style: str + # mkdocstrings specific options + + allow_inspection: bool + """See [mkdocstring documentation](https://mkdocstrings.github.io/python/usage/configuration/general/#allow_inspection)""" + + preload_modules: Sequence[str] | None + """See [mkdocstring documentation](https://mkdocstrings.github.io/python/usage/configuration/general/#preload_modules)""" + + show_bases: bool + """See [mkdocstring documentation](https://mkdocstrings.github.io/python/usage/configuration/general/#show_bases)""" + + # griffe2md options + + annotations_path: typing.Literal["brief", "full"] + """Style of annotations paths. "brief" creates a single link to the element denoted by the path; "full" creates a link to each segment of the path.""" + + docstring_section_style: typing.Literal["table", "list"] + """Style of list-like sections, e.g. parameters, exceptions""" + docstring_style: typing.Literal["google", "numpy", "sphinx", "auto"] """Style of project docstring.""" - filters: Any + filters: Sequence[str] | None + """List of regular expressions, optionally prefixed with "!", used to include or exclude members.""" + group_by_category: bool + """If true, group children by category.""" + heading_level: int - inherited_members: bool + """Starting level of headings.""" + + inherited_members: bool | Sequence[str] + """Wether or not to include inherited members.""" + line_length: int load_external_modules: bool - members: Any - members_order: Any + members: bool | Sequence[str] | None + + members_order: typing.Literal["alphabetical", "source"] + """Whether to order the members alphabetically or keep the source order.""" + merge_init_into_class: bool - preload_modules: Any + separate_signature: bool - show_bases: bool + """Whether to place signatures separately or keep in headers.""" + show_category_heading: bool show_docstring_attributes: bool show_docstring_description: bool @@ -90,8 +125,12 @@ class ConfigDict(typing.TypedDict): show_signature: bool show_signature_annotations: bool show_submodules: bool + signature_crossrefs: bool - summary: bool | dict + """Whether to cross-reference types in the signature""" + + summary: bool | SummaryConfig + """Whether or not to include summaries for attributes, classes, functions and modules. Use boolean to set value for all types.""" default_config: ConfigDict = { From 90f1190e7dd80c7032e53b13e0cb531de0dcc5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 19 Aug 2025 18:05:13 +0200 Subject: [PATCH 11/12] fixup --- README.md | 10 +- src/griffe2md/config.py | 217 +++++++++++++++++- src/griffe2md/main.py | 20 +- src/griffe2md/rendering.py | 96 +------- .../templates/summary/modules.md.jinja | 2 +- 5 files changed, 233 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index dc804d3..e6307dc 100644 --- a/README.md +++ b/README.md @@ -34,17 +34,19 @@ Use the `-o`, `--output` option to write to a file instead of standard output: griffe2md markdown -o markdown.md ``` -`griffe2md` can be configured by either 'pyproject.toml' or 'griffe2md.toml' files. The latter can be placed either in '.config' or 'config' directory in the project root. +`griffe2md` can be configured in either `pyproject.toml` or a `griffe2md.toml` file. The latter can be placed in a `.config` or `config` directory in the project root. + +`griffe2md.toml` file is structured as a simple key-value dictionary, e.g.: -'griffe2md.toml' file is structured as a simple key-value dictionary, e.g.: ```toml docstring_style = "sphinx" ``` -If you configure it in `pyproject.toml`, the configuration should go under 'tool.griffe2md' key: +If you configure it in `pyproject.toml`, the configuration should go under the `tool.griffe2md` key: + ```toml [tool.griffe2md] docstring_style = "sphinx" ``` -See [the documentation](https://mkdocstrings.github.io/griffe2md/reference/griffe2md/rendering/#griffe2md.rendering.ConfigDict) for reference. +See [the documentation](https://mkdocstrings.github.io/griffe2md/reference/griffe2md/rendering/#griffe2md.config.ConfigDict) for reference. diff --git a/src/griffe2md/config.py b/src/griffe2md/config.py index 70cdf1e..13a635b 100644 --- a/src/griffe2md/config.py +++ b/src/griffe2md/config.py @@ -4,11 +4,8 @@ import logging import sys -import typing from pathlib import Path - -if typing.TYPE_CHECKING: - from griffe2md import rendering +from typing import TYPE_CHECKING, Literal, TypedDict, cast # YORE: EOL 3.10: Replace block with line 2. if sys.version_info >= (3, 11): @@ -16,6 +13,9 @@ else: import tomli as tomllib +if TYPE_CHECKING: + from re import Pattern + logger = logging.getLogger(__name__) CONFIG_FILE_PATHS = ( @@ -32,7 +32,7 @@ def _locate_config_file() -> Path | None: return None -def load_config() -> rendering.ConfigDict | None: +def load_config() -> ConfigDict | None: """Load the configuration if config file or config entry in pyproject.toml exists. If neither config file was found or pyproject.toml file doesn't have @@ -48,4 +48,209 @@ def load_config() -> rendering.ConfigDict | None: if config_path.name == "pyproject.toml": return config.get("tool", {}).get("griffe2md", None) - return typing.cast("rendering.ConfigDict", config) + return cast("ConfigDict", config) + + +class ConfigDict(TypedDict): + """Configuration for griffe2md, griffe and mkdocstrings.""" + + allow_inspection: bool + """Allow using introspection on modules for which sources aren't available (compiled modules, etc.).""" + + annotations_path: Literal["brief", "source", "full"] + """The verbosity for annotations path: `brief` (recommended), `source` (as written in the source), or `full`.""" + + docstring_options: dict + """mkdocstring [configuration](https://mkdocstrings.github.io/python/usage/configuration/general/)""" + + docstring_section_style: Literal["list", "table"] + """The style used to render docstring sections.""" + + docstring_style: Literal["google", "numpy", "sphinx", "auto"] | None + """The style in which docstrings are written: `auto`, `google`, `numpy`, `sphinx`, or `None`.""" + + filters: list[str] | list[tuple[Pattern[str], bool]] + """A list of filters. + + A filter starting with `!` will exclude matching objects instead of including them. + The `members` option takes precedence over `filters` (filters will still be applied recursively + to lower members in the hierarchy). + """ + + group_by_category: bool + """Group the object's children by categories: attributes, classes, functions, and modules.""" + + heading_level: int + """The initial heading level to use.""" + + inherited_members: bool | list[str] + """A boolean, or an explicit list of inherited members to render. + + If true, select all inherited members, which can then be filtered with `members`. + If false or empty list, do not select any inherited member. + """ + + line_length: int + """Maximum line length when formatting code/signatures.""" + + load_external_modules: bool + """Whether to always load external modules/packages.""" + + members: list[str] | bool | None + """A boolean, or an explicit list of members to render. + + If true, select all members without further filtering. + If false or empty list, do not render members. + If none, select all members and apply further filtering with filters and docstrings. + """ + + members_order: Literal["alphabetical", "source"] + """The members ordering to use. + + - `alphabetical`: order members alphabetically; + - `source`: order members as they appear in the source file. + """ + + merge_init_into_class: bool + """Whether to merge the `__init__` method into the class' signature and docstring.""" + + preload_modules: list[str] | None + """Pre-load modules that are not specified directly in autodoc instructions (`::: identifier`). + + It is useful when you want to render documentation for a particular member of an object, + and this member is imported from another package than its parent. + + For an imported member to be rendered, you need to add it to the `__all__` attribute + of the importing module. + + The modules must be listed as an array of strings. + """ + + separate_signature: bool + """Whether to put the whole signature in a code block below the heading. + + If Black or Ruff are installed, the signature is also formatted using them. + """ + + show_bases: bool + """Show the base classes of a class.""" + + show_category_heading: bool + """When grouped by categories, show a heading for each category.""" + + show_docstring_attributes: bool + """Whether to display the 'Attributes' section in the object's docstring.""" + + show_docstring_classes: bool + """Whether to display the 'Classes' section in the object's docstring.""" + + show_docstring_description: bool + """Whether to display the textual block (including admonitions) in the object's docstring.""" + + show_docstring_examples: bool + """Whether to display the 'Examples' section in the object's docstring.""" + + show_docstring_functions: bool + """Whether to display the 'Functions' section in the object's docstring.""" + + show_docstring_modules: bool + """Whether to display the 'Modules' section in the object's docstring.""" + + show_docstring_other_parameters: bool + """Whether to display the 'Other Parameters' section in the object's docstring.""" + + show_docstring_parameters: bool + """Whether to display the 'Parameters' section in the object's docstring.""" + + show_docstring_raises: bool + """Whether to display the 'Raises' section in the object's docstring.""" + + show_docstring_receives: bool + """Whether to display the 'Receives' section in the object's docstring.""" + + show_docstring_returns: bool + """Whether to display the 'Returns' section in the object's docstring.""" + + show_docstring_warns: bool + """Whether to display the 'Warns' section in the object's docstring.""" + + show_docstring_yields: bool + """Whether to display the 'Yields' section in the object's docstring.""" + + show_if_no_docstring: bool + """Show the object heading even if it has no docstring or children with docstrings.""" + + show_object_full_path: bool + """Show the full Python path of every object.""" + + show_root_full_path: bool + """Show the full Python path for the root object heading.""" + + show_root_heading: bool + """Show the heading of the object at the root of the documentation tree. + + The root object is the object referenced by the identifier after `:::`. + """ + + show_root_members_full_path: bool + """Show the full Python path of the root members.""" + + show_signature: bool + """Show methods and functions signatures.""" + + show_signature_annotations: bool + """Show the type annotations in methods and functions signatures.""" + + show_submodules: bool + """When rendering a module, show its submodules recursively.""" + + signature_crossrefs: bool + """Whether to render cross-references for type annotations in signatures.""" + + summary: bool | dict + """Whether to render summaries of modules, classes, functions (methods) and attributes.""" + + +default_config: ConfigDict = { + "docstring_style": "google", + "docstring_options": {"ignore_init_summary": True}, + "show_root_heading": True, + "show_root_full_path": True, + "show_root_members_full_path": True, + "show_object_full_path": True, + "show_category_heading": False, + "show_if_no_docstring": True, + "show_signature": True, + "show_signature_annotations": False, + "signature_crossrefs": False, + "separate_signature": True, + "line_length": 80, + "merge_init_into_class": True, + "show_docstring_attributes": True, + "show_docstring_description": True, + "show_docstring_examples": True, + "show_docstring_other_parameters": True, + "show_docstring_parameters": True, + "show_docstring_raises": True, + "show_docstring_receives": True, + "show_docstring_returns": True, + "show_docstring_warns": True, + "show_docstring_yields": True, + "show_bases": True, + "show_submodules": True, + "group_by_category": False, + "heading_level": 2, + "members_order": "alphabetical", + "docstring_section_style": "list", + "members": None, + "inherited_members": True, + "filters": ["!^_"], + "annotations_path": "brief", + "preload_modules": None, + "load_external_modules": False, + "allow_inspection": True, + "summary": True, + "show_docstring_classes": True, + "show_docstring_functions": True, + "show_docstring_modules": True, +} diff --git a/src/griffe2md/main.py b/src/griffe2md/main.py index 341ce48..c7eca10 100644 --- a/src/griffe2md/main.py +++ b/src/griffe2md/main.py @@ -12,6 +12,7 @@ from jinja2 import Environment, FileSystemLoader from griffe2md import rendering +from griffe2md.config import ConfigDict, default_config if TYPE_CHECKING: from griffe import Object @@ -27,7 +28,7 @@ def _output(text: str, to: IO | str | None = None) -> None: to.write(text) -def prepare_context(obj: Object, config: rendering.ConfigDict | None = None) -> dict: +def prepare_context(obj: Object, config: ConfigDict | None = None) -> dict: """Prepare Jinja context. Parameters: @@ -37,13 +38,16 @@ def prepare_context(obj: Object, config: rendering.ConfigDict | None = None) -> Returns: The Jinja context. """ - config = cast("rendering.ConfigDict", {**rendering.default_config, **(config or {})}) + config = cast("ConfigDict", {**default_config, **(config or {})}) if config["filters"]: - config["filters"] = [(re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in config["filters"]] + config["filters"] = [ + (re.compile(filtr.lstrip("!")), filtr.startswith("!")) if isinstance(filtr, str) else filtr + for filtr in config["filters"] + ] heading_level = config["heading_level"] try: - config["members_order"] = rendering.Order(config["members_order"]) + config["members_order"] = rendering.Order(config["members_order"]).value except ValueError as error: choices = "', '".join(item.value for item in rendering.Order) raise ValueError( @@ -113,7 +117,7 @@ def prepare_env(env: Environment | None = None) -> Environment: return env -def render_object_docs(obj: Object, config: rendering.ConfigDict | None = None) -> str: +def render_object_docs(obj: Object, config: ConfigDict | None = None) -> str: """Render docs for a given object. Parameters: @@ -129,7 +133,7 @@ def render_object_docs(obj: Object, config: rendering.ConfigDict | None = None) return mdformat.text(rendered) -def render_package_docs(package: str, config: rendering.ConfigDict | None = None) -> str: +def render_package_docs(package: str, config: ConfigDict | None = None) -> str: """Render docs for a given package. Parameters: @@ -139,7 +143,7 @@ def render_package_docs(package: str, config: rendering.ConfigDict | None = None Returns: Markdown. """ - config = cast("rendering.ConfigDict", {**rendering.default_config, **(config or {})}) + config = cast("ConfigDict", {**default_config, **(config or {})}) parser = config["docstring_style"] and Parser(config["docstring_style"]) loader = GriffeLoader(docstring_parser=parser) module = loader.load(package) @@ -149,7 +153,7 @@ def render_package_docs(package: str, config: rendering.ConfigDict | None = None def write_package_docs( package: str, - config: rendering.ConfigDict | None = None, + config: ConfigDict | None = None, output: IO | str | None = None, ) -> None: """Write docs for a given package to a file or stdout. diff --git a/src/griffe2md/rendering.py b/src/griffe2md/rendering.py index cfa5179..1649307 100644 --- a/src/griffe2md/rendering.py +++ b/src/griffe2md/rendering.py @@ -8,7 +8,6 @@ import re import string import sys -import typing from functools import lru_cache, partial from re import Pattern from typing import TYPE_CHECKING, Any, Callable @@ -38,7 +37,7 @@ logger = logging.getLogger(__name__) -class Order(enum.Enum): +class Order(str, enum.Enum): """Enumeration for the possible members ordering.""" alphabetical = "alphabetical" @@ -47,95 +46,6 @@ class Order(enum.Enum): """Source code order.""" -class ConfigDict(typing.TypedDict): - """Configuration for griffe2md, griffe and mkdocstrings.""" - - allow_inspection: bool - annotations_path: str - docstring_options: dict - """mkdocstring [configuration](https://mkdocstrings.github.io/python/usage/configuration/general/)""" - - docstring_section_style: str - docstring_style: typing.Literal["google", "numpy", "sphinx", "auto"] - """Style of project docstring.""" - - filters: Any - group_by_category: bool - heading_level: int - inherited_members: bool - line_length: int - load_external_modules: bool - members: Any - members_order: Any - merge_init_into_class: bool - preload_modules: Any - separate_signature: bool - show_bases: bool - show_category_heading: bool - show_docstring_attributes: bool - show_docstring_description: bool - show_docstring_examples: bool - show_docstring_other_parameters: bool - show_docstring_parameters: bool - show_docstring_raises: bool - show_docstring_receives: bool - show_docstring_returns: bool - show_docstring_warns: bool - show_docstring_yields: bool - show_if_no_docstring: bool - show_object_full_path: bool - show_root_full_path: bool - show_root_heading: bool - show_root_members_full_path: bool - show_signature: bool - show_signature_annotations: bool - show_submodules: bool - signature_crossrefs: bool - summary: bool | dict - - -default_config: ConfigDict = { - "docstring_style": "google", - "docstring_options": {"ignore_init_summary": True}, - "show_root_heading": True, - "show_root_full_path": True, - "show_root_members_full_path": True, - "show_object_full_path": True, - "show_category_heading": False, - "show_if_no_docstring": True, - "show_signature": True, - "show_signature_annotations": False, - "signature_crossrefs": False, - "separate_signature": True, - "line_length": 80, - "merge_init_into_class": True, - "show_docstring_attributes": True, - "show_docstring_description": True, - "show_docstring_examples": True, - "show_docstring_other_parameters": True, - "show_docstring_parameters": True, - "show_docstring_raises": True, - "show_docstring_receives": True, - "show_docstring_returns": True, - "show_docstring_warns": True, - "show_docstring_yields": True, - "show_bases": True, - "show_submodules": True, - "group_by_category": False, - "heading_level": 2, - "members_order": Order.alphabetical.value, - "docstring_section_style": "list", - "members": None, - "inherited_members": True, - "filters": ["!^_"], - "annotations_path": "brief", - "preload_modules": None, - "load_external_modules": False, - "allow_inspection": True, - "summary": True, -} - - def do_any(seq: Sequence, attribute: str | None = None) -> bool: """Check if at least one of the item in the sequence evaluates to true. @@ -166,8 +76,8 @@ def _sort_key_source(item: Object | Alias) -> Any: order_map = { - Order.alphabetical: _sort_key_alphabetical, - Order.source: _sort_key_source, + Order.alphabetical.value: _sort_key_alphabetical, + Order.source.value: _sort_key_source, } diff --git a/src/griffe2md/templates/summary/modules.md.jinja b/src/griffe2md/templates/summary/modules.md.jinja index 814f0a4..c31e798 100644 --- a/src/griffe2md/templates/summary/modules.md.jinja +++ b/src/griffe2md/templates/summary/modules.md.jinja @@ -5,7 +5,7 @@ inherited_members=config.inherited_members, keep_no_docstrings=config.show_if_no_docstring, ) - |order_members(config.members_order.alphabetical, members_list) + |order_members("alphabetical", members_list) |as_modules_section(check_public=not members_list) %} {% if section %}{% include "docstring/modules.md.jinja" with context %}{% endif %} From bc9c6395626d30cae6def40c4f8c6adbb9110586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 19 Aug 2025 18:15:23 +0200 Subject: [PATCH 12/12] fixup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6307dc..6026091 100644 --- a/README.md +++ b/README.md @@ -49,4 +49,4 @@ If you configure it in `pyproject.toml`, the configuration should go under the ` docstring_style = "sphinx" ``` -See [the documentation](https://mkdocstrings.github.io/griffe2md/reference/griffe2md/rendering/#griffe2md.config.ConfigDict) for reference. +See [the documentation](https://mkdocstrings.github.io/griffe2md/reference/griffe2md/config/#griffe2md.config.ConfigDict) for reference.