Settings

Theme

We Have to Talk About Flask

blog.miguelgrinberg.com

43 points by carc1n0gen 2 years ago · 115 comments

Reader

usrbinbash 2 years ago

https://semver.org/

    Given a version number MAJOR.MINOR.PATCH, increment the:
    
    1. MAJOR version when you make incompatible API changes
So what exactly is the issue here?
  • vharuck 2 years ago

    The post's point is that an API change is a very big deal, to be used only when the older version just can't work anymore or the newer version offers something much better. But the Flask team seems to have a much lower bar on what justifies the change. So the author feels unhappy he has to update a bunch of projects for no good reason.

    • zbowling 2 years ago

      What stops folks from sticking with the last version of the last major point release? Do the flask folks not provide security or other update to older major point releases? Sometimes in the software lifecycle, you need to refactor and move on from older API designs. Even keeping old APIs around adds cruft, testable surface area you have to support, and slows down everything and adds risk with shipping software over time. Android, iOS, GTK, half the javascript and C++ libraries in the world, etc pop in into my head and all will break some amount in a major version update.

    • usrbinbash 2 years ago

      > an API change is a very big deal, to be used only when the older version just can't work anymore

      That's one opinion.

      Another opinion is, that API and major version changes can be used whenever the maintainers of an open source project feel like it. No other reason is necessary. Because it's their project. They write the code. They don't have to justify that decision.

      If a large portion of the projects userbase is unhappy about that, the project will lose traction and new project, or a fork, will arise.

    • barryrandall 2 years ago

      The post would have a point if the Flask team treated this like a minor release (2.x -> 2.x+0.1) instead of a major (2.x -> 3.x) and hadn't issued a deprecation warning.

    • paulddraper 2 years ago

      tl;dr The author things that Flask should release a 2.* and have no breaking changes.

  • fiddlerwoaroof 2 years ago

    The problem is that breaking changes in widely-used packages are disrespectful to your users. See Rich Hickey’s Spec-ulation

    • tetha 2 years ago

      I'd say the respect towards the users is displayed by the frequency of breaking changes and the overall time to migrate, through deprecation warnings and at least security maintenance of older versions. Sometimes things need to change.

      Speaking of that, flask 2 was released in May 21. I can't really complain about some breaking changes every 2 years or so. That's almost like a linux distribution.

      • pdonis 2 years ago

        > I'd say the respect towards the users is displayed by the frequency of breaking changes and the overall time to migrate, through deprecation warnings and at least security maintenance of older versions. Sometimes things need to change.

        A change that brings new added value to users is a case where the change needs to be made, yes.

        But the article's point is that the Flask changes don't seem to be doing that. They're not making breaking changes in order to introduce new features that add value for users. They're making breaking changes just because they feel like it, giving users no added value to compensate for the time and effort required to deal with the change. That's not respecting users.

        • tetha 2 years ago

          I disagree with that, to be honest.

          At a first glance, you might think "but where is the shiny carrot that makes me upgrade?" But the thing is - we have dealt with major upgrades at work which broke many things, added many features, changed things in undocumented ways, turned the whole dependency inside out.

          That's a horrible experience. You end up running after ghosts: Is it the breaking change, is it a change due to a feature, what is even going on!

          Looking at it, Flask 3 seems to be a simple batch of several breaking changes on the roadmap for quite some time. This is good - they thought about batching these breaking changes together to have one big bad one, opposed to like 6 of them over the 2 years. And you can upgrade, and you can clearly see if one of the breaking changes causes harm to your application, without having to worry about hundreds of other changes within the same major release.

          • pdonis 2 years ago

            Batching a bunch of breaking changes together so they all come at once and you only have to deal with them once is fine.

            What I am asking is, why did there even need to be a breaking change in the case of the function discussed in the article? No functionality changed; the Python standard library function was identical to the former Flask function. So why couldn't the Python standard library function have been imported into the Flask namespace to replace the former Flask function? Why force every user to do that manually?

        • ilyt 2 years ago

          Throwing the crust away and refactoring stuff also "doesn't add new features" but it needs to be done to keep codebase good.

          > giving users no added value to compensate for the time and effort required to deal with the change

          ... the users of free software. That didn't bother to find&replace one method in their plugin code.

          • fiddlerwoaroof 2 years ago

            Refactoring is not a breaking change by definition: refactoring is preserving the same contract with a new implementation.

            • ilyt 2 years ago

              I put "throwing the cruft away" in the same sentence EXPLICITLY to address that I am not just talking about refactoring.

              Learn to read before throwing dictionary definitions at people

              Providing method now-provided by standard libs is by definition unnecessary cruft. Nobody wants that in their codebase. They warned people for 2 years.

              But apparently basic competence is too hard requirement in software ecosystems.

              • pdonis 2 years ago

                > Providing method now-provided by standard libs is by definition unnecessary cruft. Nobody wants that in their codebase.

                I don't think your sweeping claims here are justified. Importing the function from the standard library into the same namespace in your library where the function you previously implemented was is not "cruft". It's helping your users by not making a breaking change when you don't actually need to--no actual functionality changed.

                > apparently basic competence is too hard requirement in software ecosystems

                Your snark here is even less justified IMO than your sweeping claims above.

    • croes 2 years ago

      >But the Flask-Login team is not actively developing the extension anymore.

      So they should tie the development to an extension that isn't in further development?

      • pdonis 2 years ago

        The issue with Flask-Login isn't even a functionality change. Flask just decided to stop making a particular function available in their namespace and now wants you to import it from the Python standard library instead.

        A better solution for a case like this would be to import the function from the Python standard library into the Flask namespace, so old code would still work. Then it wouldn't matter that Flask-Login is no longer actively maintained.

        Also, as the article notes, Flask-Login is by no means the only Flask-using Python package that was broken by this change. Are all of those other packages no longer actively maintained? I doubt it.

        • usrbinbash 2 years ago

          > Flask-Login is by no means the only Flask-using Python package that was broken by this change

          Package maintenance also means to keep up with changes in the packages dependencies. If I don't do that, that's my problem, not the dependencies.

          If I want to fix a certain version as my requirement, I can do so. Every major package system, including the ones used in Python, allow this. If I don't want that, then I need to keep my package maintained, and that means keeping an eye on what my dependencies do. That's part of package maintenance, simple as that.

          There is no onus on the dependencies maintainers to care about whether I do my maintenance or not.

          • pdonis 2 years ago

            > There is no onus on the dependencies maintainers to care about whether I do my maintenance or not.

            There's no "onus" on Flask to do anything they don't want to do. But if Flask forces every package that depends on them to fix a breaking change that they could have avoided with a one-line import statement, I would argue that is not very respectful of all those other package maintainers.

            • usrbinbash 2 years ago

              > But if Flask forces every package

              The reverse would be that every package that depends on flask forces it to make all future changes dependent on whether or not they break someones code. Which obviously isn't a sustainable model for software development.

              > I would argue that is not very respectful of all those other package maintainers.

              Define what is "respectful" then?

              The flask team announces changes. They deprecate things. They use deprecation warnings. They use major versions correctly. They honor well established good practices in software development, to give package maintainers the opportunity to react to changes early.

              Please, do explain: What else is required to meet whatever definition of "respectful" we are talking about here?

            • fiddlerwoaroof 2 years ago

              There’s also no onus on me to continue using packages that force me to spend valuable time fixing their breaking changes. My rule of thumb for dependencies is that, once I have to fix three or four breaking changes, the cost of switching to a more stable alternative or writing my own becomes more worth it.

              There’s also the option of releasing a package called something like flask2_compatibility that monkeypatches flask3 to work with flask2

              • pdonis 2 years ago

                > There’s also no onus on me to continue using packages that force me to spend valuable time fixing their breaking changes.

                Exactly.

        • paulddraper 2 years ago

          > A better solution for a case like this would be to import the function from the Python standard library into the Flask namespace, so old code would still work.

          Forever?

          • pdonis 2 years ago

            For as long as the functionality does not change. Which it didn't when the function was removed; the Python standard library function had the same functionality as the former Flask function that was removed.

        • ilyt 2 years ago

          Adding code into your framework to support abandonware plugins is the exact opposite of better solution

          • pdonis 2 years ago

            They wouldn't have needed to add any code. They could have just changed their implementation of the function to an import of it from the Python standard library. That would be a net reduction in code size.

            • ilyt 2 years ago

              Or remove it altogether, warn people for years about deprecation, then remove all of them. Which they did.

              More net lines removed too.

              But hey, it annoyed Man That Is Bad At Dependency Management and Wrote A Book About It so it must be bad!

              • pdonis 2 years ago

                > Or remove it altogether

                Which, as the GP of my original post in this subthread argued, and I agree, is not respectful to your users. Importing the function from the Python standard library is a one-liner, hardly an arduous burden.

                • ilyt 2 years ago

                  Right, then commit that one line fix to the plugin

                  • pdonis 2 years ago

                    Yes, for each of the umpteen number of packages that depends on Flask. Instead of Flask just doing it one time and avoiding that breaking change altogether.

                    Open source is supposed to be a community. Forcing a breaking change like this on all their dependencies that they could have avoided with a one-line import statement is, IMO, not very good behavior as a community member.

                    • usrbinbash 2 years ago

                      > Forcing a breaking change

                      No one is forcing a breaking change on anyone.

                          a) PIP usually retains past versions
                          b) A python package can specify it's dependencies, including their version, as hard requirements
                          c) virtualenvs exist
                      
                      If a packages maintainer doesn't want to change his code to support some changes in some_dependency-v4.2, he can specify that the package requires some_dependency-v2.1 or whatever other existing version he is happy with.

                      If he doesn't do that, and instead specifies only `some_dependency`, that signals to the package management software that the package works with the `@latest` version of that dependency. The onus to make sure that is, and continues to be, the case in code, is on the maintainer of the package, not the maintainer of the dependency, period.

                      And no, this is not "disrespectful". This doesn't go against any sense of community in FOSS. This is established practice in software development and package maintenance.

                      • fiddlerwoaroof 2 years ago

                        This is a pretty naive take that assumes the only relevant parties are the various library authors. The real issue here is the hours and hours of useless maintenance work breaking changes routinely force on anyone writing software with the supposedly "modern" tech stacks. Sure, maybe this change adds a minute of work for someone using flask. How much time does it save flask's maintainers? More than 1 minute * the number of people using flask? Being more hesitant about breaking changes as a industry would eliminate hundreds of person-years of basically useless maintenance work.

                        • usrbinbash 2 years ago

                          > Being more hesitant about breaking changes as a industry

                          ... would lead to even more outrage, because we tried that in the past. And the result were "rotting libraries", that became unmaintainable, incomprehensible, and riddled with hard to track and harder to fix bugs, because they had to drag along code that was often more than a decade old, kicking and screaming, just so libadbandonedsincebronzeage.so wouldn't have to issue an update.

                          So no, we should have breaking changes.

                          We should keep libraries vital and get rid of old code. We shouldn't drag along stuff just because we can. We have established procedures to deal with this, and with good reason.

      • davidhariri 2 years ago

        This is what I'm scratching my head at too. Why would it be a good thing for any OSS maintainer to slow themselves down for packages that don't want to fix deprecation warnings?

        • mixmastamyk 2 years ago

          - Because that's what you signed up for as maintainer of a project used by millions.

          - It's a significant piece of functionality.

          - The change is trivial, not worth the cost of losing login.

          In some instances Python deprecates something for six years, Flask six months.

      • fiddlerwoaroof 2 years ago

        Breaking changes shouldn’t happen with the same name: if you want to break your users, pick a new name too

        • usrbinbash 2 years ago

          The version number, and especially the major version, IS part of the name, so they did exactly that.

          • fiddlerwoaroof 2 years ago

            Then require people to `import flask3` so you can install both major versions together.

            • usrbinbash 2 years ago

              No.

              That would break every single module that is compliant with flask 3.x and imports it with `import flask`. This simply isn't justified by the "benefit" of some old packages not having to change a single line of code.

              Yes, maybe in hindsight it would have been beneficial to put the major version of some packages (flask is far from the only one) directly into the package name, as a workaround for pythons inability to deal with multiple versions of the same module under the same name in one environment. But python works as it does, `import flask` is how god-knows how many projects use it, so that's how the show runs, period.

              If some package requires a certain version, it can pin that version in its `setup.py`. If a project requires a certain version it can pin that version in it's `requirements.txt`. If an environment requires a certain version, the admin can create a virtualenv.

              • fiddlerwoaroof 2 years ago

                As Rich Hickey argues in the talk I referenced, semver and version pinning is a problem not a solution. I’ve written lots of code using only stable dependencies that are stable over the span of decades, and it’s just a much nicer ecosystem to be able to rely on.

                • usrbinbash 2 years ago

                  > semver and version pinning is a problem not a solution

                  Almost every practice in software development is a compromise that wouldn't be necessary if some decision in the past were different.

                  I think I agreed with you somewhere in this thread, that version-names (flask1, flask2, ...) are a better solution than major versions.

                  However, `flask` as an import name isn't going to go away. That is simply a reality and we have to work with it, because alot of projects rely on this. The same is true for tens of thousands of important software packages all over the OSS landscape.

                  So we can argue all day and then some over "what if"s...it won't change the status quo that exists, and in that state, semver is a good compromise that solves way more problems than it introduces.

    • bckr 2 years ago

      Would it not work to specify the version when installing the packages?

      • seanc 2 years ago

        Only to an extent. I can't think of a language environment where each package can have its own version of a dependency. Python certainly isn't one.

        So if you want any of the Flask 3.0 features you have to take the new Werkzeug, and see Flask-Login break.

        • fiddlerwoaroof 2 years ago

          Node lets every package have its own versions of dependencies. But, imo, it’s better (less time spent fixing upgrade breakage/incentive to pick stable dependencies) in the long run to depend on latest and always update, fixing breakage as you go and only locking versions in CI so you can deploy a known bundle.

          • rgoulter 2 years ago

            Of "Frequently update dependencies to latest" or "don't have to modify code which depends on others", you only get to pick one.

            If you're frequently updating to latest, you're on the bleeding edge; sometimes things will bleed more than others.

            If you're stable, you might not have the latest and greatest all the time.

            The attitude of expecting to always have the latest and greatest, but never have anything break, all while not paying for the effort, seems absurd to me.

            • fiddlerwoaroof 2 years ago

              It works pretty well, it’s like how continuous integration seemed absurd to people who spent months integrating changes and now is the standard practice.

              Anyways, in my experience, if you routinely use the latest and greatest versions of dependencies, over time you find that you stop using dependencies that make this painful.

              Anyways, I’m fine with accidental breakage. Deliberately choosing instability in the form of a major version release seems irresponsible for packages at the base of an entire ecosystem. (Absent some critical security issue that your users would have to address anyways as happened with log4j)

        • jasonpeacock 2 years ago

          Rust (Cargo) supports this.

      • fiddlerwoaroof 2 years ago

        No, because your users basically have to upgrade eventually, unless you commit to provide bug fixes (security especially) for every major version.

    • usrbinbash 2 years ago

      > breaking changes in widely-used packages are disrespectful to your users

      No they are not.

      The flask team announces changes, deprecates things and uses major versions correctly. The major version change also doesn't happen frequently.

      If a package absolutely requires a certain version, IT CAN SPECIFY AS MUCH in its requirements. If it doesn't, tough luck.

  • regularfry 2 years ago

    Flask doesn't follow semver. This could just as easily have happened in 3.1.

  • toolslive 2 years ago

    in the context of python, what exactly is an api change? If my api is

       ```
          def some_function(*args, **kwargs) -> JSON:
             ...
       ```
    
    In essence, I'm pretty sure plenty of the changes in the set of parameters that are actually acceptable quite often changes accidentally (same for what's in the JSON)
  • ilyt 2 years ago

    I think the author learned for first time of his life that framework plugins need to keep up with framework changes.

    2 years (flask 2.0 release) should be plenty for deprecation notice.

  • skrebbel 2 years ago

    The issue is that releasing breaking changes sucks for your users. A numbering scheme doesn’t really make it suck any less.

    • SteveNuts 2 years ago

      Breaking changes are fine (and a lot of times completely necessary) as long as they are expected _for what you're trying to do_.

      The numbering scheme is meant to give predictability to breaking changes or backwards compatibility, so if followed correctly, it absolutely should make it suck less.

    • usrbinbash 2 years ago

      > A numbering scheme doesn’t really make it suck any less.

      Yes it does, because that "numbering scheme" tells my users when and if breaking changes happen.

      It also allows them to avoid them. Don't want to keep up with the dependency? Make the version a hard requirement. Done.

dekhn 2 years ago

I have long advocated the idea that online tutorials should have unit tests: there should be a daily build that loads the tutorial, extracts the code bits, runs them, and reports a failure if a dependency broke the tutorial.

And those tutorials should have the ability to force rollbacks of minor point releases that break backwards compatibility.

Tutorials should be pinned to major point releases.

  • supriyo-biswas 2 years ago

    I have designed a personal tutorial authoring system that does exactly this, forcing you to include expected outputs in your article, which act as unit tests.

    However the idea kinda went nowhere as the main issue with writing tutorials is that you gotta compete with websites with poorly written, ad-riddled articles that are somehow ranked on top by Google; and furthermore the end is near for such tutorial websites anyway given the proliferation of ChatGPT/GPT4.

  • sdenton4 2 years ago

    I used to work on Sage, a math super package, which used 'doc tests' - documentation strings contained executable examples with expected outputs, and the test systems would run them all and check that they worked.

  • miguelgrinberg 2 years ago

    Explain to me how you would apply this concept to a book. Or to a YouTube video.

    I'm not unreasonable, I get that things have to change from time to time. I just think maintainers should think more carefully when they introduce breaking changes. The cost to them is very high!

    • dekhn 2 years ago

      I agree entirely that maintainers should be more careful with breaking changes. Few things annoy me more than getting 99% of thew way into a project and then getting an error simply because somebody moved a function from one place to the other.

      This is really just another instance of CADT, imho.

      I can't help with books- and IMHO, this is why books are obsolete for internet technology. I used to be a big OReilly fan, but at some point, the books were worse than useless because none of the examples would work 10 years later. Now, examples don't work 1 year later!

    • bluedino 2 years ago

      Books are like the ultimate "container". They are so tied to certain versions. I liked the books that came with CD's that included everything, even if they were almost immediately obsolete.

  • ilyt 2 years ago

    That reminds me my history with Ruby. Got to the famous "blog in 15 minutes" tutorial, used the stuff that comes with OS, nothing worked, didn't touch ruby again till I had to.

