'Validates the changes to the Job and makes the modifications if and only if all of them validate.'

def _modify(self, **changes):

    approved = {}
    if ('id' in changes):
        value = changes.pop('id')
        if (not isinstance(value, six.string_types)):
            raise TypeError('id    must    be    a    nonempty    string')
        if hasattr(self, 'id'):
            raise ValueError('The    job    ID    may    not    be    changed')
        approved['id'] = value
    if (('func' in changes) or ('args' in changes) or ('kwargs' in changes)):
        func = (changes.pop('func') if ('func' in changes) else self.func)
        args = (changes.pop('args') if ('args' in changes) else self.args)
        kwargs = (changes.pop('kwargs') if ('kwargs' in changes) else self.kwargs)
        if isinstance(func, str):
            func_ref = func
            func = ref_to_obj(func)
        elif callable(func):
            try:
                func_ref = obj_to_ref(func)
            except ValueError:
                func_ref = None
        else:
            raise TypeError('func    must    be    a    callable    or    a    textual    reference    to    one')
        if ((not hasattr(self, 'name')) and (changes.get('name', None) is None)):
            changes['name'] = get_callable_name(func)
        if (isinstance(args, six.string_types) or (not isinstance(args, Iterable))):
            raise TypeError('args    must    be    a    non-string    iterable')
        if (isinstance(kwargs, six.string_types) or (not isinstance(kwargs, Mapping))):
            raise TypeError('kwargs    must    be    a    dict-like    object')
        check_callable_args(func, args, kwargs)
        approved['func'] = func
        approved['func_ref'] = func_ref
        approved['args'] = args
        approved['kwargs'] = kwargs
    if ('name' in changes):
        value = changes.pop('name')
        if ((not value) or (not isinstance(value, six.string_types))):
            raise TypeError('name    must    be    a    nonempty    string')
        approved['name'] = value
    if ('misfire_grace_time' in changes):
        value = changes.pop('misfire_grace_time')
        if ((value is not None) and ((not isinstance(value, six.integer_types)) or (value <= 0))):
            raise TypeError('misfire_grace_time    must    be    either    None    or    a    positive    integer')
        approved['misfire_grace_time'] = value
    if ('coalesce' in changes):
        value = bool(changes.pop('coalesce'))
        approved['coalesce'] = value
    if ('max_instances' in changes):
        value = changes.pop('max_instances')
        if ((not isinstance(value, six.integer_types)) or (value <= 0)):
            raise TypeError('max_instances    must    be    a    positive    integer')
        approved['max_instances'] = value
    if ('trigger' in changes):
        trigger = changes.pop('trigger')
        if (not isinstance(trigger, BaseTrigger)):
            raise TypeError(('Expected    a    trigger    instance,    got    %s    instead' % trigger.__class__.__name__))
        approved['trigger'] = trigger
    if ('executor' in changes):
        value = changes.pop('executor')
        if (not isinstance(value, six.string_types)):
            raise TypeError('executor    must    be    a    string')
        approved['executor'] = value
    if ('next_run_time' in changes):
        value = changes.pop('next_run_time')
        approved['next_run_time'] = convert_to_datetime(value, self._scheduler.timezone, 'next_run_time')
    if changes:
        raise AttributeError(('The    following    are    not    modifiable    attributes    of    Job:    %s' % ',    '.join(changes)))
    for (key, value) in six.iteritems(approved):
        setattr(self, key, value)
