docs: def run(namespace=None, action_prefix='action_', args=None):
      """Run the script.  Participating actions are looked up in the caller's
      namespace if no namespace is given, otherwise in the dict provided.
      Only items that start with action_prefix are processed as actions.  If
      you want to use all items in the namespace provided as actions set
      action_prefix to an empty string.
  
      :param namespace: An optional dict where the functions are looked up in.
                        By default the local namespace of the caller is used.
      :param action_prefix: The prefix for the functions.  Everything else
                            is ignored.
      :param args: the arguments for the function.  If not specified
                   :data:`sys.argv` without the first argument is used.
      """
      if namespace is None:
          namespace = sys._getframe(1).f_locals
      actions = find_actions(namespace, action_prefix)
  
      if args is None:
          args = sys.argv[1:]
      if not args or args[0] in ('-h', '--help'):
          return print_usage(actions)
      elif args[0] not in actions:
          fail('Unknown action \'%s\'' % args[0])
  
      arguments = {}
      types = {}
      key_to_arg = {}
      long_options = []
      formatstring = ''
      func, doc, arg_def = actions[args.pop(0)]
      for idx, (arg, shortcut, default, option_type) in enumerate(arg_def):
          real_arg = arg.replace('-', '_')
          if shortcut:
              formatstring += shortcut
              if not isinstance(default, bool):
                  formatstring += ':'
              key_to_arg['-' + shortcut] = real_arg
          long_options.append(isinstance(default, bool) and arg or arg + '=')
          key_to_arg['--' + arg] = real_arg
          key_to_arg[idx] = real_arg
          types[real_arg] = option_type
          arguments[real_arg] = default
  
      try:
          optlist, posargs = getopt.gnu_getopt(args, formatstring, long_options)
      except getopt.GetoptError as e:
          fail(str(e))
  
      specified_arguments = set()
      for key, value in enumerate(posargs):
          try:
              arg = key_to_arg[key]
          except IndexError:
              fail('Too many parameters')
          specified_arguments.add(arg)
          try:
              arguments[arg] = converters[types[arg]](value)
          except ValueError:
              fail('Invalid value for argument %s (%s): %s' % (key, arg, value))
  
      for key, value in optlist:
          arg = key_to_arg[key]
          if arg in specified_arguments:
              fail('Argument \'%s\' is specified twice' % arg)
          if types[arg] == 'boolean':
              if arg.startswith('no_'):
                  value = 'no'
              else:
                  value = 'yes'
          try:
              arguments[arg] = converters[types[arg]](value)
          except ValueError:
              fail('Invalid value for \'%s\': %s' % (key, value))
  
      newargs = {}
      for k, v in iteritems(arguments):
          newargs[k.startswith('no_') and k[3:] or k] = v
      arguments = newargs
      return func(**arguments)