Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
submodules: true
- uses: actions/setup-python@v6
with:
python-version: "3.9"
python-version: "3.10"
- uses: astral-sh/setup-uv@v7
- name: Build and install kernel
run: uv run --group examples -m ipykernel install --user --name boost-hist
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
fail-fast: false
matrix:
include:
- python-version: "3.9"
- python-version: "3.10"
cmake-extras: "-DCMAKE_CXX_STANDARD=17"
- python-version: "3.11"
- python-version: "3.13t"
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:
- os: ubuntu-24.04-arm
only: cp313-manylinux_aarch64
- os: windows-latest
only: cp39-win32
only: cp310-win32
- os: windows-latest
only: cp313-win_amd64
- os: macos-13
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ repos:
hooks:
- id: mypy
files: ^src
additional_dependencies: [numpy~=2.3.0, pytest, uhi]
additional_dependencies: [numpy~=2.2.0, pytest, uhi]

- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,12 @@ python3 -m pip install boost-histogram
```

All the normal best-practices for Python apply; Pip should not be very old (Pip
9 is very old), you should be in a virtual environment, etc. Python 3.9+ is
9 is very old), you should be in a virtual environment, etc. Python 3.10+ is
required; for older versions of Python (3.5 and 2.7), `0.13` will be installed
instead, which is API equivalent to 1.0, but will not be gaining new features.
1.3.x was the last series to support Python 3.6. 1.4.x was the last series to
support Python 3.7. 1.5.x was the last series to support Python 3.8.
support Python 3.7. 1.5.x was the last series to support Python 3.8. 1.6.x was
the last to support Python 3.9.

#### Binaries available:

Expand All @@ -192,17 +193,18 @@ when you run the above command on a supported platform. Wheels are produced usin
[cibuildwheel](https://cibuildwheel.readthedocs.io/en/stable/); all common
platforms have wheels provided in boost-histogram:

| System | Arch | Python versions | PyPy versions |
| ------------- | ------ | ---------------------------------- | ------------- |
| manylinux2014 | 64-bit | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| manylinux2014 | ARM64 | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| musllinux_1_1 | 64-bit | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | |
| macOS | 64-bit | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| macOS | Arm64 | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| Windows | 32-bit | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | |
| Windows | 64-bit | 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |

PowerPC or IBM-Z wheels are not provided but are available on request.
| System | Arch | Python versions | PyPy versions |
| --------- | ------ | ------------------------------------------ | ------------- |
| manylinux | 64-bit | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | 3.11 |
| manylinux | ARM64 | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | 3.11 |
| musllinux | 64-bit | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | |
| macOS | 64-bit | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | 3.11 |
| macOS | Arm64 | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | 3.11 |
| Windows | 32-bit | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | |
| Windows | 64-bit | 3.10, 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | 3.11 |
| Windows | ARM64 | 3.11, 3.12, 3.13, 3.13t, 3.14, 3.14t | |

PowerPC, IBM-Z, and RISC-V wheels are not provided but are available on request.

If you are on a Linux system that is not part of the "many" in manylinux or musl in musllinux, such as ClearLinux, building from source is usually fine, since the compilers on those systems are often quite new. It will just take longer to install when it is using the sdist instead of a wheel. All dependencies are header-only and included.

Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Boost Histogram examples

The examples require Python 3.9. It is left as an exercise for the reader to
The examples require Python 3.10. It is left as an exercise for the reader to
convert back to older versions if they so desire.

### Setup
Expand Down
4 changes: 2 additions & 2 deletions notebooks/xarray.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
" name=\"_\".join(a.name for a in args) + \"_histogram\",\n",
" coords=[\n",
" (f\"{a.name}_bin\", arr.flatten(), a.attrs)\n",
" for a, arr in zip(args, h.axes.centers)\n",
" for a, arr in zip(args, h.axes.centers, strict=False)\n",
" ],\n",
" )"
]
Expand Down Expand Up @@ -270,7 +270,7 @@
" name=\"_\".join(a.name for a in args) + \"_histogram\",\n",
" coords=[\n",
" (f\"{a.name}_bin\", arr.flatten(), a.attrs)\n",
" for a, arr in zip(args, h.axes.centers)\n",
" for a, arr in zip(args, h.axes.centers, strict=False)\n",
" ],\n",
" )"
]
Expand Down
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "boost-histogram"
dynamic = ["version"]
description = "The Boost::Histogram Python wrapper."
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.10"
authors = [
{ name = "Hans Dembinski", email = "[email protected]" },
{ name = "Henry Schreiner", email = "[email protected]" },
Expand Down Expand Up @@ -37,7 +37,6 @@ classifiers = [
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Free Threading :: 3 - Stable",
"Programming Language :: Python :: Free Threading",
"Programming Language :: Python :: Implementation :: CPython",
Expand Down Expand Up @@ -158,7 +157,7 @@ required_plugins = ["pytest-benchmark"]
log_cli_level = "DEBUG"

[tool.mypy]
python_version = "3.9"
python_version = "3.10"
files = ["src"]
strict = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
Expand All @@ -181,8 +180,8 @@ test-command = "python -m pytest -n auto --benchmark-disable tests"
test-sources = ["pyproject.toml", "tests"]
test-environment.CI = "1" # Hypothosis needs this on GraalPy
test-skip = [
"cp3{9,10}-win_arm64",
"cp3{9,10}-musllinux_*",
"cp310-win_arm64",
"cp310-musllinux_*",
"pp310-manylinux_aarch64",
"pp310-macosx_arm64",
"cp31*-musllinux_*", # Threading test crashes
Expand Down Expand Up @@ -228,7 +227,7 @@ environment.UV_INDEX_STRATEGY = "unsafe-best-match"
test-command = "pytest --benchmark-disable tests"

[tool.pylint]
py-version = "3.9"
py-version = "3.10"
ignore-patterns = ['.*\.pyi']
ignore = "version.py"
extension-pkg-allow-list = ["boost_histogram._core"]
Expand Down
3 changes: 2 additions & 1 deletion src/boost_histogram/_core/axis/transform.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Callable
from collections.abc import Callable
from typing import Any

from typing_extensions import Self

Expand Down
19 changes: 2 additions & 17 deletions src/boost_histogram/_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from __future__ import annotations

import itertools
import sys
import typing
from collections.abc import Iterator
from typing import Any, Callable, ClassVar, Protocol, TypeVar
from collections.abc import Callable, Iterator
from typing import ClassVar, Protocol, TypeVar

import boost_histogram

Expand Down Expand Up @@ -165,16 +163,3 @@ def _walk_subclasses(cls: type[object]) -> Iterator[type[object]]:
# user subclasses to work
yield from _walk_subclasses(base)
yield base


def zip_strict(*args: Any) -> Iterator[tuple[Any, ...]]:
if sys.version_info >= (3, 10):
yield from zip(*args, strict=True)
return

marker = object()
for each in itertools.zip_longest(*args, fillvalue=marker):
for val in each:
if val is marker:
raise ValueError("zip() arguments are not the same length")
yield each
16 changes: 7 additions & 9 deletions src/boost_histogram/axis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
from __future__ import annotations

import copy
from collections.abc import Iterable, Iterator
from collections.abc import Callable, Iterable, Iterator
from dataclasses import dataclass
from functools import partial
from typing import (
Any,
Callable,
ClassVar,
Literal,
TypedDict,
TypeVar,
Union,
)

import numpy as np # pylint: disable=unused-import
Expand All @@ -20,7 +18,7 @@

from .._compat.typing import Self
from .._core import axis as ca
from .._utils import cast, register, zip_strict
from .._utils import cast, register
from . import transform
from .transform import AxisTransform

Expand Down Expand Up @@ -59,7 +57,7 @@ def _opts(**kwargs: bool) -> set[str]:
return {k for k, v in kwargs.items() if v}


AxCallOrInt = Union[int, Callable[["Axis"], int]]
AxCallOrInt = int | Callable[["Axis"], int]


@dataclass(order=True, frozen=True)
Expand Down Expand Up @@ -287,21 +285,21 @@ def __getitem__(self, i: AxCallOrInt) -> int | str | tuple[float, float]:

@property
def edges(self) -> np.typing.NDArray[Any]:
return self._ax.edges
return self._ax.edges # type: ignore[no-any-return]

@property
def centers(self) -> np.typing.NDArray[Any]:
"""
An array of bin centers.
"""
return self._ax.centers
return self._ax.centers # type: ignore[no-any-return]

@property
def widths(self) -> np.typing.NDArray[Any]:
"""
An array of bin widths.
"""
return self._ax.widths
return self._ax.widths # type: ignore[no-any-return]


# Contains all common methods and properties for Regular axes
Expand Down Expand Up @@ -910,7 +908,7 @@ def __setattr__(self, attr: str, values: Any) -> None:
try:
super().__setattr__(attr, values)
except AttributeError:
for s, v in zip_strict(self, values):
for s, v in zip(self, values, strict=True):
s.__setattr__(attr, v)

value.__doc__ = Axis.value.__doc__
Expand Down
Loading
Loading