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.