@@ -275,33 +275,43 @@ def get_signature_string(func_name, func_signature, evaldict):
275
275
276
276
# protect the parameters if needed
277
277
new_params = []
278
+ params_changed = False
278
279
for p_name , p in func_signature .parameters .items ():
279
280
# if default value can not be evaluated, protect it
280
281
default_needs_protection = _signature_symbol_needs_protection (p .default , evaldict )
281
282
new_default = _protect_signature_symbol (p .default , default_needs_protection , "DEFAULT_%s" % p_name , evaldict )
282
283
283
284
if no_type_hints_allowed :
284
285
new_annotation = Parameter .empty
286
+ annotation_needs_protection = new_annotation is not p .annotation
285
287
else :
286
288
# if type hint can not be evaluated, protect it
287
289
annotation_needs_protection = _signature_symbol_needs_protection (p .annotation , evaldict )
288
290
new_annotation = _protect_signature_symbol (p .annotation , annotation_needs_protection , "HINT_%s" % p_name ,
289
291
evaldict )
290
292
291
- # replace the parameter with the possibly new default and hint
292
- p = Parameter (p .name , kind = p .kind , default = new_default , annotation = new_annotation )
293
+ # only create if necessary (inspect __init__ methods are slow)
294
+ if default_needs_protection or annotation_needs_protection :
295
+ # replace the parameter with the possibly new default and hint
296
+ p = Parameter (p .name , kind = p .kind , default = new_default , annotation = new_annotation )
297
+ params_changed = True
298
+
293
299
new_params .append (p )
294
300
295
301
if no_type_hints_allowed :
296
302
new_return_annotation = Parameter .empty
303
+ return_needs_protection = new_return_annotation is not func_signature .return_annotation
297
304
else :
298
305
# if return type hint can not be evaluated, protect it
299
306
return_needs_protection = _signature_symbol_needs_protection (func_signature .return_annotation , evaldict )
300
307
new_return_annotation = _protect_signature_symbol (func_signature .return_annotation , return_needs_protection ,
301
308
"RETURNHINT" , evaldict )
302
309
303
- # copy signature object
304
- s = Signature (parameters = new_params , return_annotation = new_return_annotation )
310
+ # only create new signature if necessary (inspect __init__ methods are slow)
311
+ if params_changed or return_needs_protection :
312
+ s = Signature (parameters = new_params , return_annotation = new_return_annotation )
313
+ else :
314
+ s = func_signature
305
315
306
316
# return the final string representation
307
317
return "%s%s:" % (func_name , s )
@@ -316,18 +326,14 @@ def _signature_symbol_needs_protection(symbol, evaldict):
316
326
:return:
317
327
"""
318
328
if symbol is not None and symbol is not Parameter .empty and not isinstance (symbol , (int , str , float , bool )):
319
- # check if the repr() of the default value is equal to itself.
320
329
try :
321
- deflt = eval (repr (symbol ), evaldict )
322
- needs_protection = deflt != symbol
323
- except NameError :
324
- needs_protection = True
325
- except SyntaxError :
326
- needs_protection = True
330
+ # check if the repr() of the default value is equal to itself.
331
+ return eval (repr (symbol ), evaldict ) != symbol
332
+ except (NameError , SyntaxError ):
333
+ # in case of error this needs protection
334
+ return True
327
335
else :
328
- needs_protection = False
329
-
330
- return needs_protection
336
+ return False
331
337
332
338
333
339
def _protect_signature_symbol (val , needs_protection , varname , evaldict ):
0 commit comments