I don’t think any such intent was intentional. It’s probably a reference to option types found in functional languages like Haskell (although it doesn’t function like an option type). Something I haven’t seen brought up is how one would create a union programmatically without Union. Would you call type.__or__ on types recursively? Or do we consider such runtime uses to be outside the scope of typing? Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Friday, December 17th, 2021 at 14:50, Paul Moore <p.f.moore@gmail.com> wrote:
On Fri, 17 Dec 2021 at 11:32, Sebastian Rittau srittau@rittau.biz wrote:
Am 17.12.21 um 10:47 schrieb Paul Moore:
This is (to my mind, at least) very clear with
Optional, where Optional[int] says "you can provide an int, or miss
this out", but int | None says "you can provide an int or the value
None". When None is merely a sentinel, representing "use the default",
Optional[int] expresses the intent far better, and hence is more
"obvious" to me¹.
But "Optional" does not mean that you can "miss this out". (" = ..."
means that in arguments like in rest of Python.) It means "you can
provide an int or the value None". This is a common mistake and a good
demonstration why "Optional" should be deprecated.
So how do I annotate the following function to say that callers can
only pass an int, or omit the argument?
def my_fn(a=None):
if a is None:
a = <some complex calculation that I don't want to do in
the function header>
In this case, my intention is that the user should only ever pass an
integer as a value for a. The use of None is a technical detail, not a
part of the declared API. I might later choose to replace None with an
opaque sentinel, and I want the type hints to express that by saying
that a is an optional integer, but not that None is a valid value,
so that callers which pass an explicit None get flagged. (Yes, I
accept that maybe this is bad API design. But I'd rather not get
sidetracked on that point - I can argue that there are cases where
it might be reasonable, but it's not the point here).
I understand that the implementation of Optional[int] is identical
to int|None. But my point is that the intent is different, and being
able to express intent, even if it's not (currently...) possible to
actually check the difference doesn't alter that. Remember that I'm
responding to the idea that int|None is the "one obvious way" to do
this - but for me, it's not obvious because it expresses the wrong
intention.
It's similar to the fact that Python has a += 1 and a = a + 1. The
former expresses the intention "increment" whereas the latter
expresses the intention to set a to a new value based on an
expression. Which I use depends on what I intend to convey to the
human reader - even though the computer doesn't care about the
difference.
Paul
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: layday@protonmail.com