Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APE 21: APE on ending long term support releases + Updates to APE 2 to reflect new release cycle without LTS #82

Merged
merged 23 commits into from
May 31, 2023

Conversation

astrofrog
Copy link
Member

@astrofrog astrofrog commented Feb 16, 2023

This is a draft and not ready for review - it follows the related discussion on astropy-dev. If you are interested in joining as a co-author please ping me!

  • Rename file to APE_21.rst

EDIT: Close #20

Copy link
Member

@pllim pllim left a comment

Choose a reason for hiding this comment

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

I think we have to rename this file to APE_21.rst. Otherwise, the file listing will hurt my head going forward.

I think this is going to supersede #20 , so the proposed addenda there by @mhvk needs to be addressed here as well, if not already.

Why the preference on single-quote over double-quote in the text?

APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated Show resolved Hide resolved
APE_LTS.rst Outdated
Alternatives
------------

If there were any alternative solutions to solving the same problem, they should
Copy link
Member

Choose a reason for hiding this comment

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

Is this just a placeholder text?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes

APE_LTS.rst Outdated
Decision rationale
------------------

<To be filled in by the coordinating committee when the APE is accepted or rejected>
Copy link
Member

Choose a reason for hiding this comment

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

Being the coauthor and current CoCo member, I would recuse myself from CoCo discussions regarding this APE.

@pllim pllim changed the title APE on ending long term support releases APE 21: APE on ending long term support releases Feb 20, 2023
@mhvk
Copy link
Contributor

mhvk commented Feb 21, 2023

Had a quick look and liked this! Agreed that it will be important to be very clear about minor and major. After reading this, and my original proposed addendum to #20, I think the proposal is:

  • Minor releases mostly should add things and can, if needed, deprecate things. Generally, existing code should continue to work (with possible filtering of warnings), so little if anything should be removed..
  • Major releases are the same but can also remove deprecated features. So, existing code may need to be adjusted (but would have had ample warning).

Is this correct? Perhaps good to give examples. E.g., "existing code should continue to work" probably should not include that every repr remains the same, or every number exactly identical. But it would include not changing API.

@astrofrog
Copy link
Member Author

@mhvk - I agree with your assessment, I think we basically have to decide on guidelines for those exceptions of things that can change in a minor release that might be considered as 'breaking'. Things that are borderline would include:

  1. Changes in warning messages
  2. Changes in exception messages or exception types
  3. Removing functionality that was not really intended to ever be public and is probably not used (for example some random function deep in astropy.utils that is not technically private)
  4. Fixing recent API 'bugs'/mistakes that would be easier fixed sooner rather than later if it can't be fixed via a regular deprecation

Anything else?

I think something related to this APE that we don't have to necessarily figure out here but that we could mention briefly is that if we are going to have rules like this we should also be clearer on what is public API - anything tab-discoverable? Anything in the API docs in docs.astropy.org? (those two don't necessarily match currently though I think I saw @nstarman mention something about public API in another PR). Defining what is public API could almost be a separate APE.

astrofrog and others added 2 commits February 21, 2023 09:43
Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com>
Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com>
@mhvk
Copy link
Contributor

mhvk commented Feb 21, 2023

I think all four are fine in minor releases -- certainly exception and warning messages (I think it is fine to break people's tests if those are so detailed they check messages, just not to break actual code!).

But very good point about public API. The most narrow (and probably best) definition is that it is only includes thinkgs exposed at the top level of astropy's submodules (with a few exceptions in utils like iers and masked). But you're right, this is probably another APE, with the main goal to actually document our current behaviour!

@pllim
Copy link
Member

pllim commented Feb 21, 2023

How many will cry if I change astropy.utils to astropy._utils in v6.0? 😝

@pllim
Copy link
Member

pllim commented Feb 21, 2023

Why are we avoiding double quotes? I thought English prefers double quotes and you only use single quotes if you have to quote inside text that is already in double quotes?

@astrofrog
Copy link
Member Author

astrofrog commented Feb 21, 2023

Happy to change to double quotes! Can we just run black on the APE? 😛 Feel free to push a commit to fix this if you have time 😄

@pllim
Copy link
Member

pllim commented Feb 21, 2023

@astrofrog , I took some liberties in 22c9073 , feel free to revert the changes you don't agree with. Thanks!

@nstarman
Copy link
Member

nstarman commented Feb 21, 2023

I think something related to this APE that we don't have to necessarily figure out here but that we could mention briefly is that if we are going to have rules like this we should also be clearer on what is public API - anything tab-discoverable? Anything in the API docs in docs.astropy.org? (those two don't necessarily match currently though I think I saw @nstarman mention something about public API in another PR). Defining what is public API could almost be a separate APE.

