-
Notifications
You must be signed in to change notification settings - Fork 28
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
Deprecate TypeAlias
, TypeVar
, ParamSpec
, TypeVarTuple
, Generic
if you are using >= 3.12
#244
Comments
what if you want to explicitly specify the variance, you can't do that with the new generic syntax right? |
@DetachHead I once made an attempt at a PEP that uses ... anyway, what about allowing |
@jorenham We think that Also see this series of discussions where I tried to argue the same thing: It also seemed that Traut missed a lot of relevant info about other languages variance: |
But then how would you be able to explicitly mark a type type parameter as being invariant, in cases where the type checker infers it to be co- or contravariant? This could become especially confusing with With prefix operators, the obvious solution is I also think that class Spam[-V, +R: Sequence[tuple[str, int]]]: ... vs class Spam[In[V], Out[R: Sequence[tuple[str, int]]]]: ... In case of upper bounds, it isn't immediately obvious how to define it; should it be There's also the naming issue of Just like I've seen |
That would be the default: class A[T]: ... # invariant Or, if you were interested in preserving pep compliant behavior, an class A[InOut[T]]: ...
Ideally, these would be soft keywords, which would relieve your concerns: class A[in T: str]: ... Unfortunately this would be a syntax change. I prefer
Again, ideally it would be be Additionally, Kotlin, TypeScript, Dart and others all use
Under my implementation, any invalid usage would raise a type error, but what cases are you referring to? use site variance is valid: a: list[int] = []
b: list[out object] = a # no error |
That would break backwards compatibility, since the (PEP 695) default is to automatically infer variance.
It was a challenge to find something about it online, but somewhere on the third Google page, I managed to find a brief mention of
Yes, that would make it a lot better. I'm not sure whether the PEG parser will like it though, since the
I can see how it can be considered to be "more pythonic". But in the same way, class SupportsHashableGetitemThatReturnsAStringSubtype[
in KeyType: Hashable,
out ValueType: str,
](Protocol):
def __getitem__(self, key: KeyType, /) -> ValueType: ... For some reason, off-by-once formatting/indentation things like these can keep me up at night, but that's probably just me 🤷🏻♂️.
In your example you attempt to make Variance is a property of a type parameter of a specific type. So it should be used when declaring types or type-aliases. So theoretically speaking, |
Don't care about breaking backwards comparability, but for the 484 inclined, there would be the option for Basedmypy already breaks a lot of backwards compatibility, and I plan to break it a hell of a lot more.
@DetachHead has an eslint plugin that enforces the correct variant annotations
I disagree,
Yeah, it's currently an exception when you try to do it with
I disagree. No matter how I look at
Good point, but the same could be said about an invariant vs Xvariant one: class A[
X,
+Y,
]: ... Maybe formatters could special case this scenario and produce: class A[
in T1,
out T2,
]: ...
The concept of use-site variance (which no python type checkers support) is very useful to modify an invariant type parameter to become co/contra variant: a: list[int] = []
b: list[out object] = a # no error In this example, class A[T]:
def set(self, t: T): ...
def get(self) -> T: ...
a: A[out object]
a.set(1) # error: expected "Never", found "int" The same could be applied to a usage with a type parameter passed as a type argument: def f[T, R: T](r: R, t: T) -> R:
a: list[R] = [r]
b: list[out T] = a # no error
b[0] = t # error: expected "Never", found "T@f"
return b[0]
Yes, I do agree with this notion. you are correct in that the |
Biviarance is effectively being both co- and contravariant, so if
The alignment with prefix ops can be made pretty again if you're explicit about your invariance: class Generator[
-V,
~T,
+R,
]: ...
I didn't know about site-variance; it's pretty cool! Any plans on submitting a PEP for this? |
@DetachHead has different feelings about backwards-compatibility that I do. So he would probably have different ideas here for basedpyright.
Yeah, I was pushing hard before 695 was finalized, but no-one listened 😢. Although, I still think that 695 should be updated to default to invariant. The backwards breakage would be worth it in my opinion.
True, but we would just say that it falls as invariant and be done with it.
I tried working on the |
... so can I expect a basedpython fork / pre-compiler then? |
Yes. But because type annotations aren't generally evaluated at runtime, we can get away with a lot of stuff like intersections/type-guards in basedmypy: from __future__ import annotations
a: int & str # no runtime error
def guard(x: object) -> x is int: ... # no runtime error Additionally, there aren't too many use cases for evaluating runtime annotations, so it can be handled case by case: |
when deprecating Foo = int |
If you use So an alias for a type != a type alias... |
yeah but in my experience most of the time it's used as a type alias. perhaps the option to ban them can be a separate setting |
Perhaps only do it for type-only stuff, like Or maybe it's possible to detect wether |
I'd like to also add that you must use |
There's no need for class Spam[T = object]: ... |
Oops sorry, I meant you have to use it even when working with Python 3.12 |
No description provided.
The text was updated successfully, but these errors were encountered: