TypeVars with constraints in other languages #1080
Unanswered
JelleZijlstra
asked this question in
Q&A
Replies: 3 comments 7 replies
-
I don't know any. I also think that this is a very problematic piece of code.
I would really like to see it removed! 🙏 |
Beta Was this translation helpful? Give feedback.
3 replies
-
I agree that the way this kind of |
Beta Was this translation helpful? Give feedback.
3 replies
-
On Wed, Feb 16, 2022 at 3:40 PM Alex Waygood ***@***.***> wrote:
Even AnyStr could be redefined using bound: AnyStr = TypeVar("AnyStr",
bound=str|bytes)
This is subtly different from the current definition of AnyStr -- AnyStr
only allows str or bytes as values, but not subclasses of str or bytes,
whereas using a bound also allows subclasses. The AnyStr value restriction
is needed to precisely model certain nuances of stdlib functionality. For
example, this function doesn't type check correctly with a union bound,
since concatenating a string to an instance of an arbitrary str subclass
produces a str:
def concat(x: AnyStr, y: AnyStr) -> AnyStr:
return x + y # Only okay with the current definition with AnyStr
class S(str): pass
concat(S(), 'x') # Result is 'x' (str instance, not S instance)
Of course, we could also use @overload, though that would be more verbose
and type checking wouldn't be as precise (but probably good enough).
AnyStr was added quite early in the development of the typing module, and
the primary motivation was to support IO[AnyStr], Match[AnyStr] and
Pattern[AnyStr]. These work with str or bytes, but they don't properly
support subclasses of str/bytes. For example, IO[S] where S is a subclass
of str doesn't quite make sense. Maybe it would have been better to use
union bounds, even if they are arguably somewhat incorrect, but it would
probably be too disruptive to change this now. When AnyStr was added, we
didn't even have union types!
I think that documentation shouldn't emphasize AnyStr, since the use cases
where it actually is better than an overload/union are quite rare, at least
outside the stdlib. Very often people use it incorrectly. Even in the
stdlib stubs most uses of AnyStr should perhaps be replaced with overloads.
AnyStr makes some signatures more compact, but it's often used pointlessly
in cases where str|bytes would be better.
JukkaMessage ID: <python/typing/repo-discussions/1080/comments/2189618@
github.com>
… |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
We support this form for creating TypeVars:
I haven't encountered this sort of thing in other languages that support type variables. For example, TypeScript only supports a form that looks equivalent to our
bound=
(although confusingly they call it a constraint).Are there other languages that support this feature? I'm asking because the way this kind of TypeVar behaves isn't very intuitive to me, so I'd like to see how other languages handle it.
Beta Was this translation helpful? Give feedback.
All reactions