Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/keras/utils/tf_inspect.py: 0%

139 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-05 06:32 +0000

1# Copyright 2017 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================== 

15"""TFDecorator-aware replacements for the inspect module.""" 

16 

17import collections 

18import functools 

19import inspect as _inspect 

20 

21from tensorflow.python.util import tf_decorator 

22 

23try: 

24 ArgSpec = _inspect.ArgSpec 

25except: 

26 pass 

27 

28 

29if hasattr(_inspect, 'FullArgSpec'): 

30 FullArgSpec = _inspect.FullArgSpec # pylint: disable=invalid-name 

31else: 

32 FullArgSpec = collections.namedtuple('FullArgSpec', [ 

33 'args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', 'kwonlydefaults', 

34 'annotations' 

35 ]) 

36 

37 

38def _convert_maybe_argspec_to_fullargspec(argspec): 

39 if isinstance(argspec, FullArgSpec): 

40 return argspec 

41 return FullArgSpec( 

42 args=argspec.args, 

43 varargs=argspec.varargs, 

44 varkw=argspec.keywords, 

45 defaults=argspec.defaults, 

46 kwonlyargs=[], 

47 kwonlydefaults=None, 

48 annotations={}) 

49 

50if hasattr(_inspect, 'getfullargspec'): 

51 _getfullargspec = _inspect.getfullargspec # pylint: disable=invalid-name 

52 

53 def _getargspec(target): 

54 """A python3 version of getargspec. 

55 

56 Calls `getfullargspec` and assigns args, varargs, 

57 varkw, and defaults to a python 2/3 compatible `ArgSpec`. 

58 

59 The parameter name 'varkw' is changed to 'keywords' to fit the 

60 `ArgSpec` struct. 

61 

62 Args: 

63 target: the target object to inspect. 

64 

65 Returns: 

66 An ArgSpec with args, varargs, keywords, and defaults parameters 

67 from FullArgSpec. 

68 """ 

69 fullargspecs = getfullargspec(target) 

70 if hasattr(_inspect, 'ArgSpec'): 

71 argspecs = ArgSpec( 

72 args=fullargspecs.args, 

73 varargs=fullargspecs.varargs, 

74 keywords=fullargspecs.varkw, 

75 defaults=fullargspecs.defaults) 

76 else: 

77 argspecs = FullArgSpec( 

78 args=fullargspecs.args, 

79 varargs=fullargspecs.varargs, 

80 varkw=fullargspecs.varkw, 

81 defaults=fullargspecs.defaults, 

82 kwonlyargs=[], 

83 kwonlydefaults=None, 

84 annotations={}) 

85 return argspecs 

86else: 

87 _getargspec = _inspect.getargspec 

88 

89 def _getfullargspec(target): 

90 """A python2 version of getfullargspec. 

91 

92 Args: 

93 target: the target object to inspect. 

94 

95 Returns: 

96 A FullArgSpec with empty kwonlyargs, kwonlydefaults and annotations. 

97 """ 

98 return _convert_maybe_argspec_to_fullargspec(getargspec(target)) 

99 

100 

101def currentframe(): 

102 """TFDecorator-aware replacement for inspect.currentframe.""" 

103 return _inspect.stack()[1][0] 

104 

105 

106def getargspec(obj): 

107 """TFDecorator-aware replacement for `inspect.getargspec`. 

108 

109 Note: `getfullargspec` is recommended as the python 2/3 compatible 

110 replacement for this function. 

111 

112 Args: 

113 obj: A function, partial function, or callable object, possibly decorated. 

114 

115 Returns: 

116 The `ArgSpec` that describes the signature of the outermost decorator that 

117 changes the callable's signature, or the `ArgSpec` that describes 

118 the object if not decorated. 

119 

120 Raises: 

121 ValueError: When callable's signature can not be expressed with 

122 ArgSpec. 

123 TypeError: For objects of unsupported types. 

124 """ 

125 if isinstance(obj, functools.partial): 

126 return _get_argspec_for_partial(obj) 

127 

128 decorators, target = tf_decorator.unwrap(obj) 

129 

130 spec = next((d.decorator_argspec 

131 for d in decorators 

132 if d.decorator_argspec is not None), None) 

133 if spec: 

134 return spec 

135 

136 try: 

137 # Python3 will handle most callables here (not partial). 

138 return _getargspec(target) 

139 except TypeError: 

140 pass 

141 

142 if isinstance(target, type): 

143 try: 

144 return _getargspec(target.__init__) 

145 except TypeError: 

146 pass 

147 

148 try: 

149 return _getargspec(target.__new__) 

150 except TypeError: 

151 pass 

152 

153 # The `type(target)` ensures that if a class is received we don't return 

154 # the signature of its __call__ method. 

155 return _getargspec(type(target).__call__) 

156 

157 

158def _get_argspec_for_partial(obj): 

159 """Implements `getargspec` for `functools.partial` objects. 

160 

161 Args: 

162 obj: The `functools.partial` object 

163 Returns: 

164 An `inspect.ArgSpec` 

165 Raises: 

166 ValueError: When callable's signature can not be expressed with 

167 ArgSpec. 

168 """ 

169 # When callable is a functools.partial object, we construct its ArgSpec with 

170 # following strategy: 

171 # - If callable partial contains default value for positional arguments (ie. 

172 # object.args), then final ArgSpec doesn't contain those positional arguments. 

173 # - If callable partial contains default value for keyword arguments (ie. 

174 # object.keywords), then we merge them with wrapped target. Default values 

175 # from callable partial takes precedence over those from wrapped target. 

176 # 

177 # However, there is a case where it is impossible to construct a valid 

178 # ArgSpec. Python requires arguments that have no default values must be 

179 # defined before those with default values. ArgSpec structure is only valid 

180 # when this presumption holds true because default values are expressed as a 

181 # tuple of values without keywords and they are always assumed to belong to 

182 # last K arguments where K is number of default values present. 

183 # 

184 # Since functools.partial can give default value to any argument, this 

185 # presumption may no longer hold in some cases. For example: 

186 # 

187 # def func(m, n): 

188 # return 2 * m + n 

189 # partialed = functools.partial(func, m=1) 

190 # 

191 # This example will result in m having a default value but n doesn't. This is 

192 # usually not allowed in Python and can not be expressed in ArgSpec correctly. 

193 # 

194 # Thus, we must detect cases like this by finding first argument with default 

195 # value and ensures all following arguments also have default values. When 

196 # this is not true, a ValueError is raised. 

197 

198 n_prune_args = len(obj.args) 

199 partial_keywords = obj.keywords or {} 

200 

201 args, varargs, keywords, defaults = getargspec(obj.func) 

202 

203 # Pruning first n_prune_args arguments. 

204 args = args[n_prune_args:] 

205 

206 # Partial function may give default value to any argument, therefore length 

207 # of default value list must be len(args) to allow each argument to 

208 # potentially be given a default value. 

209 no_default = object() 

210 all_defaults = [no_default] * len(args) 

211 

212 if defaults: 

213 all_defaults[-len(defaults):] = defaults 

214 

215 # Fill in default values provided by partial function in all_defaults. 

216 for kw, default in partial_keywords.items(): 

217 if kw in args: 

218 idx = args.index(kw) 

219 all_defaults[idx] = default 

220 elif not keywords: 

221 raise ValueError('Function does not have **kwargs parameter, but ' 

222 'contains an unknown partial keyword.') 

223 

224 # Find first argument with default value set. 

225 first_default = next( 

226 (idx for idx, x in enumerate(all_defaults) if x is not no_default), None) 

227 

228 # If no default values are found, return ArgSpec with defaults=None. 

229 if first_default is None: 

230 return ArgSpec(args, varargs, keywords, None) 

231 

