Skip to content

Commit 679fe28

Browse files
committed
Python >= 3.7 type annotation
1 parent d090734 commit 679fe28

File tree

15 files changed

+147
-138
lines changed

15 files changed

+147
-138
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ long_description = file: README.md
2323
long_description_content_type = text/markdown
2424

2525
[options]
26-
python_requires = >= 3.6.2
26+
python_requires = >= 3.7
2727
include_package_data = True
2828
zip_safe = False
2929
packages = find:

src/georinex/base.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
from __future__ import annotations
2+
import typing as T
13
from pathlib import Path
24
import xarray
3-
from typing import Union, Tuple, Dict, Sequence
4-
from typing.io import TextIO
55
from datetime import datetime, timedelta
66
import logging
77

@@ -18,18 +18,18 @@
1818

1919

2020
def load(
21-
rinexfn: Union[TextIO, str, Path],
21+
rinexfn: T.TextIO | str | Path,
2222
out: Path = None,
23-
use: Sequence[str] = None,
24-
tlim: Tuple[datetime, datetime] = None,
23+
use: list[str] = None,
24+
tlim: tuple[datetime, datetime] = None,
2525
useindicators: bool = False,
26-
meas: Sequence[str] = None,
26+
meas: list[str] = None,
2727
verbose: bool = False,
2828
*,
2929
overwrite: bool = False,
3030
fast: bool = True,
31-
interval: Union[float, int, timedelta] = None,
32-
) -> Union[xarray.Dataset, Dict[str, xarray.Dataset]]:
31+
interval: float | int | timedelta = None,
32+
) -> xarray.Dataset | dict[str, xarray.Dataset]:
3333
"""
3434
Reads OBS, NAV in RINEX 2.x and 3.x
3535
@@ -67,9 +67,7 @@ def load(
6767
)
6868
return None
6969

70-
if info["rinextype"] == "sp3":
71-
return load_sp3(rinexfn, outfn)
72-
elif info["rinextype"] == "nav":
70+
if info["rinextype"] == "nav":
7371
return rinexnav(rinexfn, outfn, use=use, tlim=tlim, overwrite=overwrite)
7472
elif info["rinextype"] == "obs":
7573
return rinexobs(
@@ -84,6 +82,11 @@ def load(
8482
fast=fast,
8583
interval=interval,
8684
)
85+
86+
assert isinstance(rinexfn, Path)
87+
88+
if info["rinextype"] == "sp3":
89+
return load_sp3(rinexfn, outfn)
8790
elif rinexfn.suffix == ".nc":
8891
# outfn not used here, because we already have the converted file!
8992
try:
@@ -112,10 +115,10 @@ def batch_convert(
112115
path: Path,
113116
glob: str,
114117
out: Path,
115-
use: Sequence[str] = None,
116-
tlim: Tuple[datetime, datetime] = None,
118+
use: list[str] = None,
119+
tlim: tuple[datetime, datetime] = None,
117120
useindicators: bool = False,
118-
meas: Sequence[str] = None,
121+
meas: list[str] = None,
119122
verbose: bool = False,
120123
*,
121124
fast: bool = True,
@@ -142,15 +145,15 @@ def batch_convert(
142145

143146

144147
def rinexnav(
145-
fn: Union[TextIO, str, Path],
148+
fn: T.TextIO | str | Path,
146149
outfn: Path = None,
147-
use: Sequence[str] = None,
150+
use: list[str] = None,
148151
group: str = "NAV",
149-
tlim: Tuple[datetime, datetime] = None,
152+
tlim: tuple[datetime, datetime] = None,
150153
*,
151154
overwrite: bool = False,
152155
) -> xarray.Dataset:
153-
""" Read RINEX 2 or 3 NAV files"""
156+
"""Read RINEX 2 or 3 NAV files"""
154157

155158
if isinstance(fn, (str, Path)):
156159
fn = Path(fn).expanduser()
@@ -186,18 +189,18 @@ def rinexnav(
186189

187190

188191
def rinexobs(
189-
fn: Union[TextIO, str, Path],
192+
fn: T.TextIO | Path,
190193
outfn: Path = None,
191-
use: Sequence[str] = None,
194+
use: list[str] = None,
192195
group: str = "OBS",
193-
tlim: Tuple[datetime, datetime] = None,
196+
tlim: tuple[datetime, datetime] = None,
194197
useindicators: bool = False,
195-
meas: Sequence[str] = None,
198+
meas: list[str] = None,
196199
verbose: bool = False,
197200
*,
198201
overwrite: bool = False,
199202
fast: bool = True,
200-
interval: Union[float, int, timedelta] = None,
203+
interval: float | int | timedelta = None,
201204
) -> xarray.Dataset:
202205
"""
203206
Read RINEX 2.x and 3.x OBS files in ASCII or GZIP (or Hatanaka)

