From a0c0f53e94aba1693dce5d03a479cc00e0b2ce35 Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 14:20:58 -0500 Subject: [PATCH 1/8] deprecate Python 3.9 EOL was Oct 31 2025 --- .github/workflows/generate_test_files.yml | 2 +- .github/workflows/run_all_tests.yml | 18 +++++++----------- .github/workflows/run_tests.yml | 12 ++++++------ docs/source/install_developers.rst | 6 +++--- docs/source/install_users.rst | 4 +--- pyproject.toml | 4 +--- test_pynwb_io_nwbhdf5.h5 | Bin 0 -> 187904 bytes tox.ini | 14 +++++++------- 8 files changed, 26 insertions(+), 34 deletions(-) create mode 100644 test_pynwb_io_nwbhdf5.h5 diff --git a/.github/workflows/generate_test_files.yml b/.github/workflows/generate_test_files.yml index 27848909b..3ef7700fe 100644 --- a/.github/workflows/generate_test_files.yml +++ b/.github/workflows/generate_test_files.yml @@ -15,7 +15,7 @@ jobs: matrix: include: - { name: pynwb-1.5.1, pynwb-version: "1.5.1", python-version: "3.8"} - - { name: pynwb-2.1.0, pynwb-version: "2.1.0", python-version: "3.9"} + - { name: pynwb-2.1.0, pynwb-version: "2.1.0", python-version: "3.10"} steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/run_all_tests.yml b/.github/workflows/run_all_tests.yml index 0f2cbe5ed..2fa3842d8 100644 --- a/.github/workflows/run_all_tests.yml +++ b/.github/workflows/run_all_tests.yml @@ -22,24 +22,21 @@ jobs: fail-fast: false matrix: include: - - { name: linux-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } - - { name: linux-python3.10 , test-tox-env: test-py310-pinned , build-tox-env: build-py310-pinned , python-ver: "3.10", os: ubuntu-latest } + - { name: linux-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10", os: ubuntu-latest } - { name: linux-python3.11 , test-tox-env: test-py311-pinned , build-tox-env: build-py311-pinned , python-ver: "3.11", os: ubuntu-latest } - { name: linux-python3.11-opt , test-tox-env: test-py311-optional-pinned, build-tox-env: build-py311-pinned , python-ver: "3.11", os: ubuntu-latest } - { name: linux-python3.12 , test-tox-env: test-py312-pinned , build-tox-env: build-py312-pinned , python-ver: "3.12", os: ubuntu-latest } - { name: linux-python3.13 , test-tox-env: test-py313-pinned , build-tox-env: build-py313-pinned , python-ver: "3.13", os: ubuntu-latest } - { name: linux-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13", os: ubuntu-latest } - { name: linux-python3.13-prerelease , test-tox-env: test-py313-prerelease , build-tox-env: build-py313-prerelease, python-ver: "3.13", os: ubuntu-latest } - - { name: windows-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: windows-latest } - - { name: windows-python3.10 , test-tox-env: test-py310-pinned , build-tox-env: build-py310-pinned , python-ver: "3.10", os: windows-latest } + - { name: windows-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10", os: windows-latest } - { name: windows-python3.11 , test-tox-env: test-py311-pinned , build-tox-env: build-py311-pinned , python-ver: "3.11", os: windows-latest } - { name: windows-python3.11-opt , test-tox-env: test-py311-optional-pinned, build-tox-env: build-py311-pinned , python-ver: "3.11", os: windows-latest } - { name: windows-python3.12 , test-tox-env: test-py312-pinned , build-tox-env: build-py312-pinned , python-ver: "3.12", os: windows-latest } - { name: windows-python3.13 , test-tox-env: test-py313-pinned , build-tox-env: build-py313-pinned , python-ver: "3.13", os: windows-latest } - { name: windows-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13", os: windows-latest } - { name: windows-python3.13-prerelease, test-tox-env: test-py313-prerelease , build-tox-env: build-py313-prerelease, python-ver: "3.13", os: windows-latest } - - { name: macos-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: macos-13 } - - { name: macos-python3.10 , test-tox-env: test-py310-pinned , build-tox-env: build-py310-pinned , python-ver: "3.10", os: macos-latest } + - { name: macos-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10", os: macos-latest } - { name: macos-python3.11 , test-tox-env: test-py311-pinned , build-tox-env: build-py311-pinned , python-ver: "3.11", os: macos-latest } - { name: macos-python3.11-opt , test-tox-env: test-py311-optional-pinned, build-tox-env: build-py311-pinned , python-ver: "3.11", os: macos-latest } - { name: macos-python3.12 , test-tox-env: test-py312-pinned , build-tox-env: build-py312-pinned , python-ver: "3.12", os: macos-latest } @@ -92,13 +89,13 @@ jobs: fail-fast: false matrix: include: - - { name: linux-gallery-python3.9-minimum , test-tox-env: gallery-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } + - { name: linux-gallery-python3.10-minimum , test-tox-env: gallery-py310-minimum , python-ver: "3.10", os: ubuntu-latest } - { name: linux-gallery-python3.13-upgraded , test-tox-env: gallery-py313-upgraded , python-ver: "3.13", os: ubuntu-latest } - { name: linux-gallery-python3.13-prerelease , test-tox-env: gallery-py313-prerelease, python-ver: "3.13", os: ubuntu-latest } - - { name: windows-gallery-python3.9-minimum , test-tox-env: gallery-py39-minimum , python-ver: "3.9" , os: windows-latest } + - { name: windows-gallery-python3.10-minimum , test-tox-env: gallery-py310-minimum , python-ver: "3.10", os: windows-latest } - { name: windows-gallery-python3.13-upgraded , test-tox-env: gallery-py313-upgraded , python-ver: "3.13", os: windows-latest } - { name: windows-gallery-python3.13-prerelease, test-tox-env: gallery-py313-prerelease, python-ver: "3.13", os: windows-latest } - - { name: macos-gallery-python3.9-minimum , test-tox-env: gallery-py39-minimum , python-ver: "3.9" , os: macos-13 } + - { name: macos-gallery-python3.10-minimum , test-tox-env: gallery-py310-minimum , python-ver: "3.10", os: macos-latest } - { name: macos-gallery-python3.13-upgraded , test-tox-env: gallery-py313-upgraded , python-ver: "3.13", os: macos-latest } - { name: macos-gallery-python3.13-prerelease , test-tox-env: gallery-py313-prerelease, python-ver: "3.13", os: macos-latest } steps: @@ -138,8 +135,7 @@ jobs: fail-fast: false matrix: include: - - { name: conda-linux-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } - - { name: conda-linux-python3.10 , test-tox-env: test-py310-pinned , build-tox-env: build-py310-pinned , python-ver: "3.10", os: ubuntu-latest } + - { name: conda-linux-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10", os: ubuntu-latest } - { name: conda-linux-python3.11 , test-tox-env: test-py311-pinned , build-tox-env: build-py311-pinned , python-ver: "3.11", os: ubuntu-latest } - { name: conda-linux-python3.12 , test-tox-env: test-py312-pinned , build-tox-env: build-py312-pinned , python-ver: "3.12", os: ubuntu-latest } - { name: conda-linux-python3.13 , test-tox-env: test-py313-pinned , build-tox-env: build-py313-pinned , python-ver: "3.13", os: ubuntu-latest } diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 3395bc07d..eae0adcc6 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -19,12 +19,12 @@ jobs: fail-fast: false matrix: include: - - { name: linux-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } + - { name: linux-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10" , os: ubuntu-latest } # NOTE config below with "upload-wheels: true" specifies that wheels should be uploaded as an artifact - { name: linux-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13", os: ubuntu-latest , upload-wheels: true } - - { name: windows-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: windows-latest } + - { name: windows-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10" , os: windows-latest } - { name: windows-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13", os: windows-latest } - - { name: macos-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: macos-13 } + - { name: macos-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10" , os: macos-13 } - { name: macos-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13" , os: macos-latest } steps: - name: Cancel non-latest runs @@ -79,9 +79,9 @@ jobs: fail-fast: false matrix: include: - - { name: linux-gallery-python3.9-minimum , test-tox-env: gallery-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } + - { name: linux-gallery-python3.10-minimum , test-tox-env: gallery-py310-minimum , python-ver: "3.10" , os: ubuntu-latest } - { name: linux-gallery-python3.13-upgraded , test-tox-env: gallery-py313-upgraded, python-ver: "3.13", os: ubuntu-latest } - - { name: windows-gallery-python3.9-minimum , test-tox-env: gallery-py39-minimum , python-ver: "3.9" , os: windows-latest } + - { name: windows-gallery-python3.10-minimum , test-tox-env: gallery-py310-minimum , python-ver: "3.10" , os: windows-latest } - { name: windows-gallery-python3.13-upgraded, test-tox-env: gallery-py313-upgraded, python-ver: "3.13", os: windows-latest } steps: - name: Cancel non-latest runs @@ -120,7 +120,7 @@ jobs: fail-fast: false matrix: include: - - { name: conda-linux-python3.9-minimum , test-tox-env: test-py39-minimum , build-tox-env: build-py39-minimum , python-ver: "3.9" , os: ubuntu-latest } + - { name: conda-linux-python3.10-minimum , test-tox-env: test-py310-minimum , build-tox-env: build-py310-minimum , python-ver: "3.10" , os: ubuntu-latest } - { name: conda-linux-python3.13-upgraded , test-tox-env: test-py313-upgraded , build-tox-env: build-py313-upgraded , python-ver: "3.13", os: ubuntu-latest } steps: - name: Cancel non-latest runs diff --git a/docs/source/install_developers.rst b/docs/source/install_developers.rst index cfc2c34e7..385960575 100644 --- a/docs/source/install_developers.rst +++ b/docs/source/install_developers.rst @@ -6,7 +6,7 @@ Installing PyNWB for Developers PyNWB has the following minimum requirements, which must be installed before you can get started using PyNWB. -#. Python 3.9, 3.10, 3.11, 3.12, or 3.13 +#. Python 3.10, 3.11, 3.12, or 3.13 #. pip @@ -54,11 +54,11 @@ Option 2: Using conda ^^^^^^^^^^^^^^^^^^^^^ First, install Anaconda_ to install the ``conda`` tool. Then create and -activate a new virtual environment called "venv" with Python 3.9 installed. +activate a new virtual environment called "venv" with Python 3.10 installed. .. code:: bash - conda create --name venv python=3.9 + conda create --name venv python=3.10 conda activate venv Similar to a virtual environment created with ``virtualenv``, a conda environment diff --git a/docs/source/install_users.rst b/docs/source/install_users.rst index 1bae5c754..fea91dfb5 100644 --- a/docs/source/install_users.rst +++ b/docs/source/install_users.rst @@ -6,7 +6,7 @@ Installing PyNWB PyNWB has the following minimum requirements, which must be installed before you can get started using PyNWB. -#. Python 3.9, 3.10, 3.11, 3.12, or 3.13 +#. Python 3.10, 3.11, 3.12, or 3.13 #. pip .. note:: If you are a developer then please see the :ref:`install_developers` installation instructions instead. @@ -53,5 +53,3 @@ own project against the latest version of PyNWB. .. code:: $ pip install -U pynwb --find-links https://github.com/NeurodataWithoutBorders/pynwb/releases/tag/latest --no-index - - diff --git a/pyproject.toml b/pyproject.toml index 3dcc45da2..c61a0a5e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,11 +14,10 @@ authors = [ ] description= "Package for working with Neurodata stored in the NWB format." readme = "README.rst" -requires-python = ">=3.9" +requires-python = ">=3.10" license = {text = "BSD-3-Clause"} classifiers = [ "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -122,4 +121,3 @@ line-length = 120 [tool.ruff.lint.mccabe] max-complexity = 17 - diff --git a/test_pynwb_io_nwbhdf5.h5 b/test_pynwb_io_nwbhdf5.h5 new file mode 100644 index 0000000000000000000000000000000000000000..0173c648bbf25f8b784672abcaba8c98e46ec472 GIT binary patch literal 187904 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 n= 22.0 [testenv] @@ -37,18 +37,18 @@ commands = [testenv:test-py313-upgraded] [testenv:test-py313-prerelease] [testenv:test-py311-optional-pinned] # some optional reqs not compatible with py312 yet -[testenv:test-py{39,310,311,312,313}-pinned] -[testenv:test-py39-minimum] +[testenv:test-py{310,311,312,313}-pinned] +[testenv:test-py310-minimum] [testenv:gallery-py313-upgraded] [testenv:gallery-py313-prerelease] [testenv:gallery-py311-optional-pinned] -[testenv:gallery-py{39,310,311,312,313}-pinned] -[testenv:gallery-py39-minimum] +[testenv:gallery-py{310,311,312,313}-pinned] +[testenv:gallery-py310-minimum] [testenv:build-py313-upgraded] [testenv:build-py313-prerelease] -[testenv:build-py{39,310,311,312,313}-pinned] # using tox for this so that we can have a clean build environment -[testenv:build-py39-minimum] +[testenv:build-py{310,311,312,313}-pinned] # using tox for this so that we can have a clean build environment +[testenv:build-py310-minimum] [testenv:wheelinstall] # use with `--installpkg dist/*-none-any.whl` From c1f46492a446c87af113565f4bb81887678ceaa5 Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 14:23:18 -0500 Subject: [PATCH 2/8] Update CHANGELOG to include deprecated Python 3.9 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f423afa37..a6822b6fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ - Fixed import structure test. @rly [#2136](https://github.com/NeurodataWithoutBorders/pynwb/pull/2136) ### Changed -- Change UI of documentation assistant to be an accordion that is always visible. @bendichter [#2124](https://github.com/NeurodataWithoutBorders/pynwb/pull/2124) +- Changed UI of documentation assistant to be an accordion that is always visible. @bendichter [#2124](https://github.com/NeurodataWithoutBorders/pynwb/pull/2124) +- Deprecated Python 3.9 support. (EOL was Oct 31, 2025) @bendichter [#2141](https://github.com/NeurodataWithoutBorders/pynwb/pull/2141) ## PyNWB 3.1.2 (August 13, 2025) From 33a7355784a6519f6c5ad26a380ca10c56ae6d5e Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 14:27:57 -0500 Subject: [PATCH 3/8] Remove Python 3.9 specific numpy version constraints from requirements --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - requirements.txt | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 6ba4a6998..aea445c48 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -61,7 +61,6 @@ body: label: Python Version options: - "lower version (unsupported)" - - "3.9" - "3.10" - "3.11" - "3.12" diff --git a/requirements.txt b/requirements.txt index 1ed2fcd75..3fde8e17c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,7 @@ # pinned dependencies to reproduce an entire development environment to use PyNWB h5py==3.12.1 hdmf==4.1.1 -numpy==2.1.1; python_version > "3.9" # numpy 2.1+ is not compatible with py3.9 -numpy==2.0.2; python_version == "3.9" +numpy==2.1.1 pandas==2.2.3 python-dateutil==2.9.0.post0 platformdirs==4.3.6 From f1a9f9bb543498f87aa8f88b95d388ffbfb6115d Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 15:07:13 -0500 Subject: [PATCH 4/8] Update minimum package versions in requirements-min.txt --- requirements-min.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-min.txt b/requirements-min.txt index 00e79597b..9ebd4539d 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,7 +1,7 @@ # minimum versions of package dependencies for installing PyNWB -h5py==3.2.0 +h5py==3.6.0 hdmf==4.1.1 numpy==1.24.0 -pandas==1.2.0 +pandas==1.3.0 python-dateutil==2.8.2 -platformdirs==4.1.0 \ No newline at end of file +platformdirs==4.1.0 From f67d0126600b469bfd744523da4134bb59baf555 Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 15:15:54 -0500 Subject: [PATCH 5/8] Update numpy and pandas versions in requirements-min.txt --- requirements-min.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-min.txt b/requirements-min.txt index 9ebd4539d..adf281d15 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,7 +1,7 @@ # minimum versions of package dependencies for installing PyNWB -h5py==3.6.0 +h5py==3.15.1 hdmf==4.1.1 -numpy==1.24.0 -pandas==1.3.0 +numpy==2.2.6 +pandas==2.3.3 python-dateutil==2.8.2 platformdirs==4.1.0 From 413d93f7c422f3843cbe8d39d20fab9839b3e61b Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 15:54:00 -0500 Subject: [PATCH 6/8] Apply suggestion from @stephprince Co-authored-by: Steph Prince <40640337+stephprince@users.noreply.github.com> --- requirements-min.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/requirements-min.txt b/requirements-min.txt index adf281d15..8ddf2cbfb 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -3,5 +3,9 @@ h5py==3.15.1 hdmf==4.1.1 numpy==2.2.6 pandas==2.3.3 +h5py==3.6.0 +hdmf==4.1.1 +numpy==1.24.0 +pandas==1.3.4 python-dateutil==2.8.2 platformdirs==4.1.0 From 7c5b15e63728543fc8475c8b083e3187124e4ca5 Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 15:56:47 -0500 Subject: [PATCH 7/8] Update package dependencies to latest compatible versions --- pyproject.toml | 6 +++--- requirements-min.txt | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c61a0a5e0..79f75cddb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,10 +32,10 @@ classifiers = [ "Topic :: Scientific/Engineering :: Medical Science Apps." ] dependencies = [ - "h5py>=3.2.0", - "hdmf>=4.1.0,<5", + "h5py>=3.6.0", + "hdmf>=4.1.1,<5", "numpy>=1.24.0", - "pandas>=1.2.0", + "pandas>=1.3.5", "python-dateutil>=2.8.2", "platformdirs>=4.1.0" ] diff --git a/requirements-min.txt b/requirements-min.txt index 8ddf2cbfb..ae0fd81ee 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,11 +1,7 @@ # minimum versions of package dependencies for installing PyNWB -h5py==3.15.1 -hdmf==4.1.1 -numpy==2.2.6 -pandas==2.3.3 h5py==3.6.0 hdmf==4.1.1 numpy==1.24.0 -pandas==1.3.4 +pandas==1.3.5 python-dateutil==2.8.2 platformdirs==4.1.0 From 0dc429c74656ed48806bbb78a23b23a60ee7c276 Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Mon, 3 Nov 2025 16:18:00 -0500 Subject: [PATCH 8/8] Update .github/workflows/generate_test_files.yml Co-authored-by: Steph Prince <40640337+stephprince@users.noreply.github.com> --- .github/workflows/generate_test_files.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate_test_files.yml b/.github/workflows/generate_test_files.yml index 3ef7700fe..27848909b 100644 --- a/.github/workflows/generate_test_files.yml +++ b/.github/workflows/generate_test_files.yml @@ -15,7 +15,7 @@ jobs: matrix: include: - { name: pynwb-1.5.1, pynwb-version: "1.5.1", python-version: "3.8"} - - { name: pynwb-2.1.0, pynwb-version: "2.1.0", python-version: "3.10"} + - { name: pynwb-2.1.0, pynwb-version: "2.1.0", python-version: "3.9"} steps: - uses: actions/checkout@v4 with: