docs: def signature_parser(func):
      """
          Creates an argparse.ArgumentParser from the function's signature.
  
          Arguments with no default are compulsary positional arguments,
          Arguments with defaults are optional --flags.
  
          If the default is True or False, the action of the flag will
          toggle the argument and the flag takes no parameters.
  
          If the default is None or a unicode string, the flag takes a
          string argument that passed to the function as a unicode string
          decoded using entrypoint.ENCODING
  
          If the default is a string, then the argument is passed as a binary
          string (be careful!), an int and a float cause parsing of those too.
  
          If you want the arguments to be a file, consider using the
          @withfile decorator.
  
          Documentation can be read out of the function's docstring, which should
          be of the basic form:
          '''
              A short introduction to your program.
  
                  arg: Help for positional parameter.
                  frm/from: Help for a positional parameter
                            with a reserved public name
                            (i.e. this displays to the user as "from"
                            but sets the "frm" variable)
                  --opt: Help for optional parameter.
                  -f --flag: An optional parameter that has a short version.
                  --mode=MODE: An optional parameter that takes a MODE
                  -t --type: A combination of both of the above, and one
                                  which requires continuing of the documentation
                                  on an indented line
  
              An epilog explaining anything you feel needs further clarity.
  
              ----
  
              Any documentation for the function itself that isn't covered by the
              public documentation above the line.
          '''
  
          All sections, and indeed the presence of a docstring, are not required.
  
          NOTE: for this to work, the function's signature must be in-tact
                some decorators (like @acceptargv for example) destroy, or
                mutilate the signature.
      """
  
      args, trail, kwargs, defaults = inspect.getargspec(func)
  
      if not args:
          args = []
  
      if not defaults:
          defaults = []
  
      if kwargs:
          raise Exception("Can't wrap a function with **kwargs")
  
      # Compulsary positional options
      needed = args[0:len(args) - len(defaults)]
  
      # Optional flag options
      params = args[len(needed):]
  
      shorts, metavars, helps, description, epilog = _parse_doc(func.__doc__)
  
      parser = argparse.ArgumentParser(
          description=description,
          epilog=epilog,
          formatter_class=ParagraphPreservingArgParseFormatter)
  
      # special flags
      special_flags = []
  
      special_flags += ['debug']
      defaults += (False,)
      helps['debug'] = 'set logging level to DEBUG'
      if module_version(func):
          special_flags += ['version']
          defaults += (False,)
          helps['version'] = "show program's version number and exit"
      params += special_flags
  
      # Optional flag options
      used_shorts = set()
      for param, default in zip(params, defaults):
          args = ["--%s" % param.replace("_", "-")]
          short = None
          if param in shorts:
              short = shorts[param]
          else:
              if param not in special_flags and len(param) > 1:
                  first_char = param[0]
                  if first_char not in used_shorts:
                      used_shorts.add(first_char)
                      short = '-' + first_char
          # -h conflicts with 'help'
          if short and short != '-h':
              args = [short] + args
  
          kwargs = {'default': default, 'dest': param.replace("-", "_")}
  
          if param == 'version':
              kwargs['action'] = 'version'
              kwargs['version'] = module_version(func)
          elif default is True:
              kwargs['action'] = 'store_false'
          elif default is False:
              kwargs['action'] = 'store_true'
          elif isinstance(default, list):
              kwargs['action'] = 'append'
  #  default is not working
  #            if len(default):
  #                first = default[0]
  #                if type(first) in [type(None), unicode]:
  #                    kwargs['type'] = unidecode
  #                else:
  #                    kwargs['type'] = type(first)
  #                kwargs['default'] = []
  #            else:
              kwargs['type'] = unidecode
          else:
              kwargs['action'] = 'store'
              if type(default) in [type(None), unicode]:
                  kwargs['type'] = unidecode
              else:
                  kwargs['type'] = type(default)
  
          if param in helps:
              kwargs['help'] = helps[param]
  
          if param in metavars:
              kwargs['metavar'] = metavars[param]
  
          parser.add_argument(*args, **kwargs)
  
      # Compulsary positional options
      for need in needed:
  
          kwargs = {'action': 'store', 'type': unidecode}
  
          if need in helps:
              kwargs['help'] = helps[need]
  
          if need in shorts:
              args = [shorts[need]]
          else:
              args = [need]
  
          parser.add_argument(*args, **kwargs)
  
      # The trailing arguments
      if trail:
          kwargs = {'action': 'store', 'type': unidecode, 'nargs': "*"}
  
          if trail in helps:
              kwargs['help'] = helps[trail]
  
          if trail in shorts:
              kwargs['metavar'] = shorts[trail]
          else:
              kwargs['metavar'] = trail
  
          parser.add_argument('__args', **kwargs)
  
      return parser