-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
How should we add @deprecated
to objects in the standard library?
#11002
Comments
I think (3) is the right answer in general. In versions before the one that introduces the runtime deprecation, there may not be a suitable replacement, so if we emit warnings, we're not telling users anything actionable. |
I vote for if sys.version_info >= (3, 9) and sys.version_info < (3, 11):
@deprecated("Deprecated in Python 3.9; will be removed in Python 3.11")
def example() -> None: ...
elif sys.version_info < (3, 9):
def example() -> None: ... It looks a bit too verbose. I think that deprecation warnings are generally useful. It is up to users to disable them with something like |
Moreover, users with |
I also tend to favor (3), but this is probably something where we need to gain some experience. |
Another question: how do we define "deprecated at runtime"? I also favour (3) generally, but I think it's probably okay for us to have |
Following the features Ivan introduced in python/mypy#15164, it's actually fairly easy to tackle that problem: you can just do |
Because of the potential difference between typing and runtime, I'd prefer option 2 over option 1. A bit more context and information doesn't hurt the developper. As for 2 vs 3, here's some of my immediate thoughts, whether or not these are particularly strong arguments: This only affects static checkers. And can likely be disabled in static checker. A user stuck in a case where this is not replaceable could either add a suppression comment, or disable the check entirely if it's not applicable to them. Maintainability aside (I think the stdlib should thrive to do "what's right" even if a bit more cumbersome), it is nice to follow the exact runtime implementation, but we have a lot of precedent for not doing so in the context of static typing. My gut feeling is to promote the most up to date ways of doing things. Which the python type system often offers mechanisms to do so and promote whenever possible ( I'm also biased for wanting warnings as soon as possible. Maybe option 3 could be used not to differentiate when it's been deprecated, but for when there's no replacement mechanisms?
This has happened to me a handful of times.
Ah! Nice, though idk about other checkers than mypy. Edit: quoting Jelle below:
You may also want to consider what's friendlier to older projects supporting older python versions to adopt static type checking. More early hurdles doesn't help adoption. |
We can probably have But even in the
If the effect of what we're doing is that users simply turn off deprecation warnings, we're doing it wrong. |
Most stubs won't be throwing a deprecation warning, because the implementation of deprecation wildly varies in the wild. Sometimes is printed, sometimes it's a python warning, sometimes it's just a comment, just in the doc, etc. I think it's beneficial to mark all those as deprecated in 3rd party-stubs anyway. And I think it would be beneficial for that mentality to be consistent across stdlib and 3rd party stubs. as long as it's properly documented as deprecated for that version (if going for option 3) |
Jelle already mentioned it, but here is a theoretical example, where I wouldn't want the type checker to warn: if sys.version_info >= (3, 11):
shiny() # introduced in 3.11 as alternative for cruddy()
else:
cruddy() # deprecated in 3.11 By using |
I think we should default to 2, unless there doesn't yet exist an appropriate replacement (the Something like:
Unlike CPython, we have the ability to time travel, and this is a great thing. Concretely, this would have been helpful for me when upgrading my work codebase from 3.9 to 3.11. |
#11009 covers a couple more deprecations from the standard library to help guide the decision. |
If an object is deprecated in Python 3.12, to be removed in Python 3.14, should we decorate it like this? (1)
Like this? (2)
Or like this? (3)
For somebody who uses Python 3.8, it might be surprising if a type checker started emitting warnings about an object being deprecated if the runtime only emits a
DeprecationWarning
on Python 3.12+. For that user, Python 3.14 will be a long way away; they might not even be able to switch to the newer way of doing things yet (perhaps the "replacement idiom" only exists on Python 3.9+). For us in typeshed, however, (3) is obviously the most tedious option for us to maintain, as it will mean more branches.Thoughts?
The text was updated successfully, but these errors were encountered: