10000 Issue with no co-existence of nullOK and maybeOf across channels. · Issue #74519 · flutter/flutter · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Issue with no co-existence of nullOK and maybeOf across channels. #74519

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

Closed
rydmike opened this issue Jan 22, 2021 · 21 comments
Closed

Issue with no co-existence of nullOK and maybeOf across channels. #74519

rydmike opened this issue Jan 22, 2021 · 21 comments
Labels
a: null-safety Support for Dart's null safety feature framework flutter/packages/flutter repository. See also f: labels.

Comments

@rydmike
Copy link
Contributor
rydmike commented Jan 22, 2021

Removal of nullOK - Issue with Severe Breaking Change

I'm having severe issues and hence also objections to the removal of nullOK. I am referring to these changes:

My main questions (and objections) are:

  • How do we for the moment write a single code base that needs to use past 'nullOK' APIs and now the new 'maybeOf' of APIs, that works and runs with the same codebase on at least stable, beta and dev channels, preferably also on master channel, but up to dev would be OK so we can work on Windows targets too.

  • How is this going to be introduced into the stable channel without it being a VERY severe breaking change?

  • If you introduce it into stable, by just overnight removing "nullOK", how does that not go against the Flutter compatibility policy?

Basically when you finally introduce maybeOf into stable, then nullOK should be available also for 1 year at least. If that will be the case, then fine. However, why can nullOK then also not be available on beta, dev and master channels, at least until maybeOf is introduced in stable, so we can do a well managed switch?

https://flutter.dev/docs/resources/compatibility

Deprecation policy

We will, on occasion, deprecate certain APIs rather than outright break them overnight. This is independent of our compatibility policy which is exclusively based on whether submitted tests fail, as described above.
Deprecated APIs are removed after a migration grace period. This grace period is one calendar year after being released on the stable channel, or after 4 stable releases, whichever is longer.
When a deprecation does reach end of life, we follow the same procedures listed above for making breaking changes in removing the deprecated API.


I know this is a part of this design doc, but I'm concerned about its implementation and current difficulties its transition is causing, and that it at least based on what is available on stable/dev/master looks like it will be introduced into stable as an overnight breaking change that does not adhere to the above policy regarding providing a more controlled and manageable deprecation.


Mediation possibility?
Perhaps another way to handle and avoid the current catch 22 situation, would have been to also introduce the new maybeOf API in parallel to nullOK as a hotfix to the stable channel to facility code that needs it and needs to work on channels up to at least channel dev, with a single code base. Seems like maybeOf API could very well co-exist in some form on stable in the none null-safety SDK, where as the same can probably not be said about the nullOK API variant co-existing with the Flutter null-safe SDK.


At the moment, our only recourse for managing the current situation is to dump and not use/support the Flutter stable channel at all in our projects.

@HansMuller
Copy link
Contributor

CC @gspencergoog

@tomgilder
Copy link
Contributor
tomgilder commented Jan 30, 2021

I'm also failing to understand how this transition is going to happen without a lot of pain.

This week we were suddenly unable to run our project on the dev channel due a dependency relying on a nullOk parameter that was removed. We need to be able to switch smoothly between stable, beta and dev for different platforms, now we can't, and I currently have no idea how to fix it (apart from downgrading to the last dev version).

So far we've been able to work around this by having an entry in dependency_overrides that we uncomment for different channels (which wasn't exactly a good experience), but we're no longer able to do that.

@rydmike
Copy link
Contributor Author
8000
rydmike commented Feb 1, 2021

As an additional primer to anybody else dropping by in this issue. In old SDK and well still current stable, this for example:

    ScaffoldState state1 = Scaffold.of(context);
    ScaffoldState state2 = Scaffold.of(context, nullOk: true);

Is the way nullOK is/was used. Normally the first of throws if there is no Scaffold, but the second one just returns null and you deal with it.

Understandably this is messy and not doable in NNBD if you want to have a "clean" of method that returns a non nullable type.

So in NNBD version you instead use:

    ScaffoldState state1 = Scaffold.of(context);
    ScaffoldState? state2 = Scaffold.maybeOf(context);

The difference in return types probably makes it problematic to keep nullOK in stable when NNBD hits it, or?

