From cc23e26459d88106df35d3fa35bdfbb5316d0cec Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 22 Nov 2023 12:59:42 +0100 Subject: [PATCH 1/9] docs: Add a macro to get a symbol's docstring summary This is useful when listing symbols, to avoid repeating the docs. Signed-off-by: Leandro Lucarella --- docs/_scripts/macros.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/_scripts/macros.py b/docs/_scripts/macros.py index ca54f6a4..92373806 100644 --- a/docs/_scripts/macros.py +++ b/docs/_scripts/macros.py @@ -6,8 +6,11 @@ from typing import Any import markdown as md +from griffe import Object +from griffe.collections import ModulesCollection from markdown.extensions import toc from mkdocs_macros import plugin as macros +from mkdocstrings_handlers.python.handler import PythonHandler _CODE_ANNOTATION_MARKER: str = ( r'' @@ -77,5 +80,41 @@ def define_env(env: macros.MacrosPlugin) -> None: # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER + python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") + assert isinstance(python_handler, PythonHandler) + + def _get_docstring(symbol: str) -> str: + symbols = python_handler._modules_collection # pylint: disable=protected-access + assert isinstance(symbols, ModulesCollection) + + try: + obj = symbols[symbol] + except KeyError as exc: + raise ValueError(f"Symbol {symbol!r} not found.") from exc + assert isinstance(obj, Object) + + docstring = obj.docstring + if not docstring: + raise ValueError(f"Symbol {symbol!r} has no docstring.") + + return docstring.value + + # The decorator makes the function untyped + @env.macro # type: ignore[misc] + def docstring_summary(symbol: str) -> str: + """Get the summary of a Python symbol. + + Args: + symbol: The fully qualified name of the Python symbol to get the summary of. + + Returns: + The summary of the Python symbol. + """ + docstring = _get_docstring(symbol) + summary = docstring.splitlines(keepends=False)[0] + return python_handler.do_convert_markdown( + summary, heading_level=1, strip_paragraph=True + ) + # This hook needs to be done at the end of the `define_env` function. _hook_macros_plugin(env) From 43da02caf43db45282c27ea1363716531203f089 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 26 Oct 2023 21:56:31 +0200 Subject: [PATCH 2/9] mkdocs: Sort template features Signed-off-by: Leandro Lucarella --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 6adfbe89..68369922 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,9 +24,9 @@ theme: features: - content.code.annotate - content.code.copy + - navigation.footer - navigation.indexes - navigation.instant - - navigation.footer - navigation.tabs - navigation.top - navigation.tracking From 2b1ec257daf3032b29f8634369ded5e05d8837fc Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 10:22:25 +0100 Subject: [PATCH 3/9] mkdocs: Expand the navigation bar by default Add the `navigation.expand` material template feature. Signed-off-by: Leandro Lucarella --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 68369922..b2562f8f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,7 @@ theme: features: - content.code.annotate - content.code.copy + - navigation.expand - navigation.footer - navigation.indexes - navigation.instant From 0a7f59d4792022c7d3289f81ea25fc15db36cc5d Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 10:24:42 +0100 Subject: [PATCH 4/9] Fix Markdown dependency spacing Signed-off-by: Leandro Lucarella --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 279ccd25..768ca1fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ dev-flake8 = [ dev-formatting = ["black == 23.10.1", "isort == 5.12.0"] dev-mkdocs = [ "black == 23.10.1", - "Markdown==3.5.1", + "Markdown == 3.5.1", "mike == 2.0.0", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", From f520b2a466aaa32ca35dcaa8cc27c3fb4f4a244e Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 10:26:07 +0100 Subject: [PATCH 5/9] Sort dependencies Signed-off-by: Leandro Lucarella --- pyproject.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 768ca1fc..92a3267d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,33 +45,33 @@ dev-flake8 = [ ] dev-formatting = ["black == 23.10.1", "isort == 5.12.0"] dev-mkdocs = [ - "black == 23.10.1", "Markdown == 3.5.1", + "black == 23.10.1", + "frequenz-repo-config[lib] == 0.7.5", "mike == 2.0.0", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-material == 9.4.7", "mkdocs-macros-plugin == 1.0.5", + "mkdocs-material == 9.4.7", "mkdocstrings[python] == 0.23.0", - "frequenz-repo-config[lib] == 0.7.5", ] dev-mypy = [ - "mypy == 1.6.1", - "types-Markdown == 3.5.0.0", # For checking the noxfile, docs/ script, and tests "frequenz-channels[dev-mkdocs,dev-noxfile,dev-pytest]", + "mypy == 1.6.1", + "types-Markdown == 3.5.0.0", ] dev-noxfile = ["nox == 2023.4.22", "frequenz-repo-config[lib] == 0.7.5"] dev-pylint = [ - "pylint == 3.0.2", # For checking the noxfile, docs/ script, and tests "frequenz-channels[dev-mkdocs,dev-noxfile,dev-pytest]", + "pylint == 3.0.2", ] dev-pytest = [ - "pytest == 7.4.3", "async-solipsism == 0.5", - "hypothesis == 6.88.1", "frequenz-repo-config[extra-lint-examples] == 0.7.5", + "hypothesis == 6.88.1", + "pytest == 7.4.3", "pytest-asyncio == 0.21.1", "pytest-mock == 3.12.0", ] From 7a39ebb84c802dc175d966b199ee32514c771bd8 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 10:27:53 +0100 Subject: [PATCH 6/9] Add the `mkdocs-include-markdown-plugin` This extension allows documentation to include other markdown files. This is especially useful to be able to share parts of the README in the generated documentation, as normally there is an overlap in the introductory concepts. Signed-off-by: Leandro Lucarella --- mkdocs.yml | 1 + pyproject.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index b2562f8f..40676853 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -91,6 +91,7 @@ plugins: - gen-files: scripts: - docs/_scripts/mkdocstrings_autoapi.py + - include-markdown - literate-nav: nav_file: SUMMARY.md - mike: diff --git a/pyproject.toml b/pyproject.toml index 92a3267d..42445300 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ dev-mkdocs = [ "frequenz-repo-config[lib] == 0.7.5", "mike == 2.0.0", "mkdocs-gen-files == 0.5.0", + "mkdocs-include-markdown-plugin == 6.0.4", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.0.5", "mkdocs-material == 9.4.7", From 79097a6db8a56eb83f727893159a2900614a55fd Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 15:43:05 +0100 Subject: [PATCH 7/9] Add the `markdown-svgbob` extension This extension allows documentation to include ASCII diagrams/graphs that are rendered as SVG when the documentation is generated, giving a nicer look to the diagrams/graphs while keeping the documents readable in text form. This is especially useful for docstrings, are they will be seen by users in text form, but we still want to render them nicely. Signed-off-by: Leandro Lucarella --- mkdocs.yml | 2 ++ pyproject.toml | 1 + 2 files changed, 3 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 40676853..4fce883f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -68,6 +68,8 @@ markdown_extensions: - attr_list - def_list - footnotes + - markdown_svgbob: + min_char_width: 0 - pymdownx.details - pymdownx.highlight: anchor_linenums: true diff --git a/pyproject.toml b/pyproject.toml index 42445300..7e433b22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ dev-mkdocs = [ "Markdown == 3.5.1", "black == 23.10.1", "frequenz-repo-config[lib] == 0.7.5", + "markdown-svgbob == 202112.1022", "mike == 2.0.0", "mkdocs-gen-files == 0.5.0", "mkdocs-include-markdown-plugin == 6.0.4", From a76eda1ca42a149b91008992b807383e69b960ab Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 15:45:41 +0100 Subject: [PATCH 8/9] Render `Timer` diagrams with svgbob This uses a syntax that is more friendly with svgbob and make the diagrams render nicely. Signed-off-by: Leandro Lucarella --- src/frequenz/channels/timer.py | 38 ++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/frequenz/channels/timer.py b/src/frequenz/channels/timer.py index 95594ec7..c4d65bc9 100644 --- a/src/frequenz/channels/timer.py +++ b/src/frequenz/channels/timer.py @@ -87,12 +87,16 @@ class TriggerAllMissed(MissedTickPolicy): `T5`, happens at 5.1 (0.1 seconds late), so it triggers immediately again. The seventh tick, `T6`, happens at 6.0, right on time. - ``` - 0 1 2 3 4 o 5 6 - o---------|-o-------|--o------|---------|--o------|o--------o-----> time +
+ ```bob + 0 1 2 3 4 T4 5 6 + *---------o-*-------o--*------o---------o--**-----o*--------*-----> time T0 T1 T2 T3 T5 T6 - T4 + + -o- "Expected ticks" + -*- "Delivered ticks" ``` +
""" def calculate_next_tick_time( @@ -134,11 +138,17 @@ class SkipMissedAndResync(MissedTickPolicy): `T5`, happens at 5.1 (0.1 seconds late), so it triggers immediately again. The seventh tick, `T6`, happens at 6.0, right on time. +
+ ```bob + 0 1 2 3 4 T4 5 6 + *---------o-*-------o--*------o---------o--*O-----o-*-------*-----> time + T0 T1 T2 T3 T5 T6 + + -o- "Expected ticks" + -*- "Delivered ticks" + -O- "Undelivered ticks (skipped)" ``` - 0 1 2 3 4 o 5 6 - o---------|-o-------|--o------|---------|--o------|o--------o-----> time - T0 T1 T2 T3 T5 T6 - ``` +
""" def calculate_next_tick_time( @@ -187,11 +197,17 @@ class SkipMissedAndDrift(MissedTickPolicy): so is right on time (no drift) and the same happens for tick `T6.3`, which triggers at 6.3 seconds. - ``` +
+ ```bob 0 1 2 3 4 5 6 - o---------|-o-------|--o------|---------|--o------|--o------|--o--> time - T0 T1 T2.2 T3.2 T5.3 T6.3 + *---------o-*-------|-o*------|-O-------|-o*------|--*------|--*--> time + T0 T1.2 T2.2 T3.2 T4.2 T5.3 T6.3 + + -o- "Expected ticks" + -*- "Delivered ticks" + -O- "Undelivered ticks (skipped)" ``` +
""" def __init__(self, *, delay_tolerance: timedelta = timedelta(0)): From d6b2275c194dae8d954c40da72738f119cd3a89c Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 23 Nov 2023 15:54:27 +0100 Subject: [PATCH 9/9] Reuse parts of `README.md` in `docs/index.md` We want to also include some basic information of the project in the documentation home page (but not all of it), so we use the include extension to reuse some README sections. Signed-off-by: Leandro Lucarella --- README.md | 8 ++++++++ docs/index.md | 24 ++++++++++++------------ mkdocs.yml | 1 + 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7633b2fd..e3bd5f61 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ ## Introduction + + Frequenz Channels is a *channels* implementation for Python. According to [Wikipedia](https://en.wikipedia.org/wiki/Channel_(programming)): @@ -20,14 +22,20 @@ Frequenz Channels are mostly designed after [Go channels](https://tour.golang.org/concurrency/2) but it also borrows ideas from [Rust channels](https://doc.rust-lang.org/book/ch16-02-message-passing.html). + + ## Supported Platforms + + The following platforms are officially supported (tested): - **Python:** 3.11 - **Operating System:** Ubuntu Linux 20.04 - **Architectures:** amd64, arm64 + + ## Quick Start We assume you are on a system with Python available. If that is not the case, diff --git a/docs/index.md b/docs/index.md index 8e2b2036..17590073 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,19 +2,19 @@ ## Introduction -Frequenz Channels is a *channels* implementation for Python. +{% + include-markdown "../README.md" + start="" + end="" +%} -According to [Wikipedia](https://en.wikipedia.org/wiki/Channel_(programming)): +## Supported Platforms -> A channel is a model for interprocess communication and synchronization via -> message passing. A message may be sent over a channel, and another process or -> thread is able to receive messages sent over a channel it has a reference to, -> as a stream. Different implementations of channels may be buffered or not, -> and either synchronous or asynchronous. - -Frequenz Channels are mostly designed after [Go -channels](https://tour.golang.org/concurrency/2) but it also borrows ideas from -[Rust channels](https://doc.rust-lang.org/book/ch16-02-message-passing.html). +{% + include-markdown "../README.md" + start="" + end="" +%} ## Installation @@ -77,5 +77,5 @@ $ python3 Python 3.11.4 (main, Jun 7 2023, 10:13:09) [GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import frequenz.channels ->>> +>>> ``` diff --git a/mkdocs.yml b/mkdocs.yml index 4fce883f..c184f59c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -133,3 +133,4 @@ plugins: watch: - "src" - CONTRIBUTING.md + - README.md