Skip to content

Commit 52b0f84

Browse files
authored
Merge pull request #127 from csiro-coasts/pep-585-generics
Use Python 3.9 typing features
2 parents 65c9f8f + 3e197e1 commit 52b0f84

40 files changed

+228
-265
lines changed

docs/developing/grass.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# > imports
22
import enum
3+
from collections.abc import Hashable, Sequence
34
from functools import cached_property
4-
from typing import Dict, Hashable, Optional, Sequence, Tuple
5+
from typing import Optional
56

67
import numpy
78
import xarray
@@ -19,7 +20,7 @@ class GrassGridKind(enum.Enum):
1920
fence = 'fence'
2021

2122

22-
GrassIndex = Tuple[GrassGridKind, Sequence[int]]
23+
GrassIndex = tuple[GrassGridKind, Sequence[int]]
2324

2425

2526
class Grass(DimensionConvention[GrassGridKind, GrassIndex]):
@@ -37,14 +38,14 @@ def check_dataset(cls, dataset: xarray.Dataset) -> Optional[int]:
3738
return Specificity.HIGH
3839
return None
3940

40-
def unpack_index(self, index: GrassIndex) -> Tuple[GrassGridKind, Sequence[int]]:
41+
def unpack_index(self, index: GrassIndex) -> tuple[GrassGridKind, Sequence[int]]:
4142
return index[0], list(index[1])
4243

4344
def pack_index(self, grid_kind: GrassGridKind, indices: Sequence[int]) -> GrassIndex:
4445
return (grid_kind, list(indices))
4546

4647
@cached_property
47-
def grid_dimensions(self) -> Dict[GrassGridKind, Sequence[Hashable]]:
48+
def grid_dimensions(self) -> dict[GrassGridKind, Sequence[Hashable]]:
4849
return {
4950
GrassGridKind.field: ['warp', 'weft'],
5051
GrassGridKind.fence: ['post'],

docs/releases/development.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Next release (in development)
1111
* Drop dependency on importlib_metadata.
1212
This was only required to support Python 3.8, which was dropped in a previous release
1313
(:issue:`122`, :pr:`125`).
14-
* Fix an error with `ShocSimple.get_all_depth_names()`
14+
* Fix an error with ``ShocSimple.get_all_depth_names()``
1515
when the dataset had no depth coordinates
1616
(:issue:`123`, :pr:`126`).
17+
* Use `PEP 585 generic type annotations <https://peps.python.org/pep-0585/>`_
18+
and stop using `PEP 563 postponed annotation evaluation <https://peps.python.org/pep-0563/>`_
19+
(:issue:`109`, :pr:`127`).

docs/roles.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
2-
from typing import Callable, Iterable, List, Tuple, cast
2+
from collections.abc import Iterable
3+
from typing import Callable, cast
34

45
import yaml
56
from docutils import nodes, utils
@@ -30,7 +31,7 @@ def role_fn(
3031
inliner: Inliner,
3132
options: dict = {},
3233
content: list = [],
33-
) -> Tuple[list, list]:
34+
) -> tuple[list, list]:
3435
match = GITHUB_FULL_REF.match(utils.unescape(text))
3536
if match is not None:
3637
repo = match.group('repo')
@@ -83,15 +84,15 @@ def load_citation_file(self) -> dict:
8384
with open(citation_file, 'r') as f:
8485
return cast(dict, yaml.load(f, yaml.Loader))
8586

86-
def run(self) -> List[nodes.Node]:
87+
def run(self) -> list[nodes.Node]:
8788
if self.options['format'] == 'apa':
8889
return self.run_apa()
8990
elif self.options['format'] == 'biblatex':
9091
return self.run_biblatex()
9192
else:
9293
raise ValueError("Unknown format")
9394

94-
def run_apa(self) -> List[nodes.Node]:
95+
def run_apa(self) -> list[nodes.Node]:
9596
citation = self.load_citation_file()
9697
names = self.comma_ampersand_join(map(self.apa_name, citation['authors']))
9798
year = citation['date-released'].year
@@ -118,7 +119,7 @@ def comma_ampersand_join(self, items: Iterable[str]) -> str:
118119
return items[0]
119120
return '{}, & {}'.format(', '.join(items[:-1]), items[-1])
120121

121-
def run_biblatex(self) -> List[nodes.Node]:
122+
def run_biblatex(self) -> list[nodes.Node]:
122123
citation = self.load_citation_file()
123124

124125
year = citation['date-released'].year

scripts/release.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import shlex
77
import subprocess
88
import sys
9-
from typing import List, Optional
9+
from typing import Optional
1010

1111
PROJECT = pathlib.Path(__file__).parent.parent
1212

@@ -29,7 +29,7 @@
2929

3030

3131
def main(
32-
args: Optional[List[str]] = None,
32+
args: Optional[list[str]] = None,
3333
) -> None:
3434
parser = argparse.ArgumentParser()
3535
add_options(parser)

