From e594e381551c28437bae7869a09b3c1bbf906494 Mon Sep 17 00:00:00 2001 From: Yuxiang-Ren-HUB <165866978+Yuxiang-Ren-HUB@users.noreply.github.com> Date: Fri, 7 Aug 2026 10:38:55 +0800 Subject: [PATCH 1/3] Fix get_nexrad_location mutating shared NEXRAD_LOCATIONS table loc is a reference into the shared NEXRAD_LOCATIONS dict, not a copy. Writing the feet->meters conversion back into loc["elev"] mutated the table permanently, so a second call for the same station applied the conversion again and silently corrupted the elevation. --- pyart/io/nexrad_common.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pyart/io/nexrad_common.py b/pyart/io/nexrad_common.py index 8b29470547..aee68235ec 100644 --- a/pyart/io/nexrad_common.py +++ b/pyart/io/nexrad_common.py @@ -26,11 +26,17 @@ def get_nexrad_location(station): """ loc = NEXRAD_LOCATIONS[station.upper()] - # Convert from feet to meters for elevation units - loc["elev"] = loc["elev"] * 0.3048 - - return loc["lat"], loc["lon"], loc["elev"] + # Convert from feet to meters for elevation units. Read into a local + # variable and return a new value rather than writing back into + # loc["elev"] -- loc is a reference into the shared, module-level + # NEXRAD_LOCATIONS dict, so mutating it in place applied this + # conversion permanently. A second call for the same station then + # converted the already-converted value again, silently corrupting + # the elevation (e.g. KTLX: 1213 ft -> 369.72 m on the first call, + # then -> 112.7 m on the second). + elev_m = loc["elev"] * 0.3048 + return loc["lat"], loc["lon"], elev_m # Locations of NEXRAD locations was retrieved from NOAA's # Historical Observing Metadata Repository (HOMR) on From 0bb7da2f80573a304a0f85c9c1a888b1d564165a Mon Sep 17 00:00:00 2001 From: Yuxiang-Ren-HUB <165866978+Yuxiang-Ren-HUB@users.noreply.github.com> Date: Fri, 7 Aug 2026 10:44:43 +0800 Subject: [PATCH 2/3] Add unit tests for nexrad_common location functions Added unit tests for the nexrad_common module to verify location retrieval and stability across repeated calls. --- tests/io/test_nexrad_common.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/io/test_nexrad_common.py diff --git a/tests/io/test_nexrad_common.py b/tests/io/test_nexrad_common.py new file mode 100644 index 0000000000..ff40d40fbe --- /dev/null +++ b/tests/io/test_nexrad_common.py @@ -0,0 +1,29 @@ +"""Unit Tests for Py-ART's io/nexrad_common.py module.""" + +import pytest + +from pyart.io import nexrad_common + + +def test_get_nexrad_location_known_station(): + lat, lon, elev = nexrad_common.get_nexrad_location("KTLX") + assert lat == pytest.approx(35.33306, abs=1e-3) + assert lon == pytest.approx(-97.2775, abs=1e-3) + # bundled table stores elevation in feet (1213 ft); function must + # return meters + assert elev == pytest.approx(1213 * 0.3048, abs=1e-6) + + +def test_get_nexrad_location_repeated_calls_are_stable(): + # Regression test: get_nexrad_location used to mutate the shared + # NEXRAD_LOCATIONS dict in place (loc["elev"] = loc["elev"] * 0.3048, + # where loc is a reference into the module-level table, not a copy). + # A second call for the same station then applied the feet->meters + # conversion again on top of the already-converted value, silently + # corrupting the elevation. + _, _, elev_first = nexrad_common.get_nexrad_location("KTLX") + _, _, elev_second = nexrad_common.get_nexrad_location("KTLX") + _, _, elev_third = nexrad_common.get_nexrad_location("KTLX") + assert elev_first == elev_second == elev_third + # and the underlying table itself must be untouched (still in feet) + assert nexrad_common.NEXRAD_LOCATIONS["KTLX"]["elev"] == 1213 From 80964eadf85d1a0276d6e6ee97fa91427f33fbdc Mon Sep 17 00:00:00 2001 From: rencheng Date: Fri, 14 Aug 2026 08:33:00 +0800 Subject: [PATCH 3/3] Fix blank-line spacing to satisfy black The previous commit left a single blank line between get_nexrad_location and the following module-level comment block. Black requires two blank lines after a top-level definition, so the Check Black job would have failed once CI is allowed to run. No functional change. --- pyart/io/nexrad_common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyart/io/nexrad_common.py b/pyart/io/nexrad_common.py index aee68235ec..6624a06878 100644 --- a/pyart/io/nexrad_common.py +++ b/pyart/io/nexrad_common.py @@ -38,6 +38,7 @@ def get_nexrad_location(station): return loc["lat"], loc["lon"], elev_m + # Locations of NEXRAD locations was retrieved from NOAA's # Historical Observing Metadata Repository (HOMR) on # 2014-Mar-27. http://www.ncdc.noaa.gov/homr/