Skip to content

Commit

Permalink
Merge pull request #306 from ASFHyP3/add-mypy
Browse files Browse the repository at this point in the history
Add `mypy` Action for Type Checking and Address Issues
  • Loading branch information
AndrewPlayer3 authored Jan 8, 2025
2 parents e310f39 + 92857fa commit 7c0839f
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 13 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Static analysis

permissions:
contents: read

on: push

jobs:
Expand All @@ -10,3 +13,7 @@ jobs:
call-ruff-workflow:
# Docs: https://github.com/ASFHyP3/actions
uses: ASFHyP3/actions/.github/workflows/[email protected]

call-mypy-workflow:
# Docs: https://github.com/ASFHyP3/actions
uses: ASFHyP3/actions/.github/workflows/[email protected]
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [PEP 440](https://www.python.org/dev/peps/pep-0440/)
and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [7.0.3]

### Changed
* The [`static-analysis`](.github/workflows/static-analysis.yml) Github Actions workflow now uses `mypy` for type checking.

## [7.0.2]

### Changed
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
# For packaging, and testing
- python-build
- ruff
- mypy
- jupyter
- setuptools>=61
- setuptools_scm>=6.2
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,11 @@ convention = "google"
[tool.ruff.lint.isort]
case-sensitive = true
lines-after-imports = 2

[tool.mypy]
python_version = "3.10"
warn_unused_ignores = true
warn_redundant_casts = true
warn_unreachable = true
strict_equality = true
check_untyped_defs = true
6 changes: 3 additions & 3 deletions src/hyp3_sdk/hyp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def _watch_batch(self, batch: Batch, timeout: int = 10800, interval: int | float
bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{postfix[0]}]'
with tqdm(total=len(batch), bar_format=bar_format, postfix=[f'timeout in {timeout} s']) as progress_bar:
for ii in range(iterations_until_timeout):
batch = self.refresh(batch)
batch = self.refresh(batch) # type: ignore [assignment]

counts = batch._count_statuses()
complete = counts['SUCCEEDED'] + counts['FAILED']
Expand All @@ -155,7 +155,7 @@ def _watch_job(self, job: Job, timeout: int = 10800, interval: int | float = 60)
bar_format = '{n_fmt}/{total_fmt} [{postfix[0]}]'
with tqdm(total=1, bar_format=bar_format, postfix=[f'timeout in {timeout} s']) as progress_bar:
for ii in range(iterations_until_timeout):
job = self.refresh(job)
job = self.refresh(job) # type: ignore [assignment]
progress_bar.postfix = [f'timeout in {timeout - ii * interval}s']
progress_bar.update(int(job.complete()))

Expand All @@ -181,7 +181,7 @@ def _refresh_batch(self, batch: Batch):
jobs = []
for job in batch.jobs:
jobs.append(self.refresh(job))
return Batch(jobs)
return Batch(jobs) # type: ignore [arg-type]

@refresh.register
def _refresh_job(self, job: Job):
Expand Down
11 changes: 8 additions & 3 deletions src/hyp3_sdk/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def to_dict(self, for_resubmit: bool = False):
if for_resubmit:
keys_to_process = Job._attributes_for_resubmit
else:
keys_to_process = vars(self).keys()
keys_to_process = set(vars(self).keys())

for key in keys_to_process:
value = self.__getattribute__(key)
Expand Down Expand Up @@ -127,6 +127,7 @@ def download_files(self, location: Path | str = '.', create: bool = True) -> lis
if not self.succeeded():
raise HyP3SDKError(f'Only succeeded jobs can be downloaded; job is {self.status_code}.')
if self.expired():
assert self.expiration_time is not None
raise HyP3SDKError(
f'Expired jobs cannot be downloaded; '
f'job expired {self.expiration_time.isoformat(timespec="seconds")}.'
Expand All @@ -137,6 +138,8 @@ def download_files(self, location: Path | str = '.', create: bool = True) -> lis
elif not location.is_dir():
raise NotADirectoryError(str(location))

assert self.files is not None

downloaded_files = []
for file in self.files:
download_url = file['url']
Expand Down Expand Up @@ -180,14 +183,16 @@ def __len__(self):
def __contains__(self, job: Job):
return job in self.jobs

def __eq__(self, other: 'Batch'):
def __eq__(self, other: object) -> bool:
if not isinstance(other, Batch):
raise TypeError('`__eq__` can only compare a Batch object with another Batch object.')
return self.jobs == other.jobs

def __delitem__(self, job: int):
self.jobs.pop(job)
return self

def __getitem__(self, index: int):
def __getitem__(self, index: int | slice):
if isinstance(index, slice):
return Batch(self.jobs[index])
return self.jobs[index]
Expand Down
9 changes: 6 additions & 3 deletions src/hyp3_sdk/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ def chunk(itr: Sequence[Any], n: int = 200) -> Generator[Sequence[Any], None, No
itr: A sequence object to chunk
n: Size of the chunks to return
"""
if not isinstance(n, int) or n < 1:
raise ValueError(f'n must be a positive integer: {n}')
error_message = f'n must be a positive integer: {n}'
if not isinstance(n, int):
raise TypeError(error_message)
if n < 1:
raise ValueError(error_message)

for i in range(0, len(itr), n):
yield itr[i : i + n]
Expand All @@ -68,7 +71,7 @@ def get_tqdm_progress_bar():
return tqdm


def get_authenticated_session(username: str, password: str) -> requests.Session:
def get_authenticated_session(username: str | None, password: str | None) -> requests.Session:
"""Log into HyP3 using credentials for `urs.earthdata.nasa.gov` from either the provided
credentials or a `.netrc` file.
Expand Down
4 changes: 2 additions & 2 deletions tests/test_hyp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def test_find_jobs_paging(get_mock_hyp3, get_mock_job):

batch = api.find_jobs()
assert len(batch) == 3
assert 'next' not in responses.calls[0].request.params
assert 'next' in responses.calls[1].request.params
assert 'next' not in responses.calls[0].request.params # type: ignore [attr-defined]
assert 'next' in responses.calls[1].request.params # type: ignore [attr-defined]


@responses.activate
Expand Down
4 changes: 2 additions & 2 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ def test_chunk():
with pytest.raises(ValueError):
chunks = list(util.chunk(items, n=-2))

with pytest.raises(ValueError):
chunks = list(util.chunk(items, n=10.0))
with pytest.raises(TypeError):
chunks = list(util.chunk(items, n=10.0)) # type: ignore [arg-type]


def test_extract_zipped_product(product_zip):
Expand Down

0 comments on commit 7c0839f

Please sign in to comment.