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

Please switch to v1.0 and start using semantic version numbers #2961

Open
smurfix opened this issue Feb 19, 2024 · 17 comments
Open

Please switch to v1.0 and start using semantic version numbers #2961

smurfix opened this issue Feb 19, 2024 · 17 comments

Comments

@smurfix
Copy link
Contributor

smurfix commented Feb 19, 2024

The last change to Trio (dropping MultiError) caused some compatibility mayhem, most recently here.

I'd thus like to ask for a release tagged 1.0, followed by semantic version numbers. That will allow other packages that depend on Trio to use a dependency like ~1.0, thus telling pip-or-whatever that upgrading Trio from say 1.9 to 2.1 is not going to work.

IMHO Trio is sufficiently stable (and widely used) that zero-dot-anything version numbers are no longer a good idea.

@A5rocks
Copy link
Contributor

A5rocks commented Feb 19, 2024

There's one more scary-compatibility thing (#2886) that's probably better being done before v1. (yes this has been deprecated for a while, but so was MultiError!)

I don't have any comments for 1.0 after that.

@Fuyukai
Copy link
Member

Fuyukai commented Feb 20, 2024

That will allow other packages that depend on Trio to use a dependency like ~1.0, thus telling pip-or-whatever that upgrading Trio from say 1.9 to 2.1 is not going to work.

Do not do this.

See: https://hynek.me/articles/semver-will-not-save-you/, https://iscinumpy.dev/post/bound-version-constraints/.

@jakkdl
Copy link
Member

jakkdl commented Feb 20, 2024

That will allow other packages that depend on Trio to use a dependency like ~1.0, thus telling pip-or-whatever that upgrading Trio from say 1.9 to 2.1 is not going to work.

Do not do this.

See: https://hynek.me/articles/semver-will-not-save-you/, https://iscinumpy.dev/post/bound-version-constraints/.

While I generally agree with the sentiment, we knowingly did do a breaking change (after MultiError has been deprecated and raising warnings since 2022-09) and while overrelying on SemVer is Bad ™️ I think conveying some information with the versioning numbers can be quite helpful.

Speaking of, when are we ripping off the bandaid and releasing #2886?

@smurfix
Copy link
Contributor Author

smurfix commented Feb 20, 2024

conveying some information with the versioning numbers can be quite helpful.

Agreed. I mean, yes backwards compatibility is great but at some point the you got to drop the workarounds.

So if you're uptodate on version 2 and you know that any deprecation will take two releases, specifying >2.1,<5 leaves ample time to upgrade.

Do not do this.

Well, I disagree.

"Semver will not save you" — well of course it won't. Not on its own. But semver plus a sensible deprecation strategy is a whole lot better than just going with a date-based versioning scheme and watching the chips fall where they may. IMHO.

NB: the first link recommends, quite strongly,

Pin your dependencies and their transitive dependencies to their exact versions.

Well, yeah. You can and probably should do this when you're writing an application that needs to be thoroughly tested and deployed under your control.

However, things get murky when the app is intended to be installed into an existing infrastructure or, worse, when it's not an app but a package. Pinning a package to an exact version of everything it depends on doesn't scale.

@A5rocks
Copy link
Contributor

A5rocks commented Feb 20, 2024

For what it's worth I think the reply was specifically about speculatively pinning deps as a library. Not so much saying semver is bad for a library maintainer (if that's what you like) but that users shouldn't trust the version guarantees and libraries shouldn't use semver as justification for adding upper bounds (though if a version removes an API then that's a fine upper bound, just not ">=1,<2, because semver:tm:").

I'll note the original issue wouldn't have happened if there were no upper bound on anyio for moat-mqtt. It's your choice but that's the kind of thing we want to generally discourage.

(my rephased tl;dr of the iscinumpy post is: libraries should expect users to set the upper bounds based on what works. if a doesn't work with the latest b, then a user can just pip install a b<=[working version].)

@mikenerone
Copy link
Member

As the article states itself, there's value in advertising intent, and SemVer lets us do that. It's better than the Wild West. That said, it might not hurt for the documentation to try to edify users by referencing that article. :)

@richardsheridan
Copy link
Contributor

Matplotlib recently switched to EffVer and I think that's worth considering here too:

matplotlib/matplotlib#27795

@CoolCat467
Copy link
Member

I don't think changing versions on a whim is worth it. Trio ships releases when they are ready.

@dhirschfeld
Copy link
Member

IMO, in practice there's no difference between EffVer and SemVer - it's just different marketing for users who might otherwise take SemVer too literally.

@smurfix
Copy link
Contributor Author

smurfix commented Mar 6, 2024

Well, SemVer also regards backwards compatibility, i.e. if my code wants 2.6.4, it ought to work (modulo some bug fixes) with 2.6.2 or 2.7.4, but if I drop 2.5.8 or 3.0.2 in there's at least one bit that's going to break.

EffVer doesn't think about backwards compatibility at all; it considers the forward change's impact on your code instead of the question whether there is a change, no matter how large (in theory).

While all versioning methods are kindof suboptimal given that we try to squeeze a multi-dimensional array of features (and bug fixes) onto an one-dimensional vector, SemVer at least tries to say "install the latest version that satisfies every user and your code should [continue to] work", while EffVer does no such thing.

@CoolCat467 What whim? We can change versioning when we do the next when-it's-ready release.

@njsmith
Copy link
Member

njsmith commented Mar 6, 2024

I think we ultimately want some form of CalVer. The only really viable / honest / user-respecting way to make backward incompatible changes at all to a complex project like Trio is to scope them as tightly as possible and phase them in over multiple releases (e.g. quiet warning -> louder warning -> error -> new behavior, etc.), which means you likely have multiple such changes in different stages all the time, and each of them effects as small a slice of the userbase as you can manage. In these circumstances SemVer doesn't give you any useful information -- either you bump the major version every release or you never bump it at all, and either way no-one learns what they want to know (whether an upgrade will break their usage). Plus when things do break, SemVer tends to encourage people to start playing the blame game instead of fixing things.

@jakkdl
Copy link
Member

jakkdl commented Mar 8, 2024

We have had a couple recent releases that has been quite major, and the switch to defaulting to strict_exception_groups=True didn't have a deprecation period*. We've also had several bugfix or typing releases that had ~0 error on users. So I don't think EffVer/SemVer is entirely unviable, but I also don't mind CalVer.

* because it was deemed to be more disruptive to raise warnings whenever a user didn't explicitly specify.

@dhirschfeld
Copy link
Member

As a consumer of packages, I really struggle with CalVer - should I update from 2024-02-07 to 2024-03-02? I've got zero basis to make an informed decision from the output (the version string) of my packaging tool. There might be any number of breaking changes between those versions and I've got no way to rank those possibilities.

Instead, if an update were to bump a package from 1.2.6 to 1.2.8 I'd immediately hit y to update with the assumption that there are no breaking changes. If instead my install wanted to update a package from 1.2.6 to 2.0.0 I'd hit n and go to the GitHub releases page of that package to understand the changes between those versions before updating.

Using SemVer/EffVer lets me make an informed decision to not do the necessary due-diligence based on the probability of breakage. In contrast, since you have no information for a package using CalVer you have to pessimistically investigate the changes between every single release date to ensure they don't affect you.

Sure, doing that is best practice anyway, but it can add a significant overhead for run-of-the-mill updates which can be ~mostly avoided if the developer indicates, in some imperfect way, the chance that this update will break code using their library.

@mikenerone
Copy link
Member

It's a bit complicated in Trio's case because of our release pattern. SemVer (or EffVer, which tbh I'm a bit ambivalent about) is much more helpful in conjunction with a continuous delivery cycle. Historically, we basically hold releases until there's something that would be considered worthy of at least a minor version bump, but often a major version bump (setting aside the actual wild-west of being in 0.x.x). OTOH, I generally find CalVer in my deps to be harmful to my blood pressure. :P

Actually, my question is: Why not release continuously? I ask here because SemVer/EffVer would naturally make more sense as the answer if we did.

@A5rocks
Copy link
Contributor

A5rocks commented Mar 16, 2024

If by releasing continuously you mean releasing every commit to main (like hypothesis), I believe the idea is that we want to accept PRs that potentially aren't complete. (e.g. newcomer comes by, does some nice work but missing a few complicated edge cases. it's probably worth merging and making a new pr instead of having comments on their PR for changes they didn't do).

Oh yeah I forgot some other reasoning. Just look here: #220 (comment)

@CoolCat467
Copy link
Member

I agree with what was mentioned in #220 (comment), I definitely think making a release on every commit to main would drive people away. I know I would feel uncomfortable if I knew every pull request I made was going to be a new release, and if I had made any errors anywhere that tests hadn't caught and no one reviewing had caught, we would have a broken release end users would be attempting to use and it would be my fault and I would likely avoid making any future changes. With existing system, if anything is wrong there is way more time to catch issues before a release happens and we can revert changes if need be much easier.

@mikenerone
Copy link
Member

Oh yeah I forgot some other reasoning. Just look here: #220 (comment)

Ah yes, the "inexperienced contributor" problem is very real. I guess perhaps I'd argue to simply release more often, then. It doesn't have to be full-on CD for SemVer(/EffVer) to start to become more helpful. Just often enough that there's such a thing as minor and patch releases (which Trio generally hasn't done except in pretty impactful hotfix situations).

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

No branches or pull requests

9 participants