mmnfrdmcx 2 years ago

The flask-login package should have limited its dependencies to flask<3.0, that's what major versions are for.

  • miguelgrinberg 2 years ago

    So consider what happens when you try to learn Flask in a world like the one you describe. You pip install Flask, and you get 3.0. Next chapter asks you to install Flask-Login, and now you are forced to downgrade Flask.

    What you are saying makes sense when there are important reasons to break compatiblity. But I expect the Flask side to love their users a bit more and not break their code for trivial reasons.

    • lcnPylGDnU4H9OF 2 years ago

      > trivial reasons

      This is a bit like a No True Scotsman argument. It says that there are reasons for what happened but they didn't have a Good Reason. Why are their reasons so particularly trivial?

      > try to learn Flask in a world like the one you describe

      This seems moot if the Flask maintainers are using semantic versioning correctly. I'd probably look into it and think that Flask-Login maintainers should have limited their Flask version if they were going to step away from maintenance. If someone else wants to pick it up they can fork it or try to get in touch with the old maintainers to get access to the central repo.

    • JimDabell 2 years ago

      > You pip install Flask, and you get 3.0

      The learning material should specify a major version so this doesn’t happen.

    • ilyt 2 years ago

      framework developer isn't responsible for random tutorials going out of date because abandoned plugin wasn't updated in 2+ years

