Add explanation of singletons in unions to PEP484
By Ivan Levkivskyi (https://github.com/python/typing/pull/240).
This commit is contained in:
parent
a558bf5733
commit
bf22a02332
60
pep-0484.txt
60
pep-0484.txt
|
@ -846,6 +846,66 @@ This is equivalent to::
|
|||
|
||||
def handle_employee(e: Optional[Employee] = None) -> None: ...
|
||||
|
||||
|
||||
Support for singleton types in unions
|
||||
-------------------------------------
|
||||
|
||||
A singleton instance is frequently used to mark some special condition,
|
||||
in particular in situations where ``None`` is also a valid value
|
||||
for a variable. Example::
|
||||
|
||||
_empty = object()
|
||||
|
||||
def func(x=_empty):
|
||||
if x is _empty: # default argument value
|
||||
return 0
|
||||
elif x is None: # argument was provided and it's None
|
||||
return 1
|
||||
else:
|
||||
return x * 2
|
||||
|
||||
To allow precise typing in such situations, the user should use
|
||||
the ``Union`` type in conjuction with the ``enum.Enum`` class provided
|
||||
by the standard library, so that type errors can be caught statically::
|
||||
|
||||
from typing import Union
|
||||
from enum import Enum
|
||||
|
||||
class Empty(Enum):
|
||||
token = 0
|
||||
_empty = Empty.token
|
||||
|
||||
def func(x: Union[int, None, Empty] = _empty) -> int:
|
||||
|
||||
boom = x * 42 # This fails type check
|
||||
|
||||
if x is _empty:
|
||||
return 0
|
||||
elif x is None:
|
||||
return 1
|
||||
else: # At this point typechecker knows that x can only have type int
|
||||
return x * 2
|
||||
|
||||
Since the subclasses of ``Enum`` cannot be further subclassed,
|
||||
the type of variable ``x`` can be statically inferred in all branches
|
||||
of the above example. The same approach is applicable if more than one
|
||||
singleton object is needed: one can use an enumeration that has more than
|
||||
one value::
|
||||
|
||||
class Reason(Enum):
|
||||
timeout = 1
|
||||
error = 2
|
||||
|
||||
def process(response: Union[str, Reason] = '') -> str:
|
||||
if response is Reason.timeout:
|
||||
return 'TIMEOUT'
|
||||
elif response is Reason.error:
|
||||
return 'ERROR'
|
||||
else:
|
||||
# response can be only str, all other possible values exhausted
|
||||
return 'PROCESSED: ' + response
|
||||
|
||||
|
||||
The ``Any`` type
|
||||
----------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue