borgbackup / borgbackup/borg

helpers layering: split parseformat, dissolve the helpers/__init__ shim, make imports point downward again

Open
#10,016 0 comments 0 reactions 1 assignee Claimed by @ThomasWaldmann View on GitHub
Dominant language
Python
Stars
13.7k
Forks
875
Avg merge
11h 15m
Merged PRs (30d)
192

Description

From a global code review of the borg2 codebase (2026-08).

### Problem

`borg.helpers` is supposed to be the bottom layer, but it imports *upward*: `helpers/parseformat.py` pulls in `..archive`, `..manifest`, `..compress`, `..platform`, `..item` (inside functions), and `cache.py`/`archive.py` import each other. A rough count finds ~175 function-level `from ..x import y` statements in non-test code, most of them circular-import workarounds rather than genuine lazy loading.

The root cause: `parseformat.py` (1564 lines, the biggest helpers module) mixes true low-level utilities (`bin_to_hex`, size/time formatting) with high-level domain formatting (`ArchiveFormatter`, `ItemFormatter`, `DiffFormatter`) that inherently needs `Archive`/`ItemDiff`/`Manifest`. Meanwhile `helpers/__init__.py` re-exports ~100 names "for compatibility" — internal API compatibility is irrelevant for the breaking 2.0 release, and the shim encourages treating helpers as one big grab-bag.

### Proposed direction

- Move `ArchiveFormatter`/`ItemFormatter`/`DiffFormatter` (and other domain-aware formatting) up and out of helpers, e.g. into `borg/output.py` or `borg.archiver`.
- Move `Location` parsing near the repository layer where it conceptually belongs.
- Import from the specific helpers submodules directly; shrink `helpers/__init__` to little or nothing.
- Afterwards, most of the ~175 deferred imports can return to module top level.
- Add an import-linter contract (tox/CI) that pins the layer order (constants → helpers → crypto/chunkers → repository → cache/archive → archiver) so cycles cannot silently regrow.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.