@@ -42,6 +42,24 @@ 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
+
45
63
class _GapicCallable (object ):
46
64
"""Callable that applies retry, timeout, and metadata logic.
47
65
@@ -73,53 +91,44 @@ def __init__(
73
91
):
74
92
self ._target = target
75
93
self ._retry = retry
76
- if isinstance (timeout , (int , float )):
77
- timeout = TimeToDeadlineTimeout (timeout = timeout )
78
94
self ._timeout = timeout
79
95
self ._compression = compression
80
- self ._metadata = list ( metadata ) if metadata is not None else None
96
+ self ._metadata = metadata
81
97
82
98
def __call__ (
83
99
self , * args , timeout = DEFAULT , retry = DEFAULT , compression = DEFAULT , ** kwargs
84
100
):
85
101
"""Invoke the low-level RPC with retry, timeout, compression, and metadata."""
86
102
87
- if compression is DEFAULT :
88
- compression = self ._compression
89
- if compression is not None :
90
- kwargs ["compression" ] = compression
103
+ if retry is DEFAULT :
104
+ retry = self ._retry
91
105
92
- # Add the user agent metadata to the call.
93
- if self ._metadata is not None :
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
106
if timeout is DEFAULT :
111
107
timeout = self ._timeout
112
- elif isinstance (timeout , (int , float )):
108
+
109
+ if compression is DEFAULT :
110
+ compression = self ._compression
111
+
112
+ if isinstance (timeout , (int , float )):
113
113
timeout = TimeToDeadlineTimeout (timeout = timeout )
114
- if timeout is not None :
115
- wrapped_func = timeout (wrapped_func )
116
114
117
- if retry is DEFAULT :
118
- retry = self ._retry
119
- if retry is not None :
120
- wrapped_func = retry (wrapped_func )
115
+ # Apply all applicable decorators.
116
+ wrapped_func = _apply_decorators (self ._target , [retry , timeout ])
117
+
118
+ # Add the user agent metadata to the call.
119
+ 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
121
130
122
- return wrapped_func
131
+ return wrapped_func ( * args , ** kwargs )
123
132
124
133
125
134
def wrap_method (
@@ -193,9 +202,8 @@ def get_topic(name, timeout=None):
193
202
194
203
Args:
195
204
func (Callable[Any]): The function to wrap. It should accept an
196
- optional ``timeout`` (google.api_core.timeout.Timeout) argument.
197
- If ``metadata`` is not ``None``, it should accept a ``metadata``
198
- (Sequence[Tuple[str, str]]) argument.
205
+ optional ``timeout`` argument. If ``metadata`` is not ``None``, it
206
+ should accept a ``metadata`` argument.
199
207
default_retry (Optional[google.api_core.Retry]): The default retry
200
208
strategy. If ``None``, the method will not retry by default.
201
209
default_timeout (Optional[google.api_core.Timeout]): The default
0 commit comments