Skip to content

Commit 5237df4

Browse files
thodson-usgsclaude
andcommitted
fix(waterdata): materialize numpy/Series numeric params instead of str()-ing them
A numeric (_NO_NORMALIZE_PARAMS) param — water_year, year, month, day, thresholds, … — passed as a numpy array or pandas Series fell into the `args[k] = v` passthrough in _get_args without being materialized to a list. Downstream, the GET comma-join and the chunker both test `list`/`tuple`, so an ndarray/Series was neither comma-joined nor chunked: e.g. get_peaks(water_year=np.array([2020, 2021])) produced `water_year=%5B2020+2021%5D` (the array's repr) instead of `water_year=2020,2021`. Plain lists already worked. Split the branch so _NO_NORMALIZE_PARAMS values keep their element types (no string-normalization) but a non-string iterable is still listified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ee653e5 commit 5237df4

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

dataretrieval/waterdata/utils.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,11 +2015,17 @@ def _get_args(
20152015
args[k] = _check_monitoring_location_id(v)
20162016
elif k == "properties":
20172017
args[k] = _as_str_list(v, k)
2018-
elif (
2019-
k in _NO_NORMALIZE_PARAMS
2020-
or isinstance(v, str)
2021-
or not isinstance(v, Iterable)
2022-
):
2018+
elif k in _NO_NORMALIZE_PARAMS:
2019+
# Numeric params (water_year, thresholds, …) keep their element
2020+
# types — don't string-normalize — but still materialize a
2021+
# non-string iterable (numpy array, pandas Series, generator) to a
2022+
# list so the GET comma-join and the chunker, which test
2023+
# ``list``/``tuple``, handle it instead of str()-ing the whole array
2024+
# into the URL.
2025+
args[k] = (
2026+
list(v) if isinstance(v, Iterable) and not isinstance(v, str) else v
2027+
)
2028+
elif isinstance(v, str) or not isinstance(v, Iterable):
20232029
args[k] = v
20242030
else:
20252031
args[k] = _normalize_str_iterable(v, k)

tests/waterdata_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
_check_profiles,
3636
_construct_api_requests,
3737
_construct_cql_request,
38+
_get_args,
3839
_normalize_str_iterable,
3940
)
4041

@@ -284,6 +285,17 @@ def test_construct_api_requests_numeric_list_joins_with_str():
284285
assert "water_year=2020%2C2021" in str(req.url)
285286

286287

288+
def test_get_args_materializes_numpy_and_series_numeric_params():
289+
"""Regression: numeric (_NO_NORMALIZE_PARAMS) params given as a numpy array
290+
or pandas Series must be materialized to a list so they comma-join in the
291+
URL — previously the array/Series repr leaked into the query string."""
292+
for value in (np.array([2020, 2021]), pd.Series([2020, 2021])):
293+
args = _get_args({"water_year": value})
294+
assert args["water_year"] == [2020, 2021]
295+
req = _construct_api_requests("peaks", **args)
296+
assert "water_year=2020%2C2021" in str(req.url)
297+
298+
287299
def test_construct_api_requests_two_element_date_list_becomes_interval():
288300
"""A two-element date list is interpreted as start/end of an OGC datetime
289301
interval (joined with '/'), NOT as two discrete dates. The OGC `datetime`

0 commit comments

Comments
 (0)