Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
Description
Feature or enhancement
We should discourage and deprecatetyping.AnyStr
.
Pitch
typing.AnyStr
is bad for many reasons:
- The name implies that it has something to do with the type
Any
. It has nothing to do with the typeAny
. - The name implies that it means "any string". It does not mean "any string".
AnyStr
is aTypeVar
, but the name does not follow the common naming convention for TypeVars (using a "T" suffix). Many users appear to think that it is equivalent tostr | bytes
, which is incorrect.AnyStr
is the only type variable that is publicly exported from thetyping
module. Unusually, it is a constrained type variable. Constrained type variables are usually not what users want for modern APIs. Bound type variables, in general, have more intuitive semantics than constrained type variables.- One of the motivations forPEP-695 (accepted by the Steering Council, and now implemented) was the fact that reusable type variables can be confusing in terms of their scope. In general, I believe the consensus of the typing community is that usingPEP-695 syntax for creating type variables clarifies the scope of type variables and makes them more intuitive for users. As such, we should discourage using reusable TypeVars such as
AnyStr
.
For all of these reasons,AnyStr
isvery commonly misused, especially by typing beginners. We get many PRs at typeshed that misuseAnyStr
, and it can often be hard to catch these misuses in CI (careful manual review is required).
Therefore, we should discourage and deprecatetyping.AnyStr
. Unfortunately, it is very widely used, so the deprecation period will have to be a long one.
I propose the following plan:
Clarify the docs for
typing.AnyStr
. Explain more clearly the differences betweenAnyStr
and a union; give examples of uses ofAnyStr
that would be invalid. This docs clarification can be backported to 3.12 and 3.11.In Python 3.13, state in the docs that using
AnyStr
is deprecated and that users are encouraged to usePEP-695 syntax wherever possible.In Python 3.16, remove
AnyStr
fromtyping.__all__
, and start emitting aDeprecationWarning
if a user doesfrom typing import AnyStr
or accessestyping.AnyStr
.Removing it from
__all__
will be a breaking change, but it's the only way to emit aDeprecationWarning
fortyping.AnyStr
before removing it unless we're okay with emitting aDeprecationWarning
any time a user doesfrom typing import *
(and I'm not).In Python 3.18, remove
AnyStr
from thetyping
module.
Thoughts?