From a27e803d7b85420984fcd2bef10d6d81babb258a Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Tue, 22 Oct 2024 00:58:23 +0300 Subject: [PATCH] TYP: Reduce number of type aliases --- mizani/_colors/_colormaps/_interpolated.py | 6 +-- mizani/_core/date_utils.py | 37 ++++++++-------- mizani/_core/dates.py | 11 +++-- mizani/_core/types.py | 6 +-- mizani/bounds.py | 42 +++++++++++-------- mizani/breaks.py | 43 ++++++++++--------- mizani/labels.py | 15 ++++--- mizani/palettes.py | 14 +++---- mizani/scale.py | 13 +++--- mizani/transforms.py | 21 +++++----- mizani/typing.py | 49 +++++----------------- mizani/utils.py | 7 ++-- tools/release-checklist.py | 8 ++-- tools/term.py | 7 ++-- 14 files changed, 125 insertions(+), 154 deletions(-) diff --git a/mizani/_colors/_colormaps/_interpolated.py b/mizani/_colors/_colormaps/_interpolated.py index b6e4a76..da9b68c 100644 --- a/mizani/_colors/_colormaps/_interpolated.py +++ b/mizani/_colors/_colormaps/_interpolated.py @@ -9,7 +9,7 @@ from ._colormap import ColorMap, ColorMapKind if TYPE_CHECKING: - from typing import Optional, Sequence + from typing import Sequence from mizani.typing import ( FloatArrayLike, @@ -51,7 +51,7 @@ def _generate_colors(self, x: FloatArrayLike) -> Sequence[RGBHexColor]: @dataclass class InterpolatedMap(_InterpolatedGen): colors: Sequence[RGBHexColor] | Sequence[RGBColor] | RGBColorArray - values: Optional[Sequence[float]] = None + values: Sequence[float] | None = None kind: ColorMapKind = ColorMapKind.miscellaneous def __post_init__(self): @@ -93,7 +93,7 @@ def __post_init__(self): def interp_lookup( x: NDArrayFloat, values: NDArrayFloat, - values_alt: Optional[NDArrayFloat] = None, + values_alt: NDArrayFloat | None = None, ) -> NDArrayFloat: """ Create an interpolation lookup array diff --git a/mizani/_core/date_utils.py b/mizani/_core/date_utils.py index 8cebf6e..cf9064c 100644 --- a/mizani/_core/date_utils.py +++ b/mizani/_core/date_utils.py @@ -13,9 +13,6 @@ if TYPE_CHECKING: from mizani.typing import ( DatetimeBreaksUnits, - TupleDatetime2, - TupleFloat2, - TupleInt2, ) @@ -145,31 +142,33 @@ def u(self) -> int: return math.floor(self._tdelta.total_seconds() * 1e6) @property - def limits(self) -> TupleDatetime2: + def limits(self) -> tuple[datetime, datetime]: return self.start, self.end - def limits_year(self) -> TupleDatetime2: + def limits_year(self) -> tuple[datetime, datetime]: return floor_year(self.start), ceil_year(self.end) - def limits_month(self) -> TupleDatetime2: + def limits_month(self) -> tuple[datetime, datetime]: return round_month(self.start), round_month(self.end) - def limits_week(self) -> TupleDatetime2: + def limits_week(self) -> tuple[datetime, datetime]: return floor_week(self.start), ceil_week(self.end) - def limits_day(self) -> TupleDatetime2: + def limits_day(self) -> tuple[datetime, datetime]: return floor_day(self.start), ceil_day(self.end) - def limits_hour(self) -> TupleDatetime2: + def limits_hour(self) -> tuple[datetime, datetime]: return floor_hour(self.start), ceil_hour(self.end) - def limits_minute(self) -> TupleDatetime2: + def limits_minute(self) -> tuple[datetime, datetime]: return floor_minute(self.start), ceil_minute(self.end) - def limits_second(self) -> TupleDatetime2: + def limits_second(self) -> tuple[datetime, datetime]: return floor_second(self.start), ceil_second(self.end) - def limits_for_frequency(self, freq: DateFrequency) -> TupleDatetime2: + def limits_for_frequency( + self, freq: DateFrequency + ) -> tuple[datetime, datetime]: lookup = { DF.YEARLY: self.limits_year, DF.MONTHLY: self.limits_month, @@ -389,7 +388,7 @@ def at_the_second(d: datetime) -> bool: return d.time().microsecond == 0 -def align_limits(limits: TupleInt2, width: float) -> TupleFloat2: +def align_limits(limits: tuple[int, int], width: float) -> tuple[float, float]: """ Return limits so that breaks should be multiples of the width @@ -409,8 +408,10 @@ def align_limits(limits: TupleInt2, width: float) -> TupleFloat2: def shift_limits_down( - candidate_limits: TupleInt2, original_limits: TupleInt2, width: int -) -> TupleInt2: + candidate_limits: tuple[int, int], + original_limits: tuple[int, int], + width: int, +) -> tuple[int, int]: """ Shift candidate limits down so that they can be a multiple of width @@ -438,8 +439,10 @@ def shift_limits_down( def expand_datetime_limits( - limits: TupleDatetime2, width: int, units: DatetimeBreaksUnits -) -> TupleDatetime2: + limits: tuple[datetime, datetime], + width: int, + units: DatetimeBreaksUnits, +) -> tuple[datetime, datetime]: ival = Interval(*limits) if units == "year": start, end = ival.limits_year() diff --git a/mizani/_core/dates.py b/mizani/_core/dates.py index 34ca910..998b4a9 100644 --- a/mizani/_core/dates.py +++ b/mizani/_core/dates.py @@ -15,7 +15,7 @@ from .types import DateFrequency, date_breaks_info if TYPE_CHECKING: - from typing import Generator, Optional, Sequence + from typing import Generator, Sequence from mizani.typing import ( Datetime, @@ -26,7 +26,6 @@ SeqDatetime, Timedelta, TimedeltaArrayLike, - TzInfo, ) @@ -81,7 +80,7 @@ def _from_ordinalf(x: float, tz: tzinfo | None) -> datetime: _from_ordinalf_np_vectorized = np.vectorize(_from_ordinalf, otypes="O") -def get_tzinfo(tz: Optional[str | TzInfo] = None) -> TzInfo | None: +def get_tzinfo(tz: str | tzinfo | None = None) -> tzinfo | None: """ Generate `~datetime.tzinfo` from a string or return `~datetime.tzinfo`. @@ -146,7 +145,7 @@ def datetime64_to_num(x: NDArrayDatetime) -> NDArrayFloat: def num_to_datetime( - x: FloatArrayLike, tz: Optional[str | TzInfo] = None + x: FloatArrayLike, tz: str | tzinfo | None = None ) -> NDArrayDatetime: """ Convert any float array to numpy datetime64 array @@ -338,8 +337,8 @@ def calculate_date_breaks_byunits( limits, units: DatetimeBreaksUnits, width: int, - max_breaks: Optional[int] = None, - tz: Optional[TzInfo] = None, + max_breaks: int | None = None, + tz: tzinfo | None = None, ) -> Sequence[datetime]: """ Calcuate date breaks using appropriate units diff --git a/mizani/_core/types.py b/mizani/_core/types.py index 9101334..3ca48ce 100644 --- a/mizani/_core/types.py +++ b/mizani/_core/types.py @@ -8,9 +8,7 @@ import dateutil.rrule as rr if TYPE_CHECKING: - from mizani.typing import ( - TzInfo, - ) + from datetime import tzinfo class DateFrequency(IntEnum): @@ -44,4 +42,4 @@ class date_breaks_info: width: int start: datetime until: datetime - tz: TzInfo | None + tz: tzinfo | None diff --git a/mizani/bounds.py b/mizani/bounds.py index 7d809b3..da0e772 100644 --- a/mizani/bounds.py +++ b/mizani/bounds.py @@ -32,14 +32,12 @@ from .utils import get_null_value if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any from mizani.typing import ( FloatArrayLike, NDArrayFloat, TFloatVector, - TupleFloat2, - TupleFloat4, ) @@ -60,8 +58,8 @@ def rescale( x: FloatArrayLike, - to: TupleFloat2 = (0, 1), - _from: Optional[TupleFloat2] = None, + to: tuple[float, float] = (0, 1), + _from: tuple[float, float] | None = None, ) -> NDArrayFloat: """ Rescale numeric vector to have specified minimum and maximum. @@ -97,8 +95,8 @@ def rescale( def rescale_mid( x: FloatArrayLike, - to: TupleFloat2 = (0, 1), - _from: Optional[TupleFloat2] = None, + to: tuple[float, float] = (0, 1), + _from: tuple[float, float] | None = None, mid: float = 0, ) -> NDArrayFloat: """ @@ -157,8 +155,8 @@ def rescale_mid( def rescale_max( x: FloatArrayLike, - to: TupleFloat2 = (0, 1), - _from: Optional[TupleFloat2] = None, + to: tuple[float, float] = (0, 1), + _from: tuple[float, float] | None = None, ) -> NDArrayFloat: """ Rescale numeric vector to have specified maximum. @@ -224,7 +222,7 @@ def rescale_max( def squish_infinite( - x: FloatArrayLike, range: TupleFloat2 = (0, 1) + x: FloatArrayLike, range: tuple[float, float] = (0, 1) ) -> NDArrayFloat: """ Truncate infinite values to a range. @@ -261,7 +259,9 @@ def squish_infinite( def squish( - x: FloatArrayLike, range: TupleFloat2 = (0, 1), only_finite: bool = True + x: FloatArrayLike, + range: tuple[float, float] = (0, 1), + only_finite: bool = True, ) -> NDArrayFloat: """ Squish values into range. @@ -300,7 +300,7 @@ def squish( def censor( x: TFloatVector, - range: TupleFloat2 = (0, 1), + range: tuple[float, float] = (0, 1), only_finite: bool = True, ) -> TFloatVector: """ @@ -438,8 +438,11 @@ def zero_range(x: tuple[Any, Any], tol: float = EPSILON * 100) -> bool: def expand_range( - range: TupleFloat2, mul: float = 0, add: float = 0, zero_width: float = 1 -) -> TupleFloat2: + range: tuple[float, float], + mul: float = 0, + add: float = 0, + zero_width: float = 1, +) -> tuple[float, float]: """ Expand a range with a multiplicative or additive constant @@ -498,10 +501,15 @@ def expand_range( def expand_range_distinct( - range: TupleFloat2, - expand: TupleFloat2 | TupleFloat4 = (0, 0, 0, 0), + range: tuple[float, float], + expand: (tuple[float, float] | tuple[float, float, float, float]) = ( + 0, + 0, + 0, + 0, + ), zero_width: float = 1, -) -> TupleFloat2: +) -> tuple[float, float]: """ Expand a range with a multiplicative or additive constants diff --git a/mizani/breaks.py b/mizani/breaks.py index 53fc18f..cb41151 100644 --- a/mizani/breaks.py +++ b/mizani/breaks.py @@ -29,7 +29,7 @@ from .utils import NANOSECONDS, SECONDS, log, min_max if TYPE_CHECKING: - from typing import Callable, Literal, Optional, Sequence + from typing import Callable, Literal, Sequence from mizani.typing import ( DatetimeBreaksUnits, @@ -39,9 +39,6 @@ Timedelta, TimedeltaArrayLike, Trans, - TupleFloat2, - TupleFloat5, - TupleT2, ) @@ -83,7 +80,7 @@ def __init__(self, n: int = 5, base: float = 10): self.n = n self.base = base - def __call__(self, limits: TupleFloat2) -> NDArrayFloat: + def __call__(self, limits: tuple[float, float]) -> NDArrayFloat: """ Compute breaks @@ -151,7 +148,7 @@ def __init__(self, n: int = 5, base: float = 10): self.n = n self.base = base - def __call__(self, limits: TupleFloat2) -> NDArrayFloat: + def __call__(self, limits: tuple[float, float]) -> NDArrayFloat: base = self.base n = self.n rng = log(limits, base) @@ -243,8 +240,8 @@ def __init__(self, n: int = 1): def __call__( self, major: FloatArrayLike, - limits: Optional[TupleFloat2] = None, - n: Optional[int] = None, + limits: tuple[float, float] | None = None, + n: int | None = None, ) -> NDArrayFloat: """ Minor breaks @@ -345,8 +342,8 @@ def __init__(self, trans: Trans, n: int = 1): def __call__( self, major: FloatArrayLike, - limits: Optional[TupleFloat2] = None, - n: Optional[int] = None, + limits: tuple[float, float] | None = None, + n: int | None = None, ) -> NDArrayFloat: """ Minor breaks for transformed scales @@ -435,10 +432,10 @@ class breaks_date: """ n: int - width: Optional[int] = None - units: Optional[DatetimeBreaksUnits] = None + width: int | None = None + units: DatetimeBreaksUnits | None = None - def __init__(self, n: int = 5, width: Optional[str] = None): + def __init__(self, n: int = 5, width: str | None = None): if isinstance(n, str): width = n @@ -451,7 +448,9 @@ def __init__(self, n: int = 5, width: Optional[str] = None): self.width = int(_w) self.units = units.rstrip("s") # type: ignore - def __call__(self, limits: TupleT2[datetime]) -> Sequence[datetime]: + def __call__( + self, limits: tuple[datetime, datetime] + ) -> Sequence[datetime]: """ Compute breaks @@ -503,7 +502,7 @@ class breaks_timedelta: [0.0, 5.0, 10.0, 15.0, 20.0, 25.0] """ - _calculate_breaks: Callable[[TupleFloat2], NDArrayFloat] + _calculate_breaks: Callable[[tuple[float, float]], NDArrayFloat] def __init__(self, n: int = 5, Q: Sequence[float] = (1, 2, 5, 10)): self._calculate_breaks = breaks_extended(n=n, Q=Q) @@ -563,14 +562,14 @@ class timedelta_helper: x: TimedeltaArrayLike units: DurationUnit - limits: TupleFloat2 + limits: tuple[float, float] package: Literal["pandas", "cpython"] factor: float def __init__( self, x: TimedeltaArrayLike, - units: Optional[DurationUnit] = None, + units: DurationUnit | None = None, ): self.x = x self.package = self.determine_package(x[0]) @@ -592,7 +591,7 @@ def determine_package(cls, td: Timedelta) -> Literal["pandas", "cpython"]: @classmethod def format_info( - cls, x: TimedeltaArrayLike, units: Optional[DurationUnit] = None + cls, x: TimedeltaArrayLike, units: DurationUnit | None = None ) -> tuple[NDArrayFloat, DurationUnit]: helper = cls(x, units) return helper.timedelta_to_numeric(x), helper.units @@ -651,7 +650,7 @@ def value(td: Timedelta) -> float: else: return td.total_seconds() - def scaled_limits(self) -> TupleFloat2: + def scaled_limits(self) -> tuple[float, float]: """ Minimum and Maximum to use for computing breaks """ @@ -805,7 +804,7 @@ def legibility(self, lmin: float, lmax: float, lstep: float) -> float: # a score. Return 1 ignores all that. return 1 - def __call__(self, limits: TupleFloat2) -> NDArrayFloat: + def __call__(self, limits: tuple[float, float]) -> NDArrayFloat: """ Calculate the breaks @@ -842,7 +841,7 @@ def __call__(self, limits: TupleFloat2) -> NDArrayFloat: return np.array([dmin]) best_score = -2.0 - best: TupleFloat5 = (0, 0, 0, 0, 0) # Gives Empty breaks + best = (0, 0, 0, 0, 0) # Gives Empty breaks j = 1.0 while j < float("inf"): @@ -924,7 +923,7 @@ class breaks_symlog: array([-100, -10, 0, 10, 100]) """ - def __call__(self, limits: TupleFloat2) -> NDArrayFloat: + def __call__(self, limits: tuple[float, float]) -> NDArrayFloat: def _signed_log10(x): return np.round(np.sign(x) * np.log10(np.sign(x) * x)).astype(int) diff --git a/mizani/labels.py b/mizani/labels.py index 5af8c60..a7fb97a 100644 --- a/mizani/labels.py +++ b/mizani/labels.py @@ -30,14 +30,13 @@ if TYPE_CHECKING: from datetime import datetime, tzinfo - from typing import Literal, Optional, Sequence + from typing import Literal, Sequence from mizani.typing import ( BytesSymbol, DurationUnit, FloatArrayLike, TimedeltaArrayLike, - TupleInt2, ) __all__ = [ @@ -102,8 +101,8 @@ class label_number: ['$5', '$24', '($42)'] """ - accuracy: Optional[float] = None - precision: Optional[int] = None + accuracy: float | None = None + precision: int | None = None scale: float = 1 prefix: str = "" suffix: str = "" @@ -113,7 +112,7 @@ class label_number: style_negative: Literal["-", "hyphen", "parens"] = "-" style_positive: Literal["", "+", " "] = "" align: Literal["<", ">", "=", "^"] = ">" - width: Optional[int] = None + width: int | None = None def __post_init__(self): if self.precision is not None: @@ -381,7 +380,7 @@ class label_log: """ base: float = 10 - exponent_limits: TupleInt2 = (-4, 4) + exponent_limits: tuple[int, int] = (-4, 4) mathtex: bool = False def _tidyup_labels(self, labels: Sequence[str]) -> Sequence[str]: @@ -547,7 +546,7 @@ class label_date: """ fmt: str = "%Y-%m-%d" - tz: Optional[tzinfo] = None + tz: tzinfo | None = None def __post_init__(self): if isinstance(self.tz, str): @@ -625,7 +624,7 @@ class label_timedelta: ['0', '31', '62', '93', '124'] """ - units: Optional[DurationUnit] = None + units: DurationUnit | None = None show_units: bool = True zero_has_units: bool = True usetex: bool = False diff --git a/mizani/palettes.py b/mizani/palettes.py index 566e8e3..47c4d04 100644 --- a/mizani/palettes.py +++ b/mizani/palettes.py @@ -36,7 +36,7 @@ from .utils import identity if TYPE_CHECKING: - from typing import Any, Literal, Optional, Sequence, TypeVar + from typing import Any, Literal, Sequence, TypeVar from mizani.typing import ( Callable, @@ -45,8 +45,6 @@ FloatArrayLike, NDArrayFloat, RGBHexColor, - TupleFloat2, - TupleFloat3, ) T = TypeVar("T") @@ -112,7 +110,7 @@ def __call__(self, x: FloatArrayLike) -> Sequence[RGBHexColor | None]: def hls_palette( n_colors: int = 6, h: float = 0.01, l: float = 0.6, s: float = 0.65 -) -> Sequence[TupleFloat3]: +) -> Sequence[tuple[float, float, float]]: """ Get a set of evenly spaced colors in HLS hue space. @@ -157,7 +155,7 @@ def hls_palette( def hsluv_palette( n_colors: int = 6, h: float = 0.01, s: float = 0.9, l: float = 0.65 -) -> Sequence[TupleFloat3]: +) -> Sequence[tuple[float, float, float]]: """ Get a set of evenly spaced colors in HSLuv hue space. @@ -235,7 +233,7 @@ class rescale_pal(_continuous_pal): array([0.1 , 0.1 , 0.28, 0.46, 0.82, 1. , 1. ]) """ - range: TupleFloat2 = (0.1, 1) + range: tuple[float, float] = (0.1, 1) def __call__(self, x: FloatArrayLike) -> NDArrayFloat: return rescale(x, self.range, _from=(0, 1)) @@ -270,7 +268,7 @@ class area_pal(_continuous_pal): area space, i.e it is squared. """ - range: TupleFloat2 = (1, 6) + range: tuple[float, float] = (1, 6) def __call__(self, x: FloatArrayLike) -> NDArrayFloat: return rescale(np.sqrt(x), to=self.range, _from=(0, 1)) @@ -534,7 +532,7 @@ class gradient_n_pal(_continuous_color_pal): """ colors: Sequence[str] - values: Optional[Sequence[float]] = None + values: Sequence[float] | None = None def __post_init__(self): self._cmap = InterpolatedMap(self.colors, self.values) diff --git a/mizani/scale.py b/mizani/scale.py index f13035c..aabac1c 100644 --- a/mizani/scale.py +++ b/mizani/scale.py @@ -46,7 +46,7 @@ ) if TYPE_CHECKING: - from typing import Any, Optional, Sequence, TypeVar + from typing import Any, Sequence, TypeVar from mizani.typing import ( AnyArrayLike, @@ -56,7 +56,6 @@ FloatArrayLike, NDArrayFloat, Trans, - TupleFloat2, ) TVector = TypeVar("TVector", NDArrayFloat, pd.Series[float]) @@ -76,7 +75,7 @@ def apply( x: FloatArrayLike, palette: ContinuousPalette, na_value: Any = None, - trans: Optional[Trans] = None, + trans: Trans | None = None, ) -> NDArrayFloat: """ Scale data continuously @@ -106,8 +105,8 @@ def apply( @classmethod def train( - cls, new_data: FloatArrayLike, old: Optional[TupleFloat2] = None - ) -> TupleFloat2: + cls, new_data: FloatArrayLike, old: tuple[float, float] | None = None + ) -> tuple[float, float]: """ Train a continuous scale @@ -142,7 +141,7 @@ def map( cls, x: FloatArrayLike, palette: ContinuousPalette, - limits: TupleFloat2, + limits: tuple[float, float], na_value: Any = None, oob: Callable[[TVector], TVector] = censor, ) -> NDArrayFloat: @@ -208,7 +207,7 @@ def apply( def train( cls, new_data: AnyArrayLike, - old: Optional[Sequence[Any]] = None, + old: Sequence[Any] | None = None, drop: bool = False, na_rm: bool = False, ) -> Sequence[Any]: diff --git a/mizani/transforms.py b/mizani/transforms.py index 14bfb72..610c9c4 100644 --- a/mizani/transforms.py +++ b/mizani/transforms.py @@ -55,7 +55,7 @@ from .utils import identity if TYPE_CHECKING: - from typing import Any, Callable, Optional, Sequence, Type + from typing import Any, Callable, Sequence, Type from mizani.typing import ( BreaksFunction, @@ -70,7 +70,6 @@ TFloatArrayLike, TimedeltaArrayLike, TransformFunction, - TupleFloat2, ) @@ -155,8 +154,8 @@ def domain_is_numerical(self) -> bool: def minor_breaks( self, major: FloatArrayLike, - limits: Optional[TupleFloat2] = None, - n: Optional[int] = None, + limits: tuple[float, float] | None = None, + n: int | None = None, ) -> NDArrayFloat: """ Calculate minor_breaks @@ -260,9 +259,9 @@ def trans_new( name: str, transform: TransformFunction, inverse: InverseFunction, - breaks: Optional[BreaksFunction] = None, - minor_breaks: Optional[MinorBreaksFunction] = None, - _format: Optional[FormatFunction] = None, + breaks: BreaksFunction | None = None, + minor_breaks: MinorBreaksFunction | None = None, + _format: FormatFunction | None = None, domain=(-np.inf, np.inf), doc: str = "", **kwargs, @@ -333,7 +332,7 @@ def _get(func): return type(klass_name, (trans,), d) # type: ignore -def log_trans(base: Optional[float] = None, **kwargs: Any) -> trans: +def log_trans(base: float | None = None, **kwargs: Any) -> trans: """ Create a log transform class for *base* @@ -395,7 +394,7 @@ def inverse(x): log2_trans = log_trans(2, doc="Log 2 Transformation") -def exp_trans(base: Optional[float] = None, **kwargs: Any): +def exp_trans(base: float | None = None, **kwargs: Any): """ Create a exponential transform class for *base* @@ -890,8 +889,8 @@ def inverse(self, x: FloatArrayLike) -> NDArrayFloat: # pyright: ignore[reportI def minor_breaks( self, major: FloatArrayLike, - limits: Optional[TupleFloat2] = None, - n: Optional[int] = None, + limits: tuple[float, float] | None = None, + n: int | None = None, ) -> NDArrayFloat: n = int(self.base) - 2 if n is None else n return super().minor_breaks(major, limits, n) diff --git a/mizani/typing.py b/mizani/typing.py index 2b1c64a..4aaf862 100644 --- a/mizani/typing.py +++ b/mizani/typing.py @@ -3,13 +3,12 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from datetime import date, datetime, timedelta, tzinfo + from datetime import date, datetime, timedelta from types import NoneType from typing import ( Any, Callable, Literal, - Optional, Protocol, Sequence, TypeAlias, @@ -27,41 +26,20 @@ T = TypeVar("T") - # Tuples - TupleT2: TypeAlias = tuple[T, T] - TupleT3: TypeAlias = tuple[T, T, T] - TupleT4: TypeAlias = tuple[T, T, T, T] - TupleT5: TypeAlias = tuple[T, T, T, T, T] - - TupleInt2: TypeAlias = TupleT2[int] - TupleFloat2: TypeAlias = TupleT2[float] - TupleFloat3: TypeAlias = TupleT3[float] - TupleFloat4: TypeAlias = TupleT4[float] - TupleFloat5: TypeAlias = TupleT5[float] - TupleDatetime2: TypeAlias = TupleT2[datetime] - TupleDate2: TypeAlias = TupleT2[date] - # Arrays (strictly numpy) NDArrayAny: TypeAlias = NDArray[Any] - NDArrayBool: TypeAlias = NDArray[np.bool_] NDArrayFloat: TypeAlias = NDArray[np.float64] - NDArrayInt: TypeAlias = NDArray[np.int64] - NDArrayStr: TypeAlias = NDArray[np.str_] - NDArrayDatetime: TypeAlias = NDArray[Any] + NDArrayDatetime: TypeAlias = NDArray[np.datetime64] - # Series + # Panda Series AnySeries: TypeAlias = pd.Series[Any] - BoolSeries: TypeAlias = pd.Series[bool] - IntSeries: TypeAlias = pd.Series[int] FloatSeries: TypeAlias = pd.Series[float] DatetimeSeries: TypeAlias = pd.Series[datetime] TimedeltaSeries: TypeAlias = pd.Series[pd.Timedelta] # ArrayLikes AnyArrayLike: TypeAlias = NDArrayAny | pd.Series[Any] | Sequence[Any] - IntArrayLike: TypeAlias = NDArrayInt | IntSeries | Sequence[int] FloatArrayLike: TypeAlias = NDArrayFloat | FloatSeries | Sequence[float] - NumArrayLike: TypeAlias = IntArrayLike | FloatArrayLike DatetimeArrayLike: TypeAlias = ( NDArrayDatetime | DatetimeSeries | Sequence[datetime] ) @@ -70,15 +48,9 @@ ) # Type variable - TAnyArrayLike = TypeVar( - "TAnyArrayLike", NDArrayAny, pd.Series[Any], Sequence[Any] - ) TFloatLike = TypeVar("TFloatLike", NDArrayFloat, float) TFloatArrayLike = TypeVar("TFloatArrayLike", bound=FloatArrayLike) TFloatVector = TypeVar("TFloatVector", NDArrayFloat, FloatSeries) - TConstrained = TypeVar( - "TConstrained", int, float, bool, str, complex, datetime, timedelta - ) NumericUFunction: TypeAlias = Callable[[TFloatLike], TFloatLike] @@ -88,11 +60,10 @@ NullType: TypeAlias = ( NoneType | float - | # Cannot really use NaTType at the moment, e.g. directly # instantiating a NaTType is not the same as that from # pd.Timestamp("NaT"). Pandas chokes on it. - NaTType + | NaTType | pd.Timestamp | pd.Timedelta | np.timedelta64 @@ -154,7 +125,6 @@ class SegmentFunctionColorMapData(TypedDict): Sequence[date] | Sequence[datetime] | Sequence[np.datetime64] ) SeqDatetime64: TypeAlias = Sequence[np.datetime64] - TzInfo: TypeAlias = tzinfo SeqTimedelta: TypeAlias = Sequence[timedelta] | Sequence[pd.Timedelta] # dateutil.rrule.YEARLY, ..., but not including 2 weekly @@ -181,7 +151,8 @@ class SegmentFunctionColorMapData(TypedDict): InverseFunction: TypeAlias = Callable[[FloatArrayLike], NDArrayAny] BreaksFunction: TypeAlias = Callable[[tuple[Any, Any]], AnyArrayLike] MinorBreaksFunction: TypeAlias = Callable[ - [FloatArrayLike, Optional[TupleFloat2], Optional[int]], NDArrayFloat + [FloatArrayLike, tuple[float, float] | None, int | None], + NDArrayFloat, ] # Rescale functions @@ -190,8 +161,8 @@ class PRescale(Protocol): def __call__( self, x: FloatArrayLike, - to: TupleFloat2 = (0, 1), - _from: TupleFloat2 | None = None, + to: tuple[float, float] = (0, 1), + _from: tuple[float, float] | None = None, ) -> NDArrayFloat: ... # Censor functions @@ -199,7 +170,7 @@ class PCensor(Protocol): def __call__( self, x: NDArrayFloat, - range: TupleFloat2 = (0, 1), + range: tuple[float, float] = (0, 1), only_finite: bool = True, ) -> NDArrayFloat: ... @@ -217,7 +188,7 @@ def __lt__(self, other, /) -> bool: ... def __gt__(self, other, /) -> bool: ... - DomainType: TypeAlias = TupleT2[PComparison] + DomainType: TypeAlias = tuple[PComparison, PComparison] # This does not work probably due to a bug in the typechecker # FormatFunction: TypeAlias = Callable[[AnyArrayLike], Sequence[str]] diff --git a/mizani/utils.py b/mizani/utils.py index e9c707b..4409bab 100644 --- a/mizani/utils.py +++ b/mizani/utils.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from datetime import tzinfo - from typing import Any, Optional, Sequence, TypeGuard, TypeVar + from typing import Any, Sequence, TypeGuard, TypeVar from mizani.typing import ( AnyArrayLike, @@ -23,7 +23,6 @@ NullType, NumericUFunction, SeqDatetime, - TupleFloat2, ) T = TypeVar("T") @@ -103,7 +102,7 @@ def round_any( def min_max( x: FloatArrayLike | float, na_rm: bool = False, finite: bool = True -) -> TupleFloat2: +) -> tuple[float, float]: """ Return the minimum and maximum of x @@ -142,7 +141,7 @@ def match( v1: AnyArrayLike, v2: AnyArrayLike, nomatch: int = -1, - incomparables: Optional[Any] = None, + incomparables: Any = None, start: int = 0, ) -> list[int]: """ diff --git a/tools/release-checklist.py b/tools/release-checklist.py index 75b202c..251b359 100644 --- a/tools/release-checklist.py +++ b/tools/release-checklist.py @@ -6,7 +6,7 @@ import sys from pathlib import Path from subprocess import PIPE, Popen -from typing import Literal, Optional, Sequence, TypeAlias +from typing import Literal, Sequence, TypeAlias TPL_FILENAME = "release-checklist-tpl.md" THIS_DIR = Path(__file__).parent @@ -29,7 +29,7 @@ ) -def run(cmd: str | Sequence[str], input: Optional[str] = None) -> str: +def run(cmd: str | Sequence[str], input: str | None = None) -> str: """ Run command """ @@ -65,7 +65,7 @@ def copy_to_clipboard(s: str): clipboard.copy(s) # type: ignore -def get_previous_version(s: Optional[str] = None) -> str: +def get_previous_version(s: str | None = None) -> str: """ Get previous version @@ -139,7 +139,7 @@ def verbose(prev_version, next_version): """ from textwrap import dedent - from term import T0 as T # type: ignore + from term import T0 as T s = f""" Previous Version: {T(prev_version, "lightblue", effect="strikethrough")} diff --git a/tools/term.py b/tools/term.py index c47864a..916849d 100644 --- a/tools/term.py +++ b/tools/term.py @@ -2,7 +2,6 @@ import sys from enum import Enum -from typing import Optional RESET = "\033[0m" @@ -60,9 +59,9 @@ class Effect(Enum): def T( s: str, - fg: Optional[str] = None, - bg: Optional[str] = None, - effect: Optional[str] = None, + fg: str | None = None, + bg: str | None = None, + effect: str | None = None, ) -> str: """ Enclose text string with ANSI codes