From 025afa4099220b0d4bda6351efe2fe077e32573b Mon Sep 17 00:00:00 2001 From: Gene Dan Date: Fri, 4 Sep 2026 10:50:34 -0500 Subject: [PATCH] [FIX] Apply Ruff fixes. --- chainladder/core/correlation.py | 22 +- chainladder/core/slice.py | 236 +++++++++++++--------- chainladder/core/tests/test_arithmetic.py | 92 +++++---- chainladder/core/tests/test_grain.py | 35 ++-- chainladder/core/tests/test_slicing.py | 131 +++++++----- pyproject.toml | 5 - 6 files changed, 295 insertions(+), 226 deletions(-) diff --git a/chainladder/core/correlation.py b/chainladder/core/correlation.py index c746904b9..b00b21b4c 100644 --- a/chainladder/core/correlation.py +++ b/chainladder/core/correlation.py @@ -140,20 +140,20 @@ def __init__(self, triangle, p_critical: float = 0.5): numerator.values = numerator.values[..., :-1] numerator.ddims = numerator.ddims[:-1] - # I is the number of development periods in the triangle - I = len(triangle.development) + # n_dev_periods is the number of development periods in the triangle ("I" in the Mack 97). + n_dev_periods = len(triangle.development) # k values are the column indexes for which we are calculating T_k k = xp.array(range(2, 2 + numerator.shape[3])) # denominator is the one in formula G4 of the Mack 97 paper - denominator = ((I - k) ** 3 - I + k)[None, None, None] + denominator = ((n_dev_periods - k) ** 3 - n_dev_periods + k)[None, None, None] # complete formula G4, results in array of each T_k value self.t = 1 - 6 * xp.nan_to_num(numerator.values) / denominator # per Mack, weight is one less than the number of pairs for each T_k - weight = (I - k - 1)[None, None, None] + weight = (n_dev_periods - k - 1)[None, None, None] # Calculate big T, the weighted average of the T_k values t_expectation = ( @@ -163,7 +163,7 @@ def __init__(self, triangle, p_critical: float = 0.5): idx = triangle.index.set_index(triangle.key_labels).index # variance is result of formula G6 - self.t_variance = 2 / ((I - 2) * (I - 3)) + self.t_variance = 2 / ((n_dev_periods - 2) * (n_dev_periods - 3)) # array of t values self.t = pd.DataFrame(self.t[0, 0, ...], columns=k, index=["T_k"]) @@ -280,7 +280,7 @@ class ValuationCorrelation: def __init__(self, triangle: Triangle, p_critical: float = 0.1, total: bool = True): - def pZlower(z: int, n: int, p: float = 0.5) -> float: + def p_z_lower(z: int, n: int, p: float = 0.5) -> float: return min(1, 2 * binom.cdf(z, n, p)) self.p_critical = p_critical @@ -317,12 +317,10 @@ def pZlower(z: int, n: int, p: float = 0.5) -> float: if not self.total: T = [] for i in range(0, xp.max(m1large.shape[2:]) + 1): - T.append( - [ - pZlower(i, j, 0.5) - for j in range(0, xp.max(m1large.shape[2:]) + 1) - ] - ) + T.append([ + p_z_lower(i, j, 0.5) + for j in range(0, xp.max(m1large.shape[2:]) + 1) + ]) T = np.array(T) z_idx, n_idx = z.astype(int), n.astype(int) self.probs = T[z_idx, n_idx] diff --git a/chainladder/core/slice.py b/chainladder/core/slice.py index 519969988..984b75865 100644 --- a/chainladder/core/slice.py +++ b/chainladder/core/slice.py @@ -1,6 +1,7 @@ """ Support pandas-style slicing to the Triangle class. """ + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. @@ -9,36 +10,23 @@ import numpy as np import pandas as pd -from chainladder.core.typing import ( - _AxisKey, - _LabelKey, - TriangleProtocol -) +from chainladder.core.typing import _AxisKey, _LabelKey, TriangleProtocol from chainladder.utils.utility_functions import num_to_nan -from typing import ( - cast, - overload, - TYPE_CHECKING -) +from typing import cast, overload, TYPE_CHECKING if TYPE_CHECKING: from chainladder import Triangle - from collections.abc import ( - Callable, - Sequence - ) - from chainladder.core.typing import ( - BackendArray, - IndexExpression - ) + from collections.abc import Callable, Sequence + from chainladder.core.typing import BackendArray, IndexExpression from sparse import COO from types import ModuleType from typing import Literal from sparse import _slicing # noqa + class _LocBase: """ Base class for pandas style loc/iloc indexing. @@ -80,7 +68,9 @@ def get_idx(self, idx: tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]) -> Triangl obj.odims, obj.ddims = obj.odims[o_idx], obj.ddims[d_idx] # Set indexers. obj.iloc, obj.loc = Ilocation(obj), Location(obj) - obj.valuation_date = cast(pd.Timestamp, np.minimum(obj.valuation.max(), obj.valuation_date)) + obj.valuation_date = cast( + pd.Timestamp, np.minimum(obj.valuation.max(), obj.valuation_date) + ) return obj @staticmethod @@ -127,9 +117,9 @@ def _contig_slice(arr: _AxisKey) -> slice | np.ndarray: return slice(min_arr, max_arr, step) def __setitem__( - self, - key: tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], - values: int | float | TriangleSlicer + self, + key: tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], + values: int | float | TriangleSlicer, ) -> None: """ Supports the square bracket syntax [] for setting Triangle values. Only supported for numpy backend. @@ -147,28 +137,34 @@ def __setitem__( """ if self.obj.array_backend == "sparse": - raise ValueError('Setting values with sparse backend requires .at or .iat') + raise ValueError("Setting values with sparse backend requires .at or .iat") if isinstance(values, TriangleSlicer): values = values.values # attempt to make keys contig contig_key = tuple([_LocBase._contig_slice(x) for x in key]) # Create a slice for any key elements that are integers, otherwise preserve the slice or array. - tuple_key = tuple( - [slice(item, item + 1) if isinstance(item, int) else item for item in contig_key] - ) + tuple_key = tuple([ + slice(item, item + 1) if isinstance(item, int) else item + for item in contig_key + ]) norm_key = self._normalize_index(tuple_key) if type(norm_key[2]) is not slice or type(norm_key[3]) is not slice: - raise ValueError("Setting while fancy indexing on origin/development is not supported.") + raise ValueError( + "Setting while fancy indexing on origin/development is not supported." + ) if type(norm_key[0]) is slice or type(norm_key[1]) is slice: - cast(np.ndarray, cast(object, self.obj.values)).__setitem__(norm_key, values) + cast(np.ndarray, cast(object, self.obj.values)).__setitem__( + norm_key, values + ) else: - #the getter uses arr[idx,:][:,idx] to get the Cartesian product, using np.ix_ on the setter to match + # the getter uses arr[idx,:][:,idx] to get the Cartesian product, using np.ix_ on the setter to match cast(np.ndarray, cast(object, self.obj.values)).__setitem__( - np.ix_(norm_key[0], norm_key[1]) + (norm_key[2], norm_key[3]), - values + np.ix_(norm_key[0], norm_key[1]) + (norm_key[2], norm_key[3]), values ) - def _normalize_index(self, key: IndexExpression) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: + def _normalize_index( + self, key: IndexExpression + ) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: """ Converts an indexing expression into a standard 4-D format. When the indexing has fewer dimensions than 4, slices for the remaining dimensions are added. @@ -185,16 +181,20 @@ def _normalize_index(self, key: IndexExpression) -> tuple[_AxisKey, _AxisKey, _A """ # Apply sparse normalization, fills out the rest of the dimensions using the shape of the Triangle. - key: tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey] = _slicing.normalize_index(key, self.obj.shape) + key: tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey] = _slicing.normalize_index( + key, self.obj.shape + ) key_list = [] # Preserve start/stop/step boundaries if the user has specified them, otherwise replace them with None. # None indicates "go-to-boundary" for the slice. for n, i in enumerate(key): if isinstance(i, slice): - start: int | None= i.start if i.start > 0 else None + start: int | None = i.start if i.start > 0 else None stop: int | None = i.stop if i.stop > -1 else None stop: int | None = None if stop == self.obj.shape[n] else stop - step: int | None = None if start is None and stop is None and (i.step == 1) else i.step + step: int | None = ( + None if start is None and stop is None and (i.step == 1) else i.step + ) key_list.append(slice(start, stop, step)) else: key_list.append(i) @@ -202,9 +202,9 @@ def _normalize_index(self, key: IndexExpression) -> tuple[_AxisKey, _AxisKey, _A return key def _sparse_setitem( - self, - key: tuple[int, int, int, int], - values: int | float, + self, + key: tuple[int, int, int, int], + values: int | float, ) -> None: """ Set slice of Triangle when backend is sparse. @@ -225,10 +225,11 @@ def _sparse_setitem( arr: COO = cast("COO", cast(object, self.obj.values)) # Check if a stored value exists at the coordinate point. check = ( - (arr.coords[0] == key[0]) * - (arr.coords[1] == key[1]) * - (arr.coords[2] == key[2]) * - (arr.coords[3] == key[3])) + (arr.coords[0] == key[0]) + * (arr.coords[1] == key[1]) + * (arr.coords[2] == key[2]) + * (arr.coords[3] == key[3]) + ) # If it does, index the location and assign the value directly. if check.max(): data_index = np.where(check)[0][0] @@ -236,11 +237,9 @@ def _sparse_setitem( # Otherwise, create a new sparse array with the updated coordinates and data. else: # Append the new coordinate. - arr.coords = np.concatenate( - (arr.coords, np.array(key)[:, None]), axis=1) + arr.coords = np.concatenate((arr.coords, np.array(key)[:, None]), axis=1) # Append the new data element. - arr.data = np.concatenate( - (arr.data, np.array([values])), axis=0) + arr.data = np.concatenate((arr.data, np.array([values])), axis=0) # Construct the new sparse array and assign to Triangle. self.obj.values = self.obj.get_array_module().COO( coords=arr.coords, @@ -248,7 +247,7 @@ def _sparse_setitem( prune=True, has_duplicates=False, shape=self.obj.shape, - fill_value=arr.fill_value + fill_value=arr.fill_value, ) @staticmethod @@ -274,12 +273,9 @@ def _to_scalar(values: int | float | TriangleSlicer) -> int | float: class Location(_LocBase): - """ class to generate .loc[] functionality """ + """class to generate .loc[] functionality""" - def __getitem__( - self, - key: _LabelKey - ) -> Triangle: + def __getitem__(self, key: _LabelKey) -> Triangle: """ Support square bracket indexing of Triangle.loc[] to extract data. @@ -301,7 +297,9 @@ def __getitem__( obj.set_index(obj.index.iloc[:, 1:], inplace=True) return obj - def format_key(self, key: _LabelKey) -> tuple[_LabelKey, _LabelKey, _LabelKey, _LabelKey]: + def format_key( + self, key: _LabelKey + ) -> tuple[_LabelKey, _LabelKey, _LabelKey, _LabelKey]: """ Aligns a user-supplied label-based key to the Triangle's 4 axes, leaving each element as a label-based selector for index_key/other_key to resolve later. @@ -320,9 +318,13 @@ def format_key(self, key: _LabelKey) -> tuple[_LabelKey, _LabelKey, _LabelKey, _ # Preprocess into a common tuple-format prior to standardizing the dimensions. # Case when key is a tuple representing an index row. - if (isinstance(key, tuple) and len(key) > 1 - and len(self.obj.key_labels) > 1 and type(key[1]) is str - and key[1] in self.obj.index[self.obj.key_labels[1]].unique()): + if ( + isinstance(key, tuple) + and len(key) > 1 + and len(self.obj.key_labels) > 1 + and type(key[1]) is str + and key[1] in self.obj.index[self.obj.key_labels[1]].unique() + ): key = (key,) # Case when tuple elements represent separate dimensions, keep as-is. elif isinstance(key, tuple): @@ -364,27 +366,30 @@ def index_key(self, key: _LabelKey) -> np.ndarray: """ # Case when key is a single index row and not a boolean mask, preprocess into a DataFrame of labels. if isinstance(key, pd.Series) and len(key) != len(self.obj): - key = key.to_frame().T + key = key.to_frame().T # Case boolean mask. Extract the positions where True. if isinstance(key, pd.Series): idx = np.where(key)[0] # Case DataFrame of labels, find positions in index. elif isinstance(key, pd.DataFrame): - idx = (self.obj.index.reset_index().set_index(self.obj.key_labels) - .loc[key.set_index(list(key.columns)).index]).values.flatten() + idx = ( + self.obj.index + .reset_index() + .set_index(self.obj.key_labels) + .loc[key.set_index(list(key.columns)).index] + ).values.flatten() # Case Pandas-style label selectors, extract positions from index. elif type(key) in [slice, list, tuple]: - idx = (self.obj.index.reset_index() - .set_index(self.obj.key_labels).loc[key]).values.flatten() + idx = ( + self.obj.index.reset_index().set_index(self.obj.key_labels).loc[key] + ).values.flatten() # Case scalar, locate position in first level of index. else: - idx = np.where(self.obj.kdims[:, 0]==key)[0] + idx = np.where(self.obj.kdims[:, 0] == key)[0] return idx def other_key( - self, - key: _LabelKey, - idx: Literal['columns', 'origin', 'development'] + self, key: _LabelKey, idx: Literal["columns", "origin", "development"] ) -> np.ndarray | slice: """ Converts a label-based key into an integer-based one. Intended to be used for axes other than the index. @@ -413,13 +418,14 @@ def other_key( obj_idx = pd.Series(range(len(s)), index=s) if type(key) in [slice, list]: return obj_idx.loc[key].values - if not hasattr(key, '__iter__') or type(key) is str: + if not hasattr(key, "__iter__") or type(key) is str: return np.array([obj_idx.loc[key]]) else: raise AttributeError("Unable to slice.") - - def key_to_slice(self, key: _LabelKey) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: + def key_to_slice( + self, key: _LabelKey + ) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: """ Converts keys to integer slices. @@ -436,10 +442,12 @@ def key_to_slice(self, key: _LabelKey) -> tuple[_AxisKey, _AxisKey, _AxisKey, _A # Preprocess key into a normalized 4-D key. key = self.format_key(key) # Transform into integer-based slices. - out = (self.index_key(key[0]), - self.other_key(key[1], 'columns'), - self.other_key(key[2], 'origin'), - self.other_key(key[3], 'development')) + out = ( + self.index_key(key[0]), + self.other_key(key[1], "columns"), + self.other_key(key[2], "origin"), + self.other_key(key[3], "development"), + ) return out def __setitem__(self, key: _LabelKey, values: int | float | TriangleSlicer) -> None: @@ -458,7 +466,11 @@ def __setitem__(self, key: _LabelKey, values: int | float | TriangleSlicer) -> N None """ - super().__setitem__(cast(tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], self.key_to_slice(key)), values) + super().__setitem__( + cast(tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], self.key_to_slice(key)), + values, + ) + class Ilocation(_LocBase): """ @@ -478,12 +490,13 @@ class TriangleSlicer: """ @overload - def __getitem__(self: TriangleProtocol, key: pd.Series | np.ndarray | list[str]) -> Triangle: ... + def __getitem__( + self: TriangleProtocol, key: pd.Series | np.ndarray | list[str] + ) -> Triangle: ... @overload def __getitem__(self: TriangleProtocol, key: str | int) -> Triangle | pd.Series: ... def __getitem__( - self: TriangleProtocol, - key: pd.Series | np.ndarray | str | list[str] | int + self: TriangleProtocol, key: pd.Series | np.ndarray | str | list[str] | int ) -> Triangle | pd.Series: """ Boolean Slicer functionality. @@ -522,15 +535,17 @@ def __getitem__( out: Triangle = self.virtual_columns[key].copy() out.virtual_columns.columns = {} return out - keys: Sequence[str | int] = [key] if isinstance(key, (str, int, float, np.generic)) else key + keys: Sequence[str | int] = ( + [key] if isinstance(key, (str, int, float, np.generic)) else key + ) # Identify the position of each requested element within the valuation dimension. idx = [list(self.vdims).index(item) for item in keys] return self.iloc[:, idx] def __setitem__( - self: TriangleProtocol, - key: str | int, - value: int | float | TriangleSlicer | Callable[[Triangle], TriangleSlicer] + self: TriangleProtocol, + key: str | int, + value: int | float | TriangleSlicer | Callable[[Triangle], TriangleSlicer], ) -> None: """ Function for pandas-style column setting, i.e., Triangle[...] = value. @@ -597,7 +612,7 @@ def __setitem__( data=data, shape=self.shape, prune=True, - fill_value=xp.COO.nan + fill_value=xp.COO.nan, ) # Case numpy backend. else: @@ -614,7 +629,10 @@ def __setitem__( self.values = xp.concatenate((self.values, value.values), axis=1) except (ValueError, AttributeError, AssertionError): # For misaligned triangle support. - conc = (self.values, (self.iloc[:, 0] * 0 + cast("Triangle", value)).values) + conc = ( + self.values, + (self.iloc[:, 0] * 0 + cast("Triangle", value)).values, + ) self.values = xp.concatenate(conc, axis=1) def _slice_valuation(self: TriangleProtocol, key: np.ndarray) -> Triangle: @@ -638,16 +656,22 @@ def _slice_valuation(self: TriangleProtocol, key: np.ndarray) -> Triangle: obj.valuation_date = min(obj.valuation[key].max(), obj.valuation_date) # Filter out values by converting them to nan. key = key.reshape(self.shape[-2:], order="F") - obj.values = cast("BackendArray", num_to_nan(obj.values * obj.get_array_module().array(key))) + obj.values = cast( + "BackendArray", num_to_nan(obj.values * obj.get_array_module().array(key)) + ) # Recalculate size of the origin and development axes and return the slice. return _LocBase(obj).get_idx(( slice(None), slice(None), np.arange(obj.shape[2])[np.sum(~key, 1) != obj.shape[3]], - np.arange(obj.shape[3])[np.sum(~key, 0) != obj.shape[2]] - )) + np.arange(obj.shape[3])[np.sum(~key, 0) != obj.shape[2]], + )) - def _slice(self: TriangleProtocol, key: pd.Series | np.ndarray, axis: Literal['ddims', 'odims']) -> Triangle: + def _slice( + self: TriangleProtocol, + key: pd.Series | np.ndarray, + axis: Literal["ddims", "odims"], + ) -> Triangle: """ Private method for handling of origin/development slicing. @@ -682,14 +706,19 @@ def _set_slicers(self: TriangleProtocol) -> None: """ self.iloc, self.loc = Ilocation(self), Location(self) self.iat, self.at = Iat(self), At(self) - self.virtual_columns = VirtualColumns(cast("Triangle", self), self.virtual_columns.columns) + self.virtual_columns = VirtualColumns( + cast("Triangle", self), self.virtual_columns.columns + ) class At(Location): """ Single-element accessor. Mirrors pandas.DataFrame.at[]. """ - def _check_index(self, key: _LabelKey) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: + + def _check_index( + self, key: _LabelKey + ) -> tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey]: """ Makes sure that the requested key explicitly specifies all 4 axes (index, columns, origin, development) and that it will grab a single @@ -705,12 +734,14 @@ def _check_index(self, key: _LabelKey) -> tuple[_AxisKey, _AxisKey, _AxisKey, _A If the key passes validation, it's returned as a tuple of integer slices, otherwise an error is raised. """ - err_msg: str = 'Invalid Index in At slicer.' + err_msg: str = "Invalid Index in At slicer." # Unlike loc/iloc, at requires every axis to be specified explicitly. if not isinstance(key, tuple) or len(key) != 4 or Ellipsis in key: raise ValueError(err_msg) # Convert to integer slices. - idx = cast(tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], self.key_to_slice(key)) + idx = cast( + tuple[_AxisKey, _AxisKey, _AxisKey, _AxisKey], self.key_to_slice(key) + ) for n, item in enumerate(idx): if type(item) is slice: # A slice here is always the full axis (slice(None, None, None)), @@ -759,17 +790,23 @@ def __setitem__(self, key: _LabelKey, values: int | float | TriangleSlicer) -> N """ key = self._check_index(key) values = self._to_scalar(values) - if self.obj.array_backend == 'sparse': - key = tuple(0 if type(item) is slice else int(cast(np.ndarray, item)[0]) for item in key) + if self.obj.array_backend == "sparse": + key = tuple( + 0 if type(item) is slice else int(cast(np.ndarray, item)[0]) + for item in key + ) self._sparse_setitem(key, values) else: - cast(np.ndarray, cast(object, self.obj.values)).__setitem__(self._normalize_index(key), values) + cast(np.ndarray, cast(object, self.obj.values)).__setitem__( + self._normalize_index(key), values + ) class Iat(Ilocation): """ Single-element integer-based accessor. Mirrors pandas.DataFrame.iat[]. """ + def _check_index(self, key: IndexExpression) -> tuple[int, int, int, int]: """ Make sure the requested key accesses a single element. @@ -787,7 +824,7 @@ def _check_index(self, key: IndexExpression) -> tuple[int, int, int, int]: idx = self._normalize_index(key) types = {type(i) for i in idx} if len(types) > 1 or list(types)[0] is not int: - raise ValueError('iAt based indexing can only have integer indexers') + raise ValueError("iAt based indexing can only have integer indexers") return cast("tuple[int, int, int, int]", idx) def __getitem__(self, key: IndexExpression) -> float: @@ -807,7 +844,9 @@ def __getitem__(self, key: IndexExpression) -> float: """ return self.get_idx(self._check_index(key)).values[0, 0, 0, 0] - def __setitem__(self, key: IndexExpression, values: int | float | TriangleSlicer) -> None: + def __setitem__( + self, key: IndexExpression, values: int | float | TriangleSlicer + ) -> None: """ Sets a single-element of a Triangle to a scalar value. @@ -823,7 +862,7 @@ def __setitem__(self, key: IndexExpression, values: int | float | TriangleSlicer """ idx = self._check_index(key) - if self.obj.array_backend == 'sparse': + if self.obj.array_backend == "sparse": self._sparse_setitem(idx, self._to_scalar(values)) else: super().__setitem__(idx, values) @@ -834,6 +873,7 @@ class VirtualColumns: A virtual column is a non-computed column that enables lazy evaluation. For example, a column created by assigning a lambda expression. """ + def __init__(self, triangle: Triangle, columns=None): self.triangle = triangle self.columns = {} if not columns else columns @@ -854,7 +894,9 @@ def __getitem__(self, value: str | int) -> Triangle: """ return self.columns[value](self.triangle).rename("columns", [value]) - def __setitem__(self, name: str | int, value: Callable[[Triangle], TriangleSlicer]) -> None: + def __setitem__( + self, name: str | int, value: Callable[[Triangle], TriangleSlicer] + ) -> None: """ Set a new Callable for the requested virtual column. diff --git a/chainladder/core/tests/test_arithmetic.py b/chainladder/core/tests/test_arithmetic.py index 714f1dd18..3e89ecf5e 100644 --- a/chainladder/core/tests/test_arithmetic.py +++ b/chainladder/core/tests/test_arithmetic.py @@ -109,8 +109,8 @@ def test_arithmetic_union_val_tri(raa: Triangle) -> None: None """ val_raa = raa.dev_to_val() - a = val_raa[val_raa.valuation < '1987'] - b = val_raa[val_raa.valuation >= '1987'] + a = val_raa[val_raa.valuation < "1987"] + b = val_raa[val_raa.valuation >= "1987"] result = a + b assert isinstance(result.ddims, pd.DatetimeIndex) assert result.shape == val_raa.shape @@ -130,8 +130,8 @@ def test_origin_broadcasting(raa: Triangle) -> None: ------- None """ - single_origin = raa.sum('origin') - single_origin['values'] = 500 + single_origin = raa.sum("origin") + single_origin["values"] = 500 result = raa + single_origin assert result.shape == raa.shape assert result == raa + 500 @@ -139,7 +139,7 @@ def test_origin_broadcasting(raa: Triangle) -> None: def test_arithmetic_union(raa): assert raa.shape == (raa - raa[raa.valuation < "1987"]).shape - assert raa[raa.valuation<'1986'] + raa[raa.valuation>='1986'] == raa + assert raa[raa.valuation < "1986"] + raa[raa.valuation >= "1986"] == raa def test_arithmetic_across_keys(qtr): @@ -149,7 +149,7 @@ def test_arithmetic_across_keys(qtr): def test_arithmetic_1(raa): x = raa assert -(((x / x) + 0) * x) == -(+x) - assert 1 - (x / x) == 0 * x * 0 + assert 1 - (x / x) == 0 * x * 0 def test_eq_non_triangle(raa: Triangle) -> None: @@ -167,7 +167,8 @@ def test_eq_non_triangle(raa: Triangle) -> None: """ assert (raa == 42) is False assert (raa == "foo") is False - assert (raa == None) is False + # Ruff will flag "raa == None", so we call the dunder directly. + assert raa.__eq__(None) is False def test_pow_groupby(clrd: Triangle) -> None: @@ -177,7 +178,7 @@ def test_pow_groupby(clrd: Triangle) -> None: assert result.shape == a.shape # x^0 == 1 for every computed cell: predictable value check without overflow zeros_gb = (a * 0).groupby("LOB").sum() - result_exp_zero = (a ** zeros_gb).set_backend("numpy") + result_exp_zero = (a**zeros_gb).set_backend("numpy") non_nan = result_exp_zero.values[~np.isnan(result_exp_zero.values)] assert len(non_nan) > 0 assert np.all(non_nan == 1.0) @@ -204,9 +205,9 @@ def test_vector_division(raa: Triangle) -> None: result = raa.latest_diagonal / raa assert result.shape == raa.shape for i in range(raa.shape[2]): - orig = raa.iloc[..., i:i+1, :] - ld = raa.latest_diagonal.iloc[..., i:i+1, :] - assert result.iloc[..., i:i+1, :] == ld / orig + orig = raa.iloc[..., i : i + 1, :] + ld = raa.latest_diagonal.iloc[..., i : i + 1, :] + assert result.iloc[..., i : i + 1, :] == ld / orig def test_multiindex_broadcast(clrd): @@ -215,58 +216,60 @@ def test_multiindex_broadcast(clrd): def test_index_broadcasting(clrd): - """ Basic broadcasting where b is a subset of a """ + """Basic broadcasting where b is a subset of a""" assert ((clrd / clrd.sum()) - ((1 / clrd.sum()) * clrd)).sum().sum().sum() < 1e-4 + def test_index_broadcasting2(clrd): - """ b.key_labels are a subset of a.key_labels and b is missing some elements """ - a = clrd['CumPaidLoss'] - b = clrd['CumPaidLoss'].groupby('LOB').sum().iloc[:-1] + """b.key_labels are a subset of a.key_labels and b is missing some elements""" + a = clrd["CumPaidLoss"] + b = clrd["CumPaidLoss"].groupby("LOB").sum().iloc[:-1] c = a + b assert (a.index == c.index).all().all() def test_index_broadcasting3(clrd): - """ b.key_labels are a subset of a.key_labels and a is missing some elements """ - a = clrd[~clrd['LOB'].isin(['wkcomp', 'medmal'])]['CumPaidLoss'] - b = clrd['CumPaidLoss'].groupby('LOB').sum() + """b.key_labels are a subset of a.key_labels and a is missing some elements""" + a = clrd[~clrd["LOB"].isin(["wkcomp", "medmal"])]["CumPaidLoss"] + b = clrd["CumPaidLoss"].groupby("LOB").sum() c = a + b - assert (a.index == c[~c['LOB'].isin(['wkcomp', 'medmal'])].index).all().all() + assert (a.index == c[~c["LOB"].isin(["wkcomp", "medmal"])].index).all().all() assert len(c) - len(a) == 2 def test_index_broadcasting4(clrd): - """ b should broadcast to a if b only has one index element """ - a = clrd['CumPaidLoss'] - b = clrd['CumPaidLoss'].groupby('LOB').sum().iloc[0] + """b should broadcast to a if b only has one index element""" + a = clrd["CumPaidLoss"] + b = clrd["CumPaidLoss"].groupby("LOB").sum().iloc[0] c = a + b assert (a.index == c.index).all().all() def test_index_broadacsting4(clrd): - """ If one triangle has key_labels that are not a subset of the other, then fail """ - a = clrd['CumPaidLoss'] - b = clrd['CumPaidLoss'].groupby('LOB').sum() + """If one triangle has key_labels that are not a subset of the other, then fail""" + a = clrd["CumPaidLoss"] + b = clrd["CumPaidLoss"].groupby("LOB").sum() idx = b.index - idx['New Field'] = 'New' + idx["New Field"] = "New" b.index = idx with pytest.raises(ValueError, match="Index broadcasting is ambiguous"): - _= a + b + _ = a + b + def test_index_broadcasting5(clrd): - """ If a and b have shared key labels but no matching levels, then they will stack """ - a = clrd['CumPaidLoss'].iloc[:300] - b = clrd['CumPaidLoss'].iloc[300:] + """If a and b have shared key labels but no matching levels, then they will stack""" + a = clrd["CumPaidLoss"].iloc[:300] + b = clrd["CumPaidLoss"].iloc[300:] c = a + b - assert c.sort_index() == clrd['CumPaidLoss'].sort_index() + assert c.sort_index() == clrd["CumPaidLoss"].sort_index() def test_index_broadacsting6(clrd): - a = clrd['CumPaidLoss'].iloc[:100] - b = clrd['CumPaidLoss'].iloc[50:150] - c = clrd['CumPaidLoss'].iloc[50:100] + a = clrd["CumPaidLoss"].iloc[:100] + b = clrd["CumPaidLoss"].iloc[50:150] + c = clrd["CumPaidLoss"].iloc[50:100] d = a + b - c - assert d.sort_index() == clrd['CumPaidLoss'].iloc[:150].sort_index() + assert d.sort_index() == clrd["CumPaidLoss"].iloc[:150].sort_index() def test_index_broadcasting_ambiguous(clrd: Triangle) -> None: @@ -282,10 +285,10 @@ def test_index_broadcasting_ambiguous(clrd: Triangle) -> None: ------- None """ - a = clrd['CumPaidLoss'].groupby('GRNAME').sum() - b = clrd['CumPaidLoss'].groupby('LOB').sum() + a = clrd["CumPaidLoss"].groupby("GRNAME").sum() + b = clrd["CumPaidLoss"].groupby("LOB").sum() with pytest.raises(ValueError, match="Index broadcasting is ambiguous"): - _= a + b + _ = a + b def test_prep_columns_reindexes_superset(clrd: Triangle) -> None: @@ -303,9 +306,12 @@ def test_prep_columns_reindexes_superset(clrd: Triangle) -> None: ------- None """ - x = clrd[['CumPaidLoss', 'EarnedPremNet', 'IncurLoss']] - y = clrd[['CumPaidLoss', 'IncurLoss']] + x = clrd[["CumPaidLoss", "EarnedPremNet", "IncurLoss"]] + y = clrd[["CumPaidLoss", "IncurLoss"]] for result in [x + y, y + x]: - assert set(result.columns) == {'CumPaidLoss', 'EarnedPremNet', 'IncurLoss'} - assert result[['CumPaidLoss', 'IncurLoss']] == clrd[['CumPaidLoss', 'IncurLoss']] * 2 - assert result['EarnedPremNet'] == clrd['EarnedPremNet'] \ No newline at end of file + assert set(result.columns) == {"CumPaidLoss", "EarnedPremNet", "IncurLoss"} + assert ( + result[["CumPaidLoss", "IncurLoss"]] + == clrd[["CumPaidLoss", "IncurLoss"]] * 2 + ) + assert result["EarnedPremNet"] == clrd["EarnedPremNet"] diff --git a/chainladder/core/tests/test_grain.py b/chainladder/core/tests/test_grain.py index a92aeb65b..f3da222c4 100644 --- a/chainladder/core/tests/test_grain.py +++ b/chainladder/core/tests/test_grain.py @@ -1,30 +1,26 @@ import chainladder as cl -import pandas as pd import numpy as np -import copy import pytest def test_grain(qtr): - #this test is dense only in practice, since grain() applies auto_sparse, which is True by default + # this test is dense only in practice, since grain() applies auto_sparse, which is True by default actual = qtr.iloc[0, 0].grain("OYDY") nan = np.nan - expected = np.array( - [ - [44, 621, 950, 1020, 1070, 1069, 1089, 1094, 1097, 1099, 1100, 1100], - [42, 541, 1052, 1169, 1238, 1249, 1266, 1269, 1296, 1300, 1300, nan], - [17, 530, 966, 1064, 1100, 1128, 1155, 1196, 1201, 1200, nan, nan], - [10, 393, 935, 1062, 1126, 1209, 1243, 1286, 1298, nan, nan, nan], - [13, 481, 1021, 1267, 1400, 1476, 1550, 1583, nan, nan, nan, nan], - [2, 380, 788, 953, 1001, 1030, 1066, nan, nan, nan, nan, nan], - [4, 777, 1063, 1307, 1362, 1411, nan, nan, nan, nan, nan, nan], - [2, 472, 1617, 1818, 1820, nan, nan, nan, nan, nan, nan, nan], - [3, 597, 1092, 1221, nan, nan, nan, nan, nan, nan, nan, nan], - [4, 583, 1212, nan, nan, nan, nan, nan, nan, nan, nan, nan], - [21, 422, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan], - [13, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan], - ] - ) + expected = np.array([ + [44, 621, 950, 1020, 1070, 1069, 1089, 1094, 1097, 1099, 1100, 1100], + [42, 541, 1052, 1169, 1238, 1249, 1266, 1269, 1296, 1300, 1300, nan], + [17, 530, 966, 1064, 1100, 1128, 1155, 1196, 1201, 1200, nan, nan], + [10, 393, 935, 1062, 1126, 1209, 1243, 1286, 1298, nan, nan, nan], + [13, 481, 1021, 1267, 1400, 1476, 1550, 1583, nan, nan, nan, nan], + [2, 380, 788, 953, 1001, 1030, 1066, nan, nan, nan, nan, nan], + [4, 777, 1063, 1307, 1362, 1411, nan, nan, nan, nan, nan, nan], + [2, 472, 1617, 1818, 1820, nan, nan, nan, nan, nan, nan, nan], + [3, 597, 1092, 1221, nan, nan, nan, nan, nan, nan, nan, nan], + [4, 583, 1212, nan, nan, nan, nan, nan, nan, nan, nan, nan], + [21, 422, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan], + [13, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan], + ]) np.testing.assert_array_equal(actual.values[0, 0, :, :], expected) @@ -39,7 +35,6 @@ def test_grain_increm_arg(qtr): def test_commutative(qtr, atol): - xp = qtr.get_array_module() full = cl.Chainladder().fit(qtr).full_expectation_ assert qtr.grain("OYDY").val_to_dev() == qtr.val_to_dev().grain("OYDY") assert qtr.cum_to_incr().grain( diff --git a/chainladder/core/tests/test_slicing.py b/chainladder/core/tests/test_slicing.py index db9302ee9..acb579a4e 100644 --- a/chainladder/core/tests/test_slicing.py +++ b/chainladder/core/tests/test_slicing.py @@ -8,7 +8,8 @@ if TYPE_CHECKING: from chainladder import Triangle -def test_slice_by_boolean(clrd : Triangle) -> None: + +def test_slice_by_boolean(clrd: Triangle) -> None: assert ( clrd[clrd["LOB"] == "ppauto"].loc["Wolverine Mut Ins Co"]["CumPaidLoss"] == clrd.loc["Wolverine Mut Ins Co"].loc["ppauto"]["CumPaidLoss"] @@ -158,9 +159,9 @@ def test_at_iat(raa): def test_at_iat_exceptions(raa): with pytest.raises(ValueError): - _= raa.iat[0, 0, 4, :] + _ = raa.iat[0, 0, 4, :] with pytest.raises(ValueError): - _= raa.at["Total", "values", "1985", 0:2] + _ = raa.at["Total", "values", "1985", 0:2] def test_at_check_index_full_axis_slice_raises(raa: Triangle) -> None: @@ -177,7 +178,7 @@ def test_at_check_index_full_axis_slice_raises(raa: Triangle) -> None: None """ with pytest.raises(ValueError, match="Invalid Index in At slicer"): - _= raa.at["Total", "values"] + _ = raa.at["Total", "values"] def test_at_check_index_full_axis_slice_on_non_unit_axis_raises(raa: Triangle) -> None: @@ -195,7 +196,7 @@ def test_at_check_index_full_axis_slice_on_non_unit_axis_raises(raa: Triangle) - None """ with pytest.raises(ValueError, match="Invalid Index in At slicer"): - _= raa.at["Total", "values", slice(None, None, None), 12] + _ = raa.at["Total", "values", slice(None, None, None), 12] def test_at_check_index_full_axis_slice_on_unit_axis(raa: Triangle) -> None: @@ -212,7 +213,10 @@ def test_at_check_index_full_axis_slice_on_unit_axis(raa: Triangle) -> None: ------- None """ - assert raa.at["Total", slice(None, None, None), "1985", 12] == raa.at["Total", "values", "1985", 12] + assert ( + raa.at["Total", slice(None, None, None), "1985", 12] + == raa.at["Total", "values", "1985", 12] + ) def test_at_requires_all_axes(raa: Triangle) -> None: @@ -222,7 +226,7 @@ def test_at_requires_all_axes(raa: Triangle) -> None: both axes be given as scalar labels. Ellipsis is not allowed. """ with pytest.raises(ValueError, match="Invalid Index in At slicer"): - _= raa.at[..., "1985", 12] + _ = raa.at[..., "1985", 12] def test_other_key_unsupported_iterable_raises(raa: Triangle) -> None: @@ -240,7 +244,7 @@ def test_other_key_unsupported_iterable_raises(raa: Triangle) -> None: """ with pytest.raises(AttributeError, match="Unable to slice"): - _= raa.loc[:, (0, 1)] + _ = raa.loc[:, (0, 1)] def test_at_setitem_triangle_value(raa: Triangle) -> None: @@ -279,12 +283,15 @@ def test_loc_setitem_triangle_value(clrd: Triangle) -> None: tri = clrd.copy() sub = tri.loc["Aegis Grp", "comauto"].copy() if tri.array_backend == "sparse": - with pytest.raises(ValueError, match="Setting values with sparse backend requires .at or .iat"): + with pytest.raises( + ValueError, match="Setting values with sparse backend requires .at or .iat" + ): tri.loc["Aegis Grp", "comauto"] = sub * 2 else: tri.loc["Aegis Grp", "comauto"] = sub * 2 assert tri.loc["Aegis Grp", "comauto"] == sub * 2 + def test_loc_setitem_partial_triangles(raa: Triangle) -> None: """ Use Triangle.loc to set a few origin or develop period via a TriangleSlicer. @@ -304,14 +311,15 @@ def test_loc_setitem_partial_triangles(raa: Triangle) -> None: if raa_new.array_backend == "sparse": pytest.skip("Test is specific to the numpy backend.") else: - raa_new.loc[:,:,:,:60] = raa2.loc[:,:,:,:60] - raa_new.loc[:,:,:,72:] = raa2.loc[:,:,:,72:] + raa_new.loc[:, :, :, :60] = raa2.loc[:, :, :, :60] + raa_new.loc[:, :, :, 72:] = raa2.loc[:, :, :, 72:] assert raa_new == raa2 raa_new = raa.copy() - raa_new.loc[:,:,:'1984',:] = raa2.loc[:,:,:'1984',:] - raa_new.loc[:,:,'1985':,:] = raa2.loc[:,:,'1985':,:] + raa_new.loc[:, :, :"1984", :] = raa2.loc[:, :, :"1984", :] + raa_new.loc[:, :, "1985":, :] = raa2.loc[:, :, "1985":, :] assert raa_new == raa2 + def test_invalid_iloc_sparse_assignment(prism) -> None: """ Assignment via Triangle.iloc[] does not work on sparse backend. @@ -326,7 +334,9 @@ def test_invalid_iloc_sparse_assignment(prism) -> None: None """ - with pytest.raises(ValueError, match="Setting values with sparse backend requires .at or .iat"): + with pytest.raises( + ValueError, match="Setting values with sparse backend requires .at or .iat" + ): prism.iloc[0, 0, 0, 0] = 1.0 @@ -345,7 +355,7 @@ def test_empty_index_raises(raa: Triangle) -> None: """ with pytest.raises(ValueError, match="Slice returns empty Triangle"): - _= raa.iloc[[], :] + _ = raa.iloc[[], :] def test_get_idx_fancy_origin_raises(raa: Triangle) -> None: @@ -362,8 +372,11 @@ def test_get_idx_fancy_origin_raises(raa: Triangle) -> None: None """ - with pytest.raises(ValueError, match="Fancy indexing on origin/development is not supported"): - _= raa.iloc[0, 0, [0, 1, 5], :] + with pytest.raises( + ValueError, match="Fancy indexing on origin/development is not supported" + ): + _ = raa.iloc[0, 0, [0, 1, 5], :] + def test_set_fancy_origin_raises(raa: Triangle) -> None: """ @@ -383,10 +396,18 @@ def test_set_fancy_origin_raises(raa: Triangle) -> None: if raa.array_backend == "sparse": pytest.skip("Test is specific to the numpy backend.") else: - with pytest.raises(ValueError, match="Setting while fancy indexing on origin/development is not supported."): + with pytest.raises( + ValueError, + match="Setting while fancy indexing on origin/development is not supported.", + ): raa_copy.iloc[0, 0, [0, 1, 5], :] = raa.iloc[0, 0, :3, :] - with pytest.raises(ValueError, match="Setting while fancy indexing on origin/development is not supported."): - raa_copy.loc['Total', 'values', ['1983', '1984', '1986'], :] = raa.iloc[0, 0, :3, :] + with pytest.raises( + ValueError, + match="Setting while fancy indexing on origin/development is not supported.", + ): + raa_copy.loc["Total", "values", ["1983", "1984", "1986"], :] = raa.iloc[ + 0, 0, :3, : + ] def test_get_idx_fancy_development_raises(raa: Triangle) -> None: @@ -403,8 +424,11 @@ def test_get_idx_fancy_development_raises(raa: Triangle) -> None: None """ - with pytest.raises(ValueError, match="Fancy indexing on origin/development is not supported"): - _= raa.iloc[0, 0, :, [0, 1, 5]] + with pytest.raises( + ValueError, match="Fancy indexing on origin/development is not supported" + ): + _ = raa.iloc[0, 0, :, [0, 1, 5]] + def test_set_fancy_development_raises(raa: Triangle) -> None: """ @@ -424,10 +448,16 @@ def test_set_fancy_development_raises(raa: Triangle) -> None: if raa.array_backend == "sparse": pytest.skip("Test is specific to the numpy backend.") else: - with pytest.raises(ValueError, match="Setting while fancy indexing on origin/development is not supported."): + with pytest.raises( + ValueError, + match="Setting while fancy indexing on origin/development is not supported.", + ): raa_copy.iloc[0, 0, :, [0, 1, 5]] = raa.iloc[0, 0, :, :3] - with pytest.raises(ValueError, match="Setting while fancy indexing on origin/development is not supported."): - raa_copy.loc['Total', 'values', :, [12, 24, 48]] = raa.iloc[0, 0, :, :3] + with pytest.raises( + ValueError, + match="Setting while fancy indexing on origin/development is not supported.", + ): + raa_copy.loc["Total", "values", :, [12, 24, 48]] = raa.iloc[0, 0, :, :3] def test_get_idx_non_contiguous_index_and_columns(clrd: Triangle) -> None: @@ -447,12 +477,13 @@ def test_get_idx_non_contiguous_index_and_columns(clrd: Triangle) -> None: """ result = clrd.iloc[[0, 1, 5], [0, 1, 5], :, :] expected_index = [ - ['Adriatic Ins Co', 'othliab'], - ['Adriatic Ins Co', 'ppauto'], - ['Agency Ins Co Of MD Inc', 'ppauto'], + ["Adriatic Ins Co", "othliab"], + ["Adriatic Ins Co", "ppauto"], + ["Agency Ins Co Of MD Inc", "ppauto"], ] assert result.index.values.tolist() == expected_index - assert result.columns.tolist() == ['IncurLoss', 'CumPaidLoss', 'EarnedPremNet'] + assert result.columns.tolist() == ["IncurLoss", "CumPaidLoss", "EarnedPremNet"] + def test_loc_setting_non_contiguous_index_and_columns(clrd: Triangle) -> None: """ @@ -473,26 +504,27 @@ def test_loc_setting_non_contiguous_index_and_columns(clrd: Triangle) -> None: pytest.skip("Test is specific to the numpy backend.") else: dest_index = [ - ['Adriatic Ins Co', 'othliab'], - ['Adriatic Ins Co', 'ppauto'], - ['Agency Ins Co Of MD Inc', 'ppauto'], + ["Adriatic Ins Co", "othliab"], + ["Adriatic Ins Co", "ppauto"], + ["Agency Ins Co Of MD Inc", "ppauto"], ] val_index = [ - ['Adriatic Ins Co', 'ppauto'], - ['Aegis Grp', 'comauto'], - ['Agency Ins Co Of MD Inc', 'ppauto'], + ["Adriatic Ins Co", "ppauto"], + ["Aegis Grp", "comauto"], + ["Agency Ins Co Of MD Inc", "ppauto"], ] - dest_col = ['CumPaidLoss', 'BulkLoss', 'EarnedPremNet'] - val_col = ['IncurLoss', 'CumPaidLoss', 'EarnedPremNet'] + dest_col = ["CumPaidLoss", "BulkLoss", "EarnedPremNet"] + val_col = ["IncurLoss", "CumPaidLoss", "EarnedPremNet"] clrd_copy = clrd.copy() clrd_copy.loc[dest_index] = clrd.loc[val_index] assert clrd_copy.loc[dest_index] == clrd.loc[val_index] clrd_copy = clrd.copy() - clrd_copy.loc[:,dest_col] = clrd.loc[:,val_col] - assert clrd_copy.loc[:,dest_col] == clrd.loc[:,val_col] + clrd_copy.loc[:, dest_col] = clrd.loc[:, val_col] + assert clrd_copy.loc[:, dest_col] == clrd.loc[:, val_col] clrd_copy = clrd.copy() - clrd_copy.loc[dest_index,dest_col] = clrd.loc[val_index,val_col] - assert clrd_copy.loc[dest_index,dest_col] == clrd.loc[val_index,val_col] + clrd_copy.loc[dest_index, dest_col] = clrd.loc[val_index, val_col] + assert clrd_copy.loc[dest_index, dest_col] == clrd.loc[val_index, val_col] + def test_iloc_setting_non_contiguous_index_and_columns(clrd: Triangle) -> None: """ @@ -512,19 +544,20 @@ def test_iloc_setting_non_contiguous_index_and_columns(clrd: Triangle) -> None: if clrd.array_backend == "sparse": pytest.skip("Test is specific to the numpy backend.") else: - dest_index = [0,1,5] - val_index = [1,4,6] - dest_col = [2,3,5] - val_col = [1,2,4] + dest_index = [0, 1, 5] + val_index = [1, 4, 6] + dest_col = [2, 3, 5] + val_col = [1, 2, 4] clrd_copy = clrd.copy() clrd_copy.iloc[dest_index] = clrd.iloc[val_index] assert clrd_copy.iloc[dest_index] == clrd.iloc[val_index] clrd_copy = clrd.copy() - clrd_copy.iloc[:,dest_col] = clrd.iloc[:,val_col] - assert clrd_copy.iloc[:,dest_col] == clrd.iloc[:,val_col] + clrd_copy.iloc[:, dest_col] = clrd.iloc[:, val_col] + assert clrd_copy.iloc[:, dest_col] == clrd.iloc[:, val_col] clrd_copy = clrd.copy() - clrd_copy.iloc[dest_index,dest_col] = clrd.iloc[val_index,val_col] - assert clrd_copy.iloc[dest_index,dest_col] == clrd.iloc[val_index,val_col] + clrd_copy.iloc[dest_index, dest_col] = clrd.iloc[val_index, val_col] + assert clrd_copy.iloc[dest_index, dest_col] == clrd.iloc[val_index, val_col] + def test_sparse_at_iat1(prism): t = prism.copy() diff --git a/pyproject.toml b/pyproject.toml index 0004e8bc3..a11453772 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -118,13 +118,8 @@ select = ["E2", "E4", "E7", "E9", "F", "B018", "UP034", "N802"] "chainladder/adjustments/tests/test_berqsherm.py" = ["F841"] "chainladder/adjustments/tests/test_disposal.py" = ["E226", "E231", "E241", "E251", "E265", "F841"] "chainladder/adjustments/trend.py" = ["F401"] -"chainladder/core/correlation.py" = ["E741", "N802"] -"chainladder/core/slice.py" = ["E225"] "chainladder/core/tests/rtest_correlation.py" = ["E266", "E722", "F821"] -"chainladder/core/tests/test_arithmetic.py" = ["E222", "E225", "E226", "E711"] "chainladder/core/tests/test_display.py" = ["E722"] -"chainladder/core/tests/test_grain.py" = ["E265", "F401", "F841"] -"chainladder/core/tests/test_slicing.py" = ["E203", "E225"] "chainladder/development/barnzehn.py" = ["E201", "E202", "E231", "E251", "E275"] "chainladder/development/clark.py" = ["N802"] "chainladder/development/constant.py" = ["E712"]