Skip to content

Conversation

@sapols
Copy link
Contributor

@sapols sapols commented Jun 6, 2024

Overview

This is the initial draft of PHEP 3, which proposes adopting a Python version & upstream package support policy for the PyHC ecosystem, inspired by SPEC 0. The goal is to standardize the support duration for Python versions and popular packages across all PyHC packages, ensuring a balance between stability and the incorporation of new features.

Specifically, this PHEP recommend that projects:

  1. Support Python versions for at least 36 months (3 years) after their initial release.
  2. Support upstream core Scientific Python packages for at least 24 months (2 years) after their initial release.
  3. Adopt support for new versions of these dependencies within 6 months of their release.

The upstream core Scientific Python packages are: numpy, scipy, matplotlib, pandas, scikit-image, networkx, scikit-learn, xarray, ipython, zarr.

This policy aims to replace the current standard #11, which mandates only Python 3 support, with a more structured timeline that supports consistent and predictable maintenance across the community.

This closes #21.
This closes #20.

Renders

Rendered current text of the PHEP

Render of PHEP before scope was expanded to include upstream packages

Inspiration

This PHEP was inspired by the Python version support policies listed in:

Open questions and comments

  • There are no remaining open issues. (Dare I say it? 🫢)

Resolved questions and comments

  • We decided to use SPEC 0's 36-month policy instead of NEP 29's 42 months, because SPEC 0 officially supersedes NEP 29.
  • We decided this policy has to be a "should" not a "must."
  • We decided against a firm "drop" policy (e.g. requiring bumping python_requires to 3.X) in favor of softer language that allows packages to support older dependencies for longer if they want.
  • We decided to expand the scope of this PHEP to include upstream package support from SPEC 0, rather than save such a policy for a potential future PHEP (it originally only described a policy for minor versions of Python).
  • Use one line per sentence in the file to improve git diff/commentability

@sapols sapols changed the title Initial draft of new PHEP PHEP 3: PyHC Python Support Policy Jun 6, 2024
@sapols sapols marked this pull request as ready for review June 6, 2024 23:24
@jameswilburlewis
Copy link
Collaborator

jameswilburlewis commented Jun 7, 2024

For Python versions that age out of the proposed support window -- how firm is the expectation that package maintainers will drop support for the old Python release, in the case where there are no known incompatibilities? Could that take the form of documentation stating "Recommended Python version >= 3.X, but still works under Python 3.Y as of this writing", or would you want us to take more definitive action (bump python_requires to 3.X)? For example, if someone depends on a non-PyHC package that wants an older Python release, it could be a problem for them to upgrade Python to continue using PyHC packages.

I've read some of the discussion around NEP 29, and I see the merit in the arguments about "who's going to take the plunge first and bump their package requirements?", and general community cohesion and predictability. Just wondering what the repercussions might be, in the event one of these messy real-world edge cases collides with what is otherwise sound policy.

@sapols
Copy link
Contributor Author

sapols commented Jun 7, 2024

@jameswilburlewis that's an important question I'm wrestling with myself. I know some core packages like PlasmaPy and SunPy already go as far as bumping requires-python = ">=3.10" (as is strictly suggested in NEP 29). But I'm open to feedback here.

@jtniehof
Copy link
Contributor

Just commenting and not formal review yet, since I think we're a bit more in a "discussion" phase than wordsmithing.

As far as I can tell, PHEP 1 doesn't explicitly require the editor be distinct from the author, but I'd think it would generally be a good idea.

I'd like to suggest expanding the scope to close #21: packages probably should be able to think about Python and other dependencies in the same context even if the principles are slightly different. I appreciate trying to keep scope reasonable but these seem interconnected to me.

I really dislike the "everything not compulsory is forbidden" nature of SPEC 0. I don't think forcing our users to upgrade dependencies is a good idea. And given the difficulties with HelioCloud, we should probably err on being looser with "permitted" versions than tighter. This isn't something like Python 2 where a dedicated "kill the beast" plan was in order.

So here's the sort of thing I'd like to see:

  1. Packages must have a description of their dependency version policy, e.g. PlasmaPy, SpacePy
  2. Packages must support dependencies at least up to the timelines of SPEC 0, i.e. at the time a package version is released, it should support Python feature versions (x.y.0) released in the previous 36 months and feature versions of other dependencies released in the previous 24 months; for dependencies that do not use semantic versioning, simply versions released in the previous 24 months. (The specific numbers should be in this PHEP, with the note, as Shawn has, that it's inspired by SPEC 0).
  3. Packages may drop support immediately after those times, or may choose to continue support after, potentially in a reduced capacity.
  4. Packages that use semantic versioning should consider using their version number to indicate versions that drop support for older dependencies.
  5. There is no expectation (not even a "should") that a package "deprecate" an older dependency before dropping support for it.
  6. Packages must explicitly support (and test for) new versions of dependencies within six? twelve? months of their release. (This doesn't mean CI tests going into all eternity, just that it's been verified to work and will install).
  7. Packages which specify a maximum version number for dependencies must (terrible wording) use a carefully selected maximum, not merely specifying the current release as a maximum. (Also potentially some wording about being more aggressive about updating releases when dependencies are released?) Suggested policies include:
    a. Specifying the release after the current as the maximum, e.g. if numpy 1.26 is the current release, specify numpy<1.28. This should usually be reasonable if the package is clean of deprecation warnings and the dependency has a deprecation
    b. For dependencies using semantic versioning, specify a version that is likely to have breaking changes based on the version number, e.g. if numpy 1.26 is current, specify numpy<2.
    c. I'm sure people can come up with others
  8. Packages should test against release candidate versions of dependencies to facilitate support for future versions. Testing in CI is encouraged but ad-hoc testing is acceptable; testing against earlier pre-releases is also encouraged.

I can make edit suggestions to flow into Shawn's writing, but figured kicking the ideas around for a bit first would make sense. If any of these prove really controversial, we can just drop it out of the scope.

tldr: support for a reasonable about of time. Be clear to your users. Don't leave your package uninstallable.

@jtniehof jtniehof mentioned this pull request Jun 11, 2024
@nabobalis
Copy link

I really dislike the "everything not compulsory is forbidden" nature of SPEC 0. I don't think forcing our users to upgrade dependencies is a good idea. And given the difficulties with HelioCloud, we should probably err on being looser with "permitted" versions than tighter. This isn't something like Python 2 where a dedicated "kill the beast" plan was in order.

SPEC 0 is the high level plan from the broader scientific python community, I don't see the need to be seperate from that push, we rely on all of their packages. Reducing the scope of what we need to support reduces the burden on all package maintainers within PyHC.

We should also be telling users to create separate environments for each piece of work and that way can avoid pitfalls of updates breaking or messing with their current code or environment.

Packages must explicitly support (and test for) new versions of dependencies within six? twelve? months of their release. (This doesn't mean CI tests going into all eternity, just that it's been verified to work and will install).

Typically for sunpy since we test with upstream on a cron job schedule, we don't need to worry about at least a smaller subset of package updates.

We don't test the full suite so package updates that do break, will and do slip through, so we still have to patch and release at times for those.

The main bottleneck is typically new python versions since we have a large dependency stack and we need to wait for those to explicitly support that python version but we try to push towards 3-6 months after release. Thankfully more core packages are testing sooner with python versions and their RCs so that timeframe is getting shorter.

  1. Packages which specify a maximum version number for dependencies must (terrible wording) use a carefully selected maximum, not merely specifying the current release as a maximum. (Also potentially some wording about being more aggressive about updating releases when dependencies are released?) Suggested policies include:
    a. Specifying the release after the current as the maximum, e.g. if numpy 1.26 is the current release, specify numpy<1.28. This should usually be reasonable if the package is clean of deprecation warnings and the dependency has a deprecation
    b. For dependencies using semantic versioning, specify a version that is likely to have breaking changes based on the version number, e.g. if numpy 1.26 is current, specify numpy<2.
    c. I'm sure people can come up with others

I am hesitant to suggest max pinning of packages unless the package it self suggests it. In the numpy case due to their massive set of changes in the coming 2.0 release, it makes sense and it's pretty common in the sphinx world due how often they can break items in a release.

But in my view, pinning either a max or a specific version should be discouraged unless you have really specific requirements in your package.

  1. Packages should test against release candidate versions of dependencies to facilitate support for future versions. Testing in CI is encouraged but ad-hoc testing is acceptable; testing against earlier pre-releases is also encouraged.

Ideally packages should add something like weekly or monthly cron job to test with "main" version of the core set of dependencies they use. Won't need to be all of them but it should at least cover the install dependencies.

I don't think that adhoc testing is good enough for this, especially with how fast the python ecosystem moves.

@sapols
Copy link
Contributor Author

sapols commented Jun 13, 2024

Thank you for the thoughtful comments, @jtniehof. And I appreciate the view from SunPy, @nabobalis! To what @jtniehof said, I definitely think it's best for PyHC's long-term success if we adopt the dependency version policy from SPEC 0. I was gonna push for it eventually, so I started questioning now whether it should be in scope for this PHEP. If people are game I'd like to include it here, but if it'll be a point of contention I'm more on the fence. I like your ideas though, especially having packages explicitly document their version policies. I plan to lead a discussion about this at Monday's telecon where hopefully I can start to get a sense of community consensus. If people seem onboard, I'd welcome and appreciate your edit suggestions. Let's see how people feel in the telecon then go from there?

UPDATE: there ended up not being time to discuss this PHEP last telecon, so we'll have that discussion next telecon in two weeks instead.

Comment on lines 64 to 67
This new policy replaces the current standard [#11](https://github.com/heliophysicsPy/standards/blob/main/standards.md#standards) in the PyHC standards document with the following new text:

> **11. Python and Upstream Package Support:** All packages should support minor Python versions released within the last 36 months (3 years) and upstream core Scientific Python packages released within the last 24 months (2 years).
Additionally, packages should support new versions within 6 months of their release (see [PHEP 3](https://github.com/heliophysicsPy/standards/pull/29)).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this? This PHEP replaces standard 11, it doesn't create new text for it. 11 would just go away and people just need to comply with PHEP3 instead of Standard 11.

This is an excellent summary text for a potential summary document, though.

(Sorry I missed this earlier.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna say yes we need this. For now, the old standards doc is still PyHC's official standards and I will replace the text of standard 11 in that doc with what's written here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss in the morning how we want to handle this; fortunately that's before the PHEP3 vote :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sapols I like referencing the PHEP from the standards, but do we want the link to be to the PR discussion, to the PHEPs page on the website, to the .md blob in the repo, or to the Zenodo DOI?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably the Zenodo DOI for maximum stability. I just put the PR link there first since it's all we have currently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of us can start the Zenodo record and reserve the DOI. Since I did that process for 1 and 2, maybe we should work together (on a Zoom maybe?) so we're more than one deep, and can make sure the instructions are clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtniehof I should be more familiar with that process than I am; a Zoom would be handy. Are you saying it's possible to "start" the Zenodo record and reserve the DOI before we have an official document to upload?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you can reserve a DOI. I'll loop in on scheduling a time to tag up.

@jtniehof
Copy link
Contributor

jtniehof commented Jun 3, 2025

We should also note: passed first vote at the fall meeting.

@sapols
Copy link
Contributor Author

sapols commented Jun 11, 2025

Note: per this comment in issue 39, we should add to the top of the Standards Doc: "Updates to this document are managed via the PHEP process" when we merge this.

@sapols
Copy link
Contributor Author

sapols commented Jun 18, 2025

Note to self: the Gantt chart in here is quite outdated now; update it.
UPDATE: Gantt chart updated in latest commit.

Note to self: staged the updates we'll have to make once this gets accepted to this file here and started a draft Zenodo record.

@namurphy
Copy link
Contributor

I've been working on a side project (namurphy/bump-minimum-dependencies) to automate SPEC 0 updates to packages. This command line tool drops support for minor releases (e.g., x.y) that were released more than $N_\mbox{drop}$ months ago, with the restriction that the minimum minor release has to be at least $N_{cooldown}$ months old. It'll preserve more restrictive requirements.

The tool is mostly working but but needs some cleaning up, more tests, and better docs before doing a v0.1.0 release. There are some edge cases that it can't yet handle due to some limitations of dep_logic, like when the resulting requirement has != specifiers or multiple ranges. After that, I'm hoping to create a GitHub action that will automate monthly pull requests that do these updates.

I'd also like this to be put under the umbrella of a GitHub organization so that I'm not the only maintainer. Perhaps this one? 🤔 @sapols

This tool needn't be mentioned in PHEP 3, but would simplify the process of making SPEC 0 & PHEP 3 updates.

Important

Once again, behold the power of procrastination-driven development! 🎉🎂💖🎆🪩🌌🥦😹

@nabobalis
Copy link

nabobalis commented Nov 18, 2025

W> I've been working on a side project (namurphy/bump-minimum-dependencies) to automate SPEC 0 updates to packages. This command line tool drops support for minor releases (e.g., x.y) that were released more than $N_\mbox{drop}$ months ago, with the restriction that the minimum minor release has to be at least $N_{cooldown}$ months old. It'll preserve more restrictive requirements.

The tool is mostly working but but needs some cleaning up, more tests, and better docs before doing a v0.1.0 release. There are some edge cases that it can't yet handle due to some limitations of dep_logic, like when the resulting requirement has != specifiers or multiple ranges. After that, I'm hoping to create a GitHub action that will automate monthly pull requests that do these updates.

I'd also like this to be put under the umbrella of a GitHub organization so that I'm not the only maintainer. Perhaps this one? 🤔 @sapols

This tool needn't be mentioned in PHEP 3, but would simplify the process of making SPEC 0 & PHEP 3 updates.

[!IMPORTANT]
Once again, behold the power of procrastination-driven development! 🎉🎂💖🎆🪩🌌🥦😹

Yeah Scientific Python also just created an action for this https://github.com/scientific-python/spec0-action/tree/v1 and so did mne-tools/mne-python#13451

Hopefully we can come to one solution in the future.

Copy link

@jibarnum jibarnum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approve PHEP 3's second vote!

Copy link
Contributor

@jtniehof jtniehof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved! The pre commit CI requires some trailing whitespace trimmed, but that is not substantive.

@namurphy
Copy link
Contributor

namurphy commented Nov 20, 2025

pre-commit.ci autofix ← didn't work since I don't have write access

Copy link

@FreddyCruz FreddyCruz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me.

Copy link

@jvandegriff jvandegriff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems good to keep us in line with common dependency expectations

@jibarnum
Copy link

One abstain from the meeting

@sapols sapols merged commit cc55a07 into main Dec 2, 2025
1 check failed
@sapols sapols deleted the phep-3 branch December 2, 2025 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet