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 .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ repos:
- id: mypy
files: src
args: []
additional_dependencies: [numpy==1.20.*, uhi, types-dataclasses]
additional_dependencies: [numpy==1.21.*, uhi, types-dataclasses]

- repo: https://github.com/mgedmin/check-manifest
rev: "0.46"
Expand Down
10 changes: 5 additions & 5 deletions src/boost_histogram/_core/axis/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ class _BaseAxis:
@property
def extent(self) -> int: ...
@property
def edges(self) -> np.ndarray: ...
def edges(self) -> "np.typing.NDArray[Any]": ...
@property
def centers(self) -> np.ndarray: ...
def centers(self) -> "np.typing.NDArray[Any]": ...
@property
def widths(self) -> np.ndarray: ...
def index(self, arg0: ArrayLike) -> int | np.ndarray: ...
def value(self, arg0: ArrayLike) -> float | np.ndarray: ...
def widths(self) -> "np.typing.NDArray[Any]": ...
def index(self, arg0: ArrayLike) -> int | "np.typing.NDArray[Any]": ...
def value(self, arg0: ArrayLike) -> float | "np.typing.NDArray[Any]": ...

class _BaseRegular(_BaseAxis):
def __init__(self, bins: int, start: float, stop: float) -> None: ...
Expand Down
4 changes: 2 additions & 2 deletions src/boost_histogram/_core/hist.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class _BaseHistogram:
def __copy__(self: T) -> T: ...
def __deepcopy__(self: T, memo: Any) -> T: ...
def __iadd__(self: T, other: _BaseHistogram) -> T: ...
def to_numpy(self, flow: bool = ...) -> Tuple[np.ndarray, ...]: ...
def view(self, flow: bool = ...) -> np.ndarray: ...
def to_numpy(self, flow: bool = ...) -> Tuple["np.typing.NDArray[Any]", ...]: ...
def view(self, flow: bool = ...) -> "np.typing.NDArray[Any]": ...
def axis(self, i: int = ...) -> axis._BaseAxis: ...
def fill(self, *args: ArrayLike, weight: ArrayLike | None = ...) -> None: ...
def empty(self, flow: bool = ...) -> bool: ...
Expand Down
12 changes: 6 additions & 6 deletions src/boost_histogram/_internal/axestuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ class ArrayTuple(tuple): # type: ignore

def __getattr__(self, name: str) -> Any:
if name in self._REDUCTIONS:
return partial(getattr(np, name), np.broadcast_arrays(*self))
return partial(getattr(np, name), np.broadcast_arrays(*self)) # type: ignore
else:
return self.__class__(getattr(a, name) for a in self)

def __dir__(self) -> List[str]:
names = dir(self.__class__) + dir(np.ndarray)
names = dir(self.__class__) + dir("np.typing.NDArray[Any]")
return sorted(n for n in names if not n.startswith("_"))

def __call__(self, *args: Any, **kwargs: Any) -> Any:
Expand All @@ -34,7 +34,7 @@ def broadcast(self: A) -> A:
Use this method to broadcast them out into their full memory
representation.
"""
return self.__class__(np.broadcast_arrays(*self))
return self.__class__(np.broadcast_arrays(*self)) # type: ignore


B = TypeVar("B", bound="AxesTuple")
Expand All @@ -56,17 +56,17 @@ def extent(self) -> Tuple[int, ...]:
@property
def centers(self) -> ArrayTuple:
gen = (s.centers for s in self)
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS))
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS)) # type: ignore

@property
def edges(self) -> ArrayTuple:
gen = (s.edges for s in self)
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS))
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS)) # type: ignore

@property
def widths(self) -> ArrayTuple:
gen = (s.widths for s in self)
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS))
return ArrayTuple(np.meshgrid(*gen, **self._MGRIDOPTS)) # type: ignore

def value(self, *indexes: float) -> Tuple[float, ...]:
if len(indexes) != len(self):
Expand Down
6 changes: 3 additions & 3 deletions src/boost_histogram/_internal/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,18 +248,18 @@ def __getitem__(self, i: AxCallOrInt) -> Union[int, str, Tuple[float, float]]:
return self.bin(i)

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

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

@property
def widths(self) -> np.ndarray:
def widths(self) -> "np.typing.NDArray[Any]":
"""
An array of bin widths.
"""
Expand Down
79 changes: 52 additions & 27 deletions src/boost_histogram/_internal/hist.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@
T = TypeVar("T")


def _fill_cast(value: T, *, inner: bool = False) -> Union[T, np.ndarray, Tuple[T, ...]]:
def _fill_cast(
value: T, *, inner: bool = False
) -> Union[T, "np.typing.NDArray[Any]", Tuple[T, ...]]:
"""
Convert to NumPy arrays. Some buffer objects do not get converted by forcecast.
If not called by itself (inner=False), then will work through one level of tuple/list.
Expand Down Expand Up @@ -297,13 +299,13 @@ def ndim(self) -> int:

