'Constructs Signature for the given python function'

@classmethod
def from_function(cls, func):

    if (not isinstance(func, types.FunctionType)):
        raise TypeError('{0!r}    is    not    a    Python    function'.format(func))
    Parameter = cls._parameter_cls
    func_code = func.__code__
    pos_count = func_code.co_argcount
    arg_names = func_code.co_varnames
    positional = tuple(arg_names[:pos_count])
    keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
    keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
    annotations = getattr(func, '__annotations__', {})
    defaults = func.__defaults__
    kwdefaults = getattr(func, '__kwdefaults__', None)
    if defaults:
        pos_default_count = len(defaults)
    else:
        pos_default_count = 0
    parameters = []
    non_default_count = (pos_count - pos_default_count)
    for name in positional[:non_default_count]:
        annotation = annotations.get(name, _empty)
        parameters.append(Parameter(name, annotation=annotation, kind=_POSITIONAL_OR_KEYWORD))
    for (offset, name) in enumerate(positional[non_default_count:]):
        annotation = annotations.get(name, _empty)
        parameters.append(Parameter(name, annotation=annotation, kind=_POSITIONAL_OR_KEYWORD, default=defaults[offset]))
    if (func_code.co_flags & 4):
        name = arg_names[(pos_count + keyword_only_count)]
        annotation = annotations.get(name, _empty)
        parameters.append(Parameter(name, annotation=annotation, kind=_VAR_POSITIONAL))
    for name in keyword_only:
        default = _empty
        if (kwdefaults is not None):
            default = kwdefaults.get(name, _empty)
        annotation = annotations.get(name, _empty)
        parameters.append(Parameter(name, annotation=annotation, kind=_KEYWORD_ONLY, default=default))
    if (func_code.co_flags & 8):
        index = (pos_count + keyword_only_count)
        if (func_code.co_flags & 4):
            index += 1
        name = arg_names[index]
        annotation = annotations.get(name, _empty)
        parameters.append(Parameter(name, annotation=annotation, kind=_VAR_KEYWORD))
    return cls(parameters, return_annotation=annotations.get('return', _empty), __validate_parameters__=False)
