@lagru and I were again discussing the transition pathway towards v2. I think the reason this keeps coming up is because all current proposals are somewhat painful.
I thought of another way in which we could transition. It would force users to transition wholesale from v1 to v2, which is less accommodating than the approach suggested in A pragmatic pathway towards skimage2, but it will make the maintainers’ lives a lot easier:
We add an additional, near-empty package: skimage-api
When you call pip install --upgrade scikit-image, you get scikit-image==2.0 but not skimage-api==2.0. When importing skimage, we detect that, and throw an error explaining that the API has been upgraded and users need to follow suit, or pin to an older version of the library.
If the user does pip install skimage2, they get both scikit-image==2.0 and skimage-api==2.0, the library imports as usual, and exposes the v2 API.
This way we:
(1) Only have to maintain one version of the API.
(2) Get an opportunity to explicitly warn users about the API transition (you never accidentally upgrade skimage and get different results silently).
(3) Do not need complicated machinery to manage the transition.
I’ll emphasize again that we do not have a lot of person-power on the project, so that we must make judicious use of resources. It is OK if we have to make some compromises to ensure that the API transition (a) happens and (b) is maintainable.
I’m not super sure about this, tbh. I don’t see why it’s any easier on maintainers than just releasing skimage2 and never upgrading scikit-image past 1.0. Is the concern that we will be stuck maintaining 1.0? Because I feel like that has a social, not technical, solution, which is to just not do it.
We could do that, but it would be good to have some mechanism by which to bring users over to the new API. If you never update scikit-image, then a lot of libraries / research scripts will get stuck right there.
This uses one of the ideas you had initially, which is to trigger an action on the user’s part by making their system break
My feeling is that attrition will be sufficient, especially since users can install both scikit-image and skimage2. All our docs will be skimage2, and all scikit-image 1 pages could e.g. get a fat banner saying it’s no longer maintained?
After some time, we could release scikit-image 1.99 which is like 1.whatever (I do expect we’ll do 1-2 small bugfix releases), but warns on import that scikit-image 1 works but is not maintained, so they should migrate.
I think my proposal was rejected for good reason, which is that it’s annoying to break users’ systems when actually nothing is broken. With the combination of:
(a) docs-based pressure
(b) (eventually) a warning
(c) (even more eventually) attrition due to CPython updates
I think that will be enough to push people to upgrade, but at their own pace.
My personal experience (for myself and working at companies) is that we migrate when there’s no choice, i.e., either when the system breaks, or right before it would break, providing the timeline was communicated to users.
OK, so after reading the above, and discussing with @matthew-brett (and, long term, with @lagru), I think the steps are:
Complete as much as we can of the 2.0 roadmap without switching to 2.0. We deprecate where we can, install mechanisms via underscore keywords, etc. We reduce the 2.0 roadmap to a minimal subset.
Reach a date where the transition needs to happen. We make a last release of skimage 0.x.
At this point, we work as hard as we can to get 2.0 out the door. It’s going to be a few intense weeks, but we’ll have a minimal roadmap to execute. Feature freeze, bug-fix freeze, just 2.0.
We make a new release of scikit-image, say scikit-image==0.30 as well as skimage2==2.0.0. 0.30 has an import warning stating that it is now in maintenance mode, that users can switch to 2.0, and that we will stop supporting 0.x in ~1.5 years. We provide a clear porting guide and a reminder to pin, should users wish to stay with 0.x.
From this point onward, all changes happen on skimage2, and we only backport critical fixes to 0.x, for a period of 1.5 years.
The above is (a) not a heavy burden on maintainers OR users (b) gives users plenty of warning, without breaking their packages / libraries (c) gives us the opportunity we seek to transition our API and (d) frees us from maintaining two versions in parallel.
The formatting nearly made me misunderstand this as releasing version 2.0.0.0.30; didn’t see the “normal” full stop there.
To clarify, skimage2==2.0.0 would be the new package name and namespace?
I support this solution.
Regardless of which way we try to approach this, we can never force users to update. Even if we break their code with an error, I guess a natural reaction in the moment would be to downgrade and deal with the update “later”. “Later” meaning, once the pressure factors Juan mentions become to much. So we don’t gain much with an error instead of a warning except of being a bit more jarring.
And totally agreed on wittling down the list of skimage2 API changes as much as possible beforehand. The more we do that, and the better our transition guide. The less we have to worry about leaving a chunk of users behind for a long time.
Yes, that’s right. So users will be able to import scikit-image=0.0.x as skimage, and skimage2==2.0.0 as skimage2.
Sorry, I wasn’t being clear: scikit-image==0.29 will be the release that includes the upfront prep-work for skimage2, but without any breaking changes. scikit-image==0.30 only differs from 0.29 in that it generates a warning that we are transitioning to 2.0, and that skimage2 is ready to be tried out / switched to.
Since we practically enter feature-freeze with the release of 0.29, we should aim to complete the first version of skimage2 quickly after that. Once we have skimage2 out, we can start adding features again.
We may also add to our transition plan going through answers on StackOverflow & Image.sc and fixing them. It’s a bit of a chore, but since it’s so routine it can be meditative
Ok, right, scikit-image==0.x doesn’t include any breaking change, by definition. And when skimage2 is ready, we release it alongside scikit-image==0.30. All clear now, thanks, @stefanv.
Ok, we’ll be sprinting on skimage2 after completing the work for scikit-image==0.29 (or, say, n-1). In theory, skimage2==2.0.0 would only need one breaking change for the transition to make sense (not even following semver to the letter here)… right? And: