Skip to content

Commit

Permalink
feat: remove Python 3.7 support (#952)
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <[email protected]>
  • Loading branch information
henryiii authored Aug 23, 2024
1 parent f305f4a commit 5d04fa0
Show file tree
Hide file tree
Showing 16 changed files with 42 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
- os: windows-2019
only: cp38-win32
- os: windows-2019
only: cp37-win_amd64
only: cp313-win_amd64
- os: macos-13
only: cp39-macosx_x86_64
- os: macos-14
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python: [37, 38, 39, 310, 311, 312, 313]
python: ["38", "39", "310", "311", "312", "313", "313t"]
arch: [aarch64]
steps:
- uses: actions/checkout@v4
Expand Down
19 changes: 4 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,8 @@ repos:
- id: prettier
types_or: [yaml, markdown, html, css, scss, javascript, json]

- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.5.0
hooks:
- id: setup-cfg-fmt
args:
[
--include-version-classifiers,
--min-py3-version=3.7,
--max-py-version=3.12,
]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.5.6"
rev: "v0.6.2"
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand All @@ -61,7 +50,7 @@ repos:
hooks:
- id: mypy
files: ^src
additional_dependencies: [numpy~=1.26.0, pytest, uhi, types-dataclasses]
additional_dependencies: [numpy~=1.26.0, pytest, uhi]

- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
Expand Down Expand Up @@ -92,12 +81,12 @@ repos:
- id: rst-inline-touching-normal

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.29.1
rev: 0.29.2
hooks:
- id: check-readthedocs
- id: check-github-workflows

- repo: https://github.com/henryiii/validate-pyproject-schema-store
rev: 2024.07.29
rev: 2024.08.19
hooks:
- id: validate-pyproject
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,11 @@ 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.7+ is
9 is very old), you should be in a virtual environment, etc. Python 3.8+ 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.3.x was the last series to support Python 3.6. 1.4.x was the last series to
support Python 3.7.

#### Binaries available:

Expand All @@ -190,15 +191,15 @@ 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.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.9, 3.10 |
| manylinux2014 | ARM64 | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.9, 3.10 |
| musllinux_1_1 | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | |
| macOS 10.9+ Intel | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.9, 3.10 |
| macOS 11+ AS | Arm64 | 3.8, 3.9, 3.10, 3.11, 3.12 | 3.9, 3.10 |
| Windows | 32-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | |
| Windows | 64-bit | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | 3.9, 3.10 |
| System | Arch | Python versions | PyPy versions |
| ----------------- | ------ | --------------------------------------- | ------------- |
| manylinux2014 | 64-bit | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| manylinux2014 | ARM64 | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| musllinux_1_1 | 64-bit | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | |
| macOS 10.9+ Intel | 64-bit | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| macOS 11+ AS | Arm64 | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | 3.9, 3.10 |
| Windows | 32-bit | 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.13t | |
| Windows | 64-bit | 3.8, 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.

Expand Down
1 change: 0 additions & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ numpy
pytest >=6,!=6.1.0,!=7.1.0
pytest-benchmark
setuptools_scm[toml] >=3.4,!=4.0.0
typing_extensions; python_version<'3.8'
uproot
12 changes: 3 additions & 9 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.7"
requires-python = ">=3.8"
authors = [
{ name = "Hans Dembinski", email = "[email protected]" },
{ name = "Henry Schreiner", email = "[email protected]" },
Expand All @@ -29,7 +29,6 @@ classifiers = [
"Programming Language :: C++",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand All @@ -49,7 +48,6 @@ classifiers = [
]
dependencies = [
"numpy",
"typing-extensions;python_version<'3.8'",
]

[project.optional-dependencies]
Expand Down Expand Up @@ -165,7 +163,7 @@ build-frontend = "build[uv]"
test-extras = "test"
test-command = "pytest --benchmark-disable {project}/tests"
skip = [
"pp3[78]-*",
"pp38-*",
]
test-skip = [
"cp*-musllinux_*", # Segfaults
Expand All @@ -187,7 +185,7 @@ environment.MACOSX_DEPLOYMENT_TARGET = "14.0"


[tool.pylint]
py-version = "3.7"
py-version = "3.8"
ignore-patterns = ['.*\.pyi']
extension-pkg-allow-list = ["boost_histogram._core"]
reports.output-format = "colorized"
Expand All @@ -212,10 +210,6 @@ messages_control.disable = [
"wrong-import-position",
]

[tool.ruff]
target-version = "py37"
src = ["src"]

[tool.ruff.lint]
extend-select = [
"B", # flake8-bugbear
Expand Down
16 changes: 8 additions & 8 deletions src/boost_histogram/_core/accumulators.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class WeightedSum(_BaseAccumulator):
def __iadd__(self: T, arg0: float) -> T: ...
def fill(self: T, value: ArrayLike, variance: ArrayLike | None = None) -> T: ...
@staticmethod
def _make(self: T, a: ArrayLike, b: ArrayLike) -> T: ...
def _make(a: ArrayLike, b: ArrayLike) -> WeightedSum: ...
@staticmethod
def _array(self: T, a: ArrayLike, b: ArrayLike) -> T: ...
def _array(a: ArrayLike, b: ArrayLike) -> WeightedSum: ...
def __getitem__(self, key: str) -> float: ...
def __setitem__(self, key: str, value: float) -> None: ...

Expand Down Expand Up @@ -76,12 +76,12 @@ class WeightedMean(_BaseAccumulator):
def fill(self: T, value: ArrayLike, *, weight: ArrayLike | None = None) -> T: ...
@staticmethod
def _make(
self: T, arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
) -> T: ...
arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
) -> WeightedMean: ...
@staticmethod
def _array(
self: T, arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
) -> T: ...
arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
) -> WeightedMean: ...
def __getitem__(self, key: str) -> float: ...
def __setitem__(self, key: str, value: float) -> None: ...

Expand All @@ -103,8 +103,8 @@ class Mean(_BaseAccumulator):
) -> T: ...
def fill(self: T, value: ArrayLike, *, weight: ArrayLike | None = None) -> T: ...
@staticmethod
def _make(self: T, arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> T: ...
def _make(arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> Mean: ...
@staticmethod
def _array(self: T, arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> T: ...
def _array(arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> Mean: ...
def __getitem__(self, key: str) -> float: ...
def __setitem__(self, key: str, value: float) -> None: ...
3 changes: 1 addition & 2 deletions src/boost_histogram/_internal/axestuple.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from __future__ import annotations

from functools import partial
from typing import Any, ClassVar, Iterable, TypeVar
from typing import Any, ClassVar, Iterable, Literal, TypedDict, TypeVar

import numpy as np

from .axis import Axis
from .typing import Literal, TypedDict
from .utils import set_module, zip_strict

A = TypeVar("A", bound="ArrayTuple")
Expand Down
3 changes: 2 additions & 1 deletion src/boost_histogram/_internal/hist.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
List,
Mapping,
NewType,
SupportsIndex,
Tuple,
TypeVar,
Union,
Expand All @@ -30,7 +31,7 @@
from .axis import Axis
from .enum import Kind
from .storage import Double, Storage
from .typing import Accumulator, ArrayLike, CppHistogram, SupportsIndex
from .typing import Accumulator, ArrayLike, CppHistogram
from .utils import cast, register, set_module
from .view import MeanView, WeightedMeanView, WeightedSumView, _to_view

Expand Down
12 changes: 1 addition & 11 deletions src/boost_histogram/_internal/typing.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
from __future__ import annotations

import sys
from typing import TYPE_CHECKING, Any, Tuple, Union

if sys.version_info < (3, 8):
from typing_extensions import Literal, Protocol, SupportsIndex, TypedDict
else:
from typing import Literal, Protocol, SupportsIndex, TypedDict
from typing import TYPE_CHECKING, Any, Protocol, Tuple, Union

if TYPE_CHECKING:
from builtins import ellipsis
Expand All @@ -26,16 +20,12 @@


__all__ = (
"Protocol",
"CppHistogram",
"SupportsIndex",
"AxisLike",
"ArrayLike",
"Ufunc",
"StdIndex",
"StrIndex",
"Literal",
"TypedDict",
)


Expand Down
4 changes: 1 addition & 3 deletions src/boost_histogram/_internal/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import itertools
import sys
import typing
from typing import Any, Callable, ClassVar, Iterator, TypeVar
from typing import Any, Callable, ClassVar, Iterator, Protocol, TypeVar

import boost_histogram

from .typing import Protocol


class Registerable(Protocol):
_types: ClassVar[set[type[object]]]
Expand Down
8 changes: 4 additions & 4 deletions src/boost_histogram/_internal/view.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from __future__ import annotations

from typing import Any, Callable, ClassVar, Mapping, MutableMapping
from typing import Any, Callable, ClassVar, Literal, Mapping, MutableMapping

import numpy as np

from ..accumulators import Mean, WeightedMean, WeightedSum
from .typing import ArrayLike, Literal, StrIndex, Ufunc
from .typing import ArrayLike, StrIndex, Ufunc

UFMethod = Literal["__call__", "reduce", "reduceat", "accumulate", "outer", "inner"]

Expand Down Expand Up @@ -50,7 +50,7 @@ def __setitem__(self, ind: StrIndex, value: ArrayLike) -> None:
msg = "Needs matching ndarray or n+1 dim array"
if array.ndim == current_ndim + 1:
if len(self._FIELDS) == array.shape[-1]:
self.__setitem__(ind, self._PARENT._array(*np.moveaxis(array, -1, 0)))
self.__setitem__(ind, self._PARENT._array(*np.moveaxis(array, -1, 0))) # type: ignore[assignment]
return
msg += f", final dimension should be {len(self._FIELDS)} for this storage, got {array.shape[-1]} instead"
raise ValueError(msg)
Expand Down Expand Up @@ -224,7 +224,7 @@ def __array_ufunc__(
# ufuncs that are allowed to reduce
if ufunc in {np.add} and method == "reduce" and len(raw_inputs) == 1:
results = (ufunc.reduce(self[field], **kwargs) for field in self._FIELDS)
return self._PARENT._make(*results) # type: ignore[no-any-return]
return self._PARENT._make(*results) # type: ignore[return-value]

# ufuncs that are allowed to accumulate
if ufunc in {np.add} and method == "accumulate" and len(raw_inputs) == 1:
Expand Down
8 changes: 2 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import contextlib
import importlib.metadata
import sys
from pathlib import Path

Expand Down Expand Up @@ -74,11 +75,6 @@ def count_single_storage(request):


def pytest_report_header() -> str:
if sys.version_info < (3, 8):
import importlib_metadata as metadata
else:
from importlib import metadata

with BASE.joinpath("pyproject.toml").open("rb") as f:
pyproject = tomllib.load(f)
project = pyproject.get("project", {})
Expand All @@ -94,7 +90,7 @@ def pytest_report_header() -> str:
valid = []
for package in sorted(interesting_packages):
with contextlib.suppress(ModuleNotFoundError):
valid.append(f"{package}=={metadata.version(package)}")
valid.append(f"{package}=={importlib.metadata.version(package)}")
reqs = " ".join(valid)
lines = [
f"installed packages of interest: {reqs}",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_axes_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import boost_histogram as bh


@pytest.fixture()
@pytest.fixture
def h():
return bh.Histogram(
bh.axis.Regular(10, 0, 10, metadata=2),
Expand Down
4 changes: 0 additions & 4 deletions tests/test_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -1104,10 +1104,6 @@ def test_fill_with_sequence_3():
assert_array_equal(h.view(True), [3, 1])


@pytest.mark.skipif(
platform.machine() == "ppc64le" and sys.version_info < (3, 8),
reason="ppc64le segfault",
)
def test_fill_with_sequence_4():
h = bh.Histogram(
bh.axis.StrCategory([], growth=True), bh.axis.Integer(0, 0, growth=True)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import boost_histogram as bh


@pytest.fixture()
@pytest.fixture
def v():
h = bh.Histogram(bh.axis.Integer(0, 4), storage=bh.storage.Weight())
h.fill([1, 1, 1, 2, 2, 3])
Expand Down

0 comments on commit 5d04fa0

Please sign in to comment.