From cdec8b38eb3c92fa6a5db3d41690006b26535394 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 18:51:23 +0200 Subject: [PATCH 1/6] .gitignore: Ignore hatch-vcs _version.py file --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c29453a6..a04bd25f 100644 --- a/.gitignore +++ b/.gitignore @@ -89,3 +89,6 @@ venv.bak/ # MacOS Finder .DS_Store + +# hatch-vcs +ipfx/_version.py From 54cafc49f51202c2c254928b170322975f2c2a03 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 16:04:16 +0200 Subject: [PATCH 2/6] pyproject.toml: Add it Created with hatch new --init. --- pyproject.toml | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..6f358701 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,63 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "IPFX" +dynamic = ["version"] +description = "Intrinsic Physiology Feature Extractor (IPFX) - tool for computing neuronal features from the intracellular electrophysiological recordings" +readme = "README.md" +license = "" +authors = [ + { name = "Allen Institute for Brain Science", email = "Marmot@AllenInstitute.onmicrosoft.com" }, +] +keywords = [ + "bioinformatics", + "neuroscience", + "scientific", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "License :: Other/Proprietary License", + "Natural Language :: English", + "Operating System :: OS Independent", + "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 :: Bio-Informatics", +] +dependencies = [ + "argschema", + "dictdiffer", + "h5py", + "marshmallow", + "matplotlib", + "methodtools", + "numpy", + "pandas", + "pg8000", + "pillow", + "pyabf", + "pynwb==3.1.2", + "pyYAML", + "python-dateutil", + "ruamel.yaml<0.18.0", + "scipy", + "simplejson", + "watchdog", +] + +[project.urls] +Homepage = "https://github.com/AllenInstitute/ipfx" + +[tool.hatch.version] +path = "ipfx/__init__.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/ipfx", +] From dd03ec8b7d10bf5cff84ae716b5a99478ba26251 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 16:45:58 +0200 Subject: [PATCH 3/6] Move to pyproject.toml packaging The new way of packaging in python is based on pyproject.toml. This allows us to have only one file defining the package properties instead of three. We also switch to hatch instead of setuptools. And the version number is now gathered from git instead of being hardcoded in ipfx/version.txt. The new source package (sdist) has the following differences: - We don't ship the tests folder anymore. It is not usable without datafiles anyway and including them would require ~250MB of disc space. - `ipfx/version.txt` is gone as the version is now gathered from git with the build-time created `ipfx/_version.py` - No more IPFX.egg-info/MANIFEST.in/setup.cfg/setup.py but only pyproject.toml - Added missing files in docs The wheel is now different in the following regard: - It is not an universal wheel anymore as Python 2 support is already long gone - No more `*dist-info` folder as we are now packaging with hatch, the files LICENSE and AUTHORS.rst are therefore manually included - Same comment regarding `ipfx/version.txt` as in the sdist The flake8 configuration can not be included in pyproject.toml, see https://github.com/PyCQA/flake8/issues/234. It will also be replaced by another linter in a future commit. --- MANIFEST.in | 12 -------- ipfx/__init__.py | 6 +--- ipfx/version.txt | 1 - pyproject.toml | 46 +++++++++++++++++++++++++--- pytest.ini | 14 --------- setup.cfg | 6 ---- setup.py | 80 ------------------------------------------------ 7 files changed, 43 insertions(+), 122 deletions(-) delete mode 100644 MANIFEST.in delete mode 100755 ipfx/version.txt delete mode 100644 pytest.ini delete mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 1db431d4..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,12 +0,0 @@ -include requirements.txt -include requirements-test.txt -include AUTHORS.rst -include CHANGELOG.md -include README.md - -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] - -recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif - -recursive-include ipfx *.json *.txt *.md *.csv diff --git a/ipfx/__init__.py b/ipfx/__init__.py index d4af3b0a..dde91335 100644 --- a/ipfx/__init__.py +++ b/ipfx/__init__.py @@ -1,10 +1,6 @@ # -*- coding: utf-8 -*- """Top-level package for ipfx.""" -import os +from ._version import __version__ __author__ = """Allen Institute for Brain Science""" - -version_file_path = os.path.join(os.path.dirname(__file__), "version.txt") -with open(version_file_path, "r") as version_file: - __version__ = version_file.read() diff --git a/ipfx/version.txt b/ipfx/version.txt deleted file mode 100755 index 7ec1d6db..00000000 --- a/ipfx/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.1.0 diff --git a/pyproject.toml b/pyproject.toml index 6f358701..0ca68037 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["hatchling"] +requires = ["hatchling >= 1.27", "hatch-vcs"] build-backend = "hatchling.build" [project] @@ -7,15 +7,20 @@ name = "IPFX" dynamic = ["version"] description = "Intrinsic Physiology Feature Extractor (IPFX) - tool for computing neuronal features from the intracellular electrophysiological recordings" readme = "README.md" -license = "" +license = "LicenseRef-Proprietary" +license-files = ["LICENSE"] authors = [ { name = "Allen Institute for Brain Science", email = "Marmot@AllenInstitute.onmicrosoft.com" }, ] + +requires-python = ">= 3.9" + keywords = [ "bioinformatics", "neuroscience", "scientific", ] + classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Science/Research", @@ -30,6 +35,8 @@ classifiers = [ "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering :: Bio-Informatics", ] + +# https://github.com/repo-helper/hatch-requirements-txt looks promising but seems unmaintained dependencies = [ "argschema", "dictdiffer", @@ -53,11 +60,42 @@ dependencies = [ [project.urls] Homepage = "https://github.com/AllenInstitute/ipfx" +Documentation = "https://ipfx.readthedocs.io/en/latest/" +"Bug Tracker" = "https://github.com/AllenInstitute/ipfx/issues" +Changelog = "https://github.com/AllenInstitute/ipfx/blob/master/CHANGELOG.md" [tool.hatch.version] -path = "ipfx/__init__.py" +source = "vcs" + +[tool.hatch.build.hooks.vcs] +version-file = "ipfx/_version.py" [tool.hatch.build.targets.sdist] include = [ "/ipfx", -] + "/docs", + "requirements.txt", + "requirements-test.txt", + "AUTHORS.rst", + "CHANGELOG.md", + "README.md"] +exclude = ["/ipfx/bin/*.sh", "docker", "test", ".flake8"] + +[tool.hatch.build.targets.wheel] +include = [ + "/ipfx", + "AUTHORS.rst", + "LICENSE"] +exclude = ["/ipfx/bin/*.sh", "docs", "docker", "test", ".flake8"] + +[tool.pytest.ini_options] +addopts = "--junitxml=test-reports/test.xml" +markers = ["slow: slow tests", + "requires_lims: require connection to LIMS", + "requires_inhouse_data: require inhouse data"] +filterwarnings = ["error", + "ignore:add_child is deprecated. Set the parent attribute instead.:DeprecationWarning", + "ignore::marshmallow.warnings.RemovedInMarshmallow4Warning", + "ignore::marshmallow.warnings.ChangedInMarshmallow4Warning", + "ignore:scipy.misc is deprecated and will be removed in 2.0.0", + "ignore:.*behaviour will change in pandas 3.0!.*:FutureWarning"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index a68d124f..00000000 --- a/pytest.ini +++ /dev/null @@ -1,14 +0,0 @@ -[pytest] - -markers = - slow: slow tests - requires_lims: require connection to LIMS - requires_inhouse_data: require inhouse data - -filterwarnings = - error - ignore:add_child is deprecated. Set the parent attribute instead.:DeprecationWarning - ignore::marshmallow.warnings.RemovedInMarshmallow4Warning - ignore::marshmallow.warnings.ChangedInMarshmallow4Warning - ignore:scipy.misc is deprecated and will be removed in 2.0.0 - ignore:.*behaviour will change in pandas 3.0!.*:FutureWarning diff --git a/setup.cfg b/setup.cfg index 8cf23bad..7dcd8371 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,2 @@ -[bdist_wheel] -universal = 1 - [flake8] exclude = docs - -[tool:pytest] -addopts = --junitxml=test-reports/test.xml diff --git a/setup.py b/setup.py deleted file mode 100644 index 1b7eb848..00000000 --- a/setup.py +++ /dev/null @@ -1,80 +0,0 @@ -import os -from setuptools import setup, find_packages -from distutils.cmd import Command -import glob - -with open("requirements.txt", "r") as requirements_file: - required = requirements_file.read().splitlines() - -version_file_path = os.path.join( - os.path.dirname(__file__), - "ipfx", - "version.txt" -) -with open(version_file_path, "r") as version_file: - version = version_file.readline().strip() - - -readme_path = os.path.join( - os.path.dirname(__file__), - "README.md" -) -with open(readme_path, "r") as readme_file: - readme = readme_file.read() - - -class CheckVersionCommand(Command): - description = ( - "Check that this package's version matches a user-supplied version" - ) - user_options = [ - ('expected-version=', "e", 'Compare package version against this value') - ] - - def initialize_options(self): - self.package_version = version - self.expected_version = None - - def finalize_options(self): - assert self.expected_version is not None - if self.expected_version[0] == "v": - self.expected_version = self.expected_version[1:] - - def run(self): - if self.expected_version != self.package_version: - raise ValueError( - f"expected version {self.expected_version}, but this package " - f"has version {self.package_version}" - ) - - -setup( - name='IPFX', - version=version, - description="""Intrinsic Physiology Feature Extractor (IPFX) - tool for computing neuronal features from the intracellular electrophysiological recordings""", - long_description=readme, - long_description_content_type='text/markdown', - author="Allen Institute for Brain Science", - author_email="Marmot@AllenInstitute.onmicrosoft.com", - url="https://github.com/AllenInstitute/ipfx", - packages=find_packages(exclude=["tests", "tests.*"]), - install_requires=required, - include_package_data=True, - setup_requires=['pytest-runner'], - keywords=["neuroscience", "bioinformatics", "scientific"], - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "License :: Other/Proprietary License", # Allen Institute Software License - "Natural Language :: English", - "Operating System :: OS Independent", - "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 :: Bio-Informatics" - ], - cmdclass={'check_version': CheckVersionCommand} -) From b1aa9b93ccff9d43306b6b65332e95439e5732db Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 19:41:37 +0200 Subject: [PATCH 4/6] pyproject.toml: Add requirements-docs.txt And also standardize on dashes like we do for test. --- .readthedocs.yml | 2 +- pyproject.toml | 1 + requirements_docs.txt => requirements-docs.txt | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename requirements_docs.txt => requirements-docs.txt (100%) diff --git a/.readthedocs.yml b/.readthedocs.yml index fa4c70e7..e0614d57 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,7 +10,7 @@ sphinx: python: version: 3.6 install: - - requirements: requirements_docs.txt + - requirements: requirements-docs.txt - requirements: requirements.txt formats: diff --git a/pyproject.toml b/pyproject.toml index 0ca68037..1843ffc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,6 +76,7 @@ include = [ "/docs", "requirements.txt", "requirements-test.txt", + "requirements-docs.txt", "AUTHORS.rst", "CHANGELOG.md", "README.md"] diff --git a/requirements_docs.txt b/requirements-docs.txt similarity index 100% rename from requirements_docs.txt rename to requirements-docs.txt From fb21e4329fbb89d422cb4accc5572c15c6318d85 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 19:47:33 +0200 Subject: [PATCH 5/6] RELEASE_INSTRUCTIONS.md: Update them We don't use a dev branch anymore and also version.txt is gone. Mention also the switch from setuptools to hatch. --- RELEASE_INSTRUCTIONS.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/RELEASE_INSTRUCTIONS.md b/RELEASE_INSTRUCTIONS.md index 486fad5d..2e748e32 100644 --- a/RELEASE_INSTRUCTIONS.md +++ b/RELEASE_INSTRUCTIONS.md @@ -5,12 +5,11 @@ or a predetermined release date is approaching ## GitHub - [ ] Assign a developer to be responsible for the release deployment -- [ ] Create a release branch from dev +- [ ] Create a release branch from master - [ ] Create a draft pull request for the release - [ ] Add the Project Owner as a reviewer - [ ] Copy this checklist into the draft pull request description - [ ] Prepare the official release commit - - [ ] Bump version in the version.txt - [ ] Move changes from the "Unreleased" section to the proper sections in the CHANGELOG.md - [ ] Confirm all GitHub Actions tests pass - [ ] Change the draft to pull request to "ready for review" @@ -24,11 +23,9 @@ or a predetermined release date is approaching ### PyPI and BKP -- [ ] Reconfirm the version is correct in `version.txt` -- [ ] Set release version with "git tag v#.#.#" (e.g. "git tag v1.0.0", equivalent to the version you bumped to), this triggers circleci to publish ipfx to PyPI (deprecated, need to move to GitHub Actions) -- [ ] After release/deployment, merge master branch (bug fixes, document generation, etc.) back into dev and delete the release branch +- [ ] Set release version with "git tag v#.#.#" (e.g. "git tag v1.0.0"), this triggers circleci to publish ipfx to PyPI (deprecated, need to move to GitHub Actions) - [ ] Build and deploy: - - [ ] `python setup.py sdist` and `python setup.py bdist_wheel` + - [ ] `hatch build` - [ ] `twine upload dist/* --verbose --config-file ~/.pypirc` - [ ] Announce release on https://community.brain-map.org From 7ce45c40a491178f12f42699615955da99d7769c Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 8 Aug 2025 21:02:11 +0200 Subject: [PATCH 6/6] .github/workflows: Install ipfx as editable package Only this creates ipfx/_version.py. --- .github/workflows/github-actions-ci.yml | 1 + docker/run_tests_with_docker.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/github-actions-ci.yml b/.github/workflows/github-actions-ci.yml index 20c72982..e18c8c2d 100644 --- a/.github/workflows/github-actions-ci.yml +++ b/.github/workflows/github-actions-ci.yml @@ -44,6 +44,7 @@ jobs: git config lfs.url 'https://github.com/AllenInstitute/ipfx.git/info/lfs' git lfs env git lfs pull + pip install -e . python -m pytest --junitxml=test-results/junit.xml --verbose diff --git a/docker/run_tests_with_docker.sh b/docker/run_tests_with_docker.sh index 92cd9d40..412d615b 100755 --- a/docker/run_tests_with_docker.sh +++ b/docker/run_tests_with_docker.sh @@ -27,4 +27,5 @@ docker run git config lfs.url 'https://github.com/AllenInstitute/ipfx.git/info/lfs'; \ git lfs env; \ git lfs pull; \ + pip install -e .; \ python -m pytest --junitxml=test-reports/test.xml --verbose"