diff --git a/.ci/release_check.py b/.ci/release_check.py index 1ba2af59..4fdc7656 100644 --- a/.ci/release_check.py +++ b/.ci/release_check.py @@ -1,4 +1,5 @@ """Ensure that current version is not in conflict with published releases.""" + from pkg_resources import parse_version import subprocess as subp from pathlib import PurePath diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 53b30875..f89823fa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,13 +34,13 @@ repos: # Python formatting - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.11.0 + rev: 24.1.1 hooks: - id: black # Ruff linter, replacement for flake8, pydocstyle, isort - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.1.6' + rev: 'v0.1.14' hooks: - id: ruff args: [--fix, --show-fixes] @@ -62,7 +62,7 @@ repos: # Python type checking - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.7.1' + rev: 'v1.8.0' hooks: - id: mypy additional_dependencies: [numpy] diff --git a/src/iminuit/__init__.py b/src/iminuit/__init__.py index ea492fee..25d5c804 100644 --- a/src/iminuit/__init__.py +++ b/src/iminuit/__init__.py @@ -20,6 +20,7 @@ def fcn(x, y, z): * Code: https://github.com/scikit-hep/iminuit * Docs: https://iminuit.readthedocs.io """ + from iminuit.minuit import Minuit from iminuit.minimize import minimize from iminuit.util import describe diff --git a/src/iminuit/cost.py b/src/iminuit/cost.py index c1c6d8d2..49611ee4 100644 --- a/src/iminuit/cost.py +++ b/src/iminuit/cost.py @@ -80,6 +80,7 @@ the histogram, the sum of weights and the sum of squared weights is needed then, see class documentation for details. """ + from __future__ import annotations from .util import ( @@ -194,14 +195,14 @@ def __init__(self, val: ArrayLike, var: ArrayLike): self._obs = val * self._scale @overload - def __call__(self, val: ArrayLike) -> Tuple[NDArray, NDArray]: - ... # pragma: no cover + def __call__( + self, val: ArrayLike + ) -> Tuple[NDArray, NDArray]: ... # pragma: no cover @overload def __call__( self, val: ArrayLike, var: ArrayLike - ) -> Tuple[NDArray, NDArray, NDArray]: - ... # pragma: no cover + ) -> Tuple[NDArray, NDArray, NDArray]: ... # pragma: no cover def __call__(self, val, var=None): """ @@ -657,16 +658,13 @@ def has_grad(self) -> bool: return self._has_grad() @abc.abstractmethod - def _value(self, args: Sequence[float]) -> float: - ... # pragma: no cover + def _value(self, args: Sequence[float]) -> float: ... # pragma: no cover @abc.abstractmethod - def _grad(self, args: Sequence[float]) -> NDArray: - ... # pragma: no cover + def _grad(self, args: Sequence[float]) -> NDArray: ... # pragma: no cover @abc.abstractmethod - def _has_grad(self) -> bool: - ... # pragma: no cover + def _has_grad(self) -> bool: ... # pragma: no cover class Constant(Cost): @@ -920,8 +918,7 @@ def _ndata(self): return np.prod(self._masked.shape[: self._ndim]) @abc.abstractmethod - def _pulls(self, args: Sequence[float]) -> NDArray: - ... # pragma: no cover + def _pulls(self, args: Sequence[float]) -> NDArray: ... # pragma: no cover class UnbinnedCost(MaskedCost): @@ -1054,8 +1051,9 @@ def covariance(self, *args: float) -> NDArray: return np.linalg.inv(self.fisher_information(*args)) @abc.abstractmethod - def _pointwise_score(self, args: Sequence[float]) -> NDArray: - ... # pragma: no cover + def _pointwise_score( + self, args: Sequence[float] + ) -> NDArray: ... # pragma: no cover def _has_grad(self) -> bool: return self._model_grad is not None @@ -1402,8 +1400,9 @@ def _visualize(self, args: Sequence[float]) -> None: plt.stairs(mu, xe, fill=True, color="C0") @abc.abstractmethod - def _pred(self, args: Sequence[float]) -> Union[NDArray, Tuple[NDArray, NDArray]]: - ... # pragma: no cover + def _pred( + self, args: Sequence[float] + ) -> Union[NDArray, Tuple[NDArray, NDArray]]: ... # pragma: no cover def _n_err(self) -> Tuple[NDArray, NDArray]: d = self.data @@ -1440,14 +1439,14 @@ def _update_cache(self): self._set_bohm_zech(self._masked, self._bohm_zech_scale is not None) @overload - def _transformed(self, val: NDArray) -> Tuple[NDArray, NDArray]: - ... # pragma: no cover + def _transformed( + self, val: NDArray + ) -> Tuple[NDArray, NDArray]: ... # pragma: no cover @overload def _transformed( self, val: NDArray, var: NDArray - ) -> Tuple[NDArray, NDArray, NDArray]: - ... # pragma: no cover + ) -> Tuple[NDArray, NDArray, NDArray]: ... # pragma: no cover def _transformed(self, val, var=None): s = self._bohm_zech_scale diff --git a/src/iminuit/minuit.py b/src/iminuit/minuit.py index f4f1a3eb..0482c9c9 100644 --- a/src/iminuit/minuit.py +++ b/src/iminuit/minuit.py @@ -1,4 +1,5 @@ """Minuit class.""" + from __future__ import annotations import warnings @@ -1242,9 +1243,11 @@ def __call__(self, par, v): fcn, start, method=method, - bounds=Bounds(lower_bound, upper_bound, keep_feasible=True) - if has_limits - else None, + bounds=( + Bounds(lower_bound, upper_bound, keep_feasible=True) + if has_limits + else None + ), jac=grad, hess=hess, hessp=hessp, @@ -1793,10 +1796,14 @@ def _draw_profile( if text: plt.title( - (f"{pname} = {v:.3g}") - if vmin is None - else ( - "{} = {:.3g} - {:.3g} + {:.3g}".format(pname, v, v - vmin, vmax - v) + ( + (f"{pname} = {v:.3g}") + if vmin is None + else ( + "{} = {:.3g} - {:.3g} + {:.3g}".format( + pname, v, v - vmin, vmax - v + ) + ) ), fontsize="large", ) diff --git a/src/iminuit/util.py b/src/iminuit/util.py index b8b891ef..50e398d6 100644 --- a/src/iminuit/util.py +++ b/src/iminuit/util.py @@ -3,6 +3,7 @@ You can look up the interface of data classes that iminuit uses here. """ + from __future__ import annotations import inspect from collections import OrderedDict @@ -1118,15 +1119,13 @@ def g(x, p): ... @overload -def describe(callable: Callable) -> List[str]: - ... # pragma: no cover +def describe(callable: Callable) -> List[str]: ... # pragma: no cover @overload def describe( callable: Callable, annotations: bool -) -> Dict[str, Optional[Tuple[float, float]]]: - ... # pragma: no cover +) -> Dict[str, Optional[Tuple[float, float]]]: ... # pragma: no cover def describe(callable, *, annotations=False): diff --git a/tests/test_describe.py b/tests/test_describe.py index a19f8c9e..9a04e963 100644 --- a/tests/test_describe.py +++ b/tests/test_describe.py @@ -200,8 +200,7 @@ def foo( d: Annotated[float, Ge(1)], e: Annotated[float, Le(2)], f: Annotated[float, Interval(gt=2, lt=3)], - ): - ... + ): ... r = describe(foo, annotations=True) assert r == { @@ -215,8 +214,7 @@ def foo( } class Foo: - def __call__(self, x: NDArray, a: Annotated[float, Gt(0), Lt(1)], b: float): - ... + def __call__(self, x: NDArray, a: Annotated[float, Gt(0), Lt(1)], b: float): ... r = describe(Foo.__call__, annotations=True) assert r == {"self": None, "x": None, "a": (0, 1), "b": None} @@ -235,8 +233,7 @@ def foo( c: float, d: Annotated[float, tp.annotated_types.Gt(1)], e: Annotated[float, tp.annotated_types.Interval(gt=0, lt=1)], - ): - ... + ): ... r = describe(foo, annotations=True) assert r == { @@ -257,8 +254,7 @@ def foo( a: float, b: Annotated[float, tp.Gt(1)], c: Annotated[float, tp.Interval(gt=0, lt=1)], - ): - ... + ): ... r = describe(foo, annotations=True) assert r == {