--error-stale-baseline fails when a baseline entry's file is gone$ mkdir -p $TMPDIR/baseline_error_stale && \ > echo "x: str = 1" > $TMPDIR/baseline_error_stale/bad.py && \ > echo '{"errors": [{"line": 1, "column": 10, "stop_line": 1, "stop_column": 11, "path": "bad.py", "code": -2, "name": "bad-assignment", "description": "test", "concise_description": "test"}, {"line": 1, "column": 1, "stop_line": 1, "stop_column": 2, "path": "gone.py", "code": -2, "name": "bad-return", "description": "test", "concise_description": "test"}]}' > $TMPDIR/baseline_error_stale/baseline.json && \ > touch $TMPDIR/baseline_error_stale/pyrefly.toml && \ > cd $TMPDIR/baseline_error_stale && \ > $PYREFLY check bad.py --baseline=baseline.json --error-stale-baseline --summary=none ERROR Baseline file has 1 unused suppression; rerun with `--prune-baseline` to update it [1]
--error-stale-baseline succeeds when every baseline entry still matches$ mkdir -p $TMPDIR/baseline_error_stale_clean && \ > echo "x: str = 1" > $TMPDIR/baseline_error_stale_clean/bad.py && \ > echo '{"errors": [{"line": 1, "column": 10, "stop_line": 1, "stop_column": 11, "path": "bad.py", "code": -2, "name": "bad-assignment", "description": "test", "concise_description": "test"}]}' > $TMPDIR/baseline_error_stale_clean/baseline.json && \ > touch $TMPDIR/baseline_error_stale_clean/pyrefly.toml && \ > cd $TMPDIR/baseline_error_stale_clean && \ > $PYREFLY check bad.py --baseline=baseline.json --error-stale-baseline --summary=none [0]
$ mkdir -p $TMPDIR/baseline_checked_fixed && \ > echo "x: str = 'fixed'" > $TMPDIR/baseline_checked_fixed/fixed.py && \ > echo '{"errors": [{"column": 10, "path": "fixed.py", "name": "bad-assignment", "concise_description": "test"}]}' > $TMPDIR/baseline_checked_fixed/baseline.json && \ > touch $TMPDIR/baseline_checked_fixed/pyrefly.toml && \ > cd $TMPDIR/baseline_checked_fixed && \ > $PYREFLY check fixed.py --baseline=baseline.json --error-stale-baseline --summary=none ERROR Baseline file has 1 unused suppression; rerun with `--prune-baseline` to update it [1]
$ mkdir -p $TMPDIR/baseline_narrowed && \ > echo "x: str = 1" > $TMPDIR/baseline_narrowed/checked.py && \ > touch $TMPDIR/baseline_narrowed/unchecked.py $TMPDIR/baseline_narrowed/pyrefly.toml && \ > echo '{"errors": [{"column": 10, "path": "checked.py", "name": "bad-assignment", "concise_description": "checked"}, {"column": 1, "path": "unchecked.py", "name": "bad-return", "concise_description": "unchecked"}]}' > $TMPDIR/baseline_narrowed/baseline.json && \ > cd $TMPDIR/baseline_narrowed && \ > $PYREFLY check checked.py --baseline=baseline.json --prune-baseline --summary=none INFO Baseline file has no unused suppressions to remove [0]
$ $JQ '.errors | length' $TMPDIR/baseline_narrowed/baseline.json 2 [0]
--prune-baseline drops stale entries without recording new errors$ mkdir -p $TMPDIR/baseline_prune && \ > printf 'x: str = 1\nyyyy: int = ""\n' > $TMPDIR/baseline_prune/bad.py && \ > echo '{"errors": [{"line": 1, "column": 10, "stop_line": 1, "stop_column": 11, "path": "bad.py", "code": -2, "name": "bad-assignment", "description": "test", "concise_description": "test"}, {"line": 1, "column": 1, "stop_line": 1, "stop_column": 2, "path": "gone.py", "code": -2, "name": "bad-return", "description": "test", "concise_description": "test"}]}' > $TMPDIR/baseline_prune/baseline.json && \ > touch $TMPDIR/baseline_prune/pyrefly.toml && \ > cd $TMPDIR/baseline_prune && \ > $PYREFLY check bad.py --baseline=baseline.json --prune-baseline --summary=none --output-format=omit-errors INFO Removed 1 unused suppression from the baseline file [1]
The still-matching entry is kept, and the new error on line 2 is not added.
$ grep -c '"name":' $TMPDIR/baseline_prune/baseline.json 1 [0]
The surviving entry keeps its existing concise description rather than refreshing it from the current error.
$ grep -c '"concise_description": "test"' $TMPDIR/baseline_prune/baseline.json 1 [0]
--prune-baseline does not apply baseline-formatChanging the configured format from full to minimal does not change the fields of retained entries while pruning.
$ mkdir -p $TMPDIR/baseline_prune_full && \ > echo 'x: str = 1' > $TMPDIR/baseline_prune_full/bad.py && \ > echo '{"errors":[{"column":10,"path":"bad.py","name":"bad-assignment","concise_description":"test","severity":"error"},{"column":1,"path":"gone.py","name":"bad-return","concise_description":"stale","severity":"error"}]}' > $TMPDIR/baseline_prune_full/baseline.json && \ > printf 'baseline = "baseline.json"\nbaseline-format = "minimal"\n' > $TMPDIR/baseline_prune_full/pyrefly.toml && \ > cd $TMPDIR/baseline_prune_full && \ > $PYREFLY check bad.py --prune-baseline --summary=none --output-format=omit-errors >/dev/null 2>/dev/null && \ > $JQ -c '.errors[0] | keys' baseline.json ["column","concise_description","name","path","severity"] [0]
Changing the configured format from minimal to full likewise leaves the fields of retained entries minimal.
$ mkdir -p $TMPDIR/baseline_prune_minimal && \ > echo 'x: str = 1' > $TMPDIR/baseline_prune_minimal/bad.py && \ > echo '{"errors":[{"column":10,"path":"bad.py","name":"bad-assignment"},{"column":1,"path":"gone.py","name":"bad-return"}]}' > $TMPDIR/baseline_prune_minimal/baseline.json && \ > printf 'baseline = "baseline.json"\nbaseline-format = "full"\n' > $TMPDIR/baseline_prune_minimal/pyrefly.toml && \ > cd $TMPDIR/baseline_prune_minimal && \ > $PYREFLY check bad.py --prune-baseline --summary=none --output-format=omit-errors >/dev/null 2>/dev/null && \ > $JQ -c '.errors[0] | keys' baseline.json ["column","name","path"] [0]
--min-severity--prune-baseline only removes entries whose diagnostics no longer occur. In contrast, --update-baseline regenerates the file using the severity threshold.
$ mkdir -p $TMPDIR/baseline_hidden_warning && \ > echo "x: str = 1" > $TMPDIR/baseline_hidden_warning/bad.py && \ > echo '{"errors": [{"column": 10, "path": "bad.py", "name": "bad-assignment", "concise_description": "test"}]}' > $TMPDIR/baseline_hidden_warning/baseline.json && \ > touch $TMPDIR/baseline_hidden_warning/pyrefly.toml && \ > cd $TMPDIR/baseline_hidden_warning && \ > $PYREFLY check bad.py --warn=bad-assignment --baseline=baseline.json --prune-baseline --summary=none INFO Baseline file has no unused suppressions to remove [0]
--error-stale-baseline$ mkdir -p $TMPDIR/baseline_broken && \ > echo "x: str = 1" > $TMPDIR/baseline_broken/bad.py && \ > echo 'not valid json' > $TMPDIR/baseline_broken/baseline.json && \ > touch $TMPDIR/baseline_broken/pyrefly.toml && \ > cd $TMPDIR/baseline_broken && \ > $PYREFLY check bad.py --baseline=baseline.json --error-stale-baseline --summary=none *failed to read baseline file*baseline.json* (glob) [1]
--error-stale-baseline instead of silently passing$ mkdir -p $TMPDIR/baseline_missing_stale && \ > echo "x: str = 1" > $TMPDIR/baseline_missing_stale/bad.py && \ > touch $TMPDIR/baseline_missing_stale/pyrefly.toml && \ > cd $TMPDIR/baseline_missing_stale && \ > $PYREFLY check bad.py --baseline=missing.json --error-stale-baseline --summary=none *requires an existing baseline file*missing.json*does not exist* (glob) [1]
--prune-baseline instead of silently passing$ mkdir -p $TMPDIR/baseline_missing_prune && \ > echo "x: str = 1" > $TMPDIR/baseline_missing_prune/bad.py && \ > touch $TMPDIR/baseline_missing_prune/pyrefly.toml && \ > cd $TMPDIR/baseline_missing_prune && \ > $PYREFLY check bad.py --baseline=missing.json --prune-baseline --summary=none *requires an existing baseline file*missing.json*does not exist* (glob) [1]
$ cd $TMPDIR/baseline_prune && $PYREFLY check --prune-baseline --update-baseline error: the argument '--prune-baseline' cannot be used with '--update-baseline' Usage: pyrefly check --prune-baseline [FILES]... For more information, try '--help'. [2]