def __str__(self) -> str:

    def get_name(arg: Any) -> str:
        if isinstance(arg, inspect.Parameter):
            return arg.name
        if isinstance(arg, nodes.Argument):
            return arg.variable.name
        raise AssertionError

    def get_type(arg: Any) -> Optional[str]:
        if isinstance(arg, inspect.Parameter):
            return None
        if isinstance(arg, nodes.Argument):
            return str((arg.variable.type or arg.type_annotation))
        raise AssertionError

    def has_default(arg: Any) -> bool:
        if isinstance(arg, inspect.Parameter):
            return (arg.default != inspect.Parameter.empty)
        if isinstance(arg, nodes.Argument):
            return (arg.kind in (nodes.ARG_OPT, nodes.ARG_NAMED_OPT))
        raise AssertionError

    def get_desc(arg: Any) -> str:
        arg_type = get_type(arg)
        return ((get_name(arg) + (': {}'.format(arg_type) if arg_type else '')) + (' = ...' if has_default(arg) else ''))
    kw_only = sorted(self.kwonly.values(), key=(lambda a: (has_default(a), get_name(a))))
    ret = 'def ('
    ret += ', '.join(((([get_desc(arg) for arg in self.pos] + ([('*' + get_name(self.varpos))] if self.varpos else (['*'] if self.kwonly else []))) + [get_desc(arg) for arg in kw_only]) + ([('**' + get_name(self.varkw))] if self.varkw else [])))
    ret += ')'
    return ret
def __str__(self) -> str:

    def get_name(arg: Any) -> str:
        if isinstance(arg, inspect.Parameter):
            return arg.name
        if isinstance(arg, nodes.Argument):
            return arg.variable.name
        raise AssertionError

    def get_type(arg: Any) -> Optional[str]:
        if isinstance(arg, inspect.Parameter):
            return None
        if isinstance(arg, nodes.Argument):
            return str((arg.variable.type or arg.type_annotation))
        raise AssertionError

    def has_default(arg: Any) -> bool:
        if isinstance(arg, inspect.Parameter):
            return (arg.default != inspect.Parameter.empty)
        if isinstance(arg, nodes.Argument):
            return (arg.kind in (nodes.ARG_OPT, nodes.ARG_NAMED_OPT))
        raise AssertionError

    def get_desc(arg: Any) -> str:
        arg_type = get_type(arg)
        return ((get_name(arg) + (': {}'.format(arg_type) if arg_type else )) + (' = ...' if has_default(arg) else ))
    kw_only = sorted(self.kwonly.values(), key=(lambda a: (has_default(a), get_name(a))))
    ret = 'def ('
    ret += ', '.join(((([get_desc(arg) for arg in self.pos] + ([('*' + get_name(self.varpos))] if self.varpos else (['*'] if self.kwonly else []))) + [get_desc(arg) for arg in kw_only]) + ([('**' + get_name(self.varkw))] if self.varkw else [])))
    ret += ')'
    return ret