232 # Checks if all arguments have default value set after first one. 

233 invalid_default_values = [ 

234 args[i] for i, j in enumerate(all_defaults) 

235 if j is no_default and i > first_default 

236 ] 

237 

238 if invalid_default_values: 

239 raise ValueError('Some arguments %s do not have default value, but they ' 

240 'are positioned after those with default values. This can ' 

241 'not be expressed with ArgSpec.' % invalid_default_values) 

242 

243 return ArgSpec(args, varargs, keywords, tuple(all_defaults[first_default:])) 

244 

245 

246def getfullargspec(obj): 

247 """TFDecorator-aware replacement for `inspect.getfullargspec`. 

248 

249 This wrapper emulates `inspect.getfullargspec` in[^)]* Python2. 

250 

251 Args: 

252 obj: A callable, possibly decorated. 

253 

254 Returns: 

255 The `FullArgSpec` that describes the signature of 

256 the outermost decorator that changes the callable's signature. If the 

257 callable is not decorated, `inspect.getfullargspec()` will be called 

258 directly on the callable. 

259 """ 

260 decorators, target = tf_decorator.unwrap(obj) 

261 

262 for d in decorators: 

263 if d.decorator_argspec is not None: 

264 return _convert_maybe_argspec_to_fullargspec(d.decorator_argspec) 

265 return _getfullargspec(target) 

266 

267 

268def getcallargs(*func_and_positional, **named): 

269 """TFDecorator-aware replacement for inspect.getcallargs. 

270 

271 Args: 

272 *func_and_positional: A callable, possibly decorated, followed by any 

273 positional arguments that would be passed to `func`. 

274 **named: The named argument dictionary that would be passed to `func`. 

275 

276 Returns: 

277 A dictionary mapping `func`'s named arguments to the values they would 

278 receive if `func(*positional, **named)` were called. 

279 

280 `getcallargs` will use the argspec from the outermost decorator that provides 

281 it. If no attached decorators modify argspec, the final unwrapped target's 

282 argspec will be used. 

283 """ 

284 func = func_and_positional[0] 

285 positional = func_and_positional[1:] 

286 argspec = getfullargspec(func) 

287 call_args = named.copy() 

288 this = getattr(func, 'im_self', None) or getattr(func, '__self__', None) 

289 if ismethod(func) and this: 

290 positional = (this,) + positional 

291 remaining_positionals = [arg for arg in argspec.args if arg not in call_args] 

292 call_args.update(dict(zip(remaining_positionals, positional))) 

293 default_count = 0 if not argspec.defaults else len(argspec.defaults) 

294 if default_count: 

295 for arg, value in zip(argspec.args[-default_count:], argspec.defaults): 

296 if arg not in call_args: 

297 call_args[arg] = value 

298 if argspec.kwonlydefaults is not None: 

299 for k, v in argspec.kwonlydefaults.items(): 

300 if k not in call_args: 

301 call_args[k] = v 

302 return call_args 

303 

304 

305def getframeinfo(*args, **kwargs): 

306 return _inspect.getframeinfo(*args, **kwargs) 

307 

308 

309def getdoc(object): # pylint: disable=redefined-builtin 

310 """TFDecorator-aware replacement for inspect.getdoc. 

311 

312 Args: 

313 object: An object, possibly decorated. 

314 

315 Returns: 

316 The docstring associated with the object. 

317 

318 The outermost-decorated object is intended to have the most complete 

319 documentation, so the decorated parameter is not unwrapped. 

320 """ 

321 return _inspect.getdoc(object) 

322 

323 

324def getfile(object): # pylint: disable=redefined-builtin 

325 """TFDecorator-aware replacement for inspect.getfile.""" 

326 unwrapped_object = tf_decorator.unwrap(object)[1] 

327 

328 # Work around for the case when object is a stack frame 

329 # and only .pyc files are used. In this case, getfile 

330 # might return incorrect path. So, we get the path from f_globals 

