From e11697e6a0598ea500f41b830e390b6aa3bb0cc9 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Fri, 22 Nov 2024 10:16:44 +0100 Subject: [PATCH 1/2] Move `pytest` options to the `pyproject.toml` files It is very difficult to change the options if they are shipped by repo-config, so it is better to put them in the template and leave users the flexibility to change them. Signed-off-by: Leandro Lucarella --- RELEASE_NOTES.md | 9 ++++-- cookiecutter/migrate.py | 28 +++++++++++++++++++ .../pyproject.toml | 1 + pyproject.toml | 1 + src/frequenz/repo/config/nox/default.py | 5 +--- .../actor/frequenz-actor-test/pyproject.toml | 1 + .../app/frequenz-app-test/pyproject.toml | 1 + .../lib/frequenz-test-python/pyproject.toml | 1 + .../model/frequenz-model-test/pyproject.toml | 1 + 9 files changed, 42 insertions(+), 6 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4a01ccc2..e728bffb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,11 +6,16 @@ ## Upgrading - +- The `nox` default `pytest` session doesn't pass `-W=all -vv` to `pytest` anymore. You can use the `pyproject.toml` file to configure default options for `pytest`, for example: + + ```toml + [tool.pytest.ini_options] + addopts = "-W=all -vv" + ``` ### Cookiecutter template - +All upgrading should be done via the migration script or regenerating the templates. ## New Features diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py index c7311177..dfb9e4b4 100644 --- a/cookiecutter/migrate.py +++ b/cookiecutter/migrate.py @@ -29,10 +29,38 @@ def main() -> None: """Run the migration steps.""" + add_default_pytest_options() + # Add a separation line like this one after each migration step. print("=" * 72) +def add_default_pytest_options() -> None: + """Add default pytest options to pyproject.toml.""" + pyproject_toml = Path("pyproject.toml") + pyproject_toml_content = pyproject_toml.read_text(encoding="utf-8") + marker = "[tool.pytest.ini_options]\n" + new_options = "-W=all -vv" + + print(f"Adding default pytest options to {pyproject_toml}...") + if pyproject_toml_content.find(marker) == -1: + print( + "Couldn't find the the {marker.strip()} marker in pyproject.toml, skipping update." + ) + return + + if pyproject_toml_content.find("\naddopts") >= 0: + print("It looks like some options are already configured, skipping update.") + manual_step(f"Please consider `{new_options}` if they are not there yet.") + return + + replace_file_contents_atomically( + pyproject_toml, + marker, + marker + f'addopts = "{new_options}"\n', + ) + + def apply_patch(patch_content: str) -> None: """Apply a patch using the patch utility.""" subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True) diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index 2cdc06b1..40bf6964 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -203,6 +203,7 @@ disable = [ [tool.pytest.ini_options] {%- if cookiecutter.type != "api" %} +addopts = "-W=all -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" diff --git a/pyproject.toml b/pyproject.toml index c76e9b65..e7b7cc49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -205,6 +205,7 @@ module = [ ignore_missing_imports = true [tool.pytest.ini_options] +addopts = "-W=all -vv" testpaths = ["src", "tests"] markers = [ "integration: integration tests (deselect with '-m \"not integration\"')", diff --git a/src/frequenz/repo/config/nox/default.py b/src/frequenz/repo/config/nox/default.py index 40498ce0..65b4d7a3 100644 --- a/src/frequenz/repo/config/nox/default.py +++ b/src/frequenz/repo/config/nox/default.py @@ -36,10 +36,7 @@ "--check", ], mypy=[], - pytest=[ - "-W=all", - "-vv", - ], + pytest=[], ) """Default command-line options for all types of repositories.""" 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 45a10a9c..860c1956 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 @@ -153,6 +153,7 @@ disable = [ ] [tool.pytest.ini_options] +addopts = "-W=all -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 6f21a230..aa080686 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 @@ -152,6 +152,7 @@ disable = [ ] [tool.pytest.ini_options] +addopts = "-W=all -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 a2c6979b..723a3b6c 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 @@ -149,6 +149,7 @@ disable = [ ] [tool.pytest.ini_options] +addopts = "-W=all -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 6e4410d0..3e662c9d 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 @@ -153,6 +153,7 @@ disable = [ ] [tool.pytest.ini_options] +addopts = "-W=all -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" From 47b01439bd198dc20cdf660972737f5c51e74b89 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Fri, 22 Nov 2024 10:18:06 +0100 Subject: [PATCH 2/2] Treat `pytest` warnings as errors Warnings are usually a sign of something that can be improved or even wrong, like tasks not being properly awaited or cancelled, so it's a good idea to treat them as errors to avoid them getting unnoticed. We still treat deprecations as warnings, as when testing with the `pytest_min` session is normal to get deprecation warnings as we are using old versions of dependencies. Signed-off-by: Leandro Lucarella --- RELEASE_NOTES.md | 8 +++++--- cookiecutter/migrate.py | 5 ++++- .../{{cookiecutter.github_repo_name}}/pyproject.toml | 2 +- pyproject.toml | 2 +- .../actor/frequenz-actor-test/pyproject.toml | 2 +- .../app/frequenz-app-test/pyproject.toml | 2 +- .../lib/frequenz-test-python/pyproject.toml | 2 +- .../model/frequenz-model-test/pyproject.toml | 2 +- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e728bffb..c1e64630 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -10,12 +10,14 @@ ```toml [tool.pytest.ini_options] - addopts = "-W=all -vv" + addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" ``` ### Cookiecutter template -All upgrading should be done via the migration script or regenerating the templates. +All upgrading should be done via the migration script or regenerating the templates. 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. ## New Features @@ -23,7 +25,7 @@ All upgrading should be done via the migration script or regenerating the templa ### Cookiecutter template - +- `pytest` now uses `-Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning` by default. Deprecations are still treated as warnings, as when testing with the `pytest_min` session is normal to get deprecation warnings as we are using old versions of dependencies. ## Bug Fixes diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py index dfb9e4b4..a20ca6da 100644 --- a/cookiecutter/migrate.py +++ b/cookiecutter/migrate.py @@ -40,7 +40,10 @@ def add_default_pytest_options() -> None: pyproject_toml = Path("pyproject.toml") pyproject_toml_content = pyproject_toml.read_text(encoding="utf-8") marker = "[tool.pytest.ini_options]\n" - new_options = "-W=all -vv" + new_options = ( + "-W=all Werror -Wdefault::DeprecationWarning " + "-Wdefault::PendingDeprecationWarning -vv" + ) print(f"Adding default pytest options to {pyproject_toml}...") if pyproject_toml_content.find(marker) == -1: diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index 40bf6964..ef45b2ec 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -203,7 +203,7 @@ disable = [ [tool.pytest.ini_options] {%- if cookiecutter.type != "api" %} -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" diff --git a/pyproject.toml b/pyproject.toml index e7b7cc49..e923f004 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -205,7 +205,7 @@ module = [ ignore_missing_imports = true [tool.pytest.ini_options] -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["src", "tests"] markers = [ "integration: integration tests (deselect with '-m \"not integration\"')", 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 860c1956..89fd49dc 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 @@ -153,7 +153,7 @@ disable = [ ] [tool.pytest.ini_options] -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 aa080686..e0da856b 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 @@ -152,7 +152,7 @@ disable = [ ] [tool.pytest.ini_options] -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 723a3b6c..e8e51aff 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 @@ -149,7 +149,7 @@ disable = [ ] [tool.pytest.ini_options] -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" 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 3e662c9d..7fd4d4ef 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 @@ -153,7 +153,7 @@ disable = [ ] [tool.pytest.ini_options] -addopts = "-W=all -vv" +addopts = "-W=all -Werror -Wdefault::DeprecationWarning -Wdefault::PendingDeprecationWarning -vv" testpaths = ["tests", "src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function"