From 4559c595407881a3dfa9774f038ca6a86a78b206 Mon Sep 17 00:00:00 2001 From: Tobin Yehle Date: Mon, 15 May 2017 20:17:51 -0600 Subject: [PATCH 1/2] add clarification for overloading example --- docs/source/function_overloading.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/source/function_overloading.rst b/docs/source/function_overloading.rst index 43f365b5dccb..7e63a96346a0 100644 --- a/docs/source/function_overloading.rst +++ b/docs/source/function_overloading.rst @@ -56,7 +56,7 @@ accurately describe the function's behavior. # It may or may not have type hints; if it does, # these are checked against the overload definitions # as well as against the implementation body. - def __getitem__(self, index): + def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]: # This is exactly the same as before. if isinstance(index, int): ... # Return a T here @@ -65,6 +65,24 @@ accurately describe the function's behavior. else: raise TypeError(...) +Calls to overloaded functions are type checked against the variants, +not against the implementation. A call like ``my_list[5]`` would have +type ``T``, not ``Union[T, Sequence[T]]`` because it matches the first +overloaded definition, and ignores the type annotations on the +implementation of ``__getitem__``. The code in the body of the +definition of ``__getitem__`` is checked against the annotations on +the last function declaration. In this case the body is checked with +``index: Union[int, slice]`` and a return type +``Union[T, Sequence[T]]``. If there are no annotations on the last +definition, then code in the function body is not type checked. The +annotations on the function body must be compatible with the types +given for the overloaded variants listed above it. The type checker +will ensure that all the types listed for parameters and the return +type in the overloaded variants can inhabit the type given for the +implementation at the bottom. In this case it checks that ``int`` and +``slice`` can inhabit ``Union[int, slice]`` for the first argument, +and that ``T`` and ``Sequence[T]`` can inhabit ``Union[T, Sequence[T]]``. + Overloaded function variants are still ordinary Python functions and they still define a single runtime object. There is no automatic dispatch happening, and you must manually handle the different types From 01de0738dde206e195b7d6af0a5239e5c7d5b84e Mon Sep 17 00:00:00 2001 From: Tobin Yehle Date: Tue, 16 May 2017 14:08:27 -0600 Subject: [PATCH 2/2] make wording more clear and consistent --- docs/source/function_overloading.rst | 31 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/docs/source/function_overloading.rst b/docs/source/function_overloading.rst index 7e63a96346a0..5e7d2c5b1a82 100644 --- a/docs/source/function_overloading.rst +++ b/docs/source/function_overloading.rst @@ -67,21 +67,26 @@ accurately describe the function's behavior. Calls to overloaded functions are type checked against the variants, not against the implementation. A call like ``my_list[5]`` would have -type ``T``, not ``Union[T, Sequence[T]]`` because it matches the first -overloaded definition, and ignores the type annotations on the +type ``T``, not ``Union[T, Sequence[T]]`` because it matches the +first overloaded definition, and ignores the type annotations on the implementation of ``__getitem__``. The code in the body of the definition of ``__getitem__`` is checked against the annotations on -the last function declaration. In this case the body is checked with -``index: Union[int, slice]`` and a return type -``Union[T, Sequence[T]]``. If there are no annotations on the last -definition, then code in the function body is not type checked. The -annotations on the function body must be compatible with the types -given for the overloaded variants listed above it. The type checker -will ensure that all the types listed for parameters and the return -type in the overloaded variants can inhabit the type given for the -implementation at the bottom. In this case it checks that ``int`` and -``slice`` can inhabit ``Union[int, slice]`` for the first argument, -and that ``T`` and ``Sequence[T]`` can inhabit ``Union[T, Sequence[T]]``. +the the corresponding declaration. In this case the body is checked +with ``index: Union[int, slice]`` and a return type +``Union[T, Sequence[T]]``. If there are no annotations on the +corresponding definition, then code in the function body is not type +checked. + +The annotations on the function body must be compatible with the +types given for the overloaded variants listed above it. The type +checker will verify that all the types listed the overloaded variants +are compatible with the types given for the implementation. In this +case it checks that the parameter type ``int`` and the return type +``T`` are compatible with ``Union[int, slice]`` and +``Union[T, Sequence[T]]`` for the first variant. For the second +variant it verifies that the parameter type ``slice`` are the return +type ``Sequence[T]`` are compatible with ``Union[int, slice]`` and +``Union[T, Sequence[T]]``. Overloaded function variants are still ordinary Python functions and they still define a single runtime object. There is no automatic