@@ -46,6 +46,12 @@ def update_wrapper(wrapper,
4646 updated is a tuple naming the attributes of the wrapper that
4747 are updated with the corresponding attribute from the wrapped
4848 function (defaults to functools.WRAPPER_UPDATES)
49+
50+ There's a special treatment for the `__annotations__` attribute:
51+ * If the wrapper defines a return type, then that will be used, if not,
52+ the one from the wrapped function will be used if any.
53+ * If the wrapper defines any parameter types, those will be used, if
54+ not, the ones from the wrapped function will be used if any.
4955 """
5056 for attr in assigned :
5157 try :
@@ -59,24 +65,24 @@ def update_wrapper(wrapper,
5965
6066 if '__annotations__' in assigned :
6167 try :
62- # Issue #41231: copy the annotations only if there's none defined
63- # in the wrapper
68+ # Issue #41231: copy the annotations from wrapped, only if they are
69+ # not already defined in the wrapper
6470 if not wrapper .__annotations__ :
6571 wrapper .__annotations__ = wrapped .__annotations__
66- # if only the return wrapped has annotations, assume that the
67- # parameters stay the same
72+ # if the wrapper does not annotate the parameters, copy their
73+ # annotations over from the wrapped
6874 elif ('return' in wrapper .__annotations__
6975 and len (wrapper .__annotations__ ) == 1 ):
7076 wrapper .__annotations__ = {
7177 ** wrapped .__annotations__ ,
7278 ** wrapper .__annotations__ ,
7379 }
74- # if only the parameters have annotations, assume that the return
75- # type stays the same
80+ # if the wrapper does not annotate the return type, copy the
81+ # annotation from the wrapped
7682 elif ('return' not in wrapper .__annotations__
7783 and 'return' in wrapped .__annotations__ ):
7884 wrapper .__annotations__ ['return' ] = wrapped .__annotations__ ['return' ]
79- except AttributeError as error :
85+ except AttributeError :
8086 pass
8187
8288 for attr in updated :
0 commit comments