From 01b90dcc5426266b6e3823812cde6aa3665ac2eb Mon Sep 17 00:00:00 2001 From: Andrey Fedorov Date: Fri, 31 Jul 2026 12:28:18 -0400 Subject: [PATCH 1/3] enh: relax constraints on pandas version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35a5b9e..4e5a2a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ 'duckdb>=1.0.0,<2.0.0', "idc-index-data==24.2.2", "packaging", - "pandas<=2.2.4", + "pandas<=3", "platformdirs", "psutil", "pyarrow", From 7bef6dc65b4b0f2de6f686506d7f66645378f34e Mon Sep 17 00:00:00 2001 From: Andrey Fedorov Date: Fri, 31 Jul 2026 12:45:16 -0400 Subject: [PATCH 2/3] build(deps): relax pandas constraint to >=2.2.2,<4 The previous cap (`pandas<=2.2.4`, effectively 2.2.3 since 2.2.4 was never released) was inherited from the original cookiecutter scaffolding rather than motivated by any incompatibility. idc-index uses a small, conservative slice of the pandas API (read_parquet, read_csv, merge, concat, groupby.agg, the .str accessor) with no chained assignment or removed APIs, so nothing in the codebase requires the cap. Verified the full test suite (42 tests, 17 subtests, with filterwarnings=error so new FutureWarnings fail) against: - Python 3.12 + pandas 2.2.3 (previous cap) -> pass - Python 3.10 + pandas 2.3.3 -> pass - Python 3.12 + pandas 3.0.5 -> pass The floor of 2.2.2 is the first pandas release compatible with numpy 2, which pyarrow and duckdb now pull in; pandas 2.0.3 fails at import under numpy 2 with "numpy.dtype size changed". Note for users: under pandas 3, string columns in returned DataFrames use StringDtype rather than object dtype. Co-Authored-By: Claude Opus 5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4e5a2a5..48dd5af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ 'duckdb>=1.0.0,<2.0.0', "idc-index-data==24.2.2", "packaging", - "pandas<=3", + "pandas>=2.2.2,<4", "platformdirs", "psutil", "pyarrow", From 1a7b42af63c11b56b543c940b6427625c993c433 Mon Sep 17 00:00:00 2001 From: Andrey Fedorov Date: Fri, 31 Jul 2026 12:45:31 -0400 Subject: [PATCH 3/3] fix: repair get_series_size lookup and instance URL construction Two latent bugs, both independent of the pandas version (reproduced identically on 2.2.3 and 3.0.5), surfaced while testing newer pandas: - get_series_size() compared a list literal to a string (`self.index[["SeriesInstanceUID"] == seriesInstanceUID]`), which evaluates to False and made every call raise `KeyError: False`. It now goes through _filter_dataframe_by_id, which also raises the ValueError for unknown UIDs that the docstring already promised. No test covered this method. - The instance-level URL fallback used `Series.replace("/*", "/")`, which matches whole values rather than substrings and was therefore a no-op, leaving the trailing "*" in the URL. Replaced with `.str.removesuffix("*")`, matching the scalar idiom already used in get_instance_file_URL. Co-Authored-By: Claude Opus 5 --- idc_index/index.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idc_index/index.py b/idc_index/index.py index 5650398..362b843 100644 --- a/idc_index/index.py +++ b/idc_index/index.py @@ -567,9 +567,9 @@ def get_series_size(self, seriesInstanceUID): ValueError: If the `seriesInstanceUID` does not exist. """ - resp = self.index[["SeriesInstanceUID"] == seriesInstanceUID][ - "series_size_MB" - ].iloc[0] + resp = self._filter_dataframe_by_id( + "SeriesInstanceUID", self.index, seriesInstanceUID + )["series_size_MB"].iloc[0] return resp def get_patients(self, collection_id, outputFormat="dict"): @@ -2045,7 +2045,7 @@ def download_from_selection( if sopInstanceUID: if "instance_aws_url" not in result_df: result_df["instance_aws_url"] = ( - result_df["series_aws_url"].replace("/*", "/") + result_df["series_aws_url"].str.removesuffix("*") + result_df["crdc_instance_uuid"] + ".dcm" )