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