-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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 checking functions where return type is always None if an argument is None #885
Comments
I've thought a bunch about how C++ does it. I do think the right thing is to model it internally as a generic, though I'm not sure it that should be explicit, or implied because Suggested syntax:
|
For |
Its worth keeping in mind that Such functions are also silly in a design where you have |
Why is
illegal according to PEP 484? It looks perfectly legal to me. |
|
What level of inference is it reasonable to expect from a checker?
and have the function type correctly inferred from the source. |
In general, inference across functions is not something I'd like to tackle yet. This would imply whole-program analysis which is the graveyard of over-ambitious Python type checking projects. However in this particular case you could argue that a sufficiently smart type checker itself could take the definition of convert() and infer the overloaded rewrite without help. That's nice but I don't want PEP 484 to require it. So for now you'll have to write it using an overload. Hopefully allowing overloads in non-stub files will make this less painful. (#1136, also python/typing#175) |
Jukka's original example can be expressed with overloads, even outside stub files. Some of the ideas in this issue are broader, but since the original use case has been addressed, I don't think it's worth it to keep this issue open. |
The correct way of using overloads for the Jukka's example would be from typing import Optional, overload
@overload
def convert(s: str) -> int: ...
@overload
def convert(s: None) -> None: ...
def convert(s: Optional[str]) -> Optional[int]:
if s is None:
return None
return int(s) Edit: see also #6113 (comment) for when using |
Some time ago I encountered another issue in production code that we may need to solve before implementing strict
None
type checking (#357). Consider a function like this:Now code like this would be rejected according to PEP 484 rules, as the return type unconditionally includes
None
:We could use overloading or single dispatch to model this, but this would involve pretty major refactoring for existing code and probably some performance overhead.
Alternatively, we could model this as a generic function, but currently there's no syntax to model the above case. Here is a strawman proposal:
OptionalTypeVar
would work a bit likeTypeVar
with values, such asAnyStr
, with a slight twist: the first value would always beNone
, and the second value is the index value, and this could have multiple different values in different positions. SoMaybe[T]
would be replaced withNone
orT
, but all instances ofMaybe
would get either the first or second value everywhere in lock step fashion. The above function would thus be equivalent to this from type checking perspective (assuming we had overloading):We could generalize this to arbitrary collections of types. I can't come up with a good syntax, but here is the first thing that comes to mind:
The semantics would be the same as above. Now we could define a function that maps ints to string and vice versa:
Here the issue is that we can't have multiple alternate variables that could vary independently. Maybe there would be a way to define additional
Alternate
variants with different names, similar toTypeVar
.The latter could also deal with
True
andFalse
polymorphism assuming they would be considered subtypes ofbool
. Here is an example that is similar to some examples in the std library (insubprocess
, I think):Interestingly, we could replace
AnyStr
with this definition instead of usingTypeVar
:The text was updated successfully, but these errors were encountered: