Single src/hist/ package, built with hatchling + hatch-vcs. Version is auto-generated from git tags into src/hist/version.py.
- Core hierarchy:
BaseHistsubclassesboost_histogram.Histogramand provides all named-axis logic, UHI+ indexing, plotting, and fills.HistandNamedHistare thin subclasses in thehistfamily.Hist— allows positional and named access.NamedHist— enforces name-only fill, index, and project (raises on positional args).
- Axes:
hist.axis.*wrapsboost_histogram.axisclasses withAxesMixin, addingnameandlabelmetadata stored in_raw_metadata. - Quick construct:
Hist.new.Reg(...).Var(...).Int64()is powered byMetaConstructor(metaclass onBaseHist) +QuickConstruct/ConstructProxy. Exposed ashist.new. - Stack: A standalone generic container (
Stack[S]) overBaseHistinstances, not a histogram subclass. Created viah.stack(axis)orStack(h1, h2, ...). - Plotting:
BaseHist.plot*()methods delegate to thehist.plotmodule (requiresmplhep+matplotlib).plot_pull/plot_ratioadditionally needscipy+iminuit. - Dask support:
hist.daskis an optional subpackage requiringdask_histogram. Providesdask.Histanddask.NamedHist. - Interop / flattening:
fill_flattened()usesinterop.destructure()andinterop.broadcast_and_flatten()for Awkward Array support. - Serialization:
hist.serializationwrapsboost_histogram.serializationand injects ahistwriter_info block into UHI dicts. - Entry points:
from hist import Hist, NamedHist, Stack, BaseHist; CLIhistpoints tohist.classichist:main.
| Goal | Command |
|---|---|
| Install for dev | uv sync |
| Lint / format / type check | prek -a or nox -s lint |
| Type check only | prek -a mypy (strict on src/) |
| Run tests | nox -s tests or uv run pytest |
| Run full test suite (incl. mpl) | uv run pytest --mpl |
| Run single test file | uv run pytest tests/test_plot.py --mpl |
| Test minimum deps | nox -s minimums |
| Build docs | nox -s docs |
| Build package | nox -s build |
- pytest
--mpl: Matplotlib image comparison tests only run with--mpl. On non-Linux they are silently skipped because baselines are Linux-generated. Regenerating baselines (nox -s regenerate) requires Linux / Docker. - pytest treats warnings as errors (
filterwarnings = ["error"]). Any deprecation warning will fail the test suite. - pytest
xfail_strict = true: An unexpected pass on anxfailtest is treated as a failure. - mypy is strict (
strict = true,warn_unreachable = true). Do not relax without justification. - Ruff requires
from __future__ import annotationsin every file (enforced viaisort.required-imports). - Pre-commit mypy runs on
^srconly and has pinned stub dependencies in.pre-commit-config.yaml; update those if needed.
| Group | Contents |
|---|---|
test-core |
pytest, pytest-mpl, packaging, plot deps |
test |
test-core + fit + awkward |
plot |
matplotlib + mplhep |
fit |
scipy + iminuit |
dask |
dask[dataframe], dask_awkward, dask_histogram |
dev |
test + plot + dask + ipykernel |
docs |
dev + sphinx stack |
CI installs test + dask, then separately plot for the --mpl test job.
ci.ymlruns: pylint, Python 3.10–3.14 checks, minimum-dependency checks.cd.ymlruns on push tomainand releases; builds viahynek/build-and-inspect-python-packageand publishes on release.- Do not run
git commitorgit pushunless explicitly asked.