sergioisidoro 2 years ago

The problem stems from how fragmented dependency management in python is. Most tutorials use `pip install something` without much care for pinning versions.

Yes, it makes it easier for new programmers: They can skip learning a dependency management tool like poetry, or pipenv. But then these things happen.

Blame the tutorial makers and the dependency maintainers, not the Flask team.

  • kennywinker 2 years ago

    > Blame the tutorial makers and the dependency maintainers

    I'd blame the python community as a whole, for not driving everybody (flask team, tutorial makers, dependency maintainers, etc) towards pinned versions.

    This is a well-established problem in any environment where you write code that has dependencies. Strict use of semver, and tools that respect those conventions, would solve MOST of this.

    • sergioisidoro 2 years ago

      Well, they are trying... For tooling they tried to get this done well with pipenv, but (imho) failed for how slow and clunky it is. I really tried to like pipenv, but now I just go for poetry.

      But one thing that needs to be acknowledged is how difficult it is to coordinate a space with so many stakeholders (eg. Conda and Anaconda for Windows), and how python got so engrained in the sys admin (installing tools with pip.) that undoing that is a monstrous task [1]

      [1] The other day my ansible playbooks stopped working because packages that you used to be able to install globally with pip, should now be installed through the package managers (eg. jsondiff should now be installed as apt-get install pyton3-jsondiff). Exactly to push people to use virtual environments where you can better manage depedencies.

    • paulddraper 2 years ago

      Nothing unique to Python.

      You can lock Python versions.

      But people by default, people type pip/npm/apt/yum install without the version.

      Nothing unique to Python.

      • kennywinker 2 years ago

        Except the default behavior of yarn add / npm install is to pin a semver. I.e. if the current version is 1.2.3, the package.json will specify “^1.2.3” which will auto-update to any new release that’s versioned below 2.0.0. And the node community is at least half-decent about following semver and doesn’t usually push breaking changes on a point-release.

  • zbentley 2 years ago

    Python dependency management certainly has many problems, but I don't think this is one of them--or at least, it's not a problem unique to Python. The practice of tutorials/docs/guides installing unpinned/latest versions is incredibly common in most (all?) scripting languages' communities. While that's not great, I don't think it has anything to do with the fragmentation of Python's dependency management.

    • sergioisidoro 2 years ago

      Well, if there would be one accepted dependency management tool / environment, it would make things easier at least.

      For example, despite all the problems of JS, new devs don't need to create a virtual environment and activate it all the time. They don't need to manually add lines to a requirements.txt, or pick a tool like poetry or pip env [1]

      [1] Edit: ok they have to pick yarn/npm, but even those share a common file base formate - package.json

  • gaganyaan 2 years ago

    You don't even need poetry, as great as it is. Write your tutorial to include versions:

    > pip install foo==1.2.3

  • kyawzazaw 2 years ago

    poetry is very hard to setup

    • bandyaboot 2 years ago

      Could you expand on this? I recently started a new project and decided to use poetry for the first time. It didn’t seem difficult at all to me.