If it is a problem, then why was nullOK not deprecated (like half a year ago almost now when this was known already) and maybeOf introduced to stable? Is there also an issue with maybeOf in stable?

The current NNBD maybeOf method might work fine in stable too together with nullOK , just remove the "?" and it would have been a soft introduction to maybeOf over nullOK.

  static ScaffoldState? maybeOf(BuildContext context) {
    assert(context != null);
    return context.findAncestorStateOfType<ScaffoldState>();
  }

Then with a deprecation warning "Hey nullOK is going away soon", there would have been time to migrate.

Still possible with a hot fix to introduce maybeOf in stable, but very little time for it to get broadly adopted anymore, at least if 3.3.2021 is when NNBD hits stable.

@gspencergoog
Copy link
Contributor

@rydmike

We do understand your complaint with this breaking change, and we're sorry that this is making things difficult for you and others.

When designing this change, we considered a number of different alternatives, and in the end decided that having a more ergonomic API long term was more important than the short term pain that a migration would induce. We wanted to keep the .of syntax of existing methods, since it reads well, and is easy to understand, but in converting the return value to null safety, the nullOk parameter no longer made sense, and added a lot of confusion to the API. Even deprecating the parameter wouldn't be sufficient, since the call sites would need to change the type of the variable receiving the result to be non-nullable in any case.

We don't provide any guarantee that you will be able to build apps on multiple branches with the same source code. You might be able to get that to work most of the time, but we only provide assurances that code will work on one branch at a time, since API differences between branches (like this one) make some code changes necessary.

As mentioned in the compatibility policy, we do try and minimize breaking changes, but to maintain good ergonomics they are a necessary part of the evolution of an API.

This change doesn't fall under the deprecation policy, since it is not a deprecation, but a breaking change.

There is a migration guide for this change available here.

Again, we're sorry for the breakage.

@rydmike
Copy link
Contributor Author
rydmike commented Feb 1, 2021

@gspencergoog I get all that, and thanks for feeling with us regarding this quite challenging breaking change.

I still think it would have been (and would even still be) possible and better to introduce maybeOf in parallel with nullOK in stable channel, while stable is not using NNBD and deprecate nullOK in stable.

That nullOK is totally removed and broken in other channels is then easier to deal with since users of the API could also migrate to it on stable. And package devs could have migrated to the maybeOf API without a full null-safety migration as an intermediate step.

As far as I can see there is nothing in maybeOf that would not also work in stable if you remove the ? from the return type, or is there?

As it is now, devs using nullOK in stable that also develop for beta (web) and dev (desktop), cannot really prepare for when the API is gone in their app. The only recourse is basically to not use stable channel at all right now for anything (but if you depend on packages that have not migrated, you cannot even do that) and wait for nullOK to also be removed in stable so all are forced to migrate if they want to use latest version of the SDK.


Why not a migration path with maybeOf in stable?

Why was a migration path where maybeOf was introduced early on in stable not a possibility? It would have made things so much smoother and could probably have been introduced 6 months ago already.

Migration guide - nice but...

The migration as such is trivial, and it is very nice that there now is 4 days old guide for it as well. However, it does not help many that have this current issue, since it is not possible to write and develop code that runs on stable/beta/dev channels with a single code base that use the maybeOf API, so if you also want to use stable channel, you cannot migrate yet, as far as I know. So the guide does not really help, yet.

I have not seen such a hard and difficult break before in Flutter SDK, and as I can see, it could have been avoided for most parts by introducing maybeOf API to stable way before NNBD.

Not a deprecation!

This change doesn't fall under the deprecation policy, since it is not a deprecation, but a breaking change.

I knew that this easy cop out was coming too. The possibility and in this case preference to break things instead of deprecate them in a controlled manner, does make the deprecation policy a bit moot, imo.

Also the deprecation policy in this case creates a catch 22 for using it for introducing maybeOf into stable and deprecating nullOK there, since it would then have been needed to keep nullOK around for at least 1 year, at least if you decide to not break the policy for this case. That again would not have been compatible with time-line for introduction of NNBD in stable, since nullOK does not fit with it, and to fulfill the policy promise, then NNBD in stable in Flutter SDK would have had to wait at least 1 year after the deprecation of nullOK. Easier then to break stuff, I get that too. Still I and perhaps many other devs too, would have preferred to break the deprecation policy a bit instead over this current broken API mess. Doing so would have enabled a smoother transition, which is what most devs usually prefer (over policies) and 8000 what the policy is supposed to ensure too I guess. However, in this case the policy even kind of gets in the way of doing that job.


Finally and dpt btw

The Flutter team is doing a great job and we all love Flutter despite occasional hiccups and planning snafus like this! 😏
This will all be forgotten in month after NNBD has been introduced in stable, maybe even sooner. Since my guess is that NNBD is coming to stable 3.3.2021, which is not so far away, I can certainly manage until then, even if nothing is done. I hope others can too.

Although above @tomgilder describes a scenario where it is perhaps harder to wait. I happen to know he is working on an interesting production Flutter Web app that is close to release (that is about all I know about it).

Actually I just remembered, I did create temp copies of some libs/packages myself quite some time ago already. I did so to just change nullOK to maybeOf in order to make them work on master channel. This was a while ago already, back when nullOK was only broken on master, had almost forgotten about them already, so there is always that temp solution too. Had to do that since the package devs in question did not want to create two versions, one for stable and one for other channels.

--

BTW, will the new Flutter SDK with NNBD be called 2.0.0? 😃
If it would use semantic versioning it should be. Perhaps then it is easier for all to get onboard with and understand why so much stuff is broken and swallow it easier...

Well I suppose Flutter SDK is not really using semantic versioning anyway, or is it?
I seem to recall that smaller stuff have been broken in the past too without a major version bump, so it is probably using one of those, "We will bump the major version when there is a sufficiently big enough change in the SDK to feel that it is warranted" versioning schemes. Well perhaps NNBD and whatever else is coming is such a change? 😉

@gspencergoog
Copy link
Contributor

We currently don't use cherrypicks for things other than security issues or "halt-and-catch-fire" situations, in order to preserve the stability of the stable channel. Maybe we should reconsider that, but that's the current policy.

@rydmike
Copy link
Contributor Author
rydmike commented Feb 2, 2021

My point was actually that with some planning and foresight, that there would not have been any need to cherry pick anything, maybeOf could just have been introduced as a planned parallel API to nullOK in previous stable 1.22 or even already in 1.20, in order to facilitate this problematic transition.
Sure, to do anything now to fix things for stable, yet another hotfix would be need, which could indeed be called a cherry pick. :)

@gspencergoog
Copy link
Contributor

Yes, true, and if we had decided to make this change before the previous stable was released, we would have done exactly as you suggest, but we didn't make the decision on this change until a month after the most recent stable was released.

@rydmike
Copy link
Contributor Author
rydmike commented Feb 3, 2021

Thanks for all the info Greg, and I understand it is a tricky and unfortunate situation.

I and few others that suffer with this issue just work around it for now. Mostly by for any non null-safe package that has this issue, we make our own fork and change the nullOK to the maybeOf variant, let the rest be as is and use the fork until this blows over and the package is eventually fixed too. In some cases a few nested deps also have to be to dealt with, but its all doable just a bit of a hassle.

With this approach we obviously still can't use stable channel with the same code base, but perhaps that's OK too considering the timeline. Dev channel is certainly "stable" enough to develop in (probably even to release with if you have to) until all this lands in stable. No worries, I think we got it covered. :)

Looking forward to 3.3 (= 3+3=6 platforms in stable? I hope so! 😃 )

@rydmike
Copy link
Contributor Author
rydmike commented Feb 3, 2021

Since nothing is likely to change or be resolved before the next stable release, I was about to close this issue since it won't be resolved.

However, if it is kept open until it is solved by maybeOf hitting stable, it might be easier to find by others that currently run across this issue. They might find the discussions in this topic useful, or at least that they shed some light on the current situation. So I left it open for now. I can track it and close it myself when maybeOf reaches stable and this becomes a none issue.

@rydmike
Copy link
Contributor Author
rydmike commented Feb 5, 2021

Wait what is this black magic https://github.com/flutter/flutter/pull/74866/commits did @Piinks just fix it all?? 🤯

