Thereās a lot thatās missing from this that would make me unlikely to use it in Flask.
I try to be as specific and helpful as possible in my deprecation messages, because otherwise (and regardless) I have to deal with more user reports. I use some common message patterns, like:
'{name}' is deprecated and will be removed in Flask {version}. Use '{other}' instead.
The '{name}' parameter is deprecated and will be removed in Werkzeug {version}. It's always enabled now.
'{name}' has been renamed to '{other}'. The old name is deprecated and will be removed in Jinja {version}.
I write mine manually for my specific situations, but SQLAlchemy has a whole set of decorators that can handle all different types of deprecations, check call arguments, and show specific messages at runtime and in documentation. sqlalchemy/deprecations.py at 586df197615d91af56aefc0d5ff94ceac13154eb Ā· sqlalchemy/sqlalchemy Ā· GitHub
Despite the stats you have, I do remove or rename arguments and attributes/properties, and move things between modules, often enough. I donāt plan to do it a lot, because itās disruptive, but it still happens. Perhaps your stats are only considering the latest versions, whereas if you checked a few versions ago youād see a lot more of them (theyāve been fully removed at this point).
The stack level canāt always be assumed to be 2. Iād need to go back and look, but I remember using 3 for base classes where you want to show the warning from __new__
or __init__
when a subclass inherit them.
We also have to consider imports, not only calls. Iāve run into cases where a downstream library re-exported a name we deprecated. They never saw the warning during tests because they never called it themselves, so users broke when we updated even though nothing changed for them. (Yes, they should pin their dependency tree.) Now that module-level __getattr__
exists, we can make sure that warnings happen at import. This also helps for moves, allowing the old name to still work with a warning pointing at the new name. Iād hope that something in the standard library would be able to warn on both import and use at runtime.
Finally, projects like Flask and SQLAlchemy already have a really hard time using typing correctly and keeping up with changes. Adding another decorator we have to use on top of all the work we already do for deprecations, and that users will complain about if we donāt use, isnāt really helping. What would help is basically including SQLAlchemyās solution, or another solution, for full control over messaging about changing APIs.