pil0u 2 years ago

Despite the "it's your fault" vibe towards Miguel, I have to say: thank you Miguel!!

Your tutorial was a turning point for me 4 years ago, the care you take to write and help people is very precious. My ability to write modest web apps takes its roots in your free online materials, I am grateful for that.

JoeAltmaier 2 years ago

Any older product will fall into disrepair, simply due to the decreased attention old features get. Plus the years of accumulated of references to any particular feature, that would take years to track and put right whenever it changes.

Not sure there's any cure.

I hit this (OP) issue myself. Solved it somehow, don't remember, just another glitch in the neverending series of glitches that are open-source lack-of-support and obsolete documentation.

Just today, noticed Steam tutorial videos generally use some obsolete version of their website tools. Have to fish around, find where the menus etc are, they sure aren't where the video says they are.

Business as usual.

  • dekhn 2 years ago

    The cure is to put a test on it (beyonce rule), and make the test passing required for release. And do rapid rollbacks (within 1 day) if bad releases are made.

    • JoeAltmaier 2 years ago

      If you own all the code, sure.

      But big things (OS, framework etc) have code squirreled away all over the world.

    • paulddraper 2 years ago

      Flask puts a test on someone else's unmaintained pacakge?

      • dekhn 2 years ago

        In this case, I would expect that the author of this post (who, IIUC is also the creator of flask), should have a test case that trips/fails within a day of the tutorial becoming invalid. At least then he knows the tutorial is going to fail for users.

        I was burned by flask/werkzeug enough times to completely avoid flask unless absolutely neccessary.

pphysch 2 years ago

It seems unreasonable to expect anything that relies on "version:latest" to not break upon a major version change.

What makes a tutorial different than any other software process, in this context?

Your tutorial was written and functions for a particular version of a software. Pin that version. It's the straightforward thing to do.

Frankly, I would be insulted if I was miseducated by a tutorial that purports to be up to date, but was actually written for a old major version. Learning obsolete techniques, missing best-practices.

  • bscphil 2 years ago

    Right. The closest analogy I can think of is answers on Stack Overflow. Usually those answers apply to the latest version of whatever software they're about, but this means many of them will eventually be out of date. You can find plenty of answers with code that assumes Python 2, written by authors who had no idea there was going to be a Python 3.

    And that's okay. It's not a bad thing for answers to sometimes go out of date.

    A really good answer might specify the major version of software it references, just to be future proof, but that isn't strictly necessary since anyone can just add a new answer and old answers can be edited (on Stack Overflow). For tutorials, it's much more incumbent on them not to mislead users into following an old tutorial, since most people will want to start with the latest version. Put a banner at the top that says "this is a tutorial for Flask 2.x, the latest version of Flask at the time of writing", and/or pin versions in your installation instructions.

nickjj 2 years ago

I've been maintaining my Build a SAAS App with Flask video course[0] for 8 years. It has gone from Flask pre-1.0 to 2.3 and has been recorded twice with tons of incremental updates added over the years to keep things current.

In my opinion tutorial creators should pin their versions so that anyone taking the course or going through the tutorial will have a working set up that matches the video or written material.

