def _function_contents(func):
    """
    The signature is as follows (should be byte/chars):
    < _code_contents (see above) from func.__code__ >
    ,( comma separated _object_contents for function argument defaults)
    ,( comma separated _object_contents for any closure contents )


    See also: https://docs.python.org/3/reference/datamodel.html
      - func.__code__     - The code object representing the compiled function body.
      - func.__defaults__ - A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value
      - func.__closure__  - None or a tuple of cells that contain bindings for the function's free variables.

    :Returns:
      Signature contents of a function. (in bytes)
    """

    contents = [_code_contents(func.__code__, func.__doc__)]

    # The function contents depends on the value of defaults arguments
    if func.__defaults__:

        function_defaults_contents = [_object_contents(cc) for cc in func.__defaults__]

        defaults = bytearray(b',(')
        defaults.extend(bytearray(b',').join(function_defaults_contents))
        defaults.extend(b')')

        contents.append(defaults)
    else:
        contents.append(b',()')

    # The function contents depends on the closure captured cell values.
    closure = func.__closure__ or []

    try:
        closure_contents = [_object_contents(x.cell_contents) for x in closure]
    except AttributeError:
        closure_contents = []

    contents.append(b',(')
    contents.append(bytearray(b',').join(closure_contents))
    contents.append(b')')

    retval = bytearray(b'').join(contents)
    return retval