I would propose we adopt the PEP8 standard (https://peps.python.org/pep-0008/#public-and-internal-interfaces) and the typing guidelines (https://github.com/python/typing/blob/master/docs/source/libraries.rst#library-interface-public-and-private-symbols). The latter offers some small refinements to the former, namely to ensure that analyzers, static and dynamic, can easily understand what is public and help users with better tab autocomplete / code snippets / generative code, etc. In short what we need to do is define __all__ in every module indicating what is public in that module. For the most part this is having a full __all__ at the top-level __init__.py of each sub-package and empty __all__ everywhere else. Technically, PEP8 suggests that we also rename modules to have a leading underscore.

@mhvk
Copy link
Contributor

mhvk commented Feb 21, 2023

Hmm, those texts are helpful but not quite conclusive -- or at least I can read it in ways that I'm fairly sure are different from other's! Anyway, to me it sounds like if in a submodule's __init__ we do not import the actual subsubmodules (say, in coordinates.__init__, we import from representations, but not representations itself), then we basically are OK (especially if we also define an __init__.__all__). And that in units, .si is a public module since we import it in .__init__ (which may not be what we want, so we do need to define __all__ there).

I guess the only part to then clarify is that a subsubmodule should only define things in __all__ that are actually imported in the submodule proper.

p.s. Probably should move this to a different thread; sorry!

@pllim
Copy link
Member

pllim commented Feb 22, 2023

@astrofrog , is your plan to discuss this APE at the Coordination Meeting?

@astrofrog
Copy link
Member Author

Yes but only if we can't agree on it sooner!

@saimn
Copy link

saimn commented Feb 23, 2023

I like the proposal for several reasons:

  • the meaning of version numbers should be easier to understand for users (in contrast to LTS where people may hesitate on which version to use)
  • users are more likely to update to the latest minor version since it should not break their code
  • for people that were using LTS, they can update to the latest minor version and get new features more rapidly

The difficult point is how to define an API break. Tom gave some examples in #82 (comment), are changes to exception or warning messages API breaks ? IMO It's hard to define strict rules here, it depends on the impact of a change, if the code that is changed is widely used or not etc. So when reviewing PRs maintainers will need to think if something is likely to break other people's code.

There are cases where breaking the API is needed to fix a bug, depending on the impact some may be fixable in minor versions, other may have to wait for major versions with a deprecation path. I like pandas' note about this:
https://pandas.pydata.org/docs/development/policies.html#policies-version

pandas will sometimes make behavior changing bug fixes, as part of minor or patch releases. Whether or not a change is a bug fix or an API-breaking change is a judgement call

(And I like the way they have written their policy, it's simple so easily understandable by users)

Also we probably need a way to track deprecations so we know what changes need to be done in major versions ?
And I think the discussion about public API is not relevant here, it's an interesting one but it should be discussed somewhere else. Here the focus is on how to handle deprecations, and how to provide to users new versions with some guarantees of stability.

APE21.rst Outdated
This APE proposes the following:

* No longer designate any releases as LTS.
* Keep the 6-month release cycle and bump releases to x.0 every 2 years.
Copy link

Choose a reason for hiding this comment

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

Maybe make the two years period more flexible ? 2 years still seems a good period in general but it may make sense sometimes to wait a bit more before publishing a new major version. And with the new scheme delaying a new major version has no consequences.

Copy link
Member

Choose a reason for hiding this comment

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

But this also means that if someone wants a new thing that will totally break API, they have to wait 2 years? Do we not merge that PR for 2 years?

Copy link

Choose a reason for hiding this comment

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

Yeah indeed. This case should hopefully not happen too often, but we could imagine releasing a major version only 1/1.5 year after the previous one on exceptional circumstances ? But in general if there is a need to totally break the API there should be a long enough period of time before that with deprecation warnings, so the 2 years cycle seem realistic.

Copy link
Member

Choose a reason for hiding this comment

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

It's worth noting that with a fixed 2-year cycle, some API changes might wait 1.9 years, and others might be merged 1 week before the deadline.

There would tend to be a bias (maybe strong?) toward the major version feature freeze deadline, because folks might have an idea and want to get it in knowing that it will be another 2 years otherwise. Something to consider!

Copy link

Choose a reason for hiding this comment

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

Yes, that's why I think we should keep some flexibility in the 2 years cycle.
But also before a breaking change appears in a major release, there should be deprecations in a previous minor release. So major release are not the time to merge anything just because we can break things in this release, we should plan beforehand what major changes are waiting, if deprecations have been released, for how long, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree with @taldcroft here. The most annoying numpy changes we have had to deal with are things that are merged just before the release and hence we didn't catch them in -dev.

Would it be an idea to freeze further ahead of a major release? With perhaps more advertising to test the corresponding -rc?

Alternatively (or additionally), maybe the way to do this is to be more flexible about when major releases happen, and decide on whether the next release will be major ~mid-way between releases, based on what is already ready there and what is being planned (with perhaps an astropy-dev mailing to ask what people are planning).

Part of this might also be to follow pandas' example and really make sure API changes are explained and work-arounds given.

One practical question: how is it going to work with major items? Are they just going to sit on as PR requests for ~1 year? Or is there a separate branch? As long as new features are OK for minor releases, I don't think this is a super-big issue, but probably should be discussed in the document!

Copy link
Contributor

Choose a reason for hiding this comment

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

Should have read @saimn's message - agreed that if the cycle is flexible and we insist (as we should) that breaking changes have deprecation periods, that solves most of the problems.

Copy link

Choose a reason for hiding this comment

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

One practical question: how is it going to work with major items? Are they just going to sit on as PR requests for ~1 year? Or is there a separate branch? As long as new features are OK for minor releases, I don't think this is a super-big issue, but probably should be discussed in the document!

Yes new features are OK for minor releases. It's just the ones that break the API that should wait, with deprecation added in between. And that should be a minority of the PRs hopefully, so I guess we can just milestone them for the next major release and rebase when we start the major release cycle. Another way would be to have a "future" branch but if there are conflicts it will be more painful to resolve them compared to doing that for each PR.

@mhvk
Copy link
Contributor

mhvk commented Feb 23, 2023

Agreed that the pandas wording is very nice & clear. I suggest we use it! I think the main trick is in defining what API is. In my opinion, how something is typeset (repr) or worded is not included in the API (for a minor release), so the wording of an error message is not, but the structure/type/behaviour of an object or the exception type is part of the API.

@taldcroft
Copy link
Member

taldcroft commented Feb 23, 2023

so the wording of an error message is not [in the API]

The problem is that the wording of an error message is very commonly used in tests, and sometimes used in application code. So these kind of changes can certainly break downstream code, and it once again comes down to an assessment of impact.

The only way out of this I can think of is to have some policy for advertising API changes and getting a wider review. For instance, if a PR has a change that has the potential to break application code or break other package tests, then it could be brought to the attention of astropy-dev. E.g. an email with a subject like Astropy PR #yyy API change for review, with some text describing the potential impact. Allow a minimum 2-week period for review prior to accepting the PR. That extra layer of review would also serve as a reminder to developers that API changes should be avoided when possible.

The "potential for breakage" bar should be set pretty low since we aren't stopping any change from happening, but doing our best to ensure that the community is aware of a change in advance. Definitely warning and error message changes would apply.

@WilliamJamieson
Copy link

The only way out of this I can think of is to have some policy for advertising API changes and getting a wider review. For instance, if a PR has a change that has the potential to break application code or break other package tests, then it could be brought to the attention of astropy-dev. E.g. an email with a subject like Astropy PR #yyy API change for review, with some text describing the potential impact. Allow a minimum 2-week period for review prior to accepting the PR. That extra layer of review would also serve as a reminder to developers that API changes should be avoided when possible.

On top of this I think we should explicitly encourage maintainers of downstream packages to run their tests against the development version of astropy regularly (with some suggestion of what regularly means).

@mhvk
Copy link
Contributor

mhvk commented Feb 23, 2023

Agreed that we should encourage people to test against astropy-dev.

I do want to push a bit more to keep the freedom to change formats or error messages in minor releases. If people rely on details like that (presumably mostly in doctests), then I think it is fair to ask them to adjust, just like we adjust when numpy changes its output format (and, yes, sometimes that is painful, but definitely OK for a minor release).

On error and warning messages specifically, in astropy we check those internally just to ensure we actually raise the right error, but really why would anyone rely on those outside of astropy? I don't think we have any place where we specifically look for the text of an external error or warning. And it does seem one should be free to correct or clarify exception texts, certainly in a minor release, arguably even in a bug-fix release.

Anyway, I really hope we can keep things more or less like they are for minor releases!

@WilliamJamieson
Copy link

On error and warning messages specifically, in astropy we check those internally just to ensure we actually raise the right error, but really why would anyone rely on those outside of astropy? I don't think we have any place where we specifically look for the text of an external error or warning. And it does seem one should be free to correct or clarify exception texts, certainly in a minor release, arguably even in a bug-fix release.

Hypothetically, someone could be using error messages to distinguish between errors they can handle and those they cannot. Although in that case we really ought to be using a custom error class to make it easier on those use cases (they should report that behavior to us anyways).

@mhvk
Copy link
Contributor

mhvk commented Feb 23, 2023

Agreed that for that case we should have different error types (like we introduced UnitTypeError and UnitConversionError at some point -- though I think that was mostly for internal use).

One conclusion from that is that it is good to strongly encourage people to give feedback when things break!

@saimn
Copy link

saimn commented Feb 23, 2023

In my opinion, how something is typeset (repr) or worded is not included in the API (for a minor release), so the wording of an error message is not, but the structure/type/behaviour of an object or the exception type is part of the API.

I agree with this definition. The main place where people may use the messages is tests, but breaking tests is not the same as breaking the code itself. There may be exceptions but it's hard for us to know, so indeed encouraging people to run weekly (?) tests with astropy-dev seems a good solution.

@taldcroft
Copy link
Member

On error and warning messages specifically, in astropy we check those internally just to ensure we actually raise the right error, but really why would anyone rely on those outside of astropy?

The problem is that astropy very commonly uses generic exception types like ValueError and TypeError, so that the only way to catch a specific error is by using the exception message text.

We certainly could embark on a mission to improve that with custom error classes, but that is a different story.

@taldcroft
Copy link
Member

Anyway, I really hope we can keep things more or less like they are for minor releases!

I agree 100% (as a culprit for some of the changes in question). I just think we need to ensure that such changes are appropriately communicated to stakeholders (putting on a manager's hat).

@taldcroft
Copy link
Member

And I see now that I somewhat repeated #82 (comment), so we're all in agreement.

@saimn
Copy link

saimn commented May 5, 2023

I agree with the 1 year deprecation period, but not sure about the yearly major release : one of the goals of this APE was to keep the stability promise of the LTS for a ~2 years period. A major release is needed only to introduce breaking changes, i.e. removal of deprecations, or new feature that need an API break. Is there a need for a faster cadence ?

@pllim
Copy link
Member

pllim commented May 9, 2023

Is there a way to get some sort of consensus to move this forward?

@nstarman
Copy link
Member

nstarman commented May 9, 2023

Is there a need for a faster cadence ?

As I understand it, we don't want deprecations to last for 2.5 years. If something is deprecated in v5.3 and can't be removed until v7 (because v6 is too early) that's too long if v6 to v7 is 2 years

@WilliamJamieson
Copy link

I agree with @nstarman, it will become difficult to maintain multiple versions of an API for ~2 years. I also agree any deprecation should exist for at least 1 year, so it is reasonable for us to allow for having a major release every year.

Since the goal is to drop LTS version support, we will then be expecting downstream users to migrate forward as we make minor releases. Consequently, downstream users should have at least 1 year of warning prior to a breaking change.

@taldcroft
Copy link
Member

I agree with the points from @nstarman and @WilliamJamieson above, which I believe are also in agreement with the summary of the Coordination meeting outcome from @eteq.

@saimn - are you OK with the yearly major release? If so it seems like we would have achieved consensus, with the caveat that @astrofrog needs to update the APE's to reflect one year instead of two between major releases.

@astrofrog
Copy link
Member Author

I've now tried to implement the 'consensus' from the coordination meeting into these documents. The bottom line as far as I have understood is that we are basically following semantic versioning, and specifying that one year is the minimum time between major releases, six months is the default and a maximum time between non-bugfix releases, and deprecations have to be in releases for at least a year before changes are carried out.

@taldcroft @WilliamJamieson @nstarman @pllim @saimn @mhvk @eteq - could you take a look at the latest versions and leave comments/suggestions or approve if you are happy with the APEs as-is? (just to see if we are getting close to consensus)

Copy link
Member

@pllim pllim left a comment

Choose a reason for hiding this comment

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

I should not approve as I am technically a co-author but I am fine with this. The important thing is that we get buy-in from people very involved with pipelines, who include but not limited to @nden , @perrygreenfield , and @weaverba137 .

Thank you!

APE2.rst Outdated Show resolved Hide resolved
APE2.rst Outdated Show resolved Hide resolved
APE2.rst Show resolved Hide resolved
APE21.rst Outdated
Branches and pull requests
--------------------------

N/A
Copy link
Member

Choose a reason for hiding this comment

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

Should we also link astropy/astropy#14713 here?

@weaverba137
Copy link
Member

I re-read both APEs and they sound good to me. Thanx for the reminder!

@saimn
Copy link

saimn commented May 13, 2023

specifying that one year is the minimum time between major releases

If one year between major releases is a minimum, then I agree, but that was not my understanding from the above (every major release is yearly).

That was also my point earlier in the discussion (#82 (comment)), we just need to keep some flexibility on when we want to make a major release. It will depend on how many deprecated items we have accumulated. And if there is some new feature that is waiting for the end of the (1 year) deprecation period, we can wait 6 months more before releasing the next major version. But most of time we are just deprecating old functions or some renamed arguments and there is no urgency in removing those.

Also we will need a way to track the things that have been deprecated to know when they can be removed, and when we decide that next version will be a major one.

@astrofrog
Copy link
Member Author

I thought the consensus was that it was a minimum as @eteq said:

need to clarify that the semantic step happens only if there are any pending->post-deprecaton

Copy link
Member

@taldcroft taldcroft left a comment

Choose a reason for hiding this comment

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

Looks great to me, thanks for all the work and persistence!

@pllim
Copy link
Member

pllim commented May 15, 2023

How many approvals are needed here? How should we proceed? Thanks!

@astrofrog
Copy link
Member Author

My understanding is that APE 0 makes it the responsibility of the CoCo to accept/reject APEs - the main purpose of 'approvals' here is just to see how many people are broadly on board with this but it's not like there is a 'minimum' number of approvals needed. I've asked for comments by the end of the week - if there are no objections by then and no further changes, we can hand over to the CoCo to decide how to proceed.

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

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

Looks great, thanks for sticking with it!

Copy link
Contributor

@dhomeier dhomeier left a comment

Choose a reason for hiding this comment

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

Thanks, I see everything I recall from the discussions reflected here!

@pllim
Copy link
Member

pllim commented May 31, 2023

Thank you for the approval! Should we put the final date stamp and status on this PR and merge?

@hamogu
Copy link
Member

hamogu commented May 31, 2023

This has been approved by the Coco through the approvals here and internal Coco communication by those Coco members that did not comment here. I will go through the process of merging and try publishing on Zenodo etc. later today (if zenodo let's me - their webinterface has been flaky recently, if not, I might have to re-try in the next few days).

APE21.rst Outdated Show resolved Hide resolved
APE21.rst Outdated Show resolved Hide resolved
APE21.rst Outdated Show resolved Hide resolved
APE2.rst Outdated Show resolved Hide resolved
@hamogu hamogu merged commit 568e92a into astropy:main May 31, 2023
@astrofrog
Copy link
Member Author

Thank you to everyone who contributed and to the CoCo for approving!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.