On Thu, 22 Apr 2021 at 13:23, Adrian Freund <mail@freundtech.com> wrote:
According to PEP 484 all missing annotations in checked functions should be handled as Any. Any is compatible with all types.
Yep, that's what I understood to be the case.
I think from a technical standpoint it should be possible to infer protocols for arguments for most functions, but there are some edge cases where this would not be possible, making it impractical to make this the default behavior. Having an annotation to make a type checker infer a protocol would be interesting though.
Absolutely, I see no problem with "use duck typing for this argument" being opt-in.
For example:
def f(x: int): ... def g(x: str): ...
def main(t): if t[0] == 'version': f(t[1]) elif t[0] == 'name': g(t[1])
You could statically type t as Union[Tuple[Literal['version'], int], Tuple[Literal['name'], str]], but inferring a Protocol for this would be either very hard or even impossible, especially with even more complex conditions.
Yes, but that's inferred static typing which is *not* what I was proposing. I was suggesting that the checker could easily infer that t must have a __getitem__ method, and nothing more. So the protocol to infer is class TypeOfT(Protocol): def __getitem__(self, idx): ... It would be nice to go one step further and infer class TypeOfT(Protocol): def __getitem__(self, idx: int): ... but that's *absolutely* as far as I'd want to go. Note in particular that I don't want to constrain the return value - we've no way to know what type it might have in the general case. IMO, inferring anything else would over-constrain t - there's nothing in the available information, for example, that says t must be a tuple, or a list, or that t[3] should have any particular type, or anything like that. My instinct is that working out that t needs to have a __getitem__ that takes an int is pretty straightforward, as all you have to do is look at where t is used in the function. Four places, all followed by [] with a literal integer in the brackets. That's it. I fully appreciate that writing *code* to do that can be a lot harder than it looks, but that's an implementation question, not a matter of whether it's reasonable as a proposal in theory. This feels like *precisely* where there seems to be a failure of communication between the static typing and the duck typing worlds. I have no idea what I said that would make you think that I wanted anything like that Union type you quoted above. And yet obviously, you somehow got that message from what I did say. Anyway, as I said this is just an interesting idea as far as I'm concerned. I've no actual need for it right now, so I'm happy to leave it to the mypy developers whether they want to do anything with it. Paul