Rather than defining a new Any type, this seems to me rather like a TypeVar with what the Mypy docs call value restriction (not a bound).  For example:

> * ip_address() can return either an IPv4Address or an IPv6Address, depending on the input string.
> * urlopen() can return either an HTTPResponse or an addinfourl.  

def ip_address(s: str) -> TypeVar("address",  IPv4Address,  IPv6Address): ...
# and similarly for urlopen()

I think this would also require new logic from typecheckers because I don't believe you can currently have a return typevar without an argument typevar, but the spelling makes sense to me and narrowing should be as obvious as it ever is between typecheckers.

> * json.loads() et al. can return a selection of types, depending on the input.

JSON is really a case for recursive types - "we usually omit the base case" isn't much worse to me than "one or more layers in it's just Any".

--Zac 

On Tue, 22 Sep 2020 at 00:15, Guido van Rossum <guido@python.org> wrote:
If we implement this, are we sure that IDEs like PyCharm and/or vscode (e.g. pylance) will use and implement this? Or is that part just speculation?

On Mon, Sep 21, 2020 at 06:45 Sebastian Rittau <srittau@rittau.biz> wrote:
This has previously been discussed here:

https://github.com/python/typing/issues/566.



In typeshed we have found that there a quite a few cases where functions

can return two or more different, incompatible types, that can't be

distinguished by the input types alone. A few examples:



* ip_address() can return either an IPv4Address or an IPv6Address,

   depending on the input string.

* float ** float returns either a float or a complex. Currently,

   typeshed marks this as returning just float.

* json.loads() et al. can return a selection of types, depending on

   the input.

* urlopen() can return either an HTTPResponse or an addinfourl.



There are more examples in the linked issue.



In these cases, returning a Union would technically be correct, but

would also be inconvenient for callers that know what type to expect.

We usually give up and just return Any.



My suggestion would be to add a type tentatively called "AnyOf",

that acts as an unsafe union:



   ip_address(address: str) -> AnyOf[IPv4Address, IPv6Address]



I believe this could be useful for type checkers. While the use of

AnyOf is unsafe, it is safer than just treating these return values

as Any. It's also theoretically possible to use some clever

narrowing. That said, there has been some pushback from the mypy

core team in the linked issue, especially since this is most likely

complex to implement. An easy way for type checkers to implement

this, without sacrificing any already existing type safety is to

just treating AnyOf exactly like Any. At least as a first step.



Should type checkers implement full support for AnyOf later, we

could already have better types in typeshed ready to use.



But in the last years, typeshed has also gained users outside of

type checkers. For example, PyCharm and jedi use it for

autocompletion. I believe that AnyOf could be useful for those

projects, as well as others.



Is there interest in a feature like this? I would be willing to

write a PEP and contribute the AnyOf = Any solution to mypy.

Unfortunately I don't have the bandwidth to learn how to implement

this "properly" in mypy.



  - Sebastian

_______________________________________________

Typing-sig mailing list -- typing-sig@python.org

To unsubscribe send an email to typing-sig-leave@python.org

https://mail.python.org/mailman3/lists/typing-sig.python.org/

Member address: guido@python.org

--
--Guido (mobile)
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: zac.hatfield.dodds@gmail.com