src/emsarray/accessors.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import annotations
2-
31
import logging
42

53
import xarray

src/emsarray/cli/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import argparse
77
import importlib
88
import pkgutil
9-
from typing import Iterable, Type
9+
from collections.abc import Iterable
1010

1111
import emsarray
1212

@@ -40,7 +40,7 @@ def main(options: argparse.Namespace) -> None:
4040
options.func(options)
4141

4242

43-
def _find_all_commands() -> Iterable[Type[BaseCommand]]:
43+
def _find_all_commands() -> Iterable[type[BaseCommand]]:
4444
for moduleinfo in pkgutil.iter_modules(commands.__path__):
4545
if moduleinfo.name.startswith('_'):
4646
continue

src/emsarray/cli/commands/clip.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import logging
44
import tempfile
55
from pathlib import Path
6-
from typing import ContextManager
76

87
import emsarray
98
from emsarray.cli import BaseCommand
@@ -39,7 +38,7 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
3938
))
4039

4140
def handle(self, options: argparse.Namespace) -> None:
42-
work_context: ContextManager[Pathish]
41+
work_context: contextlib.AbstractContextManager[Pathish]
4342
if options.work_dir:
4443
work_context = contextlib.nullcontext(options.work_dir)
4544
else:

src/emsarray/cli/commands/export_geometry.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import argparse
22
import logging
33
from pathlib import Path
4-
from typing import Callable, Dict
4+
from typing import Callable
55

66
import xarray
77

@@ -13,7 +13,7 @@
1313
logger = logging.getLogger(__name__)
1414

1515
Writer = Callable[[xarray.Dataset, Pathish], None]
16-
format_writers: Dict[str, Writer] = {
16+
format_writers: dict[str, Writer] = {
1717
'geojson': geometry.write_geojson,
1818
'shapefile': geometry.write_shapefile,
1919
'wkt': geometry.write_wkt,

src/emsarray/cli/commands/plot.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import functools
33
import logging
44
from pathlib import Path
5-
from typing import Any, Callable, Dict, List, Optional, Text, TypeVar
5+
from typing import Any, Callable, Optional, TypeVar
66

77
import emsarray
88
from emsarray.cli import BaseCommand, CommandException
@@ -12,7 +12,7 @@
1212
logger = logging.getLogger(__name__)
1313

1414

15-
def key_value(arg: str, value_type: Callable = str) -> Dict[str, T]:
15+
def key_value(arg: str, value_type: Callable = str) -> dict[str, T]:
1616
try:
1717
name, value = arg.split("=", 2)
1818
except ValueError:
@@ -24,11 +24,11 @@ def key_value(arg: str, value_type: Callable = str) -> Dict[str, T]:
2424
class UpdateDict(argparse.Action):
2525
def __init__(
2626
self,
27-
option_strings: List[str],
27+
option_strings: list[str],
2828
dest: str,
2929
*,
3030
value_type: Callable = str,
31-
default: Optional[Dict[str, Any]] = None,
31+
default: Optional[dict[str, Any]] = None,
3232
**kwargs: Any,
3333
):
3434
if default is None:
@@ -42,7 +42,7 @@ def __call__(
4242
parser: argparse.ArgumentParser,
4343
namespace: argparse.Namespace,
4444
values: Any,
45-
option_string: Optional[Text] = None,
45+
option_string: Optional[str] = None,
4646
) -> None:
4747
super().__call__
4848
holder = getattr(namespace, self.dest, {})

src/emsarray/cli/utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
import re
1010
import sys
1111
import textwrap
12+
from collections.abc import Iterator
1213
from functools import wraps
1314
from pathlib import Path
14-
from typing import Callable, Iterator, List, Optional, Protocol
15+
from typing import Callable, Optional, Protocol
1516

1617
from shapely.geometry import box, shape
1718
from shapely.geometry.base import BaseGeometry
@@ -29,7 +30,7 @@
2930
class MainCallable(Protocol):
3031
def __call__(
3132
self,
32-
argv: Optional[List[str]] = None,
33+
argv: Optional[list[str]] = None,
3334
handle_errors: bool = True,
3435
) -> None:
3536
...
@@ -90,7 +91,7 @@ def main(options: argparse.Namespace) -> None:
9091
.. code-block:: python
9192
9293
@nice_console_errors()
93-
def main(argv: Optional[List[str]]) -> None:
94+
def main(argv: Optional[list[str]]) -> None:
9495
parser = argparse.ArgumentParser()
9596
add_verbosity_group(parser)
9697
command_line_flags(parser)
@@ -111,7 +112,7 @@ def decorator(
111112
) -> MainCallable:
112113
@wraps(fn)
113114
def wrapper(
114-
argv: Optional[List[str]] = None,
115+
argv: Optional[list[str]] = None,
115116
handle_errors: bool = True,
116117
) -> None:
117118
parser = argparse.ArgumentParser(

0 commit comments

Comments
 (0)