[This is based on a discussion between me and @gvanrossum last week. I'm writing this down so that we won't forget about this.]
Several stdlib functions have signatures where the return type depends on the value of an argument. Examples:
open returns an IO[str] or IO[bytes] depending on whether the mode argument has 'b' as a substring.subprocess.check_output returns a str or bytes depending on the value of the boolean universal_newlines argument.
A simple way to support these would be to introduce a few additional types that work with str and bool literals:
- A string pattern type that can describe the contents of a string literal, perhaps using a regular expression.
- Types for
False and True.
For example, if we had FalseType and TrueType, we could write a function whose return value depends on the value of a boolean argument:
@overloaddeff(x: FalseType) ->bytes: ...
@overloaddeff(x: TrueType) ->str: ...
deff(x: Any) ->Any:
ifx:
return'x'else:
returnb'x'reveal_type(f(False)) # bytesreveal_type(f(True) # str
Not sure about this one:
...
x=bool('')
reveal_type(f(x)) # Union[str, bytes] since we don't know the boolean value statically?We could also have a generic class where a generic type argument depends on the value of an argument to __init__. Not sure how we should represent these -- here is one potential approach:
classC(Generic[AnyStr]):
@overload@returntype('C[str]')def__init__(self, x: TrueType) ->None: ...
@overload@returntype('C[bytes]')def__init__(self, x: FalseType) ->None: ...
...
reveal_type(C(True)) # C[str]Alternatively, we could use __new__, but this would be problematic if there is no corresponding method defined at runtime.
[This is based on a discussion between me and @gvanrossum last week. I'm writing this down so that we won't forget about this.]
Several stdlib functions have signatures where the return type depends on the value of an argument. Examples:
openreturns anIO[str]orIO[bytes]depending on whether the mode argument has'b'as a substring.subprocess.check_outputreturns astrorbytesdepending on the value of the booleanuniversal_newlinesargument.A simple way to support these would be to introduce a few additional types that work with
strandboolliterals:FalseandTrue.For example, if we had
FalseTypeandTrueType, we could write a function whose return value depends on the value of a boolean argument:Not sure about this one:
We could also have a generic class where a generic type argument depends on the value of an argument to
__init__. Not sure how we should represent these -- here is one potential approach:Alternatively, we could use
__new__, but this would be problematic if there is no corresponding method defined at runtime.