Skip to content

Commit

Permalink
Use 3.9 type-hints
Browse files Browse the repository at this point in the history
  • Loading branch information
michalk8 committed Sep 15, 2024
1 parent ce219e8 commit 6e2207f
Show file tree
Hide file tree
Showing 50 changed files with 305 additions and 340 deletions.
6 changes: 3 additions & 3 deletions docs/_ext/typed_returns.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
from typing import Iterable, Iterator, List
from collections.abc import Iterable, Iterator

from sphinx.application import Sphinx
from sphinx.ext.napoleon import NumpyDocstring
Expand All @@ -18,9 +18,9 @@ def process_return(lines: Iterable[str]) -> Iterator[str]:
yield line


def _parse_returns_section(self: NumpyDocstring, section: str) -> List[str]:
def _parse_returns_section(self: NumpyDocstring, section: str) -> list[str]:
lines_raw = list(process_return(self._dedent(self._consume_to_next_section())))
lines: List[str] = self._format_block(":returns: ", lines_raw)
lines: list[str] = self._format_block(":returns: ", lines_raw)
if lines and lines[-1]:
lines.append("")
return lines
Expand Down
2 changes: 1 addition & 1 deletion docs/notebooks
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ include-package-data = true
[tool.setuptools_scm]

[tool.ruff]
target-version = "py38"
target-version = "py39"
line-length = 120

[tool.ruff.lint]
Expand Down Expand Up @@ -156,7 +156,7 @@ select = [
"T20", # flake8-print
"RET", # flake8-raise
]
unfixable = ["B", "UP", "C4", "BLE", "T20", "RET"]
unfixable = ["B", "C4", "BLE", "T20", "RET"]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["D"]
"*/__init__.py" = ["F401"]
Expand Down
23 changes: 12 additions & 11 deletions src/cellrank/_utils/_colors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, List, Optional, Sequence, Tuple, Union
from collections.abc import Sequence
from typing import Any, Optional, Union

import numpy as np
import pandas as pd
Expand All @@ -11,14 +12,14 @@


