Skip to content

Commit 97fdafa

Browse files
author
Sylvain MARIE
committed
Improved performance of get_signature_string after profiling.
1 parent 352bcdc commit 97fdafa

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

makefun/main.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -275,33 +275,43 @@ def get_signature_string(func_name, func_signature, evaldict):
275275

276276
# protect the parameters if needed
277277
new_params = []
278+
params_changed = False
278279
for p_name, p in func_signature.parameters.items():
279280
# if default value can not be evaluated, protect it
280281
default_needs_protection = _signature_symbol_needs_protection(p.default, evaldict)
281282
new_default = _protect_signature_symbol(p.default, default_needs_protection, "DEFAULT_%s" % p_name, evaldict)
282283

283284
if no_type_hints_allowed:
284285
new_annotation = Parameter.empty
286+
annotation_needs_protection = new_annotation is not p.annotation
285287
else:
286288
# if type hint can not be evaluated, protect it
287289
annotation_needs_protection = _signature_symbol_needs_protection(p.annotation, evaldict)
288290
new_annotation = _protect_signature_symbol(p.annotation, annotation_needs_protection, "HINT_%s" % p_name,
289291
evaldict)
290292

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+
293299
new_params.append(p)
294300

295301
if no_type_hints_allowed:
296302
new_return_annotation = Parameter.empty
303+
return_needs_protection = new_return_annotation is not func_signature.return_annotation
297304
else:
298305
# if return type hint can not be evaluated, protect it
299306
return_needs_protection = _signature_symbol_needs_protection(func_signature.return_annotation, evaldict)
300307
new_return_annotation = _protect_signature_symbol(func_signature.return_annotation, return_needs_protection,
301308
"RETURNHINT", evaldict)
302309

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
305315

306316
# return the final string representation
307317
return "%s%s:" % (func_name, s)
@@ -316,18 +326,14 @@ def _signature_symbol_needs_protection(symbol, evaldict):
316326
:return:
317327
"""
318328
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.
320329
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
327335
else:
328-
needs_protection = False
329-
330-
return needs_protection
336+
return False
331337

332338

333339
def _protect_signature_symbol(val, needs_protection, varname, evaldict):

0 commit comments

Comments
 (0)