I'm all for keeping things up to date and do update things every few months but expecting anyone can install any version doesn't tend to work well for tutorials because sometimes bumping a minor version requires a code change or covering new concepts. As a tutorial consumer it's frustrating when the content doesn't match the source code unless it's something simple like a version bump.

As a tutorial creator it's your responsibility to ensure things work which ultimately leads to doing everything in your power to remove time as a variable. You can commit a frozen dependency file which locks everything. I sleep pretty well at night knowing things will work tomorrow. Before I did that I had all sorts of things break over the years due to some dependency of a dependency introducing a backwards incompatible change. Now it's predictable and I can control when it's safe to update a set of packages.

I've held off upgrading Flask to 3.0 and Python 3.12 due to these open issues with popular 3rd party packages https://github.com/nickjj/docker-flask-example/issues/17. I'm sure new releases will get pushed in due time. When they are good to go then I'll add a new video update and all is well for everyone. Maintainers can work at their own pace, I can verify everything works in production and then roll it into the course and folks taking the course get an up to date version that's been proven to work.

[0]: https://buildasaasappwithflask.com/

paulddraper 2 years ago

This article uses such odd phrasing.

> Flask 3.0 was released on September 30th, 2023, along with a parallel 3.0 release of Werkzeug

> That day, the Flask-Login extension, one of the most popular of all Flask extensions, stopped working

Every major release BY DEFINITION will break things.

And breaking "that day"? It's really "that second" or "that nanosecond" by the same standard.

---

You can complain about one of two things:

1. Flask did not need to developed a backwards incompatible 3.0 release, but could have developed a backwards compatible 2.* release.

2. Flask-login is too slow to release a version compatible with the newest version of Flask released 3 weeks ago.

But this blog post presents it in...such a weird way.

amanzi 2 years ago

This is a wider issue with Flask and the surrounding ecosystem, and is also why I switched to Django a couple of years ago. I don't recall which package it was specifically, but there was a commonly used security package that was recommended by lots of blogs and tutorials, but the maintainer no longer wanted to maintain it but also didn't want to let anyone else contribute. So it led to another developer forking it and adding a '2' to the end of the name just to keep it current. This wouldn't have been such a big issue if the package didn't add really important security features to Flask, but due to the minimal nature of Flask it really depends on having a well-managed ecosystem of packages. My takeaway was that I felt I couldn't rely on Flask for an application that required features that weren't in the main Flask package itself.

But just wanted to also say, that the main reason I enjoyed working with Flask at the time, was due to Miguel's excellent mega-tutorial. Again, that speaks to the value of having a good ecosystem to support your solution. Flask have ultimately shot themselves in the foot by releasing something they must have known would break a huge number of sites, without bringing the community along with them on the journey.

hiatus 2 years ago

Shouldn't the tutorial author be specifying a version in the tutorial?

  • miguelgrinberg 2 years ago

    Normally tutorials ask readers to install latest versions of everything. If you have to provide a version for every package used in a tutorial, it means that every time any of such dependencies releases a new version the tutorial has to be updated. I guess it is possible for a blog post, but how can I update my books or my videos?

    • adocomplete 2 years ago

      There lies the issue. Installing the latest version of everything for a newly published tutorial, or one that is a few months old, you'll typically get the experience you'd expect.

      But trying to follow along to a tutorial that is old and asks you to install latest version of anything likely means that you won't get far.

      As someone that's written many tutorials, I've been guilty of using "latest" but have been much more proactive here to call out specific versions used at the top of my articles. Nothing worse than getting through half a tutorial to find out something has completely changed.

    • dragonwriter 2 years ago

      > Normally tutorials ask readers to install latest versions of everything.

      They shouldn't.

      They should be doing specified versions, either precise or bounded to the degree you trust the dependency suppliers semver compliance.

      > If you have to provide a version for every package used in a tutorial, it means that every time any of such dependencies releases a new version the tutorial has to be updated.

      No. It doesn't. You document what version is covered. You then have the choice to update that or not.

      OTOH, failing to specify dependency versions means every time abmny of the dependencies releases a new version, the tutorial potentially breaks, which is much worse than working fine but not using a newer version of a dependency when you are not, in either case, using any new features of the new version. (Because if you aren’t upgrading the tutorial, its not covering features of the new version, even if the loosely-specified packages mean uses will pull in the new versions.)

    • ska 2 years ago

      Surely you should specify at least the major version, and/or the version you tested on. Otherwise you are throwing out the entire point of semantic (or semantic-like) versioning.

    • CBLT 2 years ago

      Pip has special syntax for "compatible version" `package~=X.Y`, how about you just always use that in tutorials? The people watching tutorial videos need all the help they can get, why not give them hygienic dependency practices?

      • ehutch79 2 years ago

        next you'll demand people put dates on tutorials, like people even want to know if a tutorial is 10 years old.

    • itishappy 2 years ago

      > how can I update my books or my videos?

      You shouldn't need to. How/why are you writing tutorials for major versions that don't exist yet?

      > `pip install flask` installs the latest version, which is 2.0 at the time of writing

    • hiatus 2 years ago

      If there is a major version upgrade to a dependency, you would have to update the tutorials if there is a backwards-incompatible change.