def _create_colors(
base_color: Union[str, Tuple[float, float, float]],
base_color: Union[str, tuple[float, float, float]],
n: int,
hue_range: Optional[Tuple[float, float]] = (-0.1, 0.1),
saturation_range: Optional[Tuple[float, float]] = (-0.3, 0.3),
value_range: Optional[Tuple[float, float]] = (-0.3, 0.3),
hue_range: Optional[tuple[float, float]] = (-0.1, 0.1),
saturation_range: Optional[tuple[float, float]] = (-0.3, 0.3),
value_range: Optional[tuple[float, float]] = (-0.3, 0.3),
convert_to_rgb: bool = True,
as_hex: bool = True,
) -> List[Any]:
) -> list[Any]:
"""Create variations of colors from base color.
Parameters
Expand Down Expand Up @@ -74,7 +75,7 @@ def _create_colors(
return res[::2] # we've created twice as many colors, select every other


def _convert_to_hex_colors(cols: Sequence[Any]) -> List[str]:
def _convert_to_hex_colors(cols: Sequence[Any]) -> list[str]:
if not all(colors.is_color_like(c) for c in cols):
raise ValueError("Not all values are color-like.")

Expand Down Expand Up @@ -108,7 +109,7 @@ def _create_categorical_colors(n_categories: Optional[int] = None):
raise RuntimeError(f"Unable to create `{n_categories}` colors.")


def _insert_categorical_colors(seen_colors: Union[np.ndarray, List], n_categories: int):
def _insert_categorical_colors(seen_colors: Union[np.ndarray, list], n_categories: int):
seen_colors = set(_convert_to_hex_colors(seen_colors))
candidates = list(filter(lambda c: c not in seen_colors, _create_categorical_colors()))[:n_categories]

Expand All @@ -135,7 +136,7 @@ def _get_black_or_white(value: float, cmap) -> str:
return _contrasting_color(r, g, b)


def _get_bg_fg_colors(color, sat_scale: Optional[float] = None) -> Tuple[str, str]:
def _get_bg_fg_colors(color, sat_scale: Optional[float] = None) -> tuple[str, str]:
if not colors.is_color_like(color):
raise ValueError(f"Value `{color}` is not color-like.")

Expand All @@ -155,7 +156,7 @@ def _map_names_and_colors(
series_query: pd.Series,
colors_reference: Optional[np.array] = None,
en_cutoff: Optional[float] = None,
) -> Union[pd.Series, Tuple[pd.Series, List[Any]]]:
) -> Union[pd.Series, tuple[pd.Series, list[Any]]]:
"""Map annotations and colors from one series to another.
Parameters
Expand Down Expand Up @@ -270,7 +271,7 @@ def _map_names_and_colors(
return (names_query_new, list(_convert_to_hex_colors(colors_query_new))) if process_colors else names_query_new


def _compute_mean_color(cols: List[str]) -> str:
def _compute_mean_color(cols: list[str]) -> str:
"""Compute mean color."""
if not all(colors.is_color_like(c) for c in cols):
raise ValueError(f"Not all values are valid colors `{cols}`.")
Expand Down
6 changes: 3 additions & 3 deletions src/cellrank/_utils/_enum.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
import enum
import functools
from typing import Any, Callable, Dict, Literal, Tuple, Type
from typing import Any, Callable, Literal

__all__ = ["ModeEnum", "DEFAULT_BACKEND"]

Expand All @@ -24,7 +24,7 @@ def __str__(self) -> str:
return f"{self.value!s}"


def _pretty_raise_enum(cls: Type["ErrorFormatterABC"], func: Callable) -> Callable:
def _pretty_raise_enum(cls: type["ErrorFormatterABC"], func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> "ErrorFormatterABC":
try:
Expand All @@ -49,7 +49,7 @@ def __call__(cls, *args, **kwargs): # noqa
raise TypeError(f"Can't instantiate class `{cls.__name__}` " f"without `__error_format__` class attribute.")
return super().__call__(*args, **kwargs)

def __new__(cls, clsname: str, superclasses: Tuple[type], attributedict: Dict[str, Any]): # noqa: D102
def __new__(cls, clsname: str, superclasses: tuple[type], attributedict: dict[str, Any]): # noqa: D102
res = super().__new__(cls, clsname, superclasses, attributedict)
res.__new__ = _pretty_raise_enum(res, res.__new__)
return res
Expand Down
28 changes: 9 additions & 19 deletions src/cellrank/_utils/_lineage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,8 @@
import itertools
import pathlib
import types
from typing import (
Any,
Callable,
Iterable,
List,
Literal,
Mapping,
Optional,
Tuple,
TypeVar,
Union,
)
from collections.abc import Iterable, Mapping
from typing import Any, Callable, Literal, Optional, TypeVar, Union

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -314,7 +304,7 @@ def __getitem__(self, item) -> "Lineage":
def _mix_lineages(self, rows, mixtures: Iterable[Union[str, Any]]) -> "Lineage":
from cellrank._utils._utils import _unique_order_preserving

def unsplit(names: str) -> Tuple[str, ...]:
def unsplit(names: str) -> tuple[str, ...]:
return tuple(sorted({name.strip(" ") for name in names.strip(" ,").split(",")}))

keys = [
Expand Down Expand Up @@ -567,7 +557,7 @@ def plot_pie(
title: Optional[str] = None,
legend_loc: Optional[str] = "on data",
legend_kwargs: Mapping = types.MappingProxyType({}),
figsize: Optional[Tuple[float, float]] = None,
figsize: Optional[tuple[float, float]] = None,
dpi: Optional[float] = None,
save: Optional[Union[pathlib.Path, str]] = None,
**kwargs: Any,
Expand Down Expand Up @@ -657,7 +647,7 @@ def reduce(
normalize_weights: Literal["scale", "softmax"] = NormWeights.SOFTMAX,
softmax_scale: float = 1.0,
return_weights: bool = False,
) -> Union["Lineage", Tuple["Lineage", Optional[pd.DataFrame]]]:
) -> Union["Lineage", tuple["Lineage", Optional[pd.DataFrame]]]:
"""Subset states and normalize them so that they again sum to :math:`1`.
Parameters
Expand Down Expand Up @@ -1000,7 +990,7 @@ def copy(self, _="C") -> "Lineage":
def __copy__(self):
return self.copy()

def _check_axis1_shape(self, array: Iterable[Union[str, ColorLike]], msg: str) -> List[Union[str, ColorLike]]:
def _check_axis1_shape(self, array: Iterable[Union[str, ColorLike]], msg: str) -> list[Union[str, ColorLike]]:
"""Check whether the size of the 1D array has the correct length."""
array = list(array)
if len(array) != self._n_lineages:
Expand All @@ -1014,7 +1004,7 @@ def _maybe_convert_names(
is_singleton: bool = False,
default: Optional[Union[int, str]] = None,
make_unique: bool = True,
) -> Union[int, List[int], List[bool]]:
) -> Union[int, list[int], list[bool]]:
"""Convert string indices to their corresponding int indices."""
from cellrank._utils._utils import _unique_order_preserving

Expand Down Expand Up @@ -1045,7 +1035,7 @@ def _maybe_convert_names(

@staticmethod
def _prepare_annotation(
array: List[str],
array: list[str],
checker: Optional[Callable] = None,
transformer: Optional[Callable] = None,
checker_msg: Optional[str] = None,
Expand Down Expand Up @@ -1121,7 +1111,7 @@ def copy(self, _="C") -> Lineage:
return obj.T if was_trasposed else obj


def _remove_zero_rows(a: np.ndarray, b: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
def _remove_zero_rows(a: np.ndarray, b: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
if a.shape[0] != b.shape[0]:
raise ValueError("Lineage objects have unequal cell numbers")

Expand Down
14 changes: 7 additions & 7 deletions src/cellrank/_utils/_linear_solver.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import functools
from typing import List, Optional, Tuple, TypeVar, Union
from typing import Optional, TypeVar, Union

import numpy as np
import scipy.sparse as sp
Expand Down Expand Up @@ -72,7 +72,7 @@ def _create_solver(
solver: Optional[str],
preconditioner: Optional[str],
tol: float,
) -> Tuple["petsc4py.PETSc.KSP", "petsc4py.PETSc.Vec", "petsc4py.PETScVec"]: # noqa
) -> tuple["petsc4py.PETSc.KSP", "petsc4py.PETSc.Vec", "petsc4py.PETScVec"]: # noqa
"""
Create a linear system solver.
Expand Down Expand Up @@ -126,7 +126,7 @@ def _solve_many_sparse_problems_petsc(
_preconditioner: Optional[str] = None,
_tol: float = 1e-5,
_queue: Optional[Queue] = None,
) -> Tuple[np.ndarray, int]:
) -> tuple[np.ndarray, int]:
raise NotImplementedError(f"Not implemented for type `{type(mat_b).__name__!r}`.")


Expand All @@ -138,7 +138,7 @@ def _(
preconditioner: Optional[str] = None,
tol: float = 1e-5,
_queue: Optional[Queue] = None,
) -> Tuple[np.ndarray, int]:
) -> tuple[np.ndarray, int]:
if mat_b.ndim not in (1, 2) or (mat_b.ndim == 2 and mat_b.shape[1] != 1):
raise ValueError(f"Expected either a vector or a matrix with `1` column, got `{mat_b.shape}`.")

Expand All @@ -163,7 +163,7 @@ def _(
preconditioner: Optional[str],
tol: float,
queue: Queue,
) -> Tuple[np.ndarray, int]:
) -> tuple[np.ndarray, int]:
ksp, x, b = _create_solver(mat_a, solver, preconditioner=preconditioner, tol=tol)
xs, converged = [], 0

Expand Down Expand Up @@ -194,7 +194,7 @@ def _solve_many_sparse_problems(
solver: LinSolver,
tol: float,
queue: Queue,
) -> Tuple[np.ndarray, int]:
) -> tuple[np.ndarray, int]:
"""Solve ``mat_a * x = mat_b`` efficiently using an iterative solver.
This is a utility function which is optimized for the case of ``mat_a`` and ``mat_b`` being sparse,
Expand Down Expand Up @@ -382,7 +382,7 @@ def _solve_lin_system(
defined via columns in ``mat_b``.
"""

def extractor(res_converged: List[Tuple[np.ndarray, int]]) -> Tuple[np.ndarray, int]:
def extractor(res_converged: list[tuple[np.ndarray, int]]) -> tuple[np.ndarray, int]:
res, converged = zip(*res_converged)
return np.hstack(res), sum(converged)

Expand Down
3 changes: 2 additions & 1 deletion src/cellrank/_utils/_parallelize.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import multiprocessing
import threading
from typing import Any, Callable, Optional, Sequence, Union
from collections.abc import Sequence
from typing import Any, Callable, Optional, Union

import joblib as jl

Expand Down
Loading

0 comments on commit 6e2207f

Please sign in to comment.