Submit a new #Job to the ThreadPool.

    # Arguments
    task (function, Job): Either a function that accepts a #Job, *args* and
      *kwargs* or a #Job object that is in #~Job.PENDING state.
    target (function): A function object that accepts *args* and *kwargs*.
      Only if *task* is not specified.
    args (list, tuple): A list of arguments to be passed to *job*, if it is
      a function.
    kwargs (dict): A dictionary to be passed as keyword arguments to *job*,
      if it is a function.
    front (bool): If #True, the job will be inserted in the front of the queue.

    # Returns
    Job: The job that was added to the queue.

    # Raises
    TypeError: If a #Job object was passed but *args* or *kwargs* are non-empty.
    RuntimeError: If the ThreadPool is not running (ie. if it was shut down).

def submit(self, target=None, task=None, args=(), kwargs=None, front=False,
             dispose_inputs=None):
    """
    Submit a new #Job to the ThreadPool.

    # Arguments
    task (function, Job): Either a function that accepts a #Job, *args* and
      *kwargs* or a #Job object that is in #~Job.PENDING state.
    target (function): A function object that accepts *args* and *kwargs*.
      Only if *task* is not specified.
    args (list, tuple): A list of arguments to be passed to *job*, if it is
      a function.
    kwargs (dict): A dictionary to be passed as keyword arguments to *job*,
      if it is a function.
    front (bool): If #True, the job will be inserted in the front of the queue.

    # Returns
    Job: The job that was added to the queue.

    # Raises
    TypeError: If a #Job object was passed but *args* or *kwargs* are non-empty.
    RuntimeError: If the ThreadPool is not running (ie. if it was shut down).
    """

    if not self.__running:
      raise RuntimeError("ThreadPool ain't running")
    if dispose_inputs is None:
      dispose_inputs = self.dispose_inputs

    if isinstance(task, Job):
      if args or kwargs:
        raise TypeError('can not provide additional arguments for Job')
      if task.state != Job.PENDING:
        raise RuntimeError('job is not pending')
      job = task
    elif task is not None:
      if kwargs is None:
        kwargs = {}
      job = Job(task=task, args=args, kwargs=kwargs, dispose_inputs=dispose_inputs)
    elif target is not None:
      if kwargs is None:
        kwargs = {}
      job = Job(target=target, args=args, kwargs=kwargs, dispose_inputs=dispose_inputs)
    else:
      raise TypeError('expected Job or callable')

    job.print_exc = self.print_exc
    if front:
      self.__queue.appendleft(job)
    else:
      self.__queue.append(job)
    return job