@@ -42,24 +42,6 @@ class _MethodDefault(enum.Enum):
42
42
so the default should be used."""
43
43
44
44
45
- def _is_not_none_or_false (value ):
46
- return value is not None and value is not False
47
-
48
-
49
- def _apply_decorators (func , decorators ):
50
- """Apply a list of decorators to a given function.
51
-
52
- ``decorators`` may contain items that are ``None`` or ``False`` which will
53
- be ignored.
54
- """
55
- filtered_decorators = filter (_is_not_none_or_false , reversed (decorators ))
56
-
57
- for decorator in filtered_decorators :
58
- func = decorator (func )
59
-
60
- return func
61
-
62
-
63
45
class _GapicCallable (object ):
64
46
"""Callable that applies retry, timeout, and metadata logic.
65
47
@@ -91,6 +73,8 @@ def __init__(
91
73
):
92
74
self ._target = target
93
75
self ._retry = retry
76
+ if isinstance (timeout , (int , float )):
77
+ timeout = TimeToDeadlineTimeout (timeout = timeout )
94
78
self ._timeout = timeout
95
79
self ._compression = compression
96
80
self ._metadata = metadata
@@ -100,35 +84,42 @@ def __call__(
100
84
):
101
85
"""Invoke the low-level RPC with retry, timeout, compression, and metadata."""
102
86
103
- if retry is DEFAULT :
104
- retry = self ._retry
105
-
106
- if timeout is DEFAULT :
107
- timeout = self ._timeout
108
-
109
87
if compression is DEFAULT :
110
88
compression = self ._compression
111
-
112
- if isinstance (timeout , (int , float )):
113
- timeout = TimeToDeadlineTimeout (timeout = timeout )
114
-
115
- # Apply all applicable decorators.
116
- wrapped_func = _apply_decorators (self ._target , [retry , timeout ])
89
+ if compression is not None :
90
+ kwargs ["compression" ] = compression
117
91
118
92
# Add the user agent metadata to the call.
119
93
if self ._metadata is not None :
120
- metadata = kwargs .get ("metadata" , [])
121
- # Due to the nature of invocation, None should be treated the same
122
- # as not specified.
123
- if metadata is None :
124
- metadata = []
125
- metadata = list (metadata )
126
- metadata .extend (self ._metadata )
127
- kwargs ["metadata" ] = metadata
128
- if self ._compression is not None :
129
- kwargs ["compression" ] = compression
94
+ try :
95
+ # attempt to concatenate default metadata with user-provided metadata
96
+ kwargs ["metadata" ] = (* kwargs ["metadata" ], * self ._metadata )
97
+ except (KeyError , TypeError ):
98
+ # if metadata is not provided, use just the default metadata
99
+ kwargs ["metadata" ] = self ._metadata
100
+
101
+ call = self ._build_wrapped_call (timeout , retry )
102
+ return call (* args , ** kwargs )
103
+
104
+ @functools .lru_cache (maxsize = 4 )
105
+ def _build_wrapped_call (self , timeout , retry ):
106
+ """
107
+ Build a wrapped callable that applies retry, timeout, and metadata logic.
108
+ """
109
+ wrapped_func = self ._target
110
+ if timeout is DEFAULT :
111
+ timeout = self ._timeout
112
+ elif isinstance (timeout , (int , float )):
113
+ timeout = TimeToDeadlineTimeout (timeout = timeout )
114
+ if timeout is not None :
115
+ wrapped_func = timeout (wrapped_func )
116
+
117
+ if retry is DEFAULT :
118
+ retry = self ._retry
119
+ if retry is not None :
120
+ wrapped_func = retry (wrapped_func )
130
121
131
- return wrapped_func ( * args , ** kwargs )
122
+ return wrapped_func
132
123
133
124
134
125
def wrap_method (
0 commit comments