On master now when I use a package with a dep that uses old "nullOK", it suddenly now builds just fine!?

If I drill into to look at the package it for sure shows code that should not build (and did not before), because it uses removed nullOK and it is not resolved to anything newer that would use maybeOf. Also if look at the API in question in the Flutter SDK on used master version, it as excepted has no nullOK API, so it should indeed bomb, yet it builds! What!? Magic? Still nice save... or am I dreaming?

What is this magical "fix_data.yaml" file? Some kind of dark art magical secret sauce build pre-processor that changes and migrates code before it is built? It's usage and syntax seems to indicate that. Could not find any info on it, just this:

TODO(Piinks): Add link to public user guide when available.

Although mostly I'm happy it all seems to magically work now!

Thanks and super nice work @Piinks ! 💙

Unless I'm really dreaming or seeing things of course... 😃
If I'm not dreaming I think we can close this issue!

@rydmike
Copy link
Contributor Author
rydmike commented Feb 13, 2021

The fix #74866 has now landed on channels, beta, dev and master.

I tested by building an app with a few package dependencies that use nullOK, and do not have fixes for it in any none pre-release version.

By setting the dependency constraint for those dependencies to a min version or higher, that build and runs OK on stable, I was able to build the same project and code using same version constraints on:

  • Channel stable, 1.22.6
  • Channel beta, 1.26.0-17.5.pre
  • Channel dev, 1.27.0-1.0.pre
  • Channel master, 1.27.0-2.0.pre.96

Previously it was impossible to build an app with the same package dependencies on all channels.

This issue is resolved via #74866.
Closing the issue.

Thanks @Piinks and @gspencergoog 💙 !

@rydmike rydmike closed this as completed Feb 13, 2021
@apoleo88
Copy link

Tested with

  • Channel beta, 1.26.0-17.5.pre

I still get the same error with the library flutter_svg.

@rydmike
Copy link
Contributor Author
rydmike commented Feb 15, 2021

@apoleo88 so it appears now, so it seems like my joy was premature.
Issues do seem to persist. Interesting, I'm sure I saw them gone. In any case, I'm reopening the issue.
We clearly do not know enough about what this "fix_data.yaml" really does.

What does work though, at least for your mentioned flutter_svg issue, if that is all you need to work, is to set it's version constraint to:

flutter_svg: ^0.19.1

Then you will get version 0.19.1 on stable, but on channels beta and higher you will get version 0.19.2 or higher, that has Flutter SDK version constraint that is higher than the stable version and its implementation actually uses , maybeOf instead of the problematic nullOK, so with this version constraint you get one that works on stable, but on higher channels you get one that works on them. Nice of flutter_svg to provide this solution, it could well deserve to be mentioned in its change log, but it is not.

@rydmike rydmike reopened this Feb 15, 2021
@apoleo88
Copy link

flutter_svg: ^0.19.1

Then you will get version 0.19.1 on stable, but on channels beta and higher you will get version 0.19.2 or higher, that has Flutter SDK version constraint that is higher than the stable version and its implementation actually uses , maybeOf instead of the problematic nullOK, so with this version constraint you get one that works on stable, but on higher channels you get one that works on them. Nice of flutter_svg to provide this solution, it could well deserve to be mentioned in its change log, but it is not.

Thanks for the follow up. I tried with last beta/master using ^0.19.1, or forcing it to 0.19.1, 0.19.2, 0.19.2+1, but the same error persists:

/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_svg-0.19.2/lib/src/picture_provider.dart:57:59: Error: No named parameter with the name 'nullOk'.
        context != null ? Localizations.localeOf(context, nullOk: true) : null,
                                                          ^^^^^^