def view(
self, flow: bool = False
) -> Union[np.ndarray, WeightedSumView, WeightedMeanView, MeanView]:
) -> Union["np.typing.NDArray[Any]", WeightedSumView, WeightedMeanView, MeanView]:
"""
Return a view into the data, optionally with overflow turned on.
"""
return _to_view(self._hist.view(flow))

def __array__(self) -> np.ndarray:
def __array__(self) -> "np.typing.NDArray[Any]":
return self.view(False)

def __eq__(self, other: Any) -> bool:
Expand All @@ -312,11 +314,15 @@ def __eq__(self, other: Any) -> bool:
def __ne__(self, other: Any) -> bool:
return (not hasattr(other, "_hist")) or self._hist != other._hist

def __add__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __add__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
result = self.copy(deep=False)
return result.__iadd__(other)

def __iadd__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __iadd__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
if isinstance(other, (int, float)) and other == 0:
return self
self._compute_inplace_op("__iadd__", other)
Expand All @@ -326,36 +332,52 @@ def __iadd__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:

return self

def __radd__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __radd__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
return self + other

# If these fail, the underlying object throws the correct error
def __mul__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __mul__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
result = self.copy(deep=False)
return result._compute_inplace_op("__imul__", other)

def __rmul__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __rmul__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
return self * other

def __truediv__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __truediv__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
result = self.copy(deep=False)
return result._compute_inplace_op("__itruediv__", other)

def __div__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __div__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
result = self.copy(deep=False)
return result._compute_inplace_op("__idiv__", other)

def __idiv__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __idiv__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
return self._compute_inplace_op("__idiv__", other)

def __itruediv__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __itruediv__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
return self._compute_inplace_op("__itruediv__", other)

