diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a67b539..cf3da74d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,11 @@ 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. + The previous behavior can be restored via `--fail-on-warnings` + (currently only effective for PEtab v2) + (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/569) * Several fixes to `assignments_to_experiments`: keep a switch at the start of a later period, keep the condition changes of symbols that the model still uses elsewhere, evaluate a condition change once at the start of its diff --git a/petab/petablint.py b/petab/petablint.py index 6ff52826..4c03b172 100755 --- a/petab/petablint.py +++ b/petab/petablint.py @@ -53,6 +53,14 @@ def parse_cli_args(): action="store_true", help="More verbose output", ) + parser.add_argument( + "--fail-on-warnings", + dest="fail_on_warnings", + action="store_true", + help="Exit with a non-zero status also if there are only warnings. " + "Currently only supported for PEtab v2 problems; " + "has no effect for PEtab v1.", + ) # Call with set of files group = parser.add_argument_group( @@ -194,13 +202,24 @@ def main(): ret = petab.lint.lint_problem(problem) sys.exit(ret) case 2: - from petab.v2.lint import lint_problem + from petab.v2.lint import ( + ValidationIssueSeverity, + lint_problem, + ) + fail_level = ( + ValidationIssueSeverity.WARNING + if args.fail_on_warnings + else ValidationIssueSeverity.ERROR + ) 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 any( + issue.level >= fail_level + for issue in validation_issues + ): 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 67042bb1..5509b9e4 100644 --- a/tests/v2/test_core.py +++ b/tests/v2/test_core.py @@ -1052,6 +1052,48 @@ 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 + + # ... unless requested + result = subprocess.run( # noqa S607 + [ # noqa: S607 + "petablint", + "--fail-on-warnings", + str(Path(tmpdir, "problem.yaml")), + ], + capture_output=True, + text=True, + ) + assert result.returncode == 1 + 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."""