From cacd2c13a719157d3a6ef0955995abdcfea194a0 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 21 Oct 2026 20:51:45 +0200 Subject: [PATCH] Don't fail `petablint` for PEtab v2 problems with only warnings For PEtab v2 problems, `petablint` exited with 1 for any validation issue, including warnings. Now it reports all issues but only fails if there are errors, consistent with PEtab v1. Closes #567. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 3 +++ petab/petablint.py | 6 +++--- tests/v2/test_core.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e818060..e13a4fa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,9 @@ that PEtab condition changes are applied before its assignments. Previously, their order was undefined (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/562) +* `petablint` no longer fails for PEtab v2 problems with only warnings, + consistent with PEtab v1. Warnings are still reported + (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/569) **Features** * `petab1to2` and `petab_files_1to2` can skip validation via `validate=False` diff --git a/petab/petablint.py b/petab/petablint.py index 6ff52826..b5260d19 100755 --- a/petab/petablint.py +++ b/petab/petablint.py @@ -198,9 +198,9 @@ def main(): try: validation_issues = lint_problem(args.yaml_file_name) - if validation_issues: - # Handle petab.v2.lint.ValidationTask issues - validation_issues.log(logger=logger) + # Handle petab.v2.lint.ValidationTask issues + validation_issues.log(logger=logger) + if validation_issues.has_errors(): sys.exit(1) logger.info("PEtab format check completed successfully.") sys.exit(0) diff --git a/tests/v2/test_core.py b/tests/v2/test_core.py index 5f95ed15..f1975cd2 100644 --- a/tests/v2/test_core.py +++ b/tests/v2/test_core.py @@ -1044,6 +1044,35 @@ def test_petablint_v2(tmpdir): check=True, ) + # warnings are reported, but don't make petablint fail + problem.add_condition("unused_condition", B=1) + problem.condition_tables[0].rel_path = "conditions.tsv" + problem.config.condition_files = ["conditions.tsv"] + issues = problem.validate() + assert issues + assert not issues.has_errors() + problem.to_files(Path(tmpdir)) + result = subprocess.run( # noqa S607 + ["petablint", str(Path(tmpdir, "problem.yaml"))], # noqa S607 + capture_output=True, + text=True, + ) + assert result.returncode == 0 + assert "CheckUnusedConditions" in result.stdout + result.stderr + + # errors make petablint fail + problem.add_measurement( + "obs_undefined", time=10, measurement=2.5, experiment_id="" + ) + assert problem.validate().has_errors() + problem.to_files(Path(tmpdir)) + result = subprocess.run( # noqa S607 + ["petablint", str(Path(tmpdir, "problem.yaml"))], # noqa S607 + capture_output=True, + text=True, + ) + assert result.returncode == 1 + def test_problem_id(tmpdir): """Test that the problem ID works as expected."""