From 2baa7a10f4149307ae7b3adbfbd0a466a843fdcd Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 22 Apr 2024 14:16:31 +0200 Subject: [PATCH] pyupgrade, pre-commit autoupdate --- .pre-commit-config.yaml | 9 ++- python/sdist/amici/__init__.py | 7 ++- python/sdist/amici/_codegen/cxx_functions.py | 1 + python/sdist/amici/_codegen/model_class.py | 1 + python/sdist/amici/_codegen/template.py | 6 +- python/sdist/amici/antimony_import.py | 6 +- python/sdist/amici/bngl_import.py | 1 - python/sdist/amici/compile.py | 10 ++-- .../amici/conserved_quantities_demartino.py | 7 +-- .../sdist/amici/conserved_quantities_rref.py | 4 +- python/sdist/amici/cxxcodeprinter.py | 14 ++--- python/sdist/amici/de_export.py | 49 +++++++-------- python/sdist/amici/de_model.py | 4 +- python/sdist/amici/de_model_components.py | 28 ++++----- python/sdist/amici/debugging/__init__.py | 1 + python/sdist/amici/gradient_check.py | 19 +++--- python/sdist/amici/import_utils.py | 28 ++++----- python/sdist/amici/logging.py | 16 ++--- python/sdist/amici/numpy.py | 12 ++-- python/sdist/amici/pandas.py | 20 +++---- python/sdist/amici/petab/conditions.py | 13 ++-- python/sdist/amici/petab/import_helpers.py | 12 ++-- python/sdist/amici/petab/petab_import.py | 3 +- python/sdist/amici/petab/petab_problem.py | 19 +++--- python/sdist/amici/petab/pysb_import.py | 7 +-- python/sdist/amici/petab/sbml_import.py | 18 +++--- python/sdist/amici/petab/simulations.py | 15 ++--- python/sdist/amici/petab/simulator.py | 2 +- python/sdist/amici/petab/util.py | 7 ++- python/sdist/amici/petab_import.py | 1 + python/sdist/amici/petab_import_pysb.py | 1 + python/sdist/amici/plotting.py | 14 ++--- python/sdist/amici/pysb_import.py | 29 +++++---- python/sdist/amici/sbml_import.py | 60 +++++++++---------- python/sdist/amici/setup.template.py | 1 + python/sdist/amici/splines.py | 3 +- python/sdist/amici/swig.py | 1 + python/sdist/amici/swig_wrappers.py | 11 ++-- python/sdist/amici/sympy_utils.py | 10 ++-- python/sdist/amici/testing.py | 1 + python/sdist/pyproject.toml | 4 +- python/sdist/setup.py | 1 + python/tests/conftest.py | 1 + .../bngwiki_egfr_simple_deletemolecules.py | 1 - python/tests/splines_utils.py | 22 +++---- .../test_conserved_quantities_demartino.py | 1 + python/tests/test_edata.py | 1 + python/tests/test_events.py | 1 + python/tests/test_heavisides.py | 1 + python/tests/test_petab_simulate.py | 1 + python/tests/test_rdata.py | 1 + python/tests/test_sbml_import.py | 1 + python/tests/util.py | 1 + tests/benchmark-models/evaluate_benchmark.py | 1 + .../benchmark-models/test_petab_benchmark.py | 1 + tests/benchmark-models/test_petab_model.py | 1 + 56 files changed, 268 insertions(+), 243 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a2d00e00c1..449f94ca79 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-merge-conflict @@ -12,7 +12,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.11 + rev: v0.4.1 hooks: # Run the linter. - id: ruff @@ -28,10 +28,9 @@ repos: - python/sdist/pyproject.toml - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.2 hooks: - id: pyupgrade - args: ["--py39-plus"] - additional_dependencies: [pyupgrade==3.15.0] + args: ["--py310-plus"] exclude: '^(ThirdParty|models)/' diff --git a/python/sdist/amici/__init__.py b/python/sdist/amici/__init__.py index 76369eda37..942b669fa2 100644 --- a/python/sdist/amici/__init__.py +++ b/python/sdist/amici/__init__.py @@ -13,7 +13,8 @@ import sys from pathlib import Path from types import ModuleType as ModelModule -from typing import Any, Callable, Union +from typing import Any +from collections.abc import Callable def _get_amici_path(): @@ -138,7 +139,7 @@ def get_model(self) -> amici.Model: class add_path: """Context manager for temporarily changing PYTHONPATH""" - def __init__(self, path: Union[str, Path]): + def __init__(self, path: str | Path): self.path: str = str(path) def __enter__(self): @@ -151,7 +152,7 @@ def __exit__(self, exc_type, exc_value, traceback): def import_model_module( - module_name: str, module_path: Union[Path, str] + module_name: str, module_path: Path | str ) -> ModelModule: """ Import Python module of an AMICI model diff --git a/python/sdist/amici/_codegen/cxx_functions.py b/python/sdist/amici/_codegen/cxx_functions.py index 7831ed97c2..5fd5ead94a 100644 --- a/python/sdist/amici/_codegen/cxx_functions.py +++ b/python/sdist/amici/_codegen/cxx_functions.py @@ -1,4 +1,5 @@ """Info about C++ functions in the generated model code.""" + from __future__ import annotations from dataclasses import dataclass diff --git a/python/sdist/amici/_codegen/model_class.py b/python/sdist/amici/_codegen/model_class.py index e6366c1dfd..d24884ca89 100644 --- a/python/sdist/amici/_codegen/model_class.py +++ b/python/sdist/amici/_codegen/model_class.py @@ -1,4 +1,5 @@ """Function for generating the ``amici::Model`` subclass for an amici model.""" + from __future__ import annotations from .cxx_functions import functions, multiobs_functions diff --git a/python/sdist/amici/_codegen/template.py b/python/sdist/amici/_codegen/template.py index 34f3391ed6..2a099ba907 100644 --- a/python/sdist/amici/_codegen/template.py +++ b/python/sdist/amici/_codegen/template.py @@ -1,7 +1,7 @@ """Functions to apply template substitution to files.""" + from pathlib import Path from string import Template -from typing import Union class TemplateAmici(Template): @@ -17,8 +17,8 @@ class TemplateAmici(Template): def apply_template( - source_file: Union[str, Path], - target_file: Union[str, Path], + source_file: str | Path, + target_file: str | Path, template_data: dict[str, str], ) -> None: """ diff --git a/python/sdist/amici/antimony_import.py b/python/sdist/amici/antimony_import.py index 545a2654bd..ad269f11fe 100644 --- a/python/sdist/amici/antimony_import.py +++ b/python/sdist/amici/antimony_import.py @@ -3,11 +3,11 @@ https://antimony.sourceforge.net/ https://tellurium.readthedocs.io/en/latest/antimony.html """ + from pathlib import Path -from typing import Union -def antimony2sbml(ant_model: Union[str, Path]) -> str: +def antimony2sbml(ant_model: str | Path) -> str: """Convert Antimony model to SBML. :param ant_model: Antimony model as string or path to file @@ -46,7 +46,7 @@ def antimony2sbml(ant_model: Union[str, Path]) -> str: return sbml_str -def antimony2amici(ant_model: Union[str, Path], *args, **kwargs): +def antimony2amici(ant_model: str | Path, *args, **kwargs): """Convert Antimony model to AMICI model. Converts the Antimony model provided as string of file to SBML and then imports it into AMICI. diff --git a/python/sdist/amici/bngl_import.py b/python/sdist/amici/bngl_import.py index 960413dbe6..8624ca15f1 100644 --- a/python/sdist/amici/bngl_import.py +++ b/python/sdist/amici/bngl_import.py @@ -5,7 +5,6 @@ in the :term:`BNGL` format. """ - from pysb.importers.bngl import model_from_bngl from .pysb_import import pysb2amici diff --git a/python/sdist/amici/compile.py b/python/sdist/amici/compile.py index 6c4a336afc..eb3668bfbb 100644 --- a/python/sdist/amici/compile.py +++ b/python/sdist/amici/compile.py @@ -2,18 +2,18 @@ Functionality for building the C++ extensions of an amici-created model package. """ + import subprocess import sys -from typing import Optional, Union from pathlib import Path import os def build_model_extension( - package_dir: Union[str, Path], - verbose: Optional[Union[bool, int]] = False, - compiler: Optional[str] = None, - extra_msg: Optional[str] = None, + package_dir: str | Path, + verbose: bool | int | None = False, + compiler: str | None = None, + extra_msg: str | None = None, ) -> None: """ Compile the model extension of an amici-created model package. diff --git a/python/sdist/amici/conserved_quantities_demartino.py b/python/sdist/amici/conserved_quantities_demartino.py index 4f2d326b54..43c84fdf5a 100644 --- a/python/sdist/amici/conserved_quantities_demartino.py +++ b/python/sdist/amici/conserved_quantities_demartino.py @@ -2,7 +2,6 @@ import math import random import sys -from typing import Optional, Union from collections.abc import MutableSequence, Sequence from .logging import get_logger @@ -21,8 +20,8 @@ def compute_moiety_conservation_laws( num_species: int, num_reactions: int, max_num_monte_carlo: int = 20, - rng_seed: Union[None, bool, int] = False, - species_names: Optional[Sequence[str]] = None, + rng_seed: None | bool | int = False, + species_names: Sequence[str] | None = None, ) -> tuple[list[list[int]], list[list[float]]]: """Compute moiety conservation laws. @@ -116,7 +115,7 @@ def _output( int_matched: list[int], species_indices: list[list[int]], species_coefficients: list[list[float]], - species_names: Optional[Sequence[str]] = None, + species_names: Sequence[str] | None = None, verbose: bool = False, log_level: int = logging.DEBUG, ): diff --git a/python/sdist/amici/conserved_quantities_rref.py b/python/sdist/amici/conserved_quantities_rref.py index b16053ab08..85dbd2b9b1 100644 --- a/python/sdist/amici/conserved_quantities_rref.py +++ b/python/sdist/amici/conserved_quantities_rref.py @@ -1,12 +1,12 @@ """Find conserved quantities deterministically""" -from typing import Literal, Optional, Union +from typing import Literal import numpy as np def rref( - mat: np.array, round_ndigits: Optional[Union[Literal[False], int]] = None + mat: np.array, round_ndigits: Literal[False] | int | None = None ) -> np.array: """ Bring matrix ``mat`` to reduced row echelon form diff --git a/python/sdist/amici/cxxcodeprinter.py b/python/sdist/amici/cxxcodeprinter.py index fb98b0aca0..d9de0ca8f8 100644 --- a/python/sdist/amici/cxxcodeprinter.py +++ b/python/sdist/amici/cxxcodeprinter.py @@ -1,8 +1,8 @@ """C++ code generation""" + import itertools import os import re -from typing import Optional from collections.abc import Sequence from collections.abc import Iterable @@ -49,7 +49,7 @@ def __init__(self): else: self._fpoptimizer = None - def doprint(self, expr: sp.Expr, assign_to: Optional[str] = None) -> str: + def doprint(self, expr: sp.Expr, assign_to: str | None = None) -> str: if self._fpoptimizer: if isinstance(expr, list): expr = list(map(self._fpoptimizer, expr)) @@ -124,7 +124,7 @@ def _get_sym_lines_symbols( equations: sp.Matrix, variable: str, indent_level: int, - indices: Optional[Sequence[int]] = None, + indices: Sequence[int] | None = None, ) -> list[str]: """ Generate C++ code for where array elements are directly replaced with @@ -230,8 +230,8 @@ def print_bool(expr) -> str: def get_switch_statement( condition: str, cases: dict[int, list[str]], - indentation_level: Optional[int] = 0, - indentation_step: Optional[str] = " " * 4, + indentation_level: int | None = 0, + indentation_step: str | None = " " * 4, ): """ Generate code for a C++ switch statement. @@ -296,8 +296,8 @@ def csc_matrix( matrix: sp.Matrix, rownames: list[sp.Symbol], colnames: list[sp.Symbol], - identifier: Optional[int] = 0, - pattern_only: Optional[bool] = False, + identifier: int | None = 0, + pattern_only: bool | None = False, ) -> tuple[list[int], list[int], sp.Matrix, list[str], sp.Matrix]: """ Generates the sparse symbolic identifiers, symbolic identifiers, diff --git a/python/sdist/amici/de_export.py b/python/sdist/amici/de_export.py index fea9325ab2..147ae3d381 100644 --- a/python/sdist/amici/de_export.py +++ b/python/sdist/amici/de_export.py @@ -9,6 +9,7 @@ :py:func:`amici.sbml_import.SbmlImporter.sbml2amici` and :py:func:`amici.petab_import.import_model`. """ + from __future__ import annotations import copy import logging @@ -1140,36 +1141,36 @@ def _write_model_header_cpp(self) -> None: ] = impl continue - tpl_data[ - f"{func_name.upper()}_DEF" - ] = get_function_extern_declaration( - func_name, self.model_name, self.model.is_ode() + tpl_data[f"{func_name.upper()}_DEF"] = ( + get_function_extern_declaration( + func_name, self.model_name, self.model.is_ode() + ) ) - tpl_data[ - f"{func_name.upper()}_IMPL" - ] = get_model_override_implementation( - func_name, self.model_name, self.model.is_ode() + tpl_data[f"{func_name.upper()}_IMPL"] = ( + get_model_override_implementation( + func_name, self.model_name, self.model.is_ode() + ) ) if func_name in sparse_functions: - tpl_data[ - f"{func_name.upper()}_COLPTRS_DEF" - ] = get_sunindex_extern_declaration( - func_name, self.model_name, "colptrs" + tpl_data[f"{func_name.upper()}_COLPTRS_DEF"] = ( + get_sunindex_extern_declaration( + func_name, self.model_name, "colptrs" + ) ) - tpl_data[ - f"{func_name.upper()}_COLPTRS_IMPL" - ] = get_sunindex_override_implementation( - func_name, self.model_name, "colptrs" + tpl_data[f"{func_name.upper()}_COLPTRS_IMPL"] = ( + get_sunindex_override_implementation( + func_name, self.model_name, "colptrs" + ) ) - tpl_data[ - f"{func_name.upper()}_ROWVALS_DEF" - ] = get_sunindex_extern_declaration( - func_name, self.model_name, "rowvals" + tpl_data[f"{func_name.upper()}_ROWVALS_DEF"] = ( + get_sunindex_extern_declaration( + func_name, self.model_name, "rowvals" + ) ) - tpl_data[ - f"{func_name.upper()}_ROWVALS_IMPL" - ] = get_sunindex_override_implementation( - func_name, self.model_name, "rowvals" + tpl_data[f"{func_name.upper()}_ROWVALS_IMPL"] = ( + get_sunindex_override_implementation( + func_name, self.model_name, "rowvals" + ) ) if self.model.num_states_solver() == self.model.num_states_rdata(): diff --git a/python/sdist/amici/de_model.py b/python/sdist/amici/de_model.py index ea2807df52..f0b9c6cbb0 100644 --- a/python/sdist/amici/de_model.py +++ b/python/sdist/amici/de_model.py @@ -1,4 +1,5 @@ """Symbolic differential equation model.""" + from __future__ import annotations import contextlib @@ -6,7 +7,8 @@ import itertools import re from itertools import chain -from typing import Callable, TYPE_CHECKING +from typing import TYPE_CHECKING +from collections.abc import Callable from collections.abc import Sequence import numpy as np diff --git a/python/sdist/amici/de_model_components.py b/python/sdist/amici/de_model_components.py index eeeabb35db..bc93f44b87 100644 --- a/python/sdist/amici/de_model_components.py +++ b/python/sdist/amici/de_model_components.py @@ -1,7 +1,8 @@ """Objects for AMICI's internal differential equation model representation""" + import abc import numbers -from typing import Optional, SupportsFloat, Union +from typing import SupportsFloat import sympy as sp @@ -45,7 +46,7 @@ def __init__( self, identifier: sp.Symbol, name: str, - value: Union[SupportsFloat, numbers.Number, sp.Expr], + value: SupportsFloat | numbers.Number | sp.Expr, ): """ Create a new ModelQuantity instance. @@ -165,7 +166,7 @@ def __init__( self._ncoeff: sp.Expr = coefficients[state_id] super().__init__(identifier, name, value) - def get_ncoeff(self, state_id) -> Union[sp.Expr, int, float]: + def get_ncoeff(self, state_id) -> sp.Expr | int | float: """ Computes the normalized coefficient a_i/a_j where i is the index of the provided state_id and j is the index of the state that is @@ -216,7 +217,7 @@ class State(ModelQuantity): Base class for differential and algebraic model states """ - _conservation_law: Optional[ConservationLaw] = None + _conservation_law: ConservationLaw | None = None def get_x_rdata(self): """ @@ -323,7 +324,7 @@ def __init__( """ super().__init__(identifier, name, init) self._dt = cast_to_sym(dt, "dt") - self._conservation_law: Union[ConservationLaw, None] = None + self._conservation_law: ConservationLaw | None = None def set_conservation_law(self, law: ConservationLaw) -> None: """ @@ -394,17 +395,16 @@ class Observable(ModelQuantity): function or residuals """ - _measurement_symbol: Union[sp.Symbol, None] = None + _measurement_symbol: sp.Symbol | None = None def __init__( self, identifier: sp.Symbol, name: str, value: sp.Expr, - measurement_symbol: Optional[sp.Symbol] = None, - transformation: Optional[ - ObservableTransformation - ] = ObservableTransformation.LIN, + measurement_symbol: sp.Symbol | None = None, + transformation: None + | (ObservableTransformation) = ObservableTransformation.LIN, ): """ Create a new Observable instance. @@ -459,8 +459,8 @@ def __init__( name: str, value: sp.Expr, event: sp.Symbol, - measurement_symbol: Optional[sp.Symbol] = None, - transformation: Optional[ObservableTransformation] = "lin", + measurement_symbol: sp.Symbol | None = None, + transformation: ObservableTransformation | None = "lin", ): """ Create a new EventObservable instance. @@ -668,8 +668,8 @@ def __init__( identifier: sp.Symbol, name: str, value: sp.Expr, - state_update: Union[sp.Expr, None], - initial_value: Optional[bool] = True, + state_update: sp.Expr | None, + initial_value: bool | None = True, ): """ Create a new Event instance. diff --git a/python/sdist/amici/debugging/__init__.py b/python/sdist/amici/debugging/__init__.py index 81663d17b9..55b24e7b18 100644 --- a/python/sdist/amici/debugging/__init__.py +++ b/python/sdist/amici/debugging/__init__.py @@ -1,4 +1,5 @@ """Functions for debugging AMICI simulation failures.""" + import amici import numpy as np diff --git a/python/sdist/amici/gradient_check.py b/python/sdist/amici/gradient_check.py index c5ddb03749..019f091e86 100644 --- a/python/sdist/amici/gradient_check.py +++ b/python/sdist/amici/gradient_check.py @@ -6,7 +6,6 @@ """ import copy -from typing import Optional from collections.abc import Sequence import numpy as np @@ -31,9 +30,9 @@ def check_finite_difference( edata: ExpData, ip: int, fields: list[str], - atol: Optional[float] = 1e-4, - rtol: Optional[float] = 1e-4, - epsilon: Optional[float] = 1e-3, + atol: float | None = 1e-4, + rtol: float | None = 1e-4, + epsilon: float | None = 1e-3, ) -> None: """ Checks the computed sensitivity based derivatives against a finite @@ -138,10 +137,10 @@ def check_finite_difference( def check_derivatives( model: Model, solver: Solver, - edata: Optional[ExpData] = None, - atol: Optional[float] = 1e-4, - rtol: Optional[float] = 1e-4, - epsilon: Optional[float] = 1e-3, + edata: ExpData | None = None, + atol: float | None = 1e-4, + rtol: float | None = 1e-4, + epsilon: float | None = 1e-3, check_least_squares: bool = True, skip_zero_pars: bool = False, ) -> None: @@ -249,8 +248,8 @@ def _check_close( atol: float, rtol: float, field: str, - ip: Optional[int] = None, - verbose: Optional[bool] = True, + ip: int | None = None, + verbose: bool | None = True, ) -> None: """ Compares computed values against expected values and provides rich diff --git a/python/sdist/amici/import_utils.py b/python/sdist/amici/import_utils.py index 029c2cc6de..1a0dc782db 100644 --- a/python/sdist/amici/import_utils.py +++ b/python/sdist/amici/import_utils.py @@ -1,16 +1,16 @@ """Miscellaneous functions related to model import, independent of any specific - model format""" +model format""" + import enum import itertools as itt import numbers import sys from typing import ( Any, - Callable, - Optional, SupportsFloat, Union, ) +from collections.abc import Callable from collections.abc import Iterable, Sequence import sympy as sp @@ -69,7 +69,7 @@ class ObservableTransformation(str, enum.Enum): def noise_distribution_to_observable_transformation( - noise_distribution: Union[str, Callable], + noise_distribution: str | Callable, ) -> ObservableTransformation: """ Parse noise distribution string and extract observable transformation @@ -90,7 +90,7 @@ def noise_distribution_to_observable_transformation( def noise_distribution_to_cost_function( - noise_distribution: Union[str, Callable], + noise_distribution: str | Callable, ) -> Callable[[str], str]: """ Parse noise distribution string to a cost function definition amici can @@ -258,7 +258,7 @@ def _get_str_symbol_identifiers(str_symbol: str) -> tuple: def smart_subs_dict( sym: sp.Expr, subs: SymbolDef, - field: Optional[str] = None, + field: str | None = None, reverse: bool = True, ) -> sp.Expr: """ @@ -315,7 +315,7 @@ def smart_subs(element: sp.Expr, old: sp.Symbol, new: sp.Expr) -> sp.Expr: def toposort_symbols( - symbols: SymbolDef, field: Optional[str] = None + symbols: SymbolDef, field: str | None = None ) -> SymbolDef: """ Topologically sort symbol definitions according to their interdependency @@ -420,8 +420,8 @@ def _parse_special_functions(sym: sp.Expr, toplevel: bool = True) -> sp.Expr: def _denest_piecewise( - args: Sequence[Union[sp.Expr, sp.logic.boolalg.Boolean, bool]], -) -> tuple[Union[sp.Expr, sp.logic.boolalg.Boolean, bool]]: + args: Sequence[sp.Expr | sp.logic.boolalg.Boolean | bool], +) -> tuple[sp.Expr | sp.logic.boolalg.Boolean | bool]: """ Denest piecewise functions that contain piecewise as condition @@ -567,7 +567,7 @@ def grouper( def _check_unsupported_functions( - sym: sp.Expr, expression_type: str, full_sym: Optional[sp.Expr] = None + sym: sp.Expr, expression_type: str, full_sym: sp.Expr | None = None ): """ Recursively checks the symbolic expression for unsupported symbolic @@ -619,7 +619,7 @@ def _check_unsupported_functions( def cast_to_sym( - value: Union[SupportsFloat, sp.Expr, BooleanAtom], input_name: str + value: SupportsFloat | sp.Expr | BooleanAtom, input_name: str ) -> sp.Expr: """ Typecasts the value to :py:class:`sympy.Float` if possible, and ensures the @@ -647,7 +647,7 @@ def cast_to_sym( return value -def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): +def generate_measurement_symbol(observable_id: str | sp.Symbol): """ Generates the appropriate measurement symbol for the provided observable @@ -662,7 +662,7 @@ def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): return symbol_with_assumptions(f"m{observable_id}") -def generate_regularization_symbol(observable_id: Union[str, sp.Symbol]): +def generate_regularization_symbol(observable_id: str | sp.Symbol): """ Generates the appropriate regularization symbol for the provided observable @@ -678,7 +678,7 @@ def generate_regularization_symbol(observable_id: Union[str, sp.Symbol]): def generate_flux_symbol( - reaction_index: int, name: Optional[str] = None + reaction_index: int, name: str | None = None ) -> sp.Symbol: """ Generate identifier symbol for a reaction flux. diff --git a/python/sdist/amici/logging.py b/python/sdist/amici/logging.py index df39c4a219..0a345ee0a7 100644 --- a/python/sdist/amici/logging.py +++ b/python/sdist/amici/logging.py @@ -27,14 +27,14 @@ "CRITICAL": logging.CRITICAL, } -from typing import Callable, Optional, Union +from collections.abc import Callable def _setup_logger( - level: Optional[int] = logging.WARNING, - console_output: Optional[bool] = True, - file_output: Optional[bool] = False, - capture_warnings: Optional[bool] = False, + level: int | None = logging.WARNING, + console_output: bool | None = True, + file_output: bool | None = False, + capture_warnings: bool | None = False, ) -> logging.Logger: """ Set up a new :class:`logging.Logger` for AMICI logging. @@ -118,7 +118,7 @@ def _setup_logger( return log -def set_log_level(logger: logging.Logger, log_level: Union[int, bool]) -> None: +def set_log_level(logger: logging.Logger, log_level: int | bool) -> None: if log_level is not None and log_level is not False: if isinstance(log_level, bool): log_level = logging.DEBUG @@ -134,8 +134,8 @@ def set_log_level(logger: logging.Logger, log_level: Union[int, bool]) -> None: def get_logger( - logger_name: Optional[str] = BASE_LOGGER_NAME, - log_level: Optional[int] = None, + logger_name: str | None = BASE_LOGGER_NAME, + log_level: int | None = None, **kwargs, ) -> logging.Logger: """ diff --git a/python/sdist/amici/numpy.py b/python/sdist/amici/numpy.py index f40d0f4c6e..9aa03fc2dd 100644 --- a/python/sdist/amici/numpy.py +++ b/python/sdist/amici/numpy.py @@ -37,7 +37,7 @@ class is memory efficient as copies of the underlying C++ objects is _field_names: list[str] = [] _field_dimensions: dict[str, list[int]] = dict() - def __getitem__(self, item: str) -> Union[np.ndarray, float]: + def __getitem__(self, item: str) -> np.ndarray | float: """ Access to field names, copies data from C++ object into numpy array, reshapes according to field dimensions and stores values in @@ -76,7 +76,7 @@ def __missing__(self, key: str) -> None: """ raise KeyError(f"Unknown field name {key}.") - def __getattr__(self, item) -> Union[np.ndarray, float]: + def __getattr__(self, item) -> np.ndarray | float: """ Attribute accessor for field names @@ -245,7 +245,7 @@ class ReturnDataView(SwigPtrView): "t_last", ] - def __init__(self, rdata: Union[ReturnDataPtr, ReturnData]): + def __init__(self, rdata: ReturnDataPtr | ReturnData): """ Constructor @@ -309,7 +309,7 @@ def __init__(self, rdata: Union[ReturnDataPtr, ReturnData]): def __getitem__( self, item: str - ) -> Union[np.ndarray, ReturnDataPtr, ReturnData, float]: + ) -> np.ndarray | ReturnDataPtr | ReturnData | float: """ Access fields by name.s @@ -391,7 +391,7 @@ class ExpDataView(SwigPtrView): "fixedParametersPresimulation", ] - def __init__(self, edata: Union[ExpDataPtr, ExpData]): + def __init__(self, edata: ExpDataPtr | ExpData): """ Constructor @@ -429,7 +429,7 @@ def __init__(self, edata: Union[ExpDataPtr, ExpData]): def _field_as_numpy( field_dimensions: dict[str, list[int]], field: str, data: SwigPtrView -) -> Union[np.ndarray, float, None]: +) -> np.ndarray | float | None: """ Convert data object field to numpy array with dimensions according to specified field dimensions diff --git a/python/sdist/amici/pandas.py b/python/sdist/amici/pandas.py index b776d2d5ef..b61cfa0c79 100644 --- a/python/sdist/amici/pandas.py +++ b/python/sdist/amici/pandas.py @@ -7,7 +7,7 @@ import copy import math -from typing import Optional, SupportsFloat, Union +from typing import SupportsFloat, Union import amici import numpy as np @@ -70,7 +70,7 @@ def _process_rdata_list(rdata_list: ReturnDatas) -> list[amici.ReturnDataView]: def getDataObservablesAsDataFrame( - model: AmiciModel, edata_list: ExpDatas, by_id: Optional[bool] = False + model: AmiciModel, edata_list: ExpDatas, by_id: bool | None = False ) -> pd.DataFrame: """ Write Observables from experimental data as DataFrame. @@ -123,7 +123,7 @@ def getSimulationObservablesAsDataFrame( model: amici.Model, edata_list: ExpDatas, rdata_list: ReturnDatas, - by_id: Optional[bool] = False, + by_id: bool | None = False, ) -> pd.DataFrame: """ Write Observables from simulation results as DataFrame. @@ -181,7 +181,7 @@ def getSimulationStatesAsDataFrame( model: amici.Model, edata_list: ExpDatas, rdata_list: ReturnDatas, - by_id: Optional[bool] = False, + by_id: bool | None = False, ) -> pd.DataFrame: """ Get model state according to lists of ReturnData and ExpData. @@ -237,7 +237,7 @@ def get_expressions_as_dataframe( model: amici.Model, edata_list: ExpDatas, rdata_list: ReturnDatas, - by_id: Optional[bool] = False, + by_id: bool | None = False, ) -> pd.DataFrame: """ Get values of model expressions from lists of ReturnData as DataFrame. @@ -293,7 +293,7 @@ def getResidualsAsDataFrame( model: amici.Model, edata_list: ExpDatas, rdata_list: ReturnDatas, - by_id: Optional[bool] = False, + by_id: bool | None = False, ) -> pd.DataFrame: """ Convert a list of ReturnData and ExpData to pandas DataFrame with @@ -626,8 +626,8 @@ def _get_names_or_ids( def _get_specialized_fixed_parameters( model: AmiciModel, - condition: Union[dict[str, SupportsFloat], pd.Series], - overwrite: Union[dict[str, SupportsFloat], pd.Series], + condition: dict[str, SupportsFloat] | pd.Series, + overwrite: dict[str, SupportsFloat] | pd.Series, by_id: bool, ) -> list[float]: """ @@ -661,7 +661,7 @@ def constructEdataFromDataFrame( df: pd.DataFrame, model: AmiciModel, condition: pd.Series, - by_id: Optional[bool] = False, + by_id: bool | None = False, ) -> amici.amici.ExpData: """ Constructs an ExpData instance according to the provided Model @@ -778,7 +778,7 @@ def constructEdataFromDataFrame( def getEdataFromDataFrame( - model: AmiciModel, df: pd.DataFrame, by_id: Optional[bool] = False + model: AmiciModel, df: pd.DataFrame, by_id: bool | None = False ) -> list[amici.amici.ExpData]: """ Constructs a ExpData instances according to the provided Model and diff --git a/python/sdist/amici/petab/conditions.py b/python/sdist/amici/petab/conditions.py index 34dd44cbcb..61b8679765 100644 --- a/python/sdist/amici/petab/conditions.py +++ b/python/sdist/amici/petab/conditions.py @@ -1,4 +1,5 @@ """PEtab conditions to AMICI ExpDatas.""" + import logging import numbers import warnings @@ -218,7 +219,7 @@ def create_parameterized_edatas( problem_parameters: dict[str, numbers.Number], scaled_parameters: bool = False, parameter_mapping: ParameterMapping = None, - simulation_conditions: Union[pd.DataFrame, dict] = None, + simulation_conditions: pd.DataFrame | dict = None, ) -> list[amici.ExpData]: """Create list of :class:amici.ExpData objects with parameters filled in. @@ -284,7 +285,7 @@ def create_parameterized_edatas( def create_edata_for_condition( - condition: Union[dict, pd.Series], + condition: dict | pd.Series, measurement_df: pd.DataFrame, amici_model: AmiciModel, petab_problem: petab.Problem, @@ -369,7 +370,7 @@ def create_edata_for_condition( def create_edatas( amici_model: AmiciModel, petab_problem: petab.Problem, - simulation_conditions: Union[pd.DataFrame, dict] = None, + simulation_conditions: pd.DataFrame | dict = None, ) -> list[amici.ExpData]: """Create list of :class:`amici.amici.ExpData` objects for PEtab problem. @@ -515,7 +516,7 @@ def _get_measurements_and_sigmas( if isinstance( measurement.get(NOISE_PARAMETERS, None), numbers.Number ): - sigma_y[ - time_ix_for_obs_ix[observable_ix], observable_ix - ] = measurement[NOISE_PARAMETERS] + sigma_y[time_ix_for_obs_ix[observable_ix], observable_ix] = ( + measurement[NOISE_PARAMETERS] + ) return y, sigma_y diff --git a/python/sdist/amici/petab/import_helpers.py b/python/sdist/amici/petab/import_helpers.py index 3caf951ace..29cbff07e6 100644 --- a/python/sdist/amici/petab/import_helpers.py +++ b/python/sdist/amici/petab/import_helpers.py @@ -2,12 +2,12 @@ Functions for PEtab import that are independent of the model format. """ + import importlib import logging import os import re from pathlib import Path -from typing import Union import amici import pandas as pd @@ -30,9 +30,7 @@ def get_observation_model( observable_df: pd.DataFrame, -) -> tuple[ - dict[str, dict[str, str]], dict[str, str], dict[str, Union[str, float]] -]: +) -> tuple[dict[str, dict[str, str]], dict[str, str], dict[str, str | float]]: """ Get observables, sigmas, and noise distributions from PEtab observation table in a format suitable for @@ -128,7 +126,7 @@ def petab_scale_to_amici_scale(scale_str: str) -> int: raise ValueError(f"Invalid parameter scale {scale_str}") -def _create_model_name(folder: Union[str, Path]) -> str: +def _create_model_name(folder: str | Path) -> str: """ Create a name for the model. Just re-use the last part of the folder. @@ -136,9 +134,7 @@ def _create_model_name(folder: Union[str, Path]) -> str: return os.path.split(os.path.normpath(folder))[-1] -def _can_import_model( - model_name: str, model_output_dir: Union[str, Path] -) -> bool: +def _can_import_model(model_name: str, model_output_dir: str | Path) -> bool: """ Check whether a module of that name can already be imported. """ diff --git a/python/sdist/amici/petab/petab_import.py b/python/sdist/amici/petab/petab_import.py index cb896b39e3..0e63496d75 100644 --- a/python/sdist/amici/petab/petab_import.py +++ b/python/sdist/amici/petab/petab_import.py @@ -9,7 +9,6 @@ import os import shutil from pathlib import Path -from typing import Union from warnings import warn import amici @@ -34,7 +33,7 @@ def import_petab_problem( petab_problem: petab.Problem, - model_output_dir: Union[str, Path, None] = None, + model_output_dir: str | Path | None = None, model_name: str = None, compile_: bool = None, non_estimated_parameters_as_constants=True, diff --git a/python/sdist/amici/petab/petab_problem.py b/python/sdist/amici/petab/petab_problem.py index 8ea177ad03..618b8b5247 100644 --- a/python/sdist/amici/petab/petab_problem.py +++ b/python/sdist/amici/petab/petab_problem.py @@ -1,6 +1,6 @@ """PEtab-problem based simulations.""" + import copy -from typing import Optional, Union import amici import pandas as pd @@ -36,10 +36,10 @@ class PetabProblem: def __init__( self, petab_problem: petab.Problem, - amici_model: Optional[amici.Model] = None, - problem_parameters: Optional[dict[str, float]] = None, + amici_model: amici.Model | None = None, + problem_parameters: dict[str, float] | None = None, scaled_parameters: bool = False, - simulation_conditions: Union[pd.DataFrame, list[dict]] = None, + simulation_conditions: pd.DataFrame | list[dict] = None, store_edatas: bool = True, ): self._petab_problem = copy.deepcopy(petab_problem) @@ -63,9 +63,9 @@ def __init__( if ( preeq_id := PREEQUILIBRATION_CONDITION_ID ) in self._simulation_conditions: - self._simulation_conditions[ - preeq_id - ] = self._simulation_conditions[preeq_id].fillna("") + self._simulation_conditions[preeq_id] = ( + self._simulation_conditions[preeq_id].fillna("") + ) if problem_parameters is None: # Use PEtab nominal values as default @@ -102,7 +102,10 @@ def set_parameters( :param scaled_parameters: Whether the provided parameters are on PEtab `parameterScale` or not. """ - if scaled_parameters != self._scaled_parameters and self._parameter_mapping is not None: + if ( + scaled_parameters != self._scaled_parameters + and self._parameter_mapping is not None + ): # redo parameter mapping if scale changed self._parameter_mapping = create_parameter_mapping( petab_problem=self._petab_problem, diff --git a/python/sdist/amici/petab/pysb_import.py b/python/sdist/amici/petab/pysb_import.py index 8c67bb0785..b770603935 100644 --- a/python/sdist/amici/petab/pysb_import.py +++ b/python/sdist/amici/petab/pysb_import.py @@ -8,7 +8,6 @@ import logging import re from pathlib import Path -from typing import Optional, Union import petab import pysb @@ -165,9 +164,9 @@ def _add_initialization_variables( @log_execution_time("Importing PEtab model", logger) def import_model_pysb( petab_problem: petab.Problem, - model_output_dir: Optional[Union[str, Path]] = None, - verbose: Optional[Union[bool, int]] = True, - model_name: Optional[str] = None, + model_output_dir: str | Path | None = None, + verbose: bool | int | None = True, + model_name: str | None = None, **kwargs, ) -> None: """ diff --git a/python/sdist/amici/petab/sbml_import.py b/python/sdist/amici/petab/sbml_import.py index 2484d57a7a..2c43c3adc4 100644 --- a/python/sdist/amici/petab/sbml_import.py +++ b/python/sdist/amici/petab/sbml_import.py @@ -4,7 +4,7 @@ import tempfile from itertools import chain from pathlib import Path -from typing import Optional, Union +from typing import Union from warnings import warn import amici @@ -31,17 +31,17 @@ @log_execution_time("Importing PEtab model", logger) def import_model_sbml( sbml_model: Union[str, Path, "libsbml.Model"] = None, - condition_table: Optional[Union[str, Path, pd.DataFrame]] = None, - observable_table: Optional[Union[str, Path, pd.DataFrame]] = None, - measurement_table: Optional[Union[str, Path, pd.DataFrame]] = None, + condition_table: str | Path | pd.DataFrame | None = None, + observable_table: str | Path | pd.DataFrame | None = None, + measurement_table: str | Path | pd.DataFrame | None = None, petab_problem: petab.Problem = None, - model_name: Optional[str] = None, - model_output_dir: Optional[Union[str, Path]] = None, - verbose: Optional[Union[bool, int]] = True, + model_name: str | None = None, + model_output_dir: str | Path | None = None, + verbose: bool | int | None = True, allow_reinit_fixpar_initcond: bool = True, validate: bool = True, non_estimated_parameters_as_constants=True, - output_parameter_defaults: Optional[dict[str, float]] = None, + output_parameter_defaults: dict[str, float] | None = None, discard_sbml_annotations: bool = False, **kwargs, ) -> amici.SbmlImporter: @@ -545,7 +545,7 @@ def _get_fixed_parameters_sbml( def _create_model_output_dir_name( - sbml_model: "libsbml.Model", model_name: Optional[str] = None + sbml_model: "libsbml.Model", model_name: str | None = None ) -> Path: """ Find a folder for storing the compiled amici model. diff --git a/python/sdist/amici/petab/simulations.py b/python/sdist/amici/petab/simulations.py index 0f9aae3bfd..77f14ccb35 100644 --- a/python/sdist/amici/petab/simulations.py +++ b/python/sdist/amici/petab/simulations.py @@ -3,9 +3,10 @@ Functionality related to running simulations or evaluating the objective function as defined by a PEtab problem. """ + import copy import logging -from typing import Any, Optional, Union +from typing import Any from collections.abc import Sequence import amici @@ -72,12 +73,12 @@ def simulate_petab( petab_problem: petab.Problem, amici_model: AmiciModel, - solver: Optional[amici.Solver] = None, - problem_parameters: Optional[dict[str, float]] = None, - simulation_conditions: Union[pd.DataFrame, dict] = None, + solver: amici.Solver | None = None, + problem_parameters: dict[str, float] | None = None, + simulation_conditions: pd.DataFrame | dict = None, edatas: list[AmiciExpData] = None, parameter_mapping: ParameterMapping = None, - scaled_parameters: Optional[bool] = False, + scaled_parameters: bool | None = False, log_level: int = logging.WARNING, num_threads: int = 1, failfast: bool = True, @@ -262,11 +263,11 @@ def simulate_petab( def aggregate_sllh( amici_model: AmiciModel, rdatas: Sequence[amici.ReturnDataView], - parameter_mapping: Optional[ParameterMapping], + parameter_mapping: ParameterMapping | None, edatas: list[AmiciExpData], petab_scale: bool = True, petab_problem: petab.Problem = None, -) -> Union[None, dict[str, float]]: +) -> None | dict[str, float]: """ Aggregate likelihood gradient for all conditions, according to PEtab parameter mapping. diff --git a/python/sdist/amici/petab/simulator.py b/python/sdist/amici/petab/simulator.py index a5f50112cc..9c655b1483 100644 --- a/python/sdist/amici/petab/simulator.py +++ b/python/sdist/amici/petab/simulator.py @@ -11,7 +11,7 @@ import inspect import sys -from typing import Callable +from collections.abc import Callable import pandas as pd import petab diff --git a/python/sdist/amici/petab/util.py b/python/sdist/amici/petab/util.py index 742f7bdfe3..e30b829a04 100644 --- a/python/sdist/amici/petab/util.py +++ b/python/sdist/amici/petab/util.py @@ -1,6 +1,7 @@ """Various helper functions for working with PEtab problems.""" + import re -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING import libsbml import pandas as pd @@ -15,9 +16,9 @@ def get_states_in_condition_table( petab_problem: petab.Problem, - condition: Union[dict, pd.Series] = None, + condition: dict | pd.Series = None, return_patterns: bool = False, -) -> dict[str, tuple[Union[float, str, None], Union[float, str, None]]]: +) -> dict[str, tuple[float | str | None, float | str | None]]: """Get states and their initial condition as specified in the condition table. Returns: Dictionary: ``stateId -> (initial condition simulation, initial condition preequilibration)`` diff --git a/python/sdist/amici/petab_import.py b/python/sdist/amici/petab_import.py index d5c67753ac..b81484c1cc 100644 --- a/python/sdist/amici/petab_import.py +++ b/python/sdist/amici/petab_import.py @@ -7,6 +7,7 @@ .. deprecated:: 0.21.0 Use :mod:`amici.petab` instead. """ + import warnings warnings.warn( diff --git a/python/sdist/amici/petab_import_pysb.py b/python/sdist/amici/petab_import_pysb.py index 595018f208..a1597d53b5 100644 --- a/python/sdist/amici/petab_import_pysb.py +++ b/python/sdist/amici/petab_import_pysb.py @@ -4,6 +4,7 @@ .. deprecated:: 0.21.0 Use :mod:`amici.petab.pysb_import` instead. """ + import warnings from .petab.pysb_import import * # noqa: F401, F403 diff --git a/python/sdist/amici/plotting.py b/python/sdist/amici/plotting.py index 19dbe05f89..651ba0e23e 100644 --- a/python/sdist/amici/plotting.py +++ b/python/sdist/amici/plotting.py @@ -3,7 +3,7 @@ -------- Plotting related functions """ -from typing import Optional, Union + from collections.abc import Iterable, Sequence import matplotlib.pyplot as plt @@ -19,8 +19,8 @@ def plot_state_trajectories( rdata: ReturnDataView, - state_indices: Optional[Sequence[int]] = None, - ax: Optional[Axes] = None, + state_indices: Sequence[int] | None = None, + ax: Axes | None = None, model: Model = None, prefer_names: bool = True, marker=None, @@ -76,12 +76,12 @@ def plot_state_trajectories( def plot_observable_trajectories( rdata: ReturnDataView, - observable_indices: Optional[Iterable[int]] = None, - ax: Optional[Axes] = None, + observable_indices: Iterable[int] | None = None, + ax: Axes | None = None, model: Model = None, prefer_names: bool = True, marker=None, - edata: Union[amici.ExpData, amici.ExpDataView] = None, + edata: amici.ExpData | amici.ExpDataView = None, ) -> None: """ Plot observable trajectories. @@ -175,7 +175,7 @@ def plot_jacobian(rdata: ReturnDataView): def plot_expressions( - exprs: Union[Sequence[StrOrExpr], StrOrExpr], rdata: ReturnDataView + exprs: Sequence[StrOrExpr] | StrOrExpr, rdata: ReturnDataView ) -> None: """Plot the given expressions evaluated on the given simulation outputs. diff --git a/python/sdist/amici/pysb_import.py b/python/sdist/amici/pysb_import.py index 94aad595d9..46476a753d 100644 --- a/python/sdist/amici/pysb_import.py +++ b/python/sdist/amici/pysb_import.py @@ -12,10 +12,9 @@ from pathlib import Path from typing import ( Any, - Callable, - Optional, Union, ) +from collections.abc import Callable from collections.abc import Iterable import numpy as np @@ -53,12 +52,12 @@ def pysb2amici( model: pysb.Model, - output_dir: Optional[Union[str, Path]] = None, + output_dir: str | Path | None = None, observables: list[str] = None, constant_parameters: list[str] = None, sigmas: dict[str, str] = None, - noise_distributions: Optional[dict[str, Union[str, Callable]]] = None, - verbose: Union[int, bool] = False, + noise_distributions: dict[str, str | Callable] | None = None, + verbose: int | bool = False, assume_pow_positivity: bool = False, compiler: str = None, compute_conservation_laws: bool = True, @@ -68,7 +67,7 @@ def pysb2amici( # See https://github.com/AMICI-dev/AMICI/pull/1672 cache_simplify: bool = False, generate_sensitivity_code: bool = True, - model_name: Optional[str] = None, + model_name: str | None = None, ): r""" Generate AMICI C++ files for the provided model. @@ -194,13 +193,13 @@ def ode_model_from_pysb_importer( constant_parameters: list[str] = None, observables: list[str] = None, sigmas: dict[str, str] = None, - noise_distributions: Optional[dict[str, Union[str, Callable]]] = None, + noise_distributions: dict[str, str | Callable] | None = None, compute_conservation_laws: bool = True, simplify: Callable = sp.powsimp, # Do not enable by default without testing. # See https://github.com/AMICI-dev/AMICI/pull/1672 cache_simplify: bool = False, - verbose: Union[int, bool] = False, + verbose: int | bool = False, ) -> DEModel: """ Creates an :class:`amici.DEModel` instance from a :class:`pysb.Model` @@ -441,7 +440,7 @@ def _process_pysb_expressions( ode_model: DEModel, observables: list[str], sigmas: dict[str, str], - noise_distributions: Optional[dict[str, Union[str, Callable]]] = None, + noise_distributions: dict[str, str | Callable] | None = None, ) -> None: r""" Converts pysb expressions/observables into Observables (with @@ -506,7 +505,7 @@ def _add_expression( ode_model: DEModel, observables: list[str], sigmas: dict[str, str], - noise_distributions: Optional[dict[str, Union[str, Callable]]] = None, + noise_distributions: dict[str, str | Callable] | None = None, ): """ Adds expressions to the ODE model given and adds observables/sigmas if @@ -621,7 +620,7 @@ def _process_pysb_observables( ode_model: DEModel, observables: list[str], sigmas: dict[str, str], - noise_distributions: Optional[dict[str, Union[str, Callable]]] = None, + noise_distributions: dict[str, str | Callable] | None = None, ) -> None: """ Converts :class:`pysb.core.Observable` into @@ -1349,7 +1348,7 @@ def has_fixed_parameter_ic( def extract_monomers( - complex_patterns: Union[pysb.ComplexPattern, list[pysb.ComplexPattern]], + complex_patterns: pysb.ComplexPattern | list[pysb.ComplexPattern], ) -> list[str]: """ Constructs a list of monomer names contained in complex patterns. @@ -1415,8 +1414,8 @@ def _get_unconserved_monomers( def _get_changed_stoichiometries( - reactants: Union[pysb.ComplexPattern, list[pysb.ComplexPattern]], - products: Union[pysb.ComplexPattern, list[pysb.ComplexPattern]], + reactants: pysb.ComplexPattern | list[pysb.ComplexPattern], + products: pysb.ComplexPattern | list[pysb.ComplexPattern], ) -> set[str]: """ Constructs the set of monomer names which have different @@ -1444,7 +1443,7 @@ def _get_changed_stoichiometries( return changed_stoichiometries -def pysb_model_from_path(pysb_model_file: Union[str, Path]) -> pysb.Model: +def pysb_model_from_path(pysb_model_file: str | Path) -> pysb.Model: """Load a pysb model module and return the :class:`pysb.Model` instance :param pysb_model_file: Full or relative path to the PySB model module diff --git a/python/sdist/amici/sbml_import.py b/python/sdist/amici/sbml_import.py index 8f7f67b02f..40c4881a09 100644 --- a/python/sdist/amici/sbml_import.py +++ b/python/sdist/amici/sbml_import.py @@ -4,6 +4,7 @@ This module provides all necessary functionality to import a model specified in the `Systems Biology Markup Language (SBML) `_. """ + import copy import itertools as itt import logging @@ -15,10 +16,9 @@ from pathlib import Path from typing import ( Any, - Callable, - Optional, Union, ) +from collections.abc import Callable from collections.abc import Iterable, Sequence import libsbml as sbml @@ -134,7 +134,7 @@ class SbmlImporter: def __init__( self, - sbml_source: Union[str, Path, sbml.Model], + sbml_source: str | Path | sbml.Model, show_sbml_warnings: bool = False, from_file: bool = True, discard_annotations: bool = False, @@ -177,7 +177,7 @@ def __init__( # Long and short names for model components self.symbols: dict[SymbolId, dict[sp.Symbol, dict[str, Any]]] = {} - self._local_symbols: dict[str, Union[sp.Expr, sp.Function]] = {} + self._local_symbols: dict[str, sp.Expr | sp.Function] = {} self.compartments: SymbolicFormula = {} self.compartment_assignment_rules: SymbolicFormula = {} self.species_assignment_rules: SymbolicFormula = {} @@ -269,21 +269,21 @@ def _reset_symbols(self) -> None: def sbml2amici( self, model_name: str, - output_dir: Union[str, Path] = None, + output_dir: str | Path = None, observables: dict[str, dict[str, str]] = None, event_observables: dict[str, dict[str, str]] = None, constant_parameters: Iterable[str] = None, - sigmas: dict[str, Union[str, float]] = None, - event_sigmas: dict[str, Union[str, float]] = None, - noise_distributions: dict[str, Union[str, Callable]] = None, - event_noise_distributions: dict[str, Union[str, Callable]] = None, - verbose: Union[int, bool] = logging.ERROR, + sigmas: dict[str, str | float] = None, + event_sigmas: dict[str, str | float] = None, + noise_distributions: dict[str, str | Callable] = None, + event_noise_distributions: dict[str, str | Callable] = None, + verbose: int | bool = logging.ERROR, assume_pow_positivity: bool = False, compiler: str = None, allow_reinit_fixpar_initcond: bool = True, compile: bool = True, compute_conservation_laws: bool = True, - simplify: Optional[Callable] = _default_simplify, + simplify: Callable | None = _default_simplify, cache_simplify: bool = False, log_as_log10: bool = True, generate_sensitivity_code: bool = True, @@ -451,13 +451,13 @@ def _build_ode_model( observables: dict[str, dict[str, str]] = None, event_observables: dict[str, dict[str, str]] = None, constant_parameters: Iterable[str] = None, - sigmas: dict[str, Union[str, float]] = None, - event_sigmas: dict[str, Union[str, float]] = None, - noise_distributions: dict[str, Union[str, Callable]] = None, - event_noise_distributions: dict[str, Union[str, Callable]] = None, - verbose: Union[int, bool] = logging.ERROR, + sigmas: dict[str, str | float] = None, + event_sigmas: dict[str, str | float] = None, + noise_distributions: dict[str, str | Callable] = None, + event_noise_distributions: dict[str, str | Callable] = None, + verbose: int | bool = logging.ERROR, compute_conservation_laws: bool = True, - simplify: Optional[Callable] = _default_simplify, + simplify: Callable | None = _default_simplify, cache_simplify: bool = False, log_as_log10: bool = True, hardcode_symbols: Sequence[str] = None, @@ -1043,7 +1043,7 @@ def add_d_dt( self, d_dt: sp.Expr, variable: sp.Symbol, - variable0: Union[float, sp.Expr], + variable0: float | sp.Expr, name: str, ) -> None: """ @@ -1701,8 +1701,8 @@ def get_empty_bolus_value() -> sp.Float: @log_execution_time("processing SBML observables", logger) def _process_observables( self, - observables: Union[dict[str, dict[str, str]], None], - sigmas: dict[str, Union[str, float]], + observables: dict[str, dict[str, str]] | None, + sigmas: dict[str, str | float], noise_distributions: dict[str, str], ) -> None: """ @@ -1768,7 +1768,7 @@ def _process_observables( def _process_event_observables( self, event_observables: dict[str, dict[str, str]], - event_sigmas: dict[str, Union[str, float]], + event_sigmas: dict[str, str | float], event_noise_distributions: dict[str, str], ) -> None: """ @@ -1884,7 +1884,7 @@ def _generate_default_observables(self): def _process_log_likelihood( self, - sigmas: dict[str, Union[str, float]], + sigmas: dict[str, str | float], noise_distributions: dict[str, str], events: bool = False, event_reg: bool = False, @@ -2036,8 +2036,8 @@ def _process_species_references(self): ) def _make_initial( - self, sym_math: Union[sp.Expr, None, float] - ) -> Union[sp.Expr, None, float]: + self, sym_math: sp.Expr | None | float + ) -> sp.Expr | None | float: """ Transforms an expression to its value at the initial time point by replacing species by their initial values. @@ -2488,7 +2488,7 @@ def _clean_reserved_symbols(self) -> None: def _sympy_from_sbml_math( self, var_or_math: [sbml.SBase, str] - ) -> Union[sp.Expr, float, None]: + ) -> sp.Expr | float | None: """ Sympify Math of SBML variables with all sanity checks and transformations @@ -2541,7 +2541,7 @@ def _sympy_from_sbml_math( def _get_element_initial_assignment( self, element_id: str - ) -> Union[sp.Expr, None]: + ) -> sp.Expr | None: """ Extract value of sbml variable according to its initial assignment @@ -2926,7 +2926,7 @@ def _get_list_of_species_references( ] -def replace_logx(math_str: Union[str, float, None]) -> Union[str, float, None]: +def replace_logx(math_str: str | float | None) -> str | float | None: """ Replace logX(.) by log(., X) since sympy cannot parse the former @@ -2961,7 +2961,7 @@ def _collect_event_assignment_parameter_targets( def _check_unsupported_functions_sbml( - sym: sp.Expr, expression_type: str, full_sym: Optional[sp.Expr] = None + sym: sp.Expr, expression_type: str, full_sym: sp.Expr | None = None ): try: _check_unsupported_functions(sym, expression_type, full_sym) @@ -2979,8 +2979,8 @@ def _parse_special_functions_sbml( def _validate_observables( - observables: Union[dict[str, dict[str, str]], None], - sigmas: dict[str, Union[str, float]], + observables: dict[str, dict[str, str]] | None, + sigmas: dict[str, str | float], noise_distributions: dict[str, str], events: bool = False, ) -> None: diff --git a/python/sdist/amici/setup.template.py b/python/sdist/amici/setup.template.py index 11589564e0..1f2d099110 100644 --- a/python/sdist/amici/setup.template.py +++ b/python/sdist/amici/setup.template.py @@ -1,4 +1,5 @@ """AMICI model package setup""" + import os import sys from pathlib import Path diff --git a/python/sdist/amici/splines.py b/python/sdist/amici/splines.py index ea0cd0e06d..cd500a4570 100644 --- a/python/sdist/amici/splines.py +++ b/python/sdist/amici/splines.py @@ -5,6 +5,7 @@ annotations from/to SBML files and for adding such splines to the AMICI C++ code. """ + from __future__ import annotations from typing import TYPE_CHECKING @@ -13,9 +14,9 @@ from numbers import Real from typing import ( Any, - Callable, Union, ) + from collections.abc import Callable from collections.abc import Sequence from . import sbml_import diff --git a/python/sdist/amici/swig.py b/python/sdist/amici/swig.py index 5ba8017005..e0c518957f 100644 --- a/python/sdist/amici/swig.py +++ b/python/sdist/amici/swig.py @@ -1,4 +1,5 @@ """Functions related to SWIG or SWIG-generated code""" + from __future__ import annotations import ast import contextlib diff --git a/python/sdist/amici/swig_wrappers.py b/python/sdist/amici/swig_wrappers.py index b6023b2c34..3c4df44809 100644 --- a/python/sdist/amici/swig_wrappers.py +++ b/python/sdist/amici/swig_wrappers.py @@ -1,9 +1,10 @@ """Convenience wrappers for the swig interface""" + import logging import sys import warnings from contextlib import contextmanager, suppress -from typing import Any, Optional, Union +from typing import Any import amici import amici.amici as amici_swig @@ -49,7 +50,7 @@ def _capture_cstdout(): def runAmiciSimulation( model: AmiciModel, solver: AmiciSolver, - edata: Optional[AmiciExpData] = None, + edata: AmiciExpData | None = None, ) -> "numpy.ReturnDataView": """ Convenience wrapper around :py:func:`amici.amici.runAmiciSimulation` @@ -139,7 +140,7 @@ def runAmiciSimulations( def readSolverSettingsFromHDF5( - file: str, solver: AmiciSolver, location: Optional[str] = "solverSettings" + file: str, solver: AmiciSolver, location: str | None = "solverSettings" ) -> None: """ Convenience wrapper for :py:func:`amici.readSolverSettingsFromHDF5` @@ -153,8 +154,8 @@ def readSolverSettingsFromHDF5( def writeSolverSettingsToHDF5( solver: AmiciSolver, - file: Union[str, object], - location: Optional[str] = "solverSettings", + file: str | object, + location: str | None = "solverSettings", ) -> None: """ Convenience wrapper for :py:func:`amici.amici.writeSolverSettingsToHDF5` diff --git a/python/sdist/amici/sympy_utils.py b/python/sdist/amici/sympy_utils.py index bc20c49dc4..2c8599ba7e 100644 --- a/python/sdist/amici/sympy_utils.py +++ b/python/sdist/amici/sympy_utils.py @@ -1,7 +1,9 @@ """Functionality for working with sympy objects.""" + import os from itertools import starmap -from typing import Union, Any, Callable +from typing import Any +from collections.abc import Callable import contextlib import sympy as sp import logging @@ -111,9 +113,9 @@ def smart_jacobian( @log_execution_time("running smart_multiply", logger) def smart_multiply( - x: Union[sp.MutableDenseMatrix, sp.MutableSparseMatrix], + x: sp.MutableDenseMatrix | sp.MutableSparseMatrix, y: sp.MutableDenseMatrix, -) -> Union[sp.MutableDenseMatrix, sp.MutableSparseMatrix]: +) -> sp.MutableDenseMatrix | sp.MutableSparseMatrix: """ Wrapper around symbolic multiplication with some additional checks that reduce computation time for large matrices @@ -136,7 +138,7 @@ def smart_multiply( def smart_is_zero_matrix( - x: Union[sp.MutableDenseMatrix, sp.MutableSparseMatrix], + x: sp.MutableDenseMatrix | sp.MutableSparseMatrix, ) -> bool: """A faster implementation of sympy's is_zero_matrix diff --git a/python/sdist/amici/testing.py b/python/sdist/amici/testing.py index 8d4a73fbe1..40b791d0d8 100644 --- a/python/sdist/amici/testing.py +++ b/python/sdist/amici/testing.py @@ -1,4 +1,5 @@ """Test support functions""" + import os import sys from tempfile import TemporaryDirectory diff --git a/python/sdist/pyproject.toml b/python/sdist/pyproject.toml index 6b427e2d16..58d39d4ea7 100644 --- a/python/sdist/pyproject.toml +++ b/python/sdist/pyproject.toml @@ -127,5 +127,7 @@ line-length = 79 [tool.ruff] line-length = 79 -ignore = ["E402", "F403", "F405", "E741"] extend-include = ["*.ipynb"] + +[tool.ruff.lint] +ignore = ["E402", "F403", "F405", "E741"] diff --git a/python/sdist/setup.py b/python/sdist/setup.py index cfc474ebe8..83bf33237a 100755 --- a/python/sdist/setup.py +++ b/python/sdist/setup.py @@ -9,6 +9,7 @@ - swig>=3.0 - Optional: hdf5 libraries and headers """ + import os import sys from pathlib import Path diff --git a/python/tests/conftest.py b/python/tests/conftest.py index 1da7cb31b3..d8d882fcfd 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -1,4 +1,5 @@ """pytest configuration file""" + import copy import importlib import os diff --git a/python/tests/pysb_test_models/bngwiki_egfr_simple_deletemolecules.py b/python/tests/pysb_test_models/bngwiki_egfr_simple_deletemolecules.py index 1a39d4a846..4c40f7e815 100644 --- a/python/tests/pysb_test_models/bngwiki_egfr_simple_deletemolecules.py +++ b/python/tests/pysb_test_models/bngwiki_egfr_simple_deletemolecules.py @@ -3,7 +3,6 @@ http://bionetgen.org/index.php/Egfr_simple """ - from pysb import * Model() diff --git a/python/tests/splines_utils.py b/python/tests/splines_utils.py index 29024d3b73..6565ac80a4 100644 --- a/python/tests/splines_utils.py +++ b/python/tests/splines_utils.py @@ -8,7 +8,7 @@ import os import uuid from tempfile import mkdtemp -from typing import Any, Optional, Union +from typing import Any from collections.abc import Sequence import amici @@ -45,7 +45,7 @@ def evaluate_spline( def integrate_spline( spline: AbstractSpline, - params: Union[dict, None], + params: dict | None, tt: Sequence[float], initial_value: float = 0, ): @@ -119,12 +119,12 @@ def species_to_index(name) -> int: def create_petab_problem( splines: list[AbstractSpline], params_true: dict, - initial_values: Optional[np.ndarray] = None, + initial_values: np.ndarray | None = None, use_reactions: bool = False, measure_upsample: int = 6, sigma: float = 1.0, t_extrapolate: float = 0.25, - folder: Optional[str] = None, + folder: str | None = None, model_name: str = "test_splines", ): """ @@ -283,9 +283,9 @@ def simulate_splines( params_true, initial_values=None, *, - folder: Optional[str] = None, + folder: str | None = None, keep_temporary: bool = False, - benchmark: Union[bool, int] = False, + benchmark: bool | int = False, rtol: float = 1e-12, atol: float = 1e-12, maxsteps: int = 500_000, @@ -505,8 +505,8 @@ def check_splines( discard_annotations: bool = False, use_adjoint: bool = False, skip_sensitivity: bool = False, - debug: Union[bool, str] = False, - parameter_lists: Optional[Sequence[Sequence[int]]] = None, + debug: bool | str = False, + parameter_lists: Sequence[Sequence[int]] | None = None, llh_rtol: float = 1e-8, sllh_atol: float = 1e-8, x_rtol: float = 1e-11, @@ -515,7 +515,7 @@ def check_splines( w_atol: float = 1e-11, sx_rtol: float = 1e-10, sx_atol: float = 1e-10, - groundtruth: Optional[Union[str, dict[str, Any]]] = None, + groundtruth: str | dict[str, Any] | None = None, **kwargs, ): """ @@ -771,8 +771,8 @@ def check_splines_full( check_piecewise: bool = True, check_forward: bool = True, check_adjoint: bool = True, - folder: Optional[str] = None, - groundtruth: Optional[Union[dict, str]] = "compute", + folder: str | None = None, + groundtruth: dict | str | None = "compute", return_groundtruth: bool = False, **kwargs, ): diff --git a/python/tests/test_conserved_quantities_demartino.py b/python/tests/test_conserved_quantities_demartino.py index ca40946db3..2ed778b85e 100644 --- a/python/tests/test_conserved_quantities_demartino.py +++ b/python/tests/test_conserved_quantities_demartino.py @@ -1,4 +1,5 @@ """Tests for conservation laws / conserved moieties""" + import os from time import perf_counter diff --git a/python/tests/test_edata.py b/python/tests/test_edata.py index 27c67de61e..fab49c160e 100644 --- a/python/tests/test_edata.py +++ b/python/tests/test_edata.py @@ -1,4 +1,5 @@ """Tests related to amici.ExpData via Python""" + import amici import numpy as np from amici.testing import skip_on_valgrind diff --git a/python/tests/test_events.py b/python/tests/test_events.py index 065cdeb126..05eddab59f 100644 --- a/python/tests/test_events.py +++ b/python/tests/test_events.py @@ -1,4 +1,5 @@ """Tests for SBML events, including piecewise expressions.""" + from copy import deepcopy import amici diff --git a/python/tests/test_heavisides.py b/python/tests/test_heavisides.py index c3bea26a0c..26de4f575e 100644 --- a/python/tests/test_heavisides.py +++ b/python/tests/test_heavisides.py @@ -1,4 +1,5 @@ """Tests for SBML events, including piecewise expressions.""" + import numpy as np import pytest from util import ( diff --git a/python/tests/test_petab_simulate.py b/python/tests/test_petab_simulate.py index a8240bff33..e1da7768e3 100644 --- a/python/tests/test_petab_simulate.py +++ b/python/tests/test_petab_simulate.py @@ -1,4 +1,5 @@ """Tests for petab_simulate.py.""" + import tempfile from pathlib import Path diff --git a/python/tests/test_rdata.py b/python/tests/test_rdata.py index 8e0f78655e..80ec3b80e6 100644 --- a/python/tests/test_rdata.py +++ b/python/tests/test_rdata.py @@ -1,4 +1,5 @@ """Test amici.ReturnData(View)-related functionality""" + import amici import numpy as np import pytest diff --git a/python/tests/test_sbml_import.py b/python/tests/test_sbml_import.py index aaab5688cc..f0400396f8 100644 --- a/python/tests/test_sbml_import.py +++ b/python/tests/test_sbml_import.py @@ -1,4 +1,5 @@ """Tests related to amici.sbml_import""" + import os import re from numbers import Number diff --git a/python/tests/util.py b/python/tests/util.py index dde10eb454..58e17137a6 100644 --- a/python/tests/util.py +++ b/python/tests/util.py @@ -1,4 +1,5 @@ """Tests for SBML events, including piecewise expressions.""" + import sys import tempfile from pathlib import Path diff --git a/tests/benchmark-models/evaluate_benchmark.py b/tests/benchmark-models/evaluate_benchmark.py index 0c6e2e4122..0fe80f6625 100644 --- a/tests/benchmark-models/evaluate_benchmark.py +++ b/tests/benchmark-models/evaluate_benchmark.py @@ -3,6 +3,7 @@ """ Aggregate computation times from different benchmarks and plot """ + import os import matplotlib.pyplot as plt diff --git a/tests/benchmark-models/test_petab_benchmark.py b/tests/benchmark-models/test_petab_benchmark.py index 753c88e500..976ff3dc05 100644 --- a/tests/benchmark-models/test_petab_benchmark.py +++ b/tests/benchmark-models/test_petab_benchmark.py @@ -1,4 +1,5 @@ """Tests for simulate_petab on PEtab benchmark problems.""" + import os from pathlib import Path diff --git a/tests/benchmark-models/test_petab_model.py b/tests/benchmark-models/test_petab_model.py index 8f52a341c4..da3d37b5fb 100755 --- a/tests/benchmark-models/test_petab_model.py +++ b/tests/benchmark-models/test_petab_model.py @@ -3,6 +3,7 @@ """ Simulate a PEtab problem and compare results to reference values """ + import argparse import contextlib import importlib