From 1702b55b7da01e9b03d5aa3a6134fd829cf7e7a2 Mon Sep 17 00:00:00 2001 From: Gabriel Gerlero <gerlero@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:27:39 -0300 Subject: [PATCH] Drop support for Python < 3.9 --- .github/workflows/ci.yml | 2 +- electrolytes/__init__.py | 35 ++++++++++++-------------------- electrolytes/__main__.py | 44 +++++++++++++++++----------------------- pyproject.toml | 6 +----- 4 files changed, 34 insertions(+), 53 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bb4672..6650a54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.9', '3.10', '3.11', '3.12'] fail-fast: false steps: - name: Checkout diff --git a/electrolytes/__init__.py b/electrolytes/__init__.py index 461e97f..cb015ad 100644 --- a/electrolytes/__init__.py +++ b/electrolytes/__init__.py @@ -1,16 +1,7 @@ -import sys import pkgutil from pathlib import Path -from typing import Collection, Iterator, List, Sequence, Dict, Optional, Any - -if sys.version_info >= (3, 9): - from typing import Annotated -else: - from typing_extensions import Annotated -if sys.version_info >= (3, 8): - from functools import cached_property -else: - from backports.cached_property import cached_property +from typing import Collection, Iterator, Sequence, Optional, Any, Annotated +from functools import cached_property from contextlib import ContextDecorator from warnings import warn @@ -31,16 +22,16 @@ class Constituent(BaseModel, populate_by_name=True, frozen=True): id: Optional[int] = None name: str - u_neg: Annotated[List[float], Field(alias="uNeg")] = ( + u_neg: Annotated[list[float], Field(alias="uNeg")] = ( [] ) # [-neg_count, -neg_count+1, -neg_count+2, ..., -1] - u_pos: Annotated[List[float], Field(alias="uPos")] = ( + u_pos: Annotated[list[float], Field(alias="uPos")] = ( [] ) # [+1, +2, +3, ..., +pos_count] - pkas_neg: Annotated[List[float], Field(alias="pKaNeg")] = ( + pkas_neg: Annotated[list[float], Field(alias="pKaNeg")] = ( [] ) # [-neg_count, -neg_count+1, -neg_count+2, ..., -1] - pkas_pos: Annotated[List[float], Field(alias="pKaPos")] = ( + pkas_pos: Annotated[list[float], Field(alias="pKaPos")] = ( [] ) # [+1, +2, +3, ..., +pos_count] neg_count: Annotated[int, Field(alias="negCount", validate_default=True)] = None # type: ignore @@ -109,7 +100,7 @@ def _all_uppercase(cls, v: str, info: ValidationInfo) -> str: return v @field_validator("pkas_neg", "pkas_pos") - def _pka_lengths(cls, v: List[float], info: ValidationInfo) -> List[float]: + def _pka_lengths(cls, v: list[float], info: ValidationInfo) -> list[float]: assert isinstance(info.field_name, str) if len(v) != len(info.data[f"u_{info.field_name[5:]}"]): raise ValueError(f"len({info.field_name}) != len(u_{info.field_name[5:]})") @@ -134,16 +125,16 @@ def _pkas_not_increasing(self) -> "Constituent": return self -_StoredConstituents = TypeAdapter(Dict[str, List[Constituent]]) +_StoredConstituents = TypeAdapter(dict[str, list[Constituent]]) def _load_constituents( - data: bytes, context: Optional[Dict[str, str]] = None -) -> List[Constituent]: + data: bytes, context: Optional[dict[str, str]] = None +) -> list[Constituent]: return _StoredConstituents.validate_json(data, context=context)["constituents"] -def _dump_constituents(constituents: List[Constituent]) -> bytes: +def _dump_constituents(constituents: list[Constituent]) -> bytes: return _StoredConstituents.dump_json( {"constituents": constituents}, by_alias=True, indent=4 ) @@ -158,7 +149,7 @@ def __init__(self, user_constituents_file: Path) -> None: self._user_constituents_dirty = False @cached_property - def _default_constituents(self) -> Dict[str, Constituent]: + def _default_constituents(self) -> dict[str, Constituent]: data = pkgutil.get_data(__package__, "db1.json") if data is None: raise RuntimeError("failed to load default constituents") @@ -166,7 +157,7 @@ def _default_constituents(self) -> Dict[str, Constituent]: return {c.name: c for c in constituents} @cached_property - def _user_constituents(self) -> Dict[str, Constituent]: + def _user_constituents(self) -> dict[str, Constituent]: try: with self: user_data = self._user_constituents_file.read_bytes() diff --git a/electrolytes/__main__.py b/electrolytes/__main__.py index 2caba99..5f9f42a 100644 --- a/electrolytes/__main__.py +++ b/electrolytes/__main__.py @@ -1,10 +1,4 @@ -import sys -from typing import Tuple, List, Optional - -if sys.version_info >= (3, 9): - from typing import Annotated -else: - from typing_extensions import Annotated +from typing import Optional, Annotated import typer @@ -14,11 +8,11 @@ app = typer.Typer() -def complete_name(incomplete: str) -> List[str]: +def complete_name(incomplete: str) -> list[str]: return [name for name in database if name.startswith(incomplete.upper())] -def complete_name_user_defined(incomplete: str) -> List[str]: +def complete_name_user_defined(incomplete: str) -> list[str]: return [ name for name in database.user_defined() if name.startswith(incomplete.upper()) ] @@ -27,18 +21,18 @@ def complete_name_user_defined(incomplete: str) -> List[str]: @app.command() def add( name: Annotated[str, typer.Argument(autocompletion=complete_name_user_defined)], - p1: Annotated[Tuple[float, float], typer.Option("+1", help="Mobility (*1e-9) and pKa for +1", show_default=False)] = (None, None), # type: ignore - p2: Annotated[Tuple[float, float], typer.Option("+2", help="Mobility (*1e-9) and pKa for +2", show_default=False)] = (None, None), # type: ignore - p3: Annotated[Tuple[float, float], typer.Option("+3", help="Mobility (*1e-9) and pKa for +3", show_default=False)] = (None, None), # type: ignore - p4: Annotated[Tuple[float, float], typer.Option("+4", help="Mobility (*1e-9) and pKa for +4", show_default=False)] = (None, None), # type: ignore - p5: Annotated[Tuple[float, float], typer.Option("+5", help="Mobility (*1e-9) and pKa for +5", show_default=False)] = (None, None), # type: ignore - p6: Annotated[Tuple[float, float], typer.Option("+6", help="Mobility (*1e-9) and pKa for +6", show_default=False)] = (None, None), # type: ignore - m1: Annotated[Tuple[float, float], typer.Option("-1", help="Mobility (*1e-9) and pKa for -1", show_default=False)] = (None, None), # type: ignore - m2: Annotated[Tuple[float, float], typer.Option("-2", help="Mobility (*1e-9) and pKa for -2", show_default=False)] = (None, None), # type: ignore - m3: Annotated[Tuple[float, float], typer.Option("-3", help="Mobility (*1e-9) and pKa for -3", show_default=False)] = (None, None), # type: ignore - m4: Annotated[Tuple[float, float], typer.Option("-4", help="Mobility (*1e-9) and pKa for -4", show_default=False)] = (None, None), # type: ignore - m5: Annotated[Tuple[float, float], typer.Option("-5", help="Mobility (*1e-9) and pKa for -5", show_default=False)] = (None, None), # type: ignore - m6: Annotated[Tuple[float, float], typer.Option("-6", help="Mobility (*1e-9) and pKa for -6", show_default=False)] = (None, None), # type: ignore + p1: Annotated[tuple[float, float], typer.Option("+1", help="Mobility (*1e-9) and pKa for +1", show_default=False)] = (None, None), # type: ignore + p2: Annotated[tuple[float, float], typer.Option("+2", help="Mobility (*1e-9) and pKa for +2", show_default=False)] = (None, None), # type: ignore + p3: Annotated[tuple[float, float], typer.Option("+3", help="Mobility (*1e-9) and pKa for +3", show_default=False)] = (None, None), # type: ignore + p4: Annotated[tuple[float, float], typer.Option("+4", help="Mobility (*1e-9) and pKa for +4", show_default=False)] = (None, None), # type: ignore + p5: Annotated[tuple[float, float], typer.Option("+5", help="Mobility (*1e-9) and pKa for +5", show_default=False)] = (None, None), # type: ignore + p6: Annotated[tuple[float, float], typer.Option("+6", help="Mobility (*1e-9) and pKa for +6", show_default=False)] = (None, None), # type: ignore + m1: Annotated[tuple[float, float], typer.Option("-1", help="Mobility (*1e-9) and pKa for -1", show_default=False)] = (None, None), # type: ignore + m2: Annotated[tuple[float, float], typer.Option("-2", help="Mobility (*1e-9) and pKa for -2", show_default=False)] = (None, None), # type: ignore + m3: Annotated[tuple[float, float], typer.Option("-3", help="Mobility (*1e-9) and pKa for -3", show_default=False)] = (None, None), # type: ignore + m4: Annotated[tuple[float, float], typer.Option("-4", help="Mobility (*1e-9) and pKa for -4", show_default=False)] = (None, None), # type: ignore + m5: Annotated[tuple[float, float], typer.Option("-5", help="Mobility (*1e-9) and pKa for -5", show_default=False)] = (None, None), # type: ignore + m6: Annotated[tuple[float, float], typer.Option("-6", help="Mobility (*1e-9) and pKa for -6", show_default=False)] = (None, None), # type: ignore force: Annotated[ bool, typer.Option( @@ -55,7 +49,7 @@ def add( typer.echo("Error: at least one of the +1 or -1 options is required", err=True) raise typer.Exit(code=1) - neg: List[Tuple[float, float]] = [] + neg: list[tuple[float, float]] = [] any_omitted = False for i, m in enumerate([m1, m2, m3, m4, m5, m6]): if m[0] is None: @@ -67,7 +61,7 @@ def add( else: neg.insert(0, m) - pos: List[Tuple[float, float]] = [] + pos: list[tuple[float, float]] = [] any_omitted = False for i, p in enumerate([p1, p2, p3, p4, p5, p6]): if p[0] is None: @@ -104,7 +98,7 @@ def add( @app.command() def info( names: Annotated[ - Optional[List[str]], + Optional[list[str]], typer.Argument(help="Component names", autocompletion=complete_name), ] = None ) -> None: @@ -182,7 +176,7 @@ def ls( @app.command() def rm( names: Annotated[ - List[str], typer.Argument(autocompletion=complete_name_user_defined) + list[str], typer.Argument(autocompletion=complete_name_user_defined) ], force: Annotated[ Optional[bool], typer.Option("-f", help="Ignore non-existent components") diff --git a/pyproject.toml b/pyproject.toml index e2ff0bf..d80ae21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "electrolytes" description = "Electrolyte database manager" readme = "README.md" -requires-python = ">=3.7" +requires-python = ">=3.9" authors = [{name = "Gabriel S. Gerlero", email = "ggerlero@cimec.unl.edu.ar"}] classifiers = [ "Development Status :: 4 - Beta", @@ -17,8 +17,6 @@ classifiers = [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -34,8 +32,6 @@ dependencies = [ "typer>=0.9.0,<0.10", "pydantic>=2.0.3,<3", "filelock==3.*", - "typing-extensions>=3.7.4.3,<5; python_version<'3.9'", - "backports.cached_property>=1.0.2,<2; python_version<'3.8'", ] dynamic = ["version"]