Skip to content

Commit 81d3516

Browse files
refactor(gc): remove format_stats
Review decision: format_stats presumed a single display format and was never called by the library — scan()/collect() return plain dicts. Users inspect or render those dicts however they like, so the helper only added surface area. Removed the function and its three unit tests. GC suite 36/36. Docs that showed dj.gc.format_stats(stats) are updated to inspect the stats dict directly (datajoint-docs).
1 parent 93eb695 commit 81d3516

2 files changed

Lines changed: 0 additions & 136 deletions

File tree

src/datajoint/gc.py

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -709,71 +709,3 @@ def collect(
709709
"hash_orphaned": stats["hash_orphaned"],
710710
"schema_paths_orphaned": stats["schema_paths_orphaned"],
711711
}
712-
713-
714-
def format_stats(stats: dict[str, Any]) -> str:
715-
"""
716-
Format GC statistics as a human-readable string.
717-
718-
Parameters
719-
----------
720-
stats : dict[str, Any]
721-
Statistics dict from scan() or collect().
722-
723-
Returns
724-
-------
725-
str
726-
Formatted string.
727-
"""
728-
lines = ["Object Storage Statistics:"]
729-
730-
# Show hash-addressed storage stats if present
731-
if "hash_referenced" in stats:
732-
lines.append("")
733-
lines.append("Hash-Addressed Storage (<hash@>, <blob@>, <attach@>):")
734-
lines.append(f" Referenced: {stats['hash_referenced']}")
735-
lines.append(f" Stored: {stats['hash_stored']}")
736-
lines.append(f" Orphaned: {stats['hash_orphaned']}")
737-
if "hash_orphaned_bytes" in stats:
738-
size_mb = stats["hash_orphaned_bytes"] / (1024 * 1024)
739-
lines.append(f" Orphaned size: {size_mb:.2f} MB")
740-
741-
# Show schema-addressed storage stats if present
742-
if "schema_paths_referenced" in stats:
743-
lines.append("")
744-
lines.append("Schema-Addressed Storage (<object@>, <npy@>):")
745-
lines.append(f" Referenced: {stats['schema_paths_referenced']}")
746-
lines.append(f" Stored: {stats['schema_paths_stored']}")
747-
lines.append(f" Orphaned: {stats['schema_paths_orphaned']}")
748-
if "schema_paths_orphaned_bytes" in stats:
749-
size_mb = stats["schema_paths_orphaned_bytes"] / (1024 * 1024)
750-
lines.append(f" Orphaned size: {size_mb:.2f} MB")
751-
752-
# Show totals
753-
lines.append("")
754-
lines.append("Totals:")
755-
lines.append(f" Referenced in database: {stats['referenced']}")
756-
lines.append(f" Stored in backend: {stats['stored']}")
757-
lines.append(f" Orphaned (unreferenced): {stats['orphaned']}")
758-
759-
if "orphaned_bytes" in stats:
760-
size_mb = stats["orphaned_bytes"] / (1024 * 1024)
761-
lines.append(f" Orphaned size: {size_mb:.2f} MB")
762-
763-
# Show deletion results if this is from collect()
764-
if "deleted" in stats:
765-
lines.append("")
766-
if stats.get("dry_run", True):
767-
lines.append(" [DRY RUN - no changes made]")
768-
else:
769-
lines.append(f" Deleted: {stats['deleted']}")
770-
if "hash_deleted" in stats:
771-
lines.append(f" Hash items: {stats['hash_deleted']}")
772-
if "schema_paths_deleted" in stats:
773-
lines.append(f" Schema paths: {stats['schema_paths_deleted']}")
774-
freed_mb = stats["bytes_freed"] / (1024 * 1024)
775-
lines.append(f" Bytes freed: {freed_mb:.2f} MB")
776-
if stats.get("errors", 0) > 0:
777-
lines.append(f" Errors: {stats['errors']}")
778-
779-
return "\n".join(lines)

tests/integration/test_gc.py

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -331,74 +331,6 @@ def test_deletes_orphaned_schemas(self, mock_scan, mock_list_schemas, mock_delet
331331
mock_delete.assert_called_once_with("schema/table/pk/field", "test_store", config=mock_schema.connection._config)
332332

333333

334-
class TestFormatStats:
335-
"""Tests for format_stats function."""
336-
337-
def test_formats_scan_stats(self):
338-
"""Test formatting scan statistics."""
339-
stats = {
340-
"referenced": 10,
341-
"stored": 15,
342-
"orphaned": 5,
343-
"orphaned_bytes": 1024 * 1024, # 1 MB
344-
"hash_referenced": 6,
345-
"hash_stored": 8,
346-
"hash_orphaned": 2,
347-
"hash_orphaned_bytes": 512 * 1024,
348-
"schema_paths_referenced": 4,
349-
"schema_paths_stored": 7,
350-
"schema_paths_orphaned": 3,
351-
"schema_paths_orphaned_bytes": 512 * 1024,
352-
}
353-
354-
result = gc.format_stats(stats)
355-
356-
assert "Referenced in database: 10" in result
357-
assert "Stored in backend: 15" in result
358-
assert "Orphaned (unreferenced): 5" in result
359-
assert "1.00 MB" in result
360-
# Check for detailed sections
361-
assert "Hash-Addressed Storage" in result
362-
assert "Schema-Addressed Storage" in result
363-
364-
def test_formats_collect_stats_dry_run(self):
365-
"""Test formatting collect statistics with dry_run."""
366-
stats = {
367-
"referenced": 10,
368-
"stored": 15,
369-
"orphaned": 5,
370-
"deleted": 0,
371-
"bytes_freed": 0,
372-
"dry_run": True,
373-
}
374-
375-
result = gc.format_stats(stats)
376-
377-
assert "DRY RUN" in result
378-
379-
def test_formats_collect_stats_actual(self):
380-
"""Test formatting collect statistics after actual deletion."""
381-
stats = {
382-
"referenced": 10,
383-
"stored": 15,
384-
"orphaned": 5,
385-
"deleted": 3,
386-
"hash_deleted": 2,
387-
"schema_paths_deleted": 1,
388-
"bytes_freed": 2 * 1024 * 1024, # 2 MB
389-
"errors": 2,
390-
"dry_run": False,
391-
}
392-
393-
result = gc.format_stats(stats)
394-
395-
assert "Deleted: 3" in result
396-
assert "Hash items: 2" in result
397-
assert "Schema paths: 1" in result
398-
assert "2.00 MB" in result
399-
assert "Errors: 2" in result
400-
401-
402334
class TestScanWithLiveData:
403335
"""End-to-end tests for gc.scan() against real schemas with external storage.
404336

0 commit comments

Comments
 (0)