From 22704893dcfcd0f3d14289abec681d2b609c8a75 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:32:10 -0800 Subject: [PATCH 01/21] fix pytest v9 typing issue --- CHANGELOG.md | 5 +++++ openoa/__init__.py | 2 +- test/conftest.py | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c10559a0..292601c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog All notable changes to this project will be documented in this file. If you make a notable change to the project, please add a line describing the change to the "unreleased" section. The maintainers will make an effort to keep the [Github Releases](https://github.com/NREL/OpenOA/releases) page up to date with this changelog. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## v3.1.4 - 2025-12-01 + +- During the custom test collection, convert the `Path` objects to `str` to avoid issues with the + type enforcement of `list[str]` for `args` in Pytest v9. + ## v3.1.3 - 2025-01-31 - Pin SciPy to >= 1.7 and <1.14 to avoid an incompatibility error with PyGAM. diff --git a/openoa/__init__.py b/openoa/__init__.py index 6a4b760a..1e1df7cc 100644 --- a/openoa/__init__.py +++ b/openoa/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.1.3" +__version__ = "3.1.4" """ When bumping version, please be sure to also update parameters in sphinx/conf.py diff --git a/test/conftest.py b/test/conftest.py index fd7ccdcf..dd24a7d3 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -25,8 +25,8 @@ def pytest_configure(config): regression = config.getoption("--regression") # Provide the appropriate directories - unit_tests = [el for el in (ROOT / "unit").iterdir() if el.suffix == ".py"] - regression_tests = [el for el in (ROOT / "regression").iterdir() if el.suffix == ".py"] + unit_tests = [str(el) for el in (ROOT / "unit").iterdir() if el.suffix == ".py"] + regression_tests = [str(el) for el in (ROOT / "regression").iterdir() if el.suffix == ".py"] # If both, run them all; if neither skip any modifications; otherwise run just the appropriate subset if regression and unit: From 65584e9343be61abf9a1628b1bc9f7d22d8c0774 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 08:58:33 -0800 Subject: [PATCH 02/21] update for python 3.14 support now that pygam is being updated again --- CHANGELOG.md | 5 ++++- pyproject.toml | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 292601c3..6208b781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # Changelog All notable changes to this project will be documented in this file. If you make a notable change to the project, please add a line describing the change to the "unreleased" section. The maintainers will make an effort to keep the [Github Releases](https://github.com/NREL/OpenOA/releases) page up to date with this changelog. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## v3.1.4 - 2025-12-01 +## v3.1.4 - 2025-12-24 - During the custom test collection, convert the `Path` objects to `str` to avoid issues with the type enforcement of `list[str]` for `args` in Pytest v9. +- Update PyGAM minimum version for its latest update that includes Python 3.14 support. +- Remove maximum version pins for scipy and statsmodels with the support of the latest Python versions. +- Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12+. ## v3.1.3 - 2025-01-31 diff --git a/pyproject.toml b/pyproject.toml index 43d144c8..1ebd4d86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] authors = [{name = "NREL PRUF OA Team", email = "openoa@nrel.gov"}] readme = {file = "README.md", content-type = "text/markdown"} description = "A package for collecting and assigning wind turbine metrics" -requires-python = ">=3.8, <3.12" +requires-python = ">=3.10" license = {file = "LICENSE.txt"} dependencies = [ "scikit-learn>=1.0", @@ -18,10 +18,10 @@ dependencies = [ "shapely>=1.8", "numpy>=1.24", "pandas>=2.2", - "pygam>=0.9.0", - "scipy>=1.7,<1.14", + "pygam>=0.11.0", + "scipy>=1.7", "statsmodels>=0.11; python_version<'3.11'", - "statsmodels>=0.13.3; python_version=='3.11'", + "statsmodels>=0.13.3; python_version>='3.11'", "tqdm>=4.28.1", "matplotlib>=3.6", "bokeh>=3.3", @@ -50,10 +50,11 @@ classifiers = [ # https://pypi.org/classifiers/ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", From bec1da7cc2f81eb4aabff940d938e5438e501f69 Mon Sep 17 00:00:00 2001 From: Eric Simley Date: Wed, 19 Nov 2025 10:46:14 -0700 Subject: [PATCH 03/21] adding fill_value=False to shift function in filters.unresponsive_flag to get expected behavior at end of time series with NumPy v2 --- openoa/utils/filters.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openoa/utils/filters.py b/openoa/utils/filters.py index a6757719..3d025e4d 100644 --- a/openoa/utils/filters.py +++ b/openoa/utils/filters.py @@ -103,7 +103,9 @@ def unresponsive_flag( flag = flag == 0 # Need to flag preceding `threshold` values as well - flag = flag | np.any([flag.shift(-1 - i, axis=0) for i in range(threshold - 1)], axis=0) + flag = flag | np.any( + [flag.shift(-1 - i, axis=0, fill_value=False) for i in range(threshold - 1)], axis=0 + ) # Return back a pd.Series if one was provided, else a pd.DataFrame return flag[col[0]] if to_series else flag From 42fb30f2278db5057050ffffcdb7bb34a5eecec5 Mon Sep 17 00:00:00 2001 From: Eric Simley Date: Wed, 19 Nov 2025 11:03:02 -0700 Subject: [PATCH 04/21] change np.Inf to np.inf in timeseries tests for compatibility with NumPy v2 --- test/unit/test_timeseries_toolkit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/test_timeseries_toolkit.py b/test/unit/test_timeseries_toolkit.py index 36d66e48..7260e84b 100644 --- a/test/unit/test_timeseries_toolkit.py +++ b/test/unit/test_timeseries_toolkit.py @@ -145,8 +145,8 @@ def test_percent_nan(self): test_dict = {} # All should be float Series given PlantData requirements - test_dict["a"] = pd.Series([True, 1, 2, 1e5, np.Inf]).astype(float) - test_dict["b"] = pd.Series([False, np.nan, 2, 1e5, np.Inf]).astype(float) + test_dict["a"] = pd.Series([True, 1, 2, 1e5, np.inf]).astype(float) + test_dict["b"] = pd.Series([False, np.nan, 2, 1e5, np.inf]).astype(float) test_dict["c"] = pd.Series([np.nan, 1, 2, 1e5, np.nan]).astype(float) nan_values = {"a": 0.0, "b": 0.2, "c": 0.4} From e38cfd076536256299e20c1b84babdcf7cf90962 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 09:50:06 -0800 Subject: [PATCH 05/21] fix scikit-learn max version for unsupported functionality in pygam --- CHANGELOG.md | 1 + pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6208b781..a777a046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. If you make type enforcement of `list[str]` for `args` in Pytest v9. - Update PyGAM minimum version for its latest update that includes Python 3.14 support. - Remove maximum version pins for scipy and statsmodels with the support of the latest Python versions. +- Adds a maximum version for scikit-learn for a change in their `__sklearn_tags__` support. - Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12+. ## v3.1.3 - 2025-01-31 diff --git a/pyproject.toml b/pyproject.toml index 1ebd4d86..63c382f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ description = "A package for collecting and assigning wind turbine metrics" requires-python = ">=3.10" license = {file = "LICENSE.txt"} dependencies = [ - "scikit-learn>=1.0", + "scikit-learn>=1.0,<1.7", "requests>=2.21.0", "eia-python>=1.22", "pyproj>=3.5", From 7da8d70fd81c94b9695e51753190d1fbe938601d Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 09:53:56 -0800 Subject: [PATCH 06/21] udpate python in ci-tests --- .github/workflows/ci-tests.yml | 2 +- CHANGELOG.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 9e1487e0..adb62332 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.9, 3.11] + python-version: [3.10, 3.14] steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index a777a046..32a40d9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. If you make - Remove maximum version pins for scipy and statsmodels with the support of the latest Python versions. - Adds a maximum version for scikit-learn for a change in their `__sklearn_tags__` support. - Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12+. +- Update the min and max versions to test in the testing CI workflow. ## v3.1.3 - 2025-01-31 From 395293d094e2e272dbc4a0a8bb31e22419b81591 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 09:55:57 -0800 Subject: [PATCH 07/21] convert python versions to strings --- .github/workflows/ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index adb62332..2cffd60b 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: [3.10, 3.14] + python-version: ["3.10", "3.14"] steps: - uses: actions/checkout@v4 From 5d0edbb0645a1515b86ac9d1e74b1747c024203b Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:50:13 -0800 Subject: [PATCH 08/21] attempt sklearn 1.5.x --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 63c382f8..55475e56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ description = "A package for collecting and assigning wind turbine metrics" requires-python = ">=3.10" license = {file = "LICENSE.txt"} dependencies = [ - "scikit-learn>=1.0,<1.7", + "scikit-learn>=1.0,<1.6", "requests>=2.21.0", "eia-python>=1.22", "pyproj>=3.5", From a501f4206b1e35b50bab0cc5a19dc5b89f769f4c Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:54:23 -0800 Subject: [PATCH 09/21] drop 3.14 support due to windows scikit-learn build issues --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 55475e56..e6a59a88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,10 +8,10 @@ dynamic = ["version"] authors = [{name = "NREL PRUF OA Team", email = "openoa@nrel.gov"}] readme = {file = "README.md", content-type = "text/markdown"} description = "A package for collecting and assigning wind turbine metrics" -requires-python = ">=3.10" +requires-python = ">=3.10,<3.14" license = {file = "LICENSE.txt"} dependencies = [ - "scikit-learn>=1.0,<1.6", + "scikit-learn>=1.0,<1.7", "requests>=2.21.0", "eia-python>=1.22", "pyproj>=3.5", From 29e40c50bda9055944f4f8d49411baf051cbd3f9 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:55:16 -0800 Subject: [PATCH 10/21] update CI runner --- .github/workflows/ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 2cffd60b..bbbdff13 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.10", "3.14"] + python-version: ["3.10", "3.13"] steps: - uses: actions/checkout@v4 From 1caf95c2ea3dfeaf8493c16fe152119db35868d4 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 24 Dec 2025 11:03:09 -0800 Subject: [PATCH 11/21] update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32a40d9a..00356d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,10 @@ All notable changes to this project will be documented in this file. If you make - During the custom test collection, convert the `Path` objects to `str` to avoid issues with the type enforcement of `list[str]` for `args` in Pytest v9. -- Update PyGAM minimum version for its latest update that includes Python 3.14 support. +- Update PyGAM minimum version for its latest update that includes Python 3.10-3.13 support. - Remove maximum version pins for scipy and statsmodels with the support of the latest Python versions. - Adds a maximum version for scikit-learn for a change in their `__sklearn_tags__` support. -- Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12+. +- Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12 and 3.13. - Update the min and max versions to test in the testing CI workflow. ## v3.1.3 - 2025-01-31 From e83b838479e737f9f09e3685ae92853703f3edce Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:50:24 -0800 Subject: [PATCH 12/21] bump pytest minimum to support subtests for finnicky tests --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e6a59a88..704f0188 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ develop = [ "isort", "flake8", "flake8-docstrings", - "pytest>=5.4.2", + "pytest>=9", "pytest-cov>=2.8.1", ] docs = [ From 1f07cfeb6767c3a2b23ded37175ed6fbba1e241d Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:06:49 -0800 Subject: [PATCH 13/21] add xfail to finnicky gbm test and subtests for multiple checks --- test/regression/long_term_monte_carlo_aep.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/regression/long_term_monte_carlo_aep.py b/test/regression/long_term_monte_carlo_aep.py index f735f5e6..6f941c69 100644 --- a/test/regression/long_term_monte_carlo_aep.py +++ b/test/regression/long_term_monte_carlo_aep.py @@ -329,6 +329,7 @@ def test_daily_gam(self): sim_results = self.analysis.results self.check_simulation_results_gam_daily(sim_results) + @pytest.mark.xfail(strict=False) def test_daily_gbm(self): reset_prng() # ____________________________________________________________________ @@ -484,7 +485,8 @@ def check_process_reanalysis_data_daily(self, df): print(computed) for key in expected.keys(): - nptest.assert_array_almost_equal(expected[key], computed[key]) + with self.subTest(f"checking {key}"): + nptest.assert_array_almost_equal(expected[key], computed[key]) def check_simulation_results_lin_monthly(self, s): # Make sure AEP results are consistent to six decimal places From 61f968a9c6fb99a011c8b0eca45a83291469148d Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:14:01 -0800 Subject: [PATCH 14/21] add reason to xfail --- test/regression/long_term_monte_carlo_aep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regression/long_term_monte_carlo_aep.py b/test/regression/long_term_monte_carlo_aep.py index 6f941c69..3c8574e5 100644 --- a/test/regression/long_term_monte_carlo_aep.py +++ b/test/regression/long_term_monte_carlo_aep.py @@ -329,7 +329,7 @@ def test_daily_gam(self): sim_results = self.analysis.results self.check_simulation_results_gam_daily(sim_results) - @pytest.mark.xfail(strict=False) + @pytest.mark.xfail(reason="Fails intermittently depending, mostly on MacOS.") def test_daily_gbm(self): reset_prng() # ____________________________________________________________________ From faf087b58bbf68b49cf7e0fdc48f12afccd79772 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:14:18 -0800 Subject: [PATCH 15/21] update target versions for linting --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 704f0188..47b8bd5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -141,7 +141,7 @@ filterwarnings = [ [tool.black] # https://github.com/psf/black line-length = 100 -target-version = ["py38", "py39", "py310"] +target-version = ["py310", "py311", "py312", "py313"] include = '\.pyi?$' exclude = ''' # A regex preceded with ^/ will apply only to files and directories @@ -167,7 +167,7 @@ exclude = ''' [tool.isort] # https://github.com/PyCQA/isort profile = "black" -py_version = 39 +py_version = 310 src_paths = ["isort", "test"] line_length = "100" length_sort = "True" From 24d3fc02f4a364781eafa9aaa3c7af53ea8d06bd Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:15:02 -0800 Subject: [PATCH 16/21] autoupdate pre-commit --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 15882568..fd761832 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 7.0.0 hooks: - id: isort additional_dependencies: [toml] @@ -15,13 +15,13 @@ repos: types: [pyi] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.21.2 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 26.1.0 hooks: - id: black name: black @@ -29,7 +29,7 @@ repos: language_version: python3 - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -42,6 +42,6 @@ repos: args: [--autofix] - repo: https://github.com/pycqa/flake8 - rev: '6.0.0' + rev: '7.3.0' hooks: - id: flake8 From 7217884d9f051dd8977aaf483799b4deecb21edb Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:21:12 -0800 Subject: [PATCH 17/21] add subtests to yaw and xfail for UQ --- test/regression/yaw_misalignment.py | 86 ++++++++++++++++++----------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/test/regression/yaw_misalignment.py b/test/regression/yaw_misalignment.py index 67927e31..c46579a8 100644 --- a/test/regression/yaw_misalignment.py +++ b/test/regression/yaw_misalignment.py @@ -72,6 +72,7 @@ def test_yaw_misaliginment_with_UQ(self): ) self.check_simulation_results_yaw_misalignment_with_UQ() + @pytest.mark.xfail(reason="System-dependendent intermittent failures") def test_yaw_misaliginment_with_UQ_new_parameters(self): reset_prng() # ____________________________________________________________________ @@ -171,21 +172,24 @@ def check_simulation_results_yaw_misalignment_without_UQ(self): calculated_yaw_mis_results_overall = self.analysis.yaw_misalignment - nptest.assert_array_almost_equal( - expected_yaw_mis_results_overall, calculated_yaw_mis_results_overall, decimal=5 - ) + with self.subTest("Checking overall results"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_overall, calculated_yaw_mis_results_overall, decimal=5 + ) calculated_yaw_mis_results_ws = self.analysis.yaw_misalignment_ws - nptest.assert_array_almost_equal( - expected_yaw_mis_results_ws, calculated_yaw_mis_results_ws, decimal=5 - ) + with self.subTest("Checking wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_ws, calculated_yaw_mis_results_ws, decimal=5 + ) calculated_mean_vane_results_ws = self.analysis.mean_vane_angle_ws - nptest.assert_array_almost_equal( - expected_mean_vane_results_ws, calculated_mean_vane_results_ws, decimal=5 - ) + with self.subTest("Checking wind vane"): + nptest.assert_array_almost_equal( + expected_mean_vane_results_ws, calculated_mean_vane_results_ws, decimal=5 + ) def check_simulation_results_yaw_misalignment_with_UQ(self): # Make sure yaw misalignment results are consistent to six decimal places with UQ. @@ -254,15 +258,21 @@ def check_simulation_results_yaw_misalignment_with_UQ(self): calculated_yaw_mis_results_avg_overall = self.analysis.yaw_misalignment_avg - nptest.assert_array_almost_equal( - expected_yaw_mis_results_avg_overall, calculated_yaw_mis_results_avg_overall, decimal=5 - ) + with self.subTest("Checking average of overall results"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_avg_overall, + calculated_yaw_mis_results_avg_overall, + decimal=5, + ) calculated_yaw_mis_results_std_overall = self.analysis.yaw_misalignment_std - nptest.assert_array_almost_equal( - expected_yaw_mis_results_std_overall, calculated_yaw_mis_results_std_overall, decimal=5 - ) + with self.subTest("Checking standard deviation wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_std_overall, + calculated_yaw_mis_results_std_overall, + decimal=5, + ) # calculated_yaw_mis_results_95ci_overall = self.analysis.yaw_misalignment_95ci @@ -274,15 +284,17 @@ def check_simulation_results_yaw_misalignment_with_UQ(self): calculated_yaw_mis_results_avg_ws = self.analysis.yaw_misalignment_avg_ws - nptest.assert_array_almost_equal( - expected_yaw_mis_results_avg_ws, calculated_yaw_mis_results_avg_ws, decimal=5 - ) + with self.subTest("Checking average wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_avg_ws, calculated_yaw_mis_results_avg_ws, decimal=5 + ) calculated_yaw_mis_results_std_ws = self.analysis.yaw_misalignment_std_ws - nptest.assert_array_almost_equal( - expected_yaw_mis_results_std_ws, calculated_yaw_mis_results_std_ws, decimal=5 - ) + with self.subTest("Checking standard deviation wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_std_ws, calculated_yaw_mis_results_std_ws, decimal=5 + ) # calculated_yaw_mis_results_95ci_ws = self.analysis.yaw_misalignment_95ci_ws @@ -335,15 +347,21 @@ def check_simulation_results_yaw_misalignment_with_UQ_new_params(self): calculated_yaw_mis_results_avg_overall = self.analysis.yaw_misalignment_avg - nptest.assert_array_almost_equal( - expected_yaw_mis_results_avg_overall, calculated_yaw_mis_results_avg_overall, decimal=5 - ) + with self.subTest("Checking average of overall results"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_avg_overall, + calculated_yaw_mis_results_avg_overall, + decimal=5, + ) calculated_yaw_mis_results_std_overall = self.analysis.yaw_misalignment_std - nptest.assert_array_almost_equal( - expected_yaw_mis_results_std_overall, calculated_yaw_mis_results_std_overall, decimal=5 - ) + with self.subTest("Checking standard deviation of overall results"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_std_overall, + calculated_yaw_mis_results_std_overall, + decimal=5, + ) # calculated_yaw_mis_results_95ci_overall = self.analysis.yaw_misalignment_95ci @@ -355,15 +373,17 @@ def check_simulation_results_yaw_misalignment_with_UQ_new_params(self): calculated_yaw_mis_results_avg_ws = self.analysis.yaw_misalignment_avg_ws - nptest.assert_array_almost_equal( - expected_yaw_mis_results_avg_ws, calculated_yaw_mis_results_avg_ws, decimal=5 - ) + with self.subTest("Checking average wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_avg_ws, calculated_yaw_mis_results_avg_ws, decimal=5 + ) calculated_yaw_mis_results_std_ws = self.analysis.yaw_misalignment_std_ws - nptest.assert_array_almost_equal( - expected_yaw_mis_results_std_ws, calculated_yaw_mis_results_std_ws, decimal=5 - ) + with self.subTest("Checking standard deviation of wind speeds"): + nptest.assert_array_almost_equal( + expected_yaw_mis_results_std_ws, calculated_yaw_mis_results_std_ws, decimal=5 + ) # calculated_yaw_mis_results_95ci_ws = self.analysis.yaw_misalignment_95ci_ws From 0b9e3ae65f5db323212752fe3fdeee8568e77512 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:48:37 -0800 Subject: [PATCH 18/21] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00356d79..ee49a90b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ All notable changes to this project will be documented in this file. If you make - Adds a maximum version for scikit-learn for a change in their `__sklearn_tags__` support. - Deprecate support for Python 3.8 and 3.9, with additional support for Python 3.12 and 3.13. - Update the min and max versions to test in the testing CI workflow. +- Utilizes pytest xfail and subtests to manange intermittent and finnicky test failures until a + long-term solution can be implemented. ## v3.1.3 - 2025-01-31 From c01124eb098ade5a6cbd876a4c358334d64b9b9a Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:29:21 -0800 Subject: [PATCH 19/21] move xfail to the correct test --- test/regression/yaw_misalignment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regression/yaw_misalignment.py b/test/regression/yaw_misalignment.py index c46579a8..0e59cac7 100644 --- a/test/regression/yaw_misalignment.py +++ b/test/regression/yaw_misalignment.py @@ -50,6 +50,7 @@ def test_yaw_misaliginment_without_UQ(self): ) self.check_simulation_results_yaw_misalignment_without_UQ() + @pytest.mark.xfail(reason="System-dependendent intermittent failures") def test_yaw_misaliginment_with_UQ(self): reset_prng() # ____________________________________________________________________ @@ -72,7 +73,6 @@ def test_yaw_misaliginment_with_UQ(self): ) self.check_simulation_results_yaw_misalignment_with_UQ() - @pytest.mark.xfail(reason="System-dependendent intermittent failures") def test_yaw_misaliginment_with_UQ_new_parameters(self): reset_prng() # ____________________________________________________________________ From c50c1423d79967a661866faed767a5c1f263311b Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:57:58 -0800 Subject: [PATCH 20/21] limit pandas to <3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 47b8bd5b..11302069 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ "pyproj>=3.5", "shapely>=1.8", "numpy>=1.24", - "pandas>=2.2", + "pandas>=2.2,<3", "pygam>=0.11.0", "scipy>=1.7", "statsmodels>=0.11; python_version<'3.11'", From 8197ef55f8a5df92ad22c3414a5d7d9414301cd5 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Thu, 29 Jan 2026 13:11:01 -0800 Subject: [PATCH 21/21] update changelog with correct date --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee49a90b..2d8cde9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog All notable changes to this project will be documented in this file. If you make a notable change to the project, please add a line describing the change to the "unreleased" section. The maintainers will make an effort to keep the [Github Releases](https://github.com/NREL/OpenOA/releases) page up to date with this changelog. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## v3.1.4 - 2025-12-24 +## v3.1.4 - 2026-01-29 - During the custom test collection, convert the `Path` objects to `str` to avoid issues with the type enforcement of `list[str]` for `args` in Pytest v9. @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. If you make - Update the min and max versions to test in the testing CI workflow. - Utilizes pytest xfail and subtests to manange intermittent and finnicky test failures until a long-term solution can be implemented. +- Pin Pandas maximum version to the 2.x release cycle. ## v3.1.3 - 2025-01-31