src/georinex/common.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
from __future__ import annotations
2+
import typing as T
13
from pathlib import Path
24
from datetime import timedelta
3-
from typing import Dict, Union, Any
45
import numpy as np
56
import logging
67

@@ -26,20 +27,23 @@ def rinex_string_to_float(s: str) -> float:
2627
return float(s.replace("D", "E"))
2728

2829

29-
def check_ram(memneed: int, fn: Path):
30+
def check_ram(memneed: int, fn: T.TextIO | Path):
3031
if psutil is None:
3132
return
3233

3334
mem = psutil.virtual_memory()
3435

3536
if memneed > 0.5 * mem.available: # because of array copy Numpy => Xarray
36-
raise RuntimeError(
37-
f"{fn} needs {memneed/1e9} GBytes RAM, but only {mem.available/1e9} Gbytes available \n"
37+
errmsg = (
38+
f"needs {memneed/1e9} GBytes RAM, but only {mem.available/1e9} Gbytes available \n"
3839
"try fast=False to reduce RAM usage, raise a GitHub Issue to let us help"
3940
)
41+
if isinstance(fn, Path):
42+
errmsg = f"{fn}" + errmsg
43+
raise RuntimeError(errmsg)
4044

4145

42-
def determine_time_system(header: Dict[str, Any]) -> str:
46+
def determine_time_system(header: dict[str, T.Any]) -> str:
4347
"""Determine which time system is used in an observation file."""
4448
# Current implementation is quite inconsistent in terms what is put into
4549
# header.
@@ -70,7 +74,7 @@ def determine_time_system(header: Dict[str, Any]) -> str:
7074
return ts
7175

7276

73-
def check_time_interval(interval: Union[float, int, timedelta]) -> timedelta:
77+
def check_time_interval(interval: float | int | timedelta) -> timedelta:
7478
if isinstance(interval, (float, int)):
7579
if interval < 0:
7680
raise ValueError("time interval must be non-negative")

src/georinex/geo.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1+
from __future__ import annotations
12
import pandas
2-
from typing.io import TextIO
3-
from typing import Sequence, Union
43
import io
54
import xarray
65
from pathlib import Path
76

87
from .utils import rinexheader
98

109

11-
def get_locations(files: Union[TextIO, Sequence[Path]]) -> pandas.DataFrame:
10+
def get_locations(files: list[Path]) -> pandas.DataFrame:
1211
"""
1312
retrieve locations of GNSS receivers
1413
@@ -19,21 +18,23 @@ def get_locations(files: Union[TextIO, Sequence[Path]]) -> pandas.DataFrame:
1918

2019
if isinstance(files[0], io.StringIO):
2120
locs = pandas.DataFrame(index=["0"], columns=["lat", "lon", "interval"])
21+
elif isinstance(files[0], Path):
22+
locs = pandas.DataFrame(index=[file.name for file in files], columns=["lat", "lon", "interval"])
2223
else:
23-
locs = pandas.DataFrame(index=[f.name for f in files], columns=["lat", "lon", "interval"])
24+
raise TypeError("Expecting pathlib.Path")
2425

25-
for f in files:
26-
if isinstance(f, Path) and f.suffix == ".nc":
27-
dat = xarray.open_dataset(f, group="OBS")
26+
for file in files:
27+
if isinstance(file, Path) and file.suffix == ".nc":
28+
dat = xarray.open_dataset(file, group="OBS")
2829
hdr = dat.attrs
2930
else:
3031
try:
31-
hdr = rinexheader(f)
32+
hdr = rinexheader(file)
3233
except ValueError:
3334
continue
3435

35-
if isinstance(f, Path):
36-
key = f.name
36+
if isinstance(file, Path):
37+
key = file.name
3738
else:
3839
key = "0"
3940

src/georinex/hatanaka.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
NOTE: This is a candidate for importlib.resources in Python >= 3.7
55
"""
66

7+
from __future__ import annotations
8+
import typing as T
79
import subprocess
810
import shutil
911
from pathlib import Path
10-
from typing.io import TextIO
1112

1213
from .build import build
1314

@@ -45,7 +46,7 @@ def crxexe(path: Path = Path(__file__).parent / "rnxcmp") -> str:
4546
raise RuntimeError("Hatanaka converter is broken.")
4647

4748

48-
def opencrx(f: TextIO) -> str:
49+
def opencrx(f: T.TextIO) -> str:
4950
"""
5051
Conversion to string is necessary because of a quirk where gzip.open() even with 'rt' doesn't decompress until read.
5152

src/georinex/keplerian.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
GPS Keplerian elements => ECEF
33
Michael Hirsch, Ph.D.
44
"""
5+
6+
from __future__ import annotations
57
from datetime import datetime, timedelta
68
import xarray
79
import numpy as np
8-
from typing import Tuple
910

1011

11-
def keplerian2ecef(sv: xarray.DataArray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
12+
def keplerian2ecef(sv: xarray.DataArray) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
1213
"""
1314
based on:
1415
https://ascelibrary.org/doi/pdf/10.1061/9780784411506.ap03

src/georinex/nav2.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
#!/usr/bin/env python
1+
from __future__ import annotations
2+
import typing as T
23
from pathlib import Path
34
from datetime import datetime
4-
from typing import Dict, Union, Any, Sequence
5-
from typing.io import TextIO
65
import xarray
76
import numpy as np
87
import logging
@@ -15,7 +14,7 @@
1514
Nl = {"G": 7, "R": 3, "E": 7} # number of additional SV lines
1615

1716

18-
def rinexnav2(fn: Union[TextIO, str, Path], tlim: Sequence[datetime] = None) -> xarray.Dataset:
17+
def rinexnav2(fn: T.TextIO | Path, tlim: tuple[datetime, datetime] = None) -> xarray.Dataset:
1918
"""
2019
Reads RINEX 2.x NAV files
2120
Michael Hirsch, Ph.D.
@@ -214,7 +213,7 @@ def rinexnav2(fn: Union[TextIO, str, Path], tlim: Sequence[datetime] = None) ->
214213
return nav
215214

216215

217-
def navheader2(f: TextIO) -> Dict[str, Any]:
216+
def navheader2(f: T.TextIO) -> dict[str, T.Any]:
218217
"""
219218
For RINEX NAV version 2 only. End users should use rinexheader()
220219
"""
@@ -254,12 +253,12 @@ def _timenav(ln: str) -> datetime:
254253
)
255254

256255

257-
def _skip(f: TextIO, Nl: int):
256+
def _skip(f: T.TextIO, Nl: int):
258257
for _, _ in zip(range(Nl), f):
259258
pass
260259

261260

262-
def navtime2(fn: Union[TextIO, Path]) -> np.ndarray:
261+
def navtime2(fn: T.TextIO | Path) -> np.ndarray:
263262
"""
264263
read all times in RINEX 2 NAV file
265264
"""

src/georinex/nav3.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
#!/usr/bin/env python
1+
from __future__ import annotations
2+
import typing as T
23
from pathlib import Path
34
import xarray
45
import logging
56
import numpy as np
67
import math
78
from datetime import datetime
8-
from typing import Dict, Union, List, Any, Sequence
9-
from typing.io import TextIO
9+
1010

1111
#
1212
from .rio import opener, rinexinfo
@@ -19,7 +19,7 @@
1919

2020

2121
def rinexnav3(
22-
fn: Union[TextIO, str, Path], use: Sequence[str] = None, tlim: Sequence[datetime] = None
22+
fn: T.TextIO | Path, use: list[str] = None, tlim: tuple[datetime, datetime] = None
2323
) -> xarray.Dataset:
2424
"""
2525
Reads RINEX 3.x NAV files
@@ -34,9 +34,9 @@ def rinexnav3(
3434

3535
svs = []
3636
raws = []
37-
svtypes: List[str] = []
38-
fields: Dict[str, List[str]] = {}
39-
times: List[datetime] = []
37+
svtypes: list[str] = []
38+
fields: dict[str, list[str]] = {}
39+
times: list[datetime] = []
4040

4141
with opener(fn) as f:
4242
header = navheader3(f)
@@ -166,7 +166,7 @@ def rinexnav3(
166166
return nav
167167

168168

169-
def _skip(f: TextIO, Nl: int):
169+
def _skip(f: T.TextIO, Nl: int):
170170
for _, _ in zip(range(Nl), f):
171171
pass
172172

@@ -183,7 +183,7 @@ def _time(ln: str) -> datetime:
183183
)
184184

185185

186-
def _sparefields(cf: List[str], sys: str, raw: str) -> List[str]:
186+
def _sparefields(cf: list[str], sys: str, raw: str) -> list[str]:
187187
"""
188188
check for optional spare fields, or GPS "fit interval" field
189189
@@ -228,7 +228,7 @@ def _sparefields(cf: List[str], sys: str, raw: str) -> List[str]:
228228
return cf
229229

230230

231-
def _newnav(ln: str, sv: str) -> List[str]:
231+
def _newnav(ln: str, sv: str) -> list[str]:
232232

233233
if sv.startswith("G"):
234234
"""
@@ -461,7 +461,7 @@ def _newnav(ln: str, sv: str) -> List[str]:
461461
return fields
462462

463463

464-
def navheader3(f: TextIO) -> Dict[str, Any]:
464+
def navheader3(f: T.TextIO) -> dict[str, T.Any]:
465465

466466
if isinstance(f, (str, Path)):
467467
with opener(f, header=True) as h:
@@ -491,7 +491,7 @@ def navheader3(f: TextIO) -> Dict[str, Any]:
491491
return hdr
492492

493493

494-
def navtime3(fn: Union[TextIO, Path]) -> np.ndarray:
494+
def navtime3(fn: T.TextIO | Path) -> np.ndarray:
495495
"""
496496
return all times in RINEX file
497497
"""

0 commit comments

Comments
 (0)