Skip to content

Instantly share code, notes, and snippets.

@1st1
Created June 4, 2012 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1st1/2871349 to your computer and use it in GitHub Desktop.
Save 1st1/2871349 to your computer and use it in GitHub Desktop.
pep 362 example
def render_signature(signature):
'''Renders function definition by its signature.
Example:
>>> def test(a:'foo', *, b:'bar', c=True, **kwargs:None) -> 'spam':
... pass
>>> render_signature(inspect.signature(test))
test(a:'foo', *, b:'bar', c=True, **kwargs:None) -> 'spam'
'''
def render_param(param):
'''A helper to render a single parameter, with its default
value and annotation'''
result = param.name
# Add annotation and default value
if hasattr(param, 'annotation'):
result = '{}:{!r}'.format(result, param.annotation)
if hasattr(param, 'default'):
result = '{}={!r}'.format(result, param.default)
# Handle *args & **kwargs -like parameters
if param.is_args:
result = '*' + result
elif param.is_kwargs:
result = '**' + result
return result
result = []
render_kw_only_separator = True
for param in signature.parameters.values():
rendered = render_param(param)
if param.is_args:
# OK, we have an '*args'-like parameter, so we won't need
# a '*' to separate keyword-only arguments
render_kw_only_separator = False
elif param.is_keyword_only and render_kw_only_separator:
# We have a keyword-only parameter to render and we haven't
# rendered an '*args'-like parameter before, so add a '*'
# separator to the parameters list ("foo(arg1, *, arg2)" case)
result.append('*')
# This condition should be only triggered once, so
# reset the flag
render_kw_only_separator = False
result.append(rendered)
result = '{}({})'.format(signature.name, ', '.join(result))
if hasattr(signature, 'return_annotation'):
result += ' -> {!r}'.format(signature.return_annotation)
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment