On Thu, 22 Apr 2021 at 13:23, Adrian Freund <m...@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
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/CU7OES4P3KUCQMD3U5766XVOESL43DRF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to