diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 680bc45f0..9084d14cf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,40 +13,50 @@ updates: versioning-strategy: auto # Allow up to 10 open pull requests for updates to dependency versions open-pull-requests-limit: 10 - # We group production and development ("optional" in the context of - # pyproject.toml) dependency updates when they are patch and minor updates, - # so we end up with less PRs being generated. - # Major updates are still managed, but they'll create one PR per - # dependency, as major updates are expected to be breaking, it is better to - # manage them individually. + # We group patch updates as they should always work. + # We also group minor updates, as it works too for most libraries, + # typically except libraries that don't have a stable release yet (v0.x.x + # branch), so we make some exceptions for them. + # Major updates and dependencies excluded by the above groups are still + # managed, but they'll create one PR per dependency, as breakage is + # expected, so it might need manual intervention. + # Finally, we group some dependencies that are related to each other, and + # usually need to be updated together. groups: - required: - dependency-type: "production" + patch: update-types: - - "minor" - "patch" exclude-patterns: - - "frequenz-client-microgrid*" - optional: - dependency-type: "development" + # pydoclint has shipped breaking changes in patch updates often + - "pydoclint" + minor: update-types: - "minor" - - "patch" - in-devel-patch: + exclude-patterns: + - "async-solipsism" + - "frequenz-client-microgrid" + - "frequenz-repo-config*" + - "markdown-callouts" + - "mkdocs-gen-files" + - "mkdocs-literate-nav" + - "mkdocstrings*" + - "pydoclint" + - "pytest-asyncio" + # We group repo-config updates as it uses optional dependencies that are + # considered different dependencies otherwise, and will create one PR for + # each if we don't group them. + repo-config: patterns: - - "frequenz-client-microgrid*" - dependency-type: "production" - update-types: - - "patch" + - "frequenz-repo-config*" + mkdocstrings: + patterns: + - "mkdocstrings*" ignore: # Upgrade to time-machine 2.13.0+ breaks our tests. See: # https://github.com/frequenz-floss/frequenz-sdk-python/issues/832 - dependency-name: "time-machine" versions: [">=2.13.0"] - # Upgrading to 0.16.0+ needs a lot of changes in the code. See: - # https://github.com/frequenz-floss/frequenz-sdk-python/issues/844 - - dependency-name: "frequenz-api-microgrid" - versions: [">=0.16.0"] + - package-ecosystem: "github-actions" diff --git a/.github/workflows/ci-pr.yaml b/.github/workflows/ci-pr.yaml index 40614236c..2c74ec0cd 100644 --- a/.github/workflows/ci-pr.yaml +++ b/.github/workflows/ci-pr.yaml @@ -1,6 +1,7 @@ name: Test PR -on: pull_request +on: + pull_request: env: # Please make sure this version is included in the `matrix`, as the diff --git a/.github/workflows/ci-push.yaml b/.github/workflows/ci.yaml similarity index 99% rename from .github/workflows/ci-push.yaml rename to .github/workflows/ci.yaml index cf04303b0..55dddda6d 100644 --- a/.github/workflows/ci-push.yaml +++ b/.github/workflows/ci.yaml @@ -47,8 +47,6 @@ jobs: - name: Run nox uses: frequenz-floss/gh-action-nox@v1.0.0 with: - git-username: ${{ secrets.GIT_USER }} - git-password: ${{ secrets.GIT_PASS }} python-version: ${{ matrix.python }} nox-session: ${{ matrix.nox-session }} diff --git a/docs/_scripts/macros.py b/docs/_scripts/macros.py index 0e0a6ff6c..8023fb24f 100644 --- a/docs/_scripts/macros.py +++ b/docs/_scripts/macros.py @@ -5,65 +5,12 @@ import os import pathlib -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"" +from frequenz.repo.config.mkdocs.mkdocstrings_macros import ( + hook_env_with_everything, + slugify, ) - - -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(markdown: md.Markdown, config: dict[str, Any]) -> None: - update_env(markdown, 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 +from mkdocs_macros import plugin as macros def define_env(env: macros.MacrosPlugin) -> None: @@ -72,9 +19,6 @@ def define_env(env: macros.MacrosPlugin) -> None: 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 @env.macro # type: ignore[misc] def glossary(term: str, text: str | None = None) -> str: @@ -94,7 +38,7 @@ def glossary(term: str, text: str | None = None) -> str: # always the case, for example when referencing the glossary from the API # reference. link_path = os.path.relpath(glossary_path, current_path.parent) - return f"[{text or term}]({link_path}#{_slugify(term)})" + return f"[{text or term}]({link_path}#{slugify(term)})" - # This hook needs to be done at the end of the `define_env` function. - _hook_macros_plugin(env) + # This must be at the end to enable all standard features + hook_env_with_everything(env) diff --git a/pyproject.toml b/pyproject.toml index 7d05e86b4..d82c670bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ requires = [ "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", - "frequenz-repo-config[lib] == 0.11.0", + "frequenz-repo-config[lib] == 0.13.2", ] build-backend = "setuptools.build_meta" @@ -61,9 +61,9 @@ dev-mkdocs = [ "mkdocs-literate-nav == 0.6.1", "mkdocs-macros-plugin == 1.3.7", "mkdocs-material == 9.6.1", - "mkdocstrings[python] == 0.27.0", - "mkdocstrings-python == 1.13.0", - "frequenz-repo-config[lib] == 0.11.0", + "mkdocstrings[python] == 0.29.1", + "mkdocstrings-python == 1.16.10", + "frequenz-repo-config[lib] == 0.13.2", ] dev-mypy = [ "mypy == 1.14.1", @@ -73,7 +73,7 @@ dev-mypy = [ # For checking the noxfile, docs/ script, and tests "frequenz-sdk[dev-mkdocs,dev-noxfile,dev-pytest]", ] -dev-noxfile = ["nox == 2025.2.9", "frequenz-repo-config[lib] == 0.11.0"] +dev-noxfile = ["nox == 2025.2.9", "frequenz-repo-config[lib] == 0.13.2"] dev-pylint = [ "pylint == 3.3.4", # For checking the noxfile, docs/ script, and tests @@ -81,7 +81,7 @@ dev-pylint = [ ] dev-pytest = [ "pytest == 8.3.4", - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.13.2", "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", "time-machine == 2.12.0", @@ -163,6 +163,14 @@ disable = [ max-attributes = 12 [tool.pytest.ini_options] +# We need to ignore PytestUnraisableExceptionWarning because we have some +# cleanup issues, and sometimes exceptions are raised in __del__ methods, for +# example when trying to do async stuff and the event loop is already closed. +# This could even be caused by the GC, some time after the test function that +# has the issue was completed. +# Please see this issue for more details: +# https://github.com/frequenz-floss/frequenz-sdk-python/issues/982 +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -Wdefault::pytest.PytestUnraisableExceptionWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function"