/C:/src/flutter/packages/flutter/lib/src/widgets/localizations.dart:413:17: Context: Found this candidate, but the arguments don't match.
  static Locale localeOf(BuildContext context) {
                ^^^^^^^^

@rydmike
Copy link
Contributor Author
rydmike commented Feb 15, 2021

@apoleo88 You probably already tried, but in case did not, make sure to run: flutter pub upgrade to get the latest resolvable version(s) in effect.

If you do a flutter pub outdate and see this for flutter flutter_svg when using the beta channel, then you have the wrong version in effect.

Package Name  Current   Upgradable  Resolvable  Latest    

direct dependencies:
flutter_svg   *0.19.1   0.19.2+1    0.19.2+1    0.19.2+1  

transitive dependencies:
args          *1.6.0    *1.6.0      *1.6.0      2.0.0     
convert       *2.1.1    *2.1.1      *2.1.1      3.0.0     
:  

run: flutter pub upgrade to get the latest resolvable version.

If you don't intended to build for stable channel at all, then you can of course set the flutter_svg version to ^0.19.2+1 in your pubspec.yaml file, but that won't build on stable.

With version ^0.19.1 you can get the last resolvable version that builds on stable with flutter pub get flutter pub upgrade , and likewise on beta/dev/master, you will in fact get 0.19.1 on stable and 0.19.2+1 on the other channels due to the Flutter SDK restriction in version 0.19.2 and higher.

This web screenshot is built with latest beta channel and flutter_svg: ^0.19.1 in pubspec.yaml (but resolved to 0.19.2+1) , the shown image is an SVG file:
image


If you still have problems getting the correct flutter_svg version resolved, you could try to invalidate the cahces and restart the IDE (In IJ/AS: File -> Invalidate Caches / Restart ...), sometimes that can help too.

@apoleo88
Copy link

Unfortunatly, nothing of that worked, the version of the library is indeed correct and I cleaned multiple time, did pub get and upgrade. I had to surrender and downgrad to the beta.

@esDotDev
Copy link

We're still having this issue. We're using bits_dojo package, which imports the svg package.

We tryied to do a dependancy_override to 19.2.0+1 but it just kept complaining about nullOk and would not build.

../../../sdks/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_svg-0.19.2+1/lib/src/picture_provider.dart(57,59): error GBF4691A2: No named parameter with the name 'nullOk'.
Exception: Build process failed. 

@osaxma
Copy link
Contributor
osaxma commented Feb 18, 2021

same issue as @esDotDev on latest master 1.27.0-5.0.pre.52

Launching lib/main.dart on iPhone 12 Pro Max in debug mode...
lib/main.dart:1
Xcode build done.                                           22.3s
Failed to build iOS app
Error output from Xcode build:
↳
    ** BUILD FAILED **
Xcode's output:
↳
    ../../../../.pub-cache/hosted/pub.dartlang.org/flutter_svg-0.19.2+1/lib/src/picture_provider.dart:57:59: Error: No named parameter with the name 'nullOk'.
            context != null ? Localizations.localeOf(context, nullOk: true) : null,
                                                              ^^^^^^
    ../../../../fvm/versions/master/packages/flutter/lib/src/widgets/localizations.dart:413:17: Context: Found this candidate, but the arguments don't match.
      static Locale localeOf(BuildContext context) {
                    ^^^^^^^^
    Command PhaseScriptExecution failed with a nonzero exit code
    note: Using new build system
    note: Building targets in parallel
    note: Planning build
    note: Constructing build description
Could not build the application for the simulator.
Error launching application on iPhone 12 Pro Max.
Exited (sigterm)
flutter doctor -v
[✓] Flutter (Channel master, 1.27.0-5.0.pre.52, on Mac OS X 10.15.6 19G2021 darwin-x64, locale en)
    • Flutter version 1.27.0-5.0.pre.52 at /Users/osaxma/fvm/versions/master
    • Framework revision 03aaf062c6 (2 hours ago), 2021-02-18 11:51:03 -0500
    • Engine revision 6993cb229b
    • Dart version 2.13.0 (build 2.13.0-30.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/osaxma/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.53.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0

[✓] Connected device (2 available)
    • iPhone 12 Pro Max (mobile) • 5D894941-88ED-47BA-8FE0-0FA45101E676 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • Chrome (web)               • chrome                               • web-javascript • Google Chrome 88.0.4324.150

• No issues found!

@rydmike
Copy link
Contributor Author
rydmike commented Feb 17, 2022

I am closing this issue, it is solved a few stables releases back already.

@rydmike rydmike closed this as completed Feb 17, 2022
@github-actions
Copy link
github-actions bot commented Mar 3, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: null-safety Support for Dart's null safety feature framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

8 participants
0