331 # instead. 

332 if (hasattr(unwrapped_object, 'f_globals') and 

333 '__file__' in unwrapped_object.f_globals): 

334 return unwrapped_object.f_globals['__file__'] 

335 return _inspect.getfile(unwrapped_object) 

336 

337 

338def getmembers(object, predicate=None): # pylint: disable=redefined-builtin 

339 """TFDecorator-aware replacement for inspect.getmembers.""" 

340 return _inspect.getmembers(object, predicate) 

341 

342 

343def getmodule(object): # pylint: disable=redefined-builtin 

344 """TFDecorator-aware replacement for inspect.getmodule.""" 

345 return _inspect.getmodule(object) 

346 

347 

348def getmro(cls): 

349 """TFDecorator-aware replacement for inspect.getmro.""" 

350 return _inspect.getmro(cls) 

351 

352 

353def getsource(object): # pylint: disable=redefined-builtin 

354 """TFDecorator-aware replacement for inspect.getsource.""" 

355 return _inspect.getsource(tf_decorator.unwrap(object)[1]) 

356 

357 

358def getsourcefile(object): # pylint: disable=redefined-builtin 

359 """TFDecorator-aware replacement for inspect.getsourcefile.""" 

360 return _inspect.getsourcefile(tf_decorator.unwrap(object)[1]) 

361 

362 

363def getsourcelines(object): # pylint: disable=redefined-builtin 

364 """TFDecorator-aware replacement for inspect.getsourcelines.""" 

365 return _inspect.getsourcelines(tf_decorator.unwrap(object)[1]) 

366 

367 

368def isbuiltin(object): # pylint: disable=redefined-builtin 

369 """TFDecorator-aware replacement for inspect.isbuiltin.""" 

370 return _inspect.isbuiltin(tf_decorator.unwrap(object)[1]) 

371 

372 

373def isclass(object): # pylint: disable=redefined-builtin 

374 """TFDecorator-aware replacement for inspect.isclass.""" 

375 return _inspect.isclass(tf_decorator.unwrap(object)[1]) 

376 

377 

378def isfunction(object): # pylint: disable=redefined-builtin 

379 """TFDecorator-aware replacement for inspect.isfunction.""" 

380 return _inspect.isfunction(tf_decorator.unwrap(object)[1]) 

381 

382 

383def isframe(object): # pylint: disable=redefined-builtin 

384 """TFDecorator-aware replacement for inspect.ismodule.""" 

385 return _inspect.isframe(tf_decorator.unwrap(object)[1]) 

386 

387 

388def isgenerator(object): # pylint: disable=redefined-builtin 

389 """TFDecorator-aware replacement for inspect.isgenerator.""" 

390 return _inspect.isgenerator(tf_decorator.unwrap(object)[1]) 

391 

392 

393def isgeneratorfunction(object): # pylint: disable=redefined-builtin 

394 """TFDecorator-aware replacement for inspect.isgeneratorfunction.""" 

395 return _inspect.isgeneratorfunction(tf_decorator.unwrap(object)[1]) 

396 

397 

398def ismethod(object): # pylint: disable=redefined-builtin 

399 """TFDecorator-aware replacement for inspect.ismethod.""" 

400 return _inspect.ismethod(tf_decorator.unwrap(object)[1]) 

401 

402 

403def ismodule(object): # pylint: disable=redefined-builtin 

404 """TFDecorator-aware replacement for inspect.ismodule.""" 

405 return _inspect.ismodule(tf_decorator.unwrap(object)[1]) 

406 

407 

408def isroutine(object): # pylint: disable=redefined-builtin 

409 """TFDecorator-aware replacement for inspect.isroutine.""" 

410 return _inspect.isroutine(tf_decorator.unwrap(object)[1]) 

411 

412 

413def stack(context=1): 

414 """TFDecorator-aware replacement for inspect.stack.""" 

415 return _inspect.stack(context)[1:]