def __imul__(self: H, other: Union["Histogram", np.ndarray, float]) -> H:
def __imul__(
self: H, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
return self._compute_inplace_op("__imul__", other)

def _compute_inplace_op(
self: H, name: str, other: Union["Histogram", np.ndarray, float]
self: H, name: str, other: Union["Histogram", "np.typing.NDArray[Any]", float]
) -> H:
# Also takes CppHistogram, but that confuses mypy because it's hard to pick out
if isinstance(other, Histogram):
Expand Down Expand Up @@ -442,26 +464,26 @@ def fill(
}:
raise RuntimeError("Mean histograms do not support threaded filling")

data = [np.array_split(a, threads) for a in args_ars]
data = [np.array_split(a, threads) for a in args_ars] # type: ignore

if weight is None or np.isscalar(weight):
assert threads is not None
weights = [weight_ars] * threads
else:
weights = np.array_split(weight_ars, threads)
weights = np.array_split(weight_ars, threads) # type: ignore

if sample_ars is None or np.isscalar(sample_ars):
assert threads is not None
samples = [sample_ars] * threads
else:
samples = np.array_split(sample_ars, threads)
samples = np.array_split(sample_ars, threads) # type: ignore

if self._hist._storage_type is _core.storage.atomic_int64:

def fun(
weight: Optional[ArrayLike],
sample: Optional[ArrayLike],
*args: np.ndarray,
*args: "np.typing.NDArray[Any]",
) -> None:
self._hist.fill(*args, weight=weight, sample=sample)

Expand All @@ -471,7 +493,7 @@ def fun(
def fun(
weight: Optional[ArrayLike],
sample: Optional[ArrayLike],
*args: np.ndarray,
*args: "np.typing.NDArray[Any]",
) -> None:
local_hist = self._hist.__copy__()
local_hist.reset()
Expand Down Expand Up @@ -646,7 +668,10 @@ def _compute_commonindex(

def to_numpy(
self, flow: bool = False, *, dd: bool = False, view: bool = False
) -> Union[Tuple[np.ndarray, ...], Tuple[np.ndarray, Tuple[np.ndarray, ...]]]:
) -> Union[
Tuple["np.typing.NDArray[Any]", ...],
Tuple["np.typing.NDArray[Any]", Tuple["np.typing.NDArray[Any]", ...]],
]:
"""
Convert to a NumPy style tuple of return arrays. Edges are converted to
match NumPy standards, with upper edge inclusive, unlike
Expand Down Expand Up @@ -887,7 +912,7 @@ def __setitem__(
if (
value.ndim > 0
and len(view.dtype) > 0 # type: ignore
and len(value.dtype) == 0 # type: ignore
and len(value.dtype) == 0
and len(view.dtype) == value.shape[-1] # type: ignore
):
value_shape = value.shape[:-1]
Expand Down Expand Up @@ -984,7 +1009,7 @@ def kind(self) -> Kind:
else:
return Kind.COUNT

def values(self, flow: bool = False) -> np.ndarray:
def values(self, flow: bool = False) -> "np.typing.NDArray[Any]":
"""
Returns the accumulated values. The counts for simple histograms, the
sum of weights for weighted histograms, the mean for profiles, etc.
Expand All @@ -995,7 +1020,7 @@ def values(self, flow: bool = False) -> np.ndarray:
:param flow: Enable flow bins. Not part of PlottableHistogram, but
included for consistency with other methods and flexibility.

:return: np.ndarray[np.float64]
:return: "np.typing.NDArray[Any]"[np.float64]
"""

view = self.view(flow)
Expand All @@ -1005,7 +1030,7 @@ def values(self, flow: bool = False) -> np.ndarray:
else:
return view.value # type: ignore

def variances(self, flow: bool = False) -> Optional[np.ndarray]:
def variances(self, flow: bool = False) -> Optional["np.typing.NDArray[Any]"]:
"""
Returns the estimated variance of the accumulated values. The sum of squared
weights for weighted histograms, the variance of samples for profiles, etc.
Expand All @@ -1026,7 +1051,7 @@ def variances(self, flow: bool = False) -> Optional[np.ndarray]:
:param flow: Enable flow bins. Not part of PlottableHistogram, but
included for consistency with other methods and flexibility.

:return: np.ndarray[np.float64]
:return: "np.typing.NDArray[Any]"[np.float64]
"""

view = self.view(flow)
Expand All @@ -1053,7 +1078,7 @@ def variances(self, flow: bool = False) -> Optional[np.ndarray]:
else:
return view.variance # type: ignore

def counts(self, flow: bool = False) -> np.ndarray:
def counts(self, flow: bool = False) -> "np.typing.NDArray[Any]":
"""
Returns the number of entries in each bin for an unweighted
histogram or profile and an effective number of entries (defined below)
Expand All @@ -1073,7 +1098,7 @@ def counts(self, flow: bool = False) -> np.ndarray:
The larger the spread in weights, the smaller it is, but it is always 0
if filled 0 times, and 1 if filled once, and more than 1 otherwise.

:return: np.ndarray[np.float64]
:return: "np.typing.NDArray[Any]"[np.float64]
"""

view = self.view(flow)
Expand Down
Loading