From b8eefae952150a92855b587ff600d1a26f136ec5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 25 Jul 2025 00:12:49 +0000 Subject: [PATCH 1/2] Upgrade Python from 3.8 to 3.13 - Update pyproject.toml to require Python >=3.13,<3.14 - Update CI workflows to use Python 3.13 - Update pre-commit hooks to use --py313-plus - Update documentation to reference Python 3.13 - Update dependency constraints in requirements-py38.txt for Python 3.13 compatibility - Fix np.Inf deprecation in test_timeseries_toolkit.py (replaced with np.inf) - Fix unresponsive_flag function compatibility with Python 3.13/pandas - Add .python-version file for pyenv - Update ReadTheDocs and runtime configurations Co-Authored-By: Sam Fertig --- .github/workflows/ci-tests.yml | 2 +- .github/workflows/pypi-publish.yml | 2 +- .pre-commit-config.yaml | 2 +- .python-version | 1 + .readthedocs.yaml | 2 +- README.md | 7 +++---- openoa/utils/filters.py | 7 ++++++- pyproject.toml | 14 +++++--------- requirements-py38.txt | 25 +++++++++++++++++++++++++ runtime.txt | 2 +- sphinx/getting_started/index.rst | 3 +-- sphinx/getting_started/install.rst | 3 +-- sphinx/index.md | 4 ++-- test/unit/test_timeseries_toolkit.py | 4 ++-- 14 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 .python-version create mode 100644 requirements-py38.txt diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 9e1487e07..feb30b5f2 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.13] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index b442a0be4..941a6e004 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.13' - name: Build package run: | python -m pip install --upgrade pip diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 158825684..c23681aab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: rev: v3.15.0 hooks: - id: pyupgrade - args: [--py38-plus] + args: [--py313-plus] - repo: https://github.com/psf/black rev: 23.3.0 diff --git a/.python-version b/.python-version new file mode 100644 index 000000000..c10780c62 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13.1 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d127c6b5e..39abe894f 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.10" + python: "3.13" # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/README.md b/README.md index 9ea2e5188..4cb64a35e 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ effort more broadly,** please use citation [^1], which is provided below in BibT ### Requirements -- Python 3.8-3.11 with pip. +- Python 3.13 with pip. We strongly recommend using the Anaconda Python distribution and creating a new conda environment for OpenOA. You can download Anaconda through @@ -139,7 +139,7 @@ After installing Anaconda (or alternative), create and activate a new conda envi name "openoa-env": ```bash -conda create --name openoa-env python=3.10 +conda create --name openoa-env python=3.13 conda activate openoa-env ``` @@ -175,8 +175,7 @@ is also allowed). - `all`: for the complete dependency stack > **Important** -> If using Python 3.11, install `openoa` only, then reinstall adding the modifiers to reduce -> the amount of time it takes for pip to resolve the dependency stack. +> With Python 3.13, you can install `openoa` with any combination of modifiers directly. #### Common Installation Issues diff --git a/openoa/utils/filters.py b/openoa/utils/filters.py index a67577196..5da4907c1 100644 --- a/openoa/utils/filters.py +++ b/openoa/utils/filters.py @@ -103,7 +103,12 @@ 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) + shifts = [flag.shift(-1 - i, axis=0) for i in range(threshold - 1)] + if shifts: + any_result = shifts[0] + for shift in shifts[1:]: + any_result = any_result | shift + flag = flag | any_result # Return back a pd.Series if one was provided, else a pd.DataFrame return flag[col[0]] if to_series else flag diff --git a/pyproject.toml b/pyproject.toml index 43d144c8e..4bc3bdabd 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.13" license = {file = "LICENSE.txt"} dependencies = [ "scikit-learn>=1.0", @@ -20,8 +20,7 @@ dependencies = [ "pandas>=2.2", "pygam>=0.9.0", "scipy>=1.7,<1.14", - "statsmodels>=0.11; python_version<'3.11'", - "statsmodels>=0.13.3; python_version=='3.11'", + "statsmodels>=0.14.1", "tqdm>=4.28.1", "matplotlib>=3.6", "bokeh>=3.3", @@ -50,10 +49,7 @@ 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.13", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", @@ -140,7 +136,7 @@ filterwarnings = [ [tool.black] # https://github.com/psf/black line-length = 100 -target-version = ["py38", "py39", "py310"] +target-version = ["py313"] include = '\.pyi?$' exclude = ''' # A regex preceded with ^/ will apply only to files and directories @@ -166,7 +162,7 @@ exclude = ''' [tool.isort] # https://github.com/PyCQA/isort profile = "black" -py_version = 39 +py_version = 313 src_paths = ["isort", "test"] line_length = "100" length_sort = "True" diff --git a/requirements-py38.txt b/requirements-py38.txt new file mode 100644 index 000000000..c46d5aa44 --- /dev/null +++ b/requirements-py38.txt @@ -0,0 +1,25 @@ +scikit-learn>=1.0 +requests>=2.21.0 +eia-python>=1.22 +pyproj>=3.5 +shapely>=1.8 +numpy>=2.1.0 +pandas>=2.2.3 +pygam>=0.9.0 +scipy>=1.14 +statsmodels>=0.14.1 +tqdm>=4.28.1 +matplotlib>=3.8 +bokeh>=3.0 +attrs>=22.2 +pytz +pyyaml +tabulate +ipython +pre-commit +black +isort +flake8 +flake8-docstrings +pytest>=5.4.2 +pytest-cov>=2.8.1 diff --git a/runtime.txt b/runtime.txt index 8fdd90711..e912aa621 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.9 +python-3.13 diff --git a/sphinx/getting_started/index.rst b/sphinx/getting_started/index.rst index 8b803d875..27726e6a1 100644 --- a/sphinx/getting_started/index.rst +++ b/sphinx/getting_started/index.rst @@ -33,8 +33,7 @@ Additional Dependencies ----------------------- .. important:: - If using Python 3.11, install ``openoa`` only, then reinstall adding the modifiers to reduce - the amount of time it takes for pip to resolve the dependency stack. + With Python 3.13, you can install ``openoa`` with any combination of modifiers directly. Whether installing from PyPI or source, any combination of the following can be used to install additional dependencies. For example, the examples requirements can be installed using diff --git a/sphinx/getting_started/install.rst b/sphinx/getting_started/install.rst index 126fd9fcc..53472d5f6 100644 --- a/sphinx/getting_started/install.rst +++ b/sphinx/getting_started/install.rst @@ -32,8 +32,7 @@ at the same time with the following. pip install "OpenOA[develop]" .. important:: - If using Python 3.11, install ``openoa`` only, then reinstall adding the modifiers to reduce - the amount of time it takes for pip to resolve the dependency stack. + With Python 3.13, you can install ``openoa`` with any combination of modifiers directly. Additional options: - `develop`: for linting, automated formatting, and testing diff --git a/sphinx/index.md b/sphinx/index.md index 4b996ed56..a21b24e50 100644 --- a/sphinx/index.md +++ b/sphinx/index.md @@ -72,7 +72,7 @@ For further information about the features and citations, please see the ## Installation -Compatible with Python 3.8 through 3.11 with pip. +Compatible with Python 3.13 with pip. We strongly recommend using the Anaconda Python distribution and creating a new conda environment for OpenOA. You can download Anaconda through @@ -90,7 +90,7 @@ After installing Anaconda (or alternative), create and activate a new conda envi name "openoa-env": ```bash -conda create --name openoa-env python=3.10 +conda create --name openoa-env python=3.13 conda activate openoa-env ``` diff --git a/test/unit/test_timeseries_toolkit.py b/test/unit/test_timeseries_toolkit.py index 36d66e480..7260e84b7 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 9382cb942e035ef2d2d3ccce89390c2fab22ee46 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 25 Jul 2025 00:16:27 +0000 Subject: [PATCH 2/2] Fix scipy version constraint to allow newer versions with Python 3.13 wheels Co-Authored-By: Sam Fertig --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4bc3bdabd..6437573a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "numpy>=1.24", "pandas>=2.2", "pygam>=0.9.0", - "scipy>=1.7,<1.14", + "scipy>=1.7", "statsmodels>=0.14.1", "tqdm>=4.28.1", "matplotlib>=3.6",