From 00c1cea934d8871f96190e1df2d0e511b3943412 Mon Sep 17 00:00:00 2001 From: Pengyi Peng Date: Thu, 12 Nov 2026 10:35:56 +0800 Subject: [PATCH] TYP: accept scalar-returning IRR selectors --- numpy_financial/_financial.py | 4 ++-- typing_tests/irr_selection.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 typing_tests/irr_selection.py diff --git a/numpy_financial/_financial.py b/numpy_financial/_financial.py index 08220b2..914f087 100644 --- a/numpy_financial/_financial.py +++ b/numpy_financial/_financial.py @@ -1007,7 +1007,7 @@ def rate( return rn -def _irr_default_selection(eirr: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: +def _irr_default_selection(eirr: npt.NDArray[np.float64]) -> np.float64: """ default selection logic for IRR function when there are > 1 real solutions """ # check sign of all IRR solutions same_sign = np.all(eirr > 0) if eirr[0] > 0 else np.all(eirr < 0) @@ -1029,7 +1029,7 @@ def _irr_default_selection(eirr: npt.NDArray[np.float64]) -> npt.NDArray[np.floa _SelectionFunc: TypeAlias = Callable[ [npt.NDArray[np.float64]], - npt.NDArray[np.float64], + float | np.floating[Any], ] diff --git a/typing_tests/irr_selection.py b/typing_tests/irr_selection.py new file mode 100644 index 0000000..d97d166 --- /dev/null +++ b/typing_tests/irr_selection.py @@ -0,0 +1,29 @@ +"""Static IRR selector contract, checked by the repository-wide mypy job.""" +import numpy as np +import numpy.typing as npt + +import numpy_financial as npf + + +def select_python_float(candidates: npt.NDArray[np.float64]) -> float: + return float(candidates[0]) + + +def select_numpy_float(candidates: npt.NDArray[np.float64]) -> np.float64: + return candidates[0] + + +def select_numpy_float32(candidates: npt.NDArray[np.float64]) -> np.float32: + return np.float32(candidates[0]) + + +def select_array(candidates: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: + return candidates + + +cashflows = [-5, 10.5, 1, -8, 1] +default_result: float = npf.irr(cashflows) +python_result: float = npf.irr(cashflows, selection_logic=select_python_float) +numpy_result: float = npf.irr(cashflows, selection_logic=select_numpy_float) +float32_result: float = npf.irr(cashflows, selection_logic=select_numpy_float32) +npf.irr(cashflows, selection_logic=select_array) # type: ignore[arg-type]