diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ac1a1c98..f88f4119 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,7 +2,7 @@ ## Summary - +This release introduces a new MkDocs macros *pluglet* system that simplifies documentation setup and provides enhanced functionality for version information and code annotations. It also includes changes to how pytest warnings are handled in templates. ## Upgrading @@ -15,13 +15,21 @@ ### Cookiecutter template -All upgrading should be done via the migration script or regenerating the templates. But you might still need to adapt your code: +All upgrading should be done via the migration script or regenerating the templates. + +```bash +curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/v0.12/cookiecutter/migrate.py | python3 +``` + +But you might still need to adapt your code: - `pytest` now uses `-Werror` by default (but still treat deprecations as normal warnings), so if your tests run with warnings, they will now be turned to errors, and you'll need to fix them. +- Projects using `docs/_scripts/macros.py` with customized scripts can use the new provided utility functions. See the [`mkdocstrings_macros` documentation](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/) for the new features and setup. + ## New Features - +- Two new modules were introduced to facilitate the configuration of `macros` for use within docstrings via `mkdocstrings`: [`mkdocstrings_macros`](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/) and [`annotations`](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/annotations/). ### Cookiecutter template @@ -29,8 +37,6 @@ All upgrading should be done via the migration script or regenerating the templa ## Bug Fixes - - ### Cookiecutter template - Fixed a compatibility issue in the macros doc script with `mkdocsstrings` 0.28. diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py index a20ca6da..de0f83ae 100644 --- a/cookiecutter/migrate.py +++ b/cookiecutter/migrate.py @@ -20,6 +20,7 @@ And remember to follow any manual instructions for each run. """ # noqa: E501 +import hashlib import os import subprocess import tempfile @@ -30,8 +31,8 @@ def main() -> None: """Run the migration steps.""" add_default_pytest_options() - - # Add a separation line like this one after each migration step. + print("=" * 72) + migrate_mkdocs_macros() print("=" * 72) @@ -64,6 +65,92 @@ def add_default_pytest_options() -> None: ) +def migrate_mkdocs_macros() -> None: + """Migrate from custom macros.py to standard module.""" + macros_file = Path("docs/_scripts/macros.py") + mkdocs_yaml = Path("mkdocs.yaml") + if not mkdocs_yaml.exists(): + mkdocs_yaml = Path("mkdocs.yml") + + known_hashes = { + "47a991286132471b6cb666577beb89e78c0f5d4975c53f0dcb319c4338a2c3cb", + "6bb960c72b370ac77918f49d7a35f39c0ddb58fe52cf2d12caa2577098fd8469", + "7351276ac314955a343bab09d1602e50300887291f841643e9fb79c94acc923c", + "8fa5f9f3fd928e17f590e3ab056434474633259d615971404db0d2f3034adb62", + "ba3ff5f1612b3dd22372a8ca95394b8ea468f18dcefc494c73811c8433fcb880", + "dd32e8759abc43232bb3db5b33c0a7cf8d8442db6135c594968c499d8bae0ce5", + } + + print("Checking if docs/_scripts/macros.py can be migrated...") + + file_hash = calculate_file_sha256_skip_lines(macros_file, 2) + if not file_hash: + return + + if file_hash not in known_hashes: + manual_step("The macros.py file seems to be customized. You have two options:") + manual_step("") + manual_step( + "1. Switch to the standard module (if you don't have custom macros):" + ) + manual_step(" a. Update mkdocs.yaml to use the standard module:") + manual_step( + ' module_name: docs/_scripts/macros -> modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]' # noqa: E501 + ) + manual_step(" b. Remove docs/_scripts/macros.py") + manual_step("") + manual_step("2. Keep your custom macros but use the standard functionality:") + manual_step(" a. Update mkdocs.yaml:") + manual_step(" - Keep using module_name: docs/_scripts/macros") + manual_step(" b. Update your macros.py to be minimal:") + manual_step(" ```python") + manual_step( + " from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything" # noqa: E501 + ) + manual_step("") + manual_step(" def define_env(env):") + manual_step(" # Add your custom variables, filters, and macros here") + manual_step(" env.variables.my_var = 'Example'") + manual_step(" env.filters.my_filter = lambda x: x.upper()") + manual_step("") + manual_step( + " # This must be at the end to enable all standard features" + ) + manual_step(" hook_env_with_everything(env)") + manual_step(" ```") + manual_step("") + manual_step("See the docs for more details:") + manual_step( + "https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/" # noqa: E501 + ) + return + + if not mkdocs_yaml.exists(): + print("mkdocs.yaml/yml not found, skipping macros migration") + return + + content = mkdocs_yaml.read_text(encoding="utf-8") + if "module_name: docs/_scripts/macros" not in content: + print("Custom macros configuration not found in mkdocs.yaml") + return + + print("Updating mkdocs.yaml to use standard module...") + new_content = content.replace( + "module_name: docs/_scripts/macros", + 'modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]', + ) + new_content = new_content.replace( + "# inside docstrings. See the comment in `docs/_scripts/macros.py` for more\n" + " # details\n", + "# inside docstrings.\n", + ) + + replace_file_contents_atomically(mkdocs_yaml, content, new_content) + + print("Removing docs/_scripts/macros.py...") + macros_file.unlink() + + def apply_patch(patch_content: str) -> None: """Apply a patch using the patch utility.""" subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True) @@ -134,5 +221,25 @@ def manual_step(message: str) -> None: print(f"\033[0;33m>>> {message}\033[0m") +def calculate_file_sha256_skip_lines(filepath: Path, skip_lines: int) -> str | None: + """Calculate SHA256 of file contents excluding the first N lines. + + Args: + filepath: Path to the file to hash + skip_lines: Number of lines to skip at the beginning + + Returns: + The SHA256 hex digest, or None if the file doesn't exist + """ + if not filepath.exists(): + return None + + # Read file and normalize line endings to LF + content = filepath.read_text(encoding="utf-8").replace("\r\n", "\n") + # Skip first N lines and ensure there's a trailing newline + remaining_content = "\n".join(content.splitlines()[skip_lines:]) + "\n" + return hashlib.sha256(remaining_content.encode()).hexdigest() + + if __name__ == "__main__": main() diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py b/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py deleted file mode 100644 index 9afe325c..00000000 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: {{cookiecutter.license}} -# Copyright © {{copyright_year}} {{cookiecutter.author_name}} - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml index 4110b297..2bb2105b 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml @@ -129,10 +129,9 @@ plugins: {%- endif %} - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index 4f95d637..7b254021 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -3,17 +3,17 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0", {%- if cookiecutter.type == "api" %} # We need to pin the protobuf, grpcio and grpcio-tools dependencies to make # sure the code is generated using the minimum supported versions, as older # versions can't work with code that was generated with newer versions. # https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards - "protobuf == 5.28.0", - "grpcio-tools == 1.66.1", - "grpcio == 1.66.1", + "protobuf == 5.29.3", + "grpcio-tools == 1.70.0", + "grpcio == 1.70.0", {%- endif %} ] build-backend = "setuptools.build_meta" @@ -48,7 +48,7 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", + "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600", ] {%- elif cookiecutter.type == "app" %} dependencies = [ @@ -56,19 +56,19 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 1.0.0rc1300", + "frequenz-sdk == 1.0.0rc1500", ] {%- elif cookiecutter.type == "api" %} dependencies = [ - "frequenz-api-common >= 0.6.2, < 0.7.0", + "frequenz-api-common >= 0.6.3, < 0.7.0", # We can't widen beyond the current value unless we bump the minimum # requirements too because of protobuf cross-version runtime guarantees: # https://protobuf.dev/support/cross-version-runtime-guarantee/#major - "protobuf >= 5.28.0, < 7", # Do not widen beyond 7! + "protobuf >= 5.29.3, < 7", # Do not widen beyond 7! # We couldn't find any document with a spec about the cross-version runtime # guarantee for grpcio, so unless we find one in the future, we'll assume # major version jumps are not compatible - "grpcio >= 1.66.1, < 2", # Do not widen beyond 2! + "grpcio >= 1.70.0, < 2", # Do not widen beyond 2! ] {%- else %} dependencies = [ @@ -87,34 +87,34 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", {%- if cookiecutter.type == "api" %} - "grpc-stubs == 1.53.0.2", + "grpc-stubs == 1.53.0.5", {%- endif %} - "types-Markdown == 3.7.0.20240822", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0", + "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -122,13 +122,13 @@ dev-pylint = [ "{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", {%- if cookiecutter.type != "api" %} "pytest-mock == 3.14.0", - "pytest-asyncio == 0.24.0", - "async-solipsism == 0.6", + "pytest-asyncio == 0.25.3", + "async-solipsism == 0.7", {%- endif %} ] dev = [ diff --git a/docs/_scripts/macros.py b/docs/_scripts/macros.py deleted file mode 100644 index 82d79d7d..00000000 --- a/docs/_scripts/macros.py +++ /dev/null @@ -1,108 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -import logging -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -from frequenz.repo.config import github - -_logger = logging.getLogger(__name__) - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _add_version_variables(env: macros.MacrosPlugin) -> None: - """Add variables with git information to the environment. - - Args: - env: The environment to add the variables to. - """ - env.variables["version"] = None - env.variables["version_requirement"] = "" - try: - version_info = github.get_repo_version_info() - except Exception as exc: # pylint: disable=broad-except - _logger.warning("Failed to get version info: %s", exc) - else: - env.variables["version"] = version_info - if version_info.current_tag: - env.variables["version_requirement"] = f" == {version_info.current_tag}" - elif version_info.current_branch: - env.variables["version_requirement"] = ( - " @ git+https://github.com/frequenz-floss/frequenz-repo-config-python" - f"@{version_info.current_branch}" - ) - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - _add_version_variables(env) - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/mkdocs.yml b/mkdocs.yml index b26e85f6..f9a0397a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -124,10 +124,9 @@ plugins: - https://sybil.readthedocs.io/en/stable/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/src/frequenz/repo/config/mkdocs/annotations.py b/src/frequenz/repo/config/mkdocs/annotations.py new file mode 100644 index 00000000..08e0e7db --- /dev/null +++ b/src/frequenz/repo/config/mkdocs/annotations.py @@ -0,0 +1,80 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Code annotations using numbers. + +This module is provided almost exclusively as a documentation source. + +# Introduction + +Normally annotations are shown with a `(+)` button that expands the annotation. To be +able to explain code step by step, it is good to have annotations with numbers, shown as +`(1)`, `(2)`, etc., to be able to follow the notes in a particular order. + +To do this, we need some custom CSS rules. Before this customization was officially +supported and documented, but now they are not officially supported anymore, so it could +eventually break (it already did once). + +If that happens we either need to look into how to fix the CSS ourselves or remove the +feature. To do the customization, this is what we should be able to count on: + +> You can be sure that the data-md-annotation-id attribute will always be present in the +> source, which means you can always number them in any way you like. + +# How to implement it + +To implement numbered annotations, you need to add a custom CSS file to your +`mkdocs.yml` configuration file: + +```yaml title="mkdocs.yml" +extra_css: + - path/to/style.css +``` + +The CSS file should contain the following rules: + +```css title="path/to/style.css" +.md-typeset .md-annotation__index > ::before { + content: attr(data-md-annotation-id); +} +.md-typeset :focus-within > .md-annotation__index > ::before { + transform: none; +} +.md-typeset .md-annotation__index { + width: 4ch; +} +``` + +# Macros integration + +If you want to show an example on how an annotation looks like, you can use the +[`CODE_ANNOTATION_MARKER`][frequenz.repo.config.mkdocs.annotations.CODE_ANNOTATION_MARKER] +variable to inject the appropriate HTML code. See +[frequenz.repo.config.mkdocs.mkdocstrings_macros][] for more information. + +# References + +* [Code annotation in + `mkdocs-material`](https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#code-annotations) + +* [Original docs on how to enable numbered + annotations](https://web.archive.org/web/20230724161216/https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#annotations-with-numbers) + +* [The PR fixing the numbered annotations when they + broke](https://github.com/frequenz-floss/frequenz-sdk-python/pull/684) + +* [The regression reported when it was decided to drop support for numbered annotations + officially](https://github.com/squidfunk/mkdocs-material/issues/6042) + +* [The `sphinx-immaterial` documentation on how to do numbered + annotations](https://sphinx-immaterial.readthedocs.io/en/latest/code_annotations.html#annotation-buttons-with-numbers) +""" + +CODE_ANNOTATION_MARKER: str = ( + r'' + r'' + r'' + r"" + r"" +) +"""A variable to easily show an example code annotation.""" diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py new file mode 100644 index 00000000..82e4f78f --- /dev/null +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -0,0 +1,261 @@ +# License: MIT +# Copyright © 2025 Frequenz Energy-as-a-Service GmbH + +"""Integration between `mkdocstrings` and `macros` extensions to work together. + +# Introduction + +To be able to use macros inside docstrings, we need to integrate the `mkdocs-macros` +extension into `mkdocstrings`. This module provides the necessary functions to make this +integration work. + + +# Basic usage + +If you don't want to define your own macros, variables or filters, you can use this +module as a [pluglet](https://mkdocs-macros-plugin.readthedocs.io/en/latest/pluglets/): + +```yaml title="mkdocs.yml" +plugins: + # Order is important! mkdocstrings must come before macros! + - mkdocstrings: + default_handler: python + # ... + - macros: + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] + on_undefined: strict + on_error_fail: true +``` + +This will do the hooking and provide some useful variables and filters: + +* [`slugify`][frequenz.repo.config.mkdocs.mkdocstrings_macros.slugify]: A filter to + slugify a text. Useful to generate anchors for headings. +* [`code_annotation_marker`]: A variable to inject the appropriate HTML code for showing + an example code annotation as a number (see + [frequenz.repo.config.mkdocs.annotations][] for more information). +* [`version`]: A varaible with the version information of the repository as exposed by + [`get_repo_version_info()`][frequenz.repo.config.github.get_repo_version_info], + which means some environment variables are required (this variable will be `None` + otherwise), please read the function documentation for more details. +* [`version_requirement`]: A variable with the version requirement for the current + version of the repository. It is built using the information from `version`. Also + only available if the rigth environment variables are set, and if the resulting + version is a tag (will be empty for branches). If you want to get the version + requirement for a branch, you need to provide a `repo_url` variable in the + `mkdocs.yaml` file or do a custom setup. Please read the [Customized usage] + section for more details. + + +# Customized usage + +If you want to define your own macros, variables or filters, but you also want to get +the default behaviour described in [Basic usage], you need to provide your own [macros +module](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/) with +a `define_env()` function. You can specify it in the `mkdocs.yml` configuration file: + +```yaml title="mkdocs.yml" +plugins: + # Order is important! mkdocstrings must come before macros! + - mkdocstrings: + default_handler: python + # ... + - macros: + module_name: "path/to/macros" # Note: no .py extension here! + on_undefined: strict + on_error_fail: true +``` + +Then you need to add the `define_env()` function to the `path/to/macros.py` file. +A convenience [`hook_env_with_everything()`] is provided to pull all the same default +variables and filters and call the hooking function at the end as with the *pluglet*. + +You also need to make sure to call the function at the end, after you define your own +variables, filters and macros. You can optionally pass a `repo_url` in this case so the +`version_requirement` variable can work when the current version is a branch. If a +`repo_url` variable is present in the `mkdocs.yml` file, it will be used as the default. + +Here is an example of how to do it: + +```py title="path/to/macros.py" +from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything + +def define_env(env: macros.MacrosPlugin) -> None: + env.variables.my_var = "Example" + + # This hook needs to be done at the end of the `define_env` function. + hook_env_with_everything(env, "https://your-repo-url") +``` + +# Advanced usage + +If you don't want to pull in all the default variables and filters, you can still define +your own `define_env()` function and do the same configuration in the `mkdocs.yml` file +as in the [Customized usage] section, but instead call the +[`hook_macros_plugin()`][frequenz.repo.config.mkdocs.mkdocstrings_macros.hook_macros_plugin] +at the end. + +Here is an example of how to do it: + +```py title="path/to/macros.py" +from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_macros_plugin + +def define_env(env: macros.MacrosPlugin) -> None: + env.variables.my_var = "Example" + + # This hook needs to be done at the end of the `define_env` function. + hook_macros_plugin(env) +``` +""" + + +import logging +from typing import Any + +import markdown as md +from markdown.extensions import toc +from mkdocs_macros import plugin as macros + +from ..github import get_repo_version_info +from .annotations import CODE_ANNOTATION_MARKER + +_logger = logging.getLogger(__name__) + + +def slugify(text: str) -> str: + """Slugify a text. + + Useful to generate anchors for headings. + + Example: + ```markdown + Some URL: https://example.com/#{{ "My Heading" | slugify }}. + ``` + + Args: + text: The text to slugify. + + Returns: + The slugified text. + """ + return toc.slugify_unicode(text, "-") + + +def add_version_variables( + env: macros.MacrosPlugin, *, repo_url: str | None = None +) -> None: + """Add variables with git information to the environment. + + This function will add 2 new macro variables to `env`: + + * [`version`]: A varaible with the version information of the repository as exposed by + [`get_repo_version_info()`][frequenz.repo.config.github.get_repo_version_info], + which means some environment variables are required (this variable will be `None` + otherwise), please read the function documentation for more details. + * [`version_requirement`]: A variable with the version requirement for the current + version of the repository. It is built using the information from `version`. Also + only available if the rigth environment variables are set, and if the resulting + version is a tag (will be empty for branches). If you want to get the version + requirement for a branch, you need to provide a `repo_url` or a `repo_url` + config in the `mkdocs.yml` file. + + Args: + env: The environment to add the variables to. + repo_url: The URL of the repository to use in the `version_requirement` + variable. If `None` the `config.repo_url` mkdocs variable will be used. Only + needed if you want to use the `version_requirement` variable for branches. + """ + env.variables["version"] = None + env.variables["version_requirement"] = "" + + if repo_url is None: + repo_url = env.variables.get("config", {}).get("repo_url") + if repo_url is None: + _logger.warning( + "No repo_url provided, can't build the 'version_requirement' variable" + ) + + version_info = None + try: + version_info = get_repo_version_info() + except Exception as exc: # pylint: disable=broad-except + _logger.warning("Failed to get version info: %s", exc) + else: + env.variables["version"] = version_info + if version_info.current_tag: + env.variables["version_requirement"] = f" == {version_info.current_tag}" + + ref = None + if version_info is not None: + ref = version_info.current_branch or version_info.sha + ref = ref or env.variables.get("git", {}).get("commit") + if ref and repo_url is not None: + env.variables["version_requirement"] = f" @ git+{repo_url}@{ref}" + + +def hook_macros_plugin(env: macros.MacrosPlugin) -> None: + """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. + + This is a temporary workaround to make `mkdocs-macros` work with + `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See + https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. + + Args: + env: The environment to hook the plugin into. + """ + # get mkdocstrings' Python handler + python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") + + # get the `update_env` method of the Python handler + update_env = python_handler.update_env + + # override the `update_env` method of the Python handler + def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: + update_env(md, config) + + # get the `convert_markdown` filter of the env + convert_markdown = python_handler.env.filters["convert_markdown"] + + # build a chimera made of macros+mkdocstrings + def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: + return convert_markdown(env.render(markdown), *args, **kwargs) + + # patch the filter + python_handler.env.filters["convert_markdown"] = render_convert + + # patch the method + python_handler.update_env = patched_update_env + + +def hook_env_with_everything( + env: macros.MacrosPlugin, *, repo_url: str | None = None +) -> None: + """Hooks the `env` with all the default variables and filters. + + This function is a convenience function that adds all variables and filters and + macros provided by this module and calls + [`hook_macros_plugin()`][frequenz.repo.config.mkdocs.mkdocstrings_macros.hook_macros_plugin] + at the end. + + Args: + env: The environment to hook. + repo_url: The URL of the repository to use in the `version_requirement` + variable. If `None` the `config.repo_url` mkdocs variable will be used. Only + needed if you want to use the `version_requirement` variable for branches. + """ + env.variables.code_annotation_marker = CODE_ANNOTATION_MARKER + add_version_variables(env, repo_url=repo_url) + + env.filter(slugify, "slugify") # type: ignore[no-untyped-call] + + # This hook needs to be done at the end of the `define_env` function. + hook_macros_plugin(env) + + +def define_env(env: macros.MacrosPlugin) -> None: + """Define the hook to create macro functions for use in Markdown. + + Args: + env: The environment to define the macro functions in. + """ + hook_env_with_everything(env) diff --git a/src/frequenz/repo/config/version.py b/src/frequenz/repo/config/version.py index 39fed3ba..2acf96e0 100644 --- a/src/frequenz/repo/config/version.py +++ b/src/frequenz/repo/config/version.py @@ -516,3 +516,10 @@ def is_branch_latest(self) -> bool: ) return False return branch == latest[0] + + def __repr__(self) -> str: + """Return a string representation of the object.""" + return ( + f"{self.__class__.__name__}(sha={self._sha!r}, ref={self._ref!r}, " + f"tags={self._tags!r}, branches={self._branches!r})" + ) diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt index f4aaaaa2..8371360e 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt @@ -12,7 +12,6 @@ ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./CODEOWNERS:* TODO(cookiecutter): Add codeowners (like @{github_org}/some-team)# Temporary, should probably change ./README.md:TODO(cookiecutter): Improve the README file -./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py deleted file mode 100644 index 2ae42657..00000000 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml index b15eefcd..95d90c78 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml @@ -124,10 +124,9 @@ plugins: - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml index 336868e5..5a6009b4 100644 --- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[actor] == 0.11.0", + "frequenz-repo-config[actor] == 0.12.0", ] build-backend = "setuptools.build_meta" @@ -32,7 +32,7 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", + "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600", ] dynamic = ["version"] @@ -46,31 +46,31 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[actor] == 0.11.0", + "frequenz-repo-config[actor] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.7.0.20240822", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[actor] == 0.11.0", + "frequenz-repo-config[actor] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -78,12 +78,12 @@ dev-pylint = [ "frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.24.0", - "async-solipsism == 0.6", + "pytest-asyncio == 0.25.3", + "async-solipsism == 0.7", ] dev = [ "frequenz-actor-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", diff --git a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt index 2ec694d7..22c3da3e 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt @@ -12,7 +12,6 @@ ./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file -./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py deleted file mode 100644 index 2ae42657..00000000 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml index f02aa9d9..4c4196ab 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml @@ -124,10 +124,9 @@ plugins: - https://grpc.github.io/grpc/python/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml index 577b2092..05c9e815 100644 --- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml @@ -3,16 +3,16 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[api] == 0.11.0", + "frequenz-repo-config[api] == 0.12.0", # We need to pin the protobuf, grpcio and grpcio-tools dependencies to make # sure the code is generated using the minimum supported versions, as older # versions can't work with code that was generated with newer versions. # https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards - "protobuf == 5.28.0", - "grpcio-tools == 1.66.1", - "grpcio == 1.66.1", + "protobuf == 5.29.3", + "grpcio-tools == 1.70.0", + "grpcio == 1.70.0", ] build-backend = "setuptools.build_meta" @@ -35,15 +35,15 @@ classifiers = [ requires-python = ">= 3.11, < 4" # TODO(cookiecutter): Remove and add more dependencies if appropriate dependencies = [ - "frequenz-api-common >= 0.6.2, < 0.7.0", + "frequenz-api-common >= 0.6.3, < 0.7.0", # We can't widen beyond the current value unless we bump the minimum # requirements too because of protobuf cross-version runtime guarantees: # https://protobuf.dev/support/cross-version-runtime-guarantee/#major - "protobuf >= 5.28.0, < 7", # Do not widen beyond 7! + "protobuf >= 5.29.3, < 7", # Do not widen beyond 7! # We couldn't find any document with a spec about the cross-version runtime # guarantee for grpcio, so unless we find one in the future, we'll assume # major version jumps are not compatible - "grpcio >= 1.66.1, < 2", # Do not widen beyond 2! + "grpcio >= 1.70.0, < 2", # Do not widen beyond 2! ] dynamic = ["version"] @@ -57,32 +57,32 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[api] == 0.11.0", + "frequenz-repo-config[api] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", - "grpc-stubs == 1.53.0.2", - "types-Markdown == 3.7.0.20240822", + "grpc-stubs == 1.53.0.5", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[api] == 0.11.0", + "frequenz-repo-config[api] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -90,9 +90,9 @@ dev-pylint = [ "frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", ] dev = [ "frequenz-api-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", diff --git a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt index 8a5abb01..330fbba1 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt @@ -11,7 +11,6 @@ ./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file -./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py deleted file mode 100644 index 2ae42657..00000000 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml index c5bebc0b..ea2d972f 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml @@ -124,10 +124,9 @@ plugins: - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml index 831d049a..eca37134 100644 --- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[app] == 0.11.0", + "frequenz-repo-config[app] == 0.12.0", ] build-backend = "setuptools.build_meta" @@ -31,7 +31,7 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk == 1.0.0rc1300", + "frequenz-sdk == 1.0.0rc1500", ] dynamic = ["version"] @@ -45,31 +45,31 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[app] == 0.11.0", + "frequenz-repo-config[app] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.7.0.20240822", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[app] == 0.11.0", + "frequenz-repo-config[app] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -77,12 +77,12 @@ dev-pylint = [ "frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.24.0", - "async-solipsism == 0.6", + "pytest-asyncio == 0.25.3", + "async-solipsism == 0.7", ] dev = [ "frequenz-app-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt index 77bc53b5..3cd7667c 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt @@ -11,7 +11,6 @@ ./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file -./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py deleted file mode 100644 index 2ae42657..00000000 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml index 7e268f79..1d4c8edf 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml @@ -122,10 +122,9 @@ plugins: - https://docs.python.org/3/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml index 9dfacc94..be44fd9a 100644 --- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[lib] == 0.11.0", + "frequenz-repo-config[lib] == 0.12.0", ] build-backend = "setuptools.build_meta" @@ -42,31 +42,31 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[lib] == 0.11.0", + "frequenz-repo-config[lib] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.7.0.20240822", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[lib] == 0.11.0", + "frequenz-repo-config[lib] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -74,12 +74,12 @@ dev-pylint = [ "frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.24.0", - "async-solipsism == 0.6", + "pytest-asyncio == 0.25.3", + "async-solipsism == 0.7", ] dev = [ "frequenz-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", diff --git a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt index 0ba3358d..f48384c7 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt +++ b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt @@ -11,7 +11,6 @@ ./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it ./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct ./README.md:TODO(cookiecutter): Improve the README file -./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here. ./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here ./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/" ./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py deleted file mode 100644 index 2ae42657..00000000 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py +++ /dev/null @@ -1,80 +0,0 @@ -# License: MIT -# Copyright © 2023 Frequenz Energy-as-a-Service GmbH - -"""This module defines macros for use in Markdown files.""" - -from typing import Any - -import markdown as md -from markdown.extensions import toc -from mkdocs_macros import plugin as macros - -_CODE_ANNOTATION_MARKER: str = ( - r'' - r'' - r'' - r"" - r"" -) - - -def _slugify(text: str) -> str: - """Slugify a text. - - Args: - text: The text to slugify. - - Returns: - The slugified text. - """ - return toc.slugify_unicode(text, "-") - - -def _hook_macros_plugin(env: macros.MacrosPlugin) -> None: - """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. - - This is a temporary workaround to make `mkdocs-macros` work with - `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See - https://github.com/mkdocstrings/mkdocstrings/issues/615 for details. - - Args: - env: The environment to hook the plugin into. - """ - # get mkdocstrings' Python handler - python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python") - - # get the `update_env` method of the Python handler - update_env = python_handler.update_env - - # override the `update_env` method of the Python handler - def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None: - update_env(md=md, config=config) - - # get the `convert_markdown` filter of the env - convert_markdown = python_handler.env.filters["convert_markdown"] - - # build a chimera made of macros+mkdocstrings - def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: - return convert_markdown(env.render(markdown), *args, **kwargs) - - # patch the filter - python_handler.env.filters["convert_markdown"] = render_convert - - # patch the method - python_handler.update_env = patched_update_env - - -def define_env(env: macros.MacrosPlugin) -> None: - """Define the hook to create macro functions for use in Markdown. - - Args: - env: The environment to define the macro functions in. - """ - # A variable to easily show an example code annotation from mkdocs-material. - # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations - env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER - - # TODO(cookiecutter): Add any other macros, variables and filters here. - - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml index d7d1a203..ade2d5ab 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml @@ -124,10 +124,9 @@ plugins: - https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv - https://typing-extensions.readthedocs.io/en/stable/objects.inv # Note this plugin must be loaded after mkdocstrings to be able to use macros - # inside docstrings. See the comment in `docs/_scripts/macros.py` for more - # details + # inside docstrings. - macros: - module_name: docs/_scripts/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true - search diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml index 3a5021d3..0f9ccb1f 100644 --- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml +++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml @@ -3,9 +3,9 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[model] == 0.11.0", + "frequenz-repo-config[model] == 0.12.0", ] build-backend = "setuptools.build_meta" @@ -32,7 +32,7 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400", + "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600", ] dynamic = ["version"] @@ -46,31 +46,31 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.9", + "pydoclint == 0.6.0", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] +dev-formatting = ["black == 25.1.0", "isort == 6.0.0"] dev-mkdocs = [ "Markdown == 3.7", - "black == 24.10.0", + "black == 25.1.0", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", - "mkdocs-material == 9.5.45", + "mkdocs-material == 9.6.2", "mkdocstrings[python] == 0.28.0", "mkdocstrings-python == 1.14.0", - "frequenz-repo-config[model] == 0.11.0", + "frequenz-repo-config[model] == 0.12.0", ] dev-mypy = [ "mypy == 1.9.0", - "types-Markdown == 3.7.0.20240822", + "types-Markdown == 3.7.0.20241204", # For checking the noxfile, docs/ script, and tests "frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = [ "nox == 2024.10.9", - "frequenz-repo-config[model] == 0.11.0", + "frequenz-repo-config[model] == 0.12.0", ] dev-pylint = [ # dev-pytest already defines a dependency to pylint because of the examples @@ -78,12 +78,12 @@ dev-pylint = [ "frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.3", - "pylint == 3.3.1", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", - "pytest-asyncio == 0.24.0", - "async-solipsism == 0.6", + "pytest-asyncio == 0.25.3", + "async-solipsism == 0.7", ] dev = [ "frequenz-model-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",