@@ -846,6 +846,66 @@ This is equivalent to::
846
846
847
847
def handle_employee(e: Optional[Employee] = None) -> None: ...
848
848
849
+
850
+ Support for singleton types in unions
851
+ -------------------------------------
852
+
853
+ A singleton instance is frequently used to mark some special condition,
854
+ in particular in situations where ``None`` is also a valid value
855
+ for a variable. Example::
856
+
857
+ _empty = object()
858
+
859
+ def func(x=_empty):
860
+ if x is _empty: # default argument value
861
+ return 0
862
+ elif x is None: # argument was provided and it's None
863
+ return 1
864
+ else:
865
+ return x * 2
866
+
867
+ To allow precise typing in such situations, the user should use
868
+ the ``Union`` type in conjuction with the ``enum.Enum`` class provided
869
+ by the standard library, so that type errors can be caught statically::
870
+
871
+ from typing import Union
872
+ from enum import Enum
873
+
874
+ class Empty(Enum):
875
+ token = 0
876
+ _empty = Empty.token
877
+
878
+ def func(x: Union[int, None, Empty] = _empty) -> int:
879
+
880
+ boom = x * 42 # This fails type check
881
+
882
+ if x is _empty:
883
+ return 0
884
+ elif x is None:
885
+ return 1
886
+ else: # At this point typechecker knows that x can only have type int
887
+ return x * 2
888
+
889
+ Since the subclasses of ``Enum`` cannot be further subclassed,
890
+ the type of variable ``x`` can be statically inferred in all branches
891
+ of the above example. The same approach is applicable if more than one
892
+ singleton object is needed: one can use an enumeration that has more than
893
+ one value::
894
+
895
+ class Reason(Enum):
896
+ timeout = 1
897
+ error = 2
898
+
899
+ def process(response: Union[str, Reason] = '') -> str:
900
+ if response is Reason.timeout:
901
+ return 'TIMEOUT'
902
+ elif response is Reason.error:
903
+ return 'ERROR'
904
+ else:
905
+ # response can be only str, all other possible values exhausted
906
+ return 'PROCESSED: ' + response
907
+
908
+
849
909
The ``Any`` type
850
910
----------------
851
911
0 commit comments