Skip to content

Commit 129229d

Browse files
thodson-usgsclaude
andcommitted
Address Copilot review on PR #229
1. TypeError messages now use a fixed example ("USGS-01646500") instead of interpolating the user's value into the suggestion template. The offending value is still surfaced via "(got {value!r})" so the user can see what they actually passed — but mappings, large objects, etc. no longer produce ugly suggestion strings like "USGS-{'k': 'v'}". 2. _MONITORING_LOCATION_ID_RE switched from anchored `^.+-.+$` matched with `re.match` to un-anchored `.+-.+` matched with `re.fullmatch`. Same effective behavior, but `fullmatch` makes the intent explicit and removes the redundant anchor characters. 3. Widened the type annotations on all 10 public waterdata functions that accept `monitoring_location_id` from `str | list[str] | None` to `str | Iterable[str] | None`, matching the runtime contract that accepts tuples, pandas.Series, pandas.Index, numpy.ndarray, etc. Added `from collections.abc import Iterable` to api.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 38e0483 commit 129229d

2 files changed

Lines changed: 18 additions & 16 deletions

File tree

dataretrieval/waterdata/api.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import json
1010
import logging
11+
from collections.abc import Iterable
1112
from io import StringIO
1213
from typing import get_args
1314

@@ -38,7 +39,7 @@
3839

3940

4041
def get_daily(
41-
monitoring_location_id: str | list[str] | None = None,
42+
monitoring_location_id: str | Iterable[str] | None = None,
4243
parameter_code: str | list[str] | None = None,
4344
statistic_id: str | list[str] | None = None,
4445
properties: list[str] | None = None,
@@ -225,7 +226,7 @@ def get_daily(
225226

226227

227228
def get_continuous(
228-
monitoring_location_id: str | list[str] | None = None,
229+
monitoring_location_id: str | Iterable[str] | None = None,
229230
parameter_code: str | list[str] | None = None,
230231
statistic_id: str | list[str] | None = None,
231232
properties: list[str] | None = None,
@@ -414,7 +415,7 @@ def get_continuous(
414415

415416

416417
def get_monitoring_locations(
417-
monitoring_location_id: list[str] | None = None,
418+
monitoring_location_id: str | Iterable[str] | None = None,
418419
agency_code: list[str] | None = None,
419420
agency_name: list[str] | None = None,
420421
monitoring_location_number: list[str] | None = None,
@@ -713,7 +714,7 @@ def get_monitoring_locations(
713714

714715

715716
def get_time_series_metadata(
716-
monitoring_location_id: str | list[str] | None = None,
717+
monitoring_location_id: str | Iterable[str] | None = None,
717718
parameter_code: str | list[str] | None = None,
718719
parameter_name: str | list[str] | None = None,
719720
properties: str | list[str] | None = None,
@@ -937,7 +938,7 @@ def get_time_series_metadata(
937938

938939

939940
def get_latest_continuous(
940-
monitoring_location_id: str | list[str] | None = None,
941+
monitoring_location_id: str | Iterable[str] | None = None,
941942
parameter_code: str | list[str] | None = None,
942943
statistic_id: str | list[str] | None = None,
943944
properties: str | list[str] | None = None,
@@ -1117,7 +1118,7 @@ def get_latest_continuous(
11171118

11181119

11191120
def get_latest_daily(
1120-
monitoring_location_id: str | list[str] | None = None,
1121+
monitoring_location_id: str | Iterable[str] | None = None,
11211122
parameter_code: str | list[str] | None = None,
11221123
statistic_id: str | list[str] | None = None,
11231124
properties: str | list[str] | None = None,
@@ -1299,7 +1300,7 @@ def get_latest_daily(
12991300

13001301

13011302
def get_field_measurements(
1302-
monitoring_location_id: str | list[str] | None = None,
1303+
monitoring_location_id: str | Iterable[str] | None = None,
13031304
parameter_code: str | list[str] | None = None,
13041305
observing_procedure_code: str | list[str] | None = None,
13051306
properties: list[str] | None = None,
@@ -1816,7 +1817,7 @@ def get_stats_por(
18161817
county_code: str | list[str] | None = None,
18171818
start_date: str | None = None,
18181819
end_date: str | None = None,
1819-
monitoring_location_id: str | list[str] | None = None,
1820+
monitoring_location_id: str | Iterable[str] | None = None,
18201821
page_size: int = 1000,
18211822
parent_time_series_id: str | list[str] | None = None,
18221823
site_type_code: str | list[str] | None = None,
@@ -1941,7 +1942,7 @@ def get_stats_date_range(
19411942
county_code: str | list[str] | None = None,
19421943
start_date: str | None = None,
19431944
end_date: str | None = None,
1944-
monitoring_location_id: str | list[str] | None = None,
1945+
monitoring_location_id: str | Iterable[str] | None = None,
19451946
page_size: int = 1000,
19461947
parent_time_series_id: str | list[str] | None = None,
19471948
site_type_code: str | list[str] | None = None,
@@ -2066,7 +2067,7 @@ def get_stats_date_range(
20662067

20672068

20682069
def get_channel(
2069-
monitoring_location_id: str | list[str] | None = None,
2070+
monitoring_location_id: str | Iterable[str] | None = None,
20702071
field_visit_id: str | list[str] | None = None,
20712072
measurement_number: str | list[str] | None = None,
20722073
time: str | list[str] | None = None,

dataretrieval/waterdata/utils.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ def _check_profiles(
11531153
)
11541154

11551155

1156-
_MONITORING_LOCATION_ID_RE = re.compile(r"^.+-.+$")
1156+
_MONITORING_LOCATION_ID_RE = re.compile(r".+-.+")
11571157

11581158

11591159
def _check_monitoring_location_id(
@@ -1198,25 +1198,26 @@ def _check_monitoring_location_id(
11981198
):
11991199
raise TypeError(
12001200
f"monitoring_location_id must be a string or iterable of strings, "
1201-
f"not {type(monitoring_location_id).__name__}. "
1202-
f"Expected format: 'AGENCY-ID', e.g., 'USGS-{monitoring_location_id}'."
1201+
f"not {type(monitoring_location_id).__name__} "
1202+
f"(got {monitoring_location_id!r}). "
1203+
f"Expected 'AGENCY-ID' format, e.g., 'USGS-01646500'."
12031204
)
12041205

12051206
ids = list(monitoring_location_id)
12061207
for id_ in ids:
12071208
if not isinstance(id_, str):
12081209
raise TypeError(
12091210
f"monitoring_location_id elements must be strings, "
1210-
f"not {type(id_).__name__}. "
1211-
f"Expected format: 'AGENCY-ID', e.g., 'USGS-{id_}'."
1211+
f"not {type(id_).__name__} (got {id_!r}). "
1212+
f"Expected 'AGENCY-ID' format, e.g., 'USGS-01646500'."
12121213
)
12131214
_check_id_format(id_)
12141215
return ids
12151216

12161217

12171218
def _check_id_format(value: str) -> None:
12181219
"""Raise ``ValueError`` if ``value`` is not in ``AGENCY-ID`` format."""
1219-
if not _MONITORING_LOCATION_ID_RE.match(value):
1220+
if not _MONITORING_LOCATION_ID_RE.fullmatch(value):
12201221
raise ValueError(
12211222
f"Invalid monitoring_location_id: {value!r}. "
12221223
f"Expected 'AGENCY-ID' format, e.g., 'USGS-01646500'."

0 commit comments

Comments
 (0)