diff --git a/graphify/extract.py b/graphify/extract.py index 3d73ee7d8..dea5bd0b3 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -16254,8 +16254,13 @@ def _extract_parallel( ) return False if total_files >= _PROGRESS_INTERVAL: + # Report the same denominator the intermediate lines used (uncached files + # actually processed this run), not total_files — switching to the full + # corpus made the count jump upward at the end (cached hits + files with no + # extractor never entered uncached_work), which read as inconsistent (#1693). + _done = len(uncached_work) print( - f" AST extraction: {total_files}/{total_files} files (100%) [{max_workers} workers]", + f" AST extraction: {_done}/{_done} uncached files (100%) [{max_workers} workers]", flush=True, ) return True @@ -16290,7 +16295,9 @@ def _extract_sequential( save_cached(path, result, effective_root) per_file[idx] = result if total_files >= _PROGRESS_INTERVAL: - print(f" AST extraction: {total_files}/{total_files} files (100%)", flush=True) + # Consistent denominator with the intermediate lines (#1693). + _done = len(uncached_work) + print(f" AST extraction: {_done}/{_done} uncached files (100%)", flush=True) _PARALLEL_THRESHOLD = 20 diff --git a/tests/test_extract.py b/tests/test_extract.py index d67a763f2..7cae30776 100644 --- a/tests/test_extract.py +++ b/tests/test_extract.py @@ -1795,3 +1795,21 @@ def test_extract_no_warning_when_all_code_has_extractors(tmp_path, capsys): extract([py], cache_root=tmp_path) err = capsys.readouterr().err assert "no AST extractor" not in err + + +def test_extract_progress_final_line_uses_consistent_denominator(tmp_path, capsys): + # #1693: intermediate progress lines count against uncached_work; the final + # "100%" line must NOT switch to total_files (which includes cached hits and + # files with no extractor), or the count appears to jump upward at the end. + for i in range(100): + (tmp_path / f"m{i}.py").write_text(f"def f{i}():\n return {i}\n") + for i in range(5): + (tmp_path / f"s{i}.r").write_text(f"g{i} <- function(x) x\n") # no extractor + paths = sorted(tmp_path.glob("*.py")) + sorted(tmp_path.glob("*.r")) # total 105 + + extract(paths, cache_root=tmp_path, parallel=False) + out = capsys.readouterr().out + + # final progress line reports the uncached count (100), not the total (105) + assert "100/100 uncached files (100%)" in out + assert "105/105 files" not in out, "final line must not switch to total_files (#1693)"