-
-
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
Type constraints: dict.get doesn't accept Union type as key #1472
Comments
The reasonable middle ground I hope for would require there's some overlap (like between int and Union[int, str] in the example). @JukkaL: I don't know if that's a reasonable thing to expect mypy to implement? I don't think this can be solved with just a typeshed update. |
I've also encountered exactly the same case, and there are many related situations: Arguably the theme underlying all these cases is whether it makes sense to compare One interesting experiment would be to see whether the more specific type for
The idea would be that these constraints do not affect inference, but are simply checked just before trying to instantiate a generic function at a call site. Type variable value restrictions and upper bounds could also potentially be recast in this form (though the existing syntax would still be more convenient in many cases). |
That looks an awful lot like type classes... 🎉 |
That's not entirely a coincidence, and may reflect my biases more than anything else. It's really just the constraints part though, and not type classes themselves (class constraints are one possible form of constraint, but there are others such as type equality or subtyping constraints). I'm not proposing to allow the user to define their own type classes or instances. We could also reverse my last comment, and turn the constraint into an attribute of one of the type variables involved, which fits better with existing mechanisms.
The intended meaning of |
I've thought about supporting constraints for (generic) functions that live outside the type signature proper, though the idea of "equatable" is new to me. It sounds like a good idea. I can see us having two kinds of constraints -- type-based constraints and value-based constraints. The latter would perhaps only work for argument values that are literals or constants. Here are some examples where type based constraints could come in useful, in addition to the examples given by Reid above:
Here are potential examples of value constraints:
It's not obvious what do do when a value constraint can't be evaluated because the value is determined at runtime. To be compatible with how things work right now, we could fall back to We can't invent any new syntax for this. Here are a few ideas for a constraint syntax:
A decorator could easily make the constraints available for introspection, which could be useful. If we'd use a comment, we'd have more freedom with syntax. For example, we could have a constraint such as Even if we decide to implement this, this is likely less urgent than a bunch of major things in the pipeline such as strict optional checking, parallel type checking and a plugin system. This is also likely less important than structural subtyping. |
To address just a small part of what you said: if we can't determine the particular value in a value constraint, the return type should probably just be a Union of all the possibilities. |
Having it be a union of all possibilities could sometimes be pretty inconvenient. Also, it would be against the mypy policy of trying to not infer union types unless explicitly annotated. For example, consider
The cast wouldn't be terrible (at least as long as this isn't a common idiom), since the code could be wrong if |
But you'd only need to do that if mode was supplied dynamically, which is pretty rare. Requiring that cast is probably a good thing -- forgetting that open() might return bytes when you're expecting a str (or vice versa) is an easy mistake to make in that circumstance, in my opinion. |
I think that this is probably too complex to be worth implementing in the medium term. Anyway, type system extensions should now be proposed through the typing issue tracker or typing-sig@. |
Passing an overly-general Union to dict.get, like this:
results in this error:
Arguably, this should be allowed, because
get
provides a default if the item is not found (unlike__getitem__
). But by that logic, potentially any type should be a valid argument toget
, which doesn't seem right.@gvanrossum: further thoughts?
The text was updated successfully, but these errors were encountered: