This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
bitmath is a pure-Python library (no external runtime dependencies) for representing and converting file sizes across SI (decimal) and NIST (binary) unit systems. It supports arithmetic (including floor division, modulo, and divmod for capacity math), rich comparisons, bitwise ops, parsing, formatting, and f-string/format() support.
bitmath has been around for almost 12 years, and over that lifetime it promised to deliver backwards compatibility. It delivered on that promise and gathered a strong supporting of people and eventual "critical infrastructure" project status on the PyPI.org website.
As of January 2023 the project maintainer (me) has stated in this issue #99 that the project is still alive and the next release will be python 3 support only.
Much of that porting work has already happened in the 2023-01-26-no-more-py2 branch https://github.com/timlnx/bitmath/tree/2023-01-26-no-more-py2
Phases 1 (maintenance 1.4.0) and 2 (bitmath 2.0.0) are complete. The project:
- Supports Python 3.9 and newer only (
requires-python = ">=3.9"inpyproject.toml) - Uses
hatchlingas the build backend (replacessetup.py) - Uses
pytestas the test runner (303 tests). Coverage is high but platform-sensitive: thequery_device_capacitybranches for the other OS are naturally uncovered on any single run. - Is published on PyPI as version 2.0.0
- Drop-in compatible with the 1.x public API
# Run the full test suite with coverage (creates venv, runs pytest + linting + bandit)
make ci
# Run security scan only
make ci-bandit
# Run linting only
make ci-pylint
# Build a wheel
make build
# Install in development mode
pip install -e .Run a single test file:
python -m pytest tests/test_arithmetic.py -vAlmost all logic lives in a single file: bitmath/__init__.py (~1650 lines).
Class hierarchy:
Bitmath— base class with all arithmetic, comparison, bitwise, formatting, and conversion logicByte— byte-based units; subclasses:KiB MiB GiB TiB PiB EiB(NIST/base-2) andkB MB GB TB PB EB ZB YB(SI/base-10)Bit— bit-based units; subclasses:Kib Mib Gib Tib Pib Eib(NIST) andkb Mb Gb Tb Pb Eb Zb Yb(SI)
All unit values are normalized to bits internally; conversion between units happens at construction time via _norm_value and class-level _base_value / _unit_value constants.
Key module-level functions:
best_prefix(value, system=NIST)— pick the most human-readable unit for a raw byte valuegetsize(path, ...)— file size with automatic prefix selectionlistdir(search_base, ...)— recursive directory listing with sizesparse_string(s)/parse_string_unsafe(s, system=SI)— string → bitmath objectquery_capacity(path)— volume/mount-point capacity as aCapacity(total, used, free)NamedTuple ofByteinstances; cross-platform, no elevated privileges requiredquery_device_capacity(device_fd)— raw physical block device capacity (Linux: requires root; Windows: requires administrator; macOS: raisesNotImplementedErrordue to SIP)
Constants: NIST, SI, NIST_PREFIXES, SI_PREFIXES, ALL_UNIT_TYPES
The single source of truth for the version is the VERSION file. pyproject.toml reads it dynamically via [tool.hatch.version] — do not edit the version in pyproject.toml directly. The Makefile also reads VERSION for docs, man pages, and RPM builds. To bump the version, edit VERSION only.
Bandit runs as part of make ci via the ci-bandit target, scanning both bitmath/ and tests/. It also runs as a GitHub Actions workflow (.github/workflows/bandit.yml) on push/PR to master and weekly. No issues were present as of 2.0.2.
- Test runner:
pytest - All tests are in
tests/astest_*.pyfiles - Test case names must be unique across the suite — enforced by
tests/test_unique_testcase_names.sh - Coverage is platform-sensitive: Windows and POSIX
query_device_capacitypaths only run on their respective OS unittest.mock(stdlib) is used for patching in integration tests