nicoz3 2 years ago

By reading many of the comments here, it looks like that you are missing the point (maybe you are not a Flask user): it would be great if Flask would only introduce breaking changes in major releases. Unfortunately, many things break with minor releases too. We develop a framework built with Flask, and it is very painful. We always pin Flask< minor version (not major). This is unfortunately happening with other software too. The community should really align and stick to SemVer.

  • acdha 2 years ago

    It’s not missing the point, it’s that the author of this screed lead with whining about a project breaking compatibility on a major release. Since most of the software world has collectively agreed that’s how it’s supposed to work, whatever else they wrote is going to be buried because the author chose to start the post that way. Since they picked a deliberately provocative title there’s little chance that’s going to be a salvageable conversation.

regularfry 2 years ago

It seems to me that the problem here is that everyone directly depends on pypi. The Debian model would be to introduce another repository layer, explicitly to say "everything you install from this repository will work together". Hoping to achieve the same effect with version numbers is a fool's errand, especially when nobody agrees what version numbers mean.

Saphyel 2 years ago

So this is yet another post about how terrible is the python ecosystem with the versions.

The author of the post seems unfamiliar with the meaning of a major release.

maxcountryman (author of flask-login) doesn't know how to pin down versions.

I'm not a big fan of Flask to be honest but this doesn't seem a problem from them. I'd rather blame maxcountryman , the author of the post or pip for this case

  • amanzi 2 years ago

    Flask is a minimal web framework that relies on its ecosystem of packages and tutorials to keep it current and relevant. So yes, this is a problem for Flask if key packages that are recommended in just about all tutorials do not keep up to date.

    • Saphyel 2 years ago

      Technically wrong. Parallels only develops Flask and they want to keep Flask as minimal as possible, they don't even want to move away from the legacy optparse for Click, so this kind of "minimal work".

      Key packages are developed by the community so lack of understanding or no cooperation with Parallels it's not really a Flask issue.

      Unfortunately the only solutions for this are:

      * Join Parallels and try to change things.

      * Use different package, there's plenty web frameworks.

      * Understand better semver, and python should try to promote this, or move away from semver to calendar releases like Ubuntu/Jetbrains

jollyllama 2 years ago

Can anyone challenge the author's assertion that the 3.0 release doesn't bring any improvements?

  • miguelgrinberg 2 years ago

    My assertion is that none of the refactorings in the 3.0 release bring a benefit to the community. I did not imply that the entire 3.0 release is void of improvements.

    • jollyllama 2 years ago

      The nuance escapes me, but I'm sorry to put words in your mouth.

      I'm still interested in any countervailing opinions on this particular detail.

    • ilyt 2 years ago

      But it (presumably) brings benefits to the authors. Sometimes you need to cut the zipties and install the air filter properly...

rs_rs_rs_rs_rs 2 years ago

"Don't make breaking changes because they break my book" is peak entitlement.

JodieBenitez 2 years ago

Hence why I prefer Django over Flask any day. Less moving parts, more stability. I even upgraded Django apps from one major version to another with little to no change to the apps.

bigdog42 2 years ago

Looks like the changes are already in FlaskLogin

https://github.com/wangsha/flask-login/commit/6d1b352dd5106e...

but not yet released.

This is more an issue with versioning

Forgotthepass8 2 years ago

This occurs all the time when using LLMs for code due to the variety of versions of each lib in their training data (which is typically years old already)

Some sort of automatic functionality to find deltas in libraries (even just crude function inspection between versions) and detect/remap them (or roll back versions) might solve that and issues like this.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection