-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
WIP: unify [] and [1] to list[int] rather than object #2257
Conversation
This isn't really sound ( The right way to fix this would be at type inference time, though it's tricky because we need the result of type checking one argument in a function call to affect the type inferred for another argument of that call. |
@rwbarton but the case of list-literal is different, since the literal itself is immutable. Am I wrong? |
In other words, if hypothetically we had a "list literal" type - essentially a tuple - this was going naturally and smoothly. We already have this type, but we don't give it its own class . Instead, we special-case it in multiple assignment and in other circumstances, thus being forced to carry syntax information to type checking. |
@rwbarton: I had hoped that the mechanism whereby We see the same issue occur with e.g. @elazarg: IIUC what we need is a way to say that the type of Care would however have to be taken that whenever such a specially marked "coercible" list is assigned to a variable or passed to a function it is coerced to a regular (invariant) list type, since the following two examples are not the same:
vs.
In the first case the type of the empty list literal can be coerced to |
(I still have much to learn here, but I'll speak my mind anyway) The Regarding your concerns, perhaps a better name to "literal type" is "temporary type" - as long as we know that the list cannot be mutated outside the inferred context (which does not hold in your last example), it should be fine[1]. I think this information is partially kept in Expression as Having this information about temporary-value-types (or literal types), maybe the conditional expression problem will just solve itself. [1] Even things like |
If it's not the join, maybe it's the meet? They are each others opposites.
|
No, it is the join. It's just that (IIUC) the function does not have the information to be sure it's sound unless t <: s or s <: t, even though it is sound in the case of e.g. literal. Your patch hard coded this information in the case of UninhabitedType, and as @rwbarton and you pointed out it might be sound, as long as we reject UninhabitedType from being a type-argument in a type of something that can be mutated. It is the case in "pure" literals, but I am not sure it is the case in general. (Meet is related to intersection, which means each element of the list is "both" s and t. As in a fallback, promotion or multiple inheritance. I can't see how it applies to this case; I will enjoy being proved shortsighted here though) |
My brain hurts. I'll close this PR. |
In an early predecessor of mypy I actually had separate types for things like However, just supporting this for empty collections could be more straightforward, though it seems like the benefit would be pretty marginal and better error messages would perhaps make the problem mostly go away. |
@JukkaL and/or @ddfisher Can you help me make this work? I'm trying to fix #2255, which has this example:
and the type inferred is list[object] rather than e.g. list[int].