def update_object(self, columns, extra_fields, state): """ Actually do the action, like create or update an object. """ if extra_fields: errors = {} for key in extra_fields.keys(): errors[key] = Invalid( self.message('notExpected', state, name=repr(key)), columns, state) raise Invalid( schema.format_compound_error(errors), columns, state, error_dict=errors) obj = self.object() create = False if self.instance(): if obj.id != columns['id']: raise Invalid(self.message('badID', state, value=columns['id']), columns['id'], state) del columns['id'] elif 'id' in columns: obj = obj.get(columns['id']) del columns['id'] else: create = True if create: obj = obj(**columns) else: obj.set(**columns) return obj
def attempt_convert(self, value, state, validate): if self.convert_to_list: value = self._convert_to_list(value) if self.if_empty is not NoDefault and not value: return self.if_empty if self.not_empty and not value: if validate is from_python and self.accept_python: return [] raise Invalid( self.message('empty', state), value, state) new_list = [] errors = [] all_good = True is_set = isinstance(value, (set, Set)) if state is not None: previous_index = getattr(state, 'index', NoDefault) previous_full_list = getattr(state, 'full_list', NoDefault) index = 0 state.full_list = value try: for sub_value in value: if state: state.index = index index += 1 good_pass = True for validator in self.validators: try: sub_value = validate(validator, sub_value, state) except Invalid, e: errors.append(e) all_good = False good_pass = False break if good_pass: errors.append(None) new_list.append(sub_value) if all_good: if is_set: new_list = set(new_list) return new_list else: raise Invalid( 'Errors:\n%s' % '\n'.join([unicode(e) for e in errors if e]), value, state, error_list=errors)
def to_python(self, value_dict, state): # Since we aren't really supposed to modify things in-place, # we'll give the validation function a copy: value_dict = value_dict.copy() errors = self.func(value_dict, state, self) if not errors: return value_dict if isinstance(errors, basestring): raise Invalid(errors, value_dict, state) elif isinstance(errors, dict): raise Invalid(format_compound_error(errors), value_dict, state, error_dict=errors) elif isinstance(errors, Invalid): raise errors else: raise TypeError("Invalid error value: %r" % errors) return value_dict
def _to_python(self, value_dict, state): value_dict = value_dict.copy() add_values = {} if self.instance() or value_dict.get('id'): if not self.instance() and not self.allow_edit: raise Invalid(self.message('editNotAllowed', state, value=value_dict['id']), value_dict['id'], state) if 'id' not in value_dict: raise Invalid(self.message('missingValue', state), None, state) id = value_dict.pop('id') if self.sign_id: id = self._signer.to_python(id) try: id = self.object().sqlmeta.idType(id) except ValueError, e: raise Invalid(self.message('invalidID', state, error=e), id, state) add_values['id'] = id
def assert_dict(self, value, state): """ Helper to assure we have proper input """ if not hasattr(value, 'items'): # Not a dict or dict-like object raise Invalid( self.message('badDictType', state, type=type(value), value=value), value, state)
def _to_python_dictionary(self, value_dict, state): obj = self.object() sqlmeta = obj.sqlmeta columns = sqlmeta.columns extra = value_dict.copy() found = [] for name, value in value_dict.items(): if name not in columns: continue found.append(name) del extra[name] if columns[name].validator: # We throw the result away, but let the exception # get through columns[name].validator.to_python(value, state) if columns[name].notNone and value is None: # This isn't present in the validator information exc = Invalid(self.message('notNone', state), value, state) raise Invalid( '%s: %s' % (name, exc), value_dict, state, error_dict={name: exc}) if not isinstance(obj, sqlobject.SQLObject): for name, column in columns.items(): if (name not in found and column.default is sqlobject.col.NoDefault): exc = Invalid(self.message('missingValue', state), value_dict, state) raise Invalid( '%s: %s' % (name, exc), value_dict, state, error_dict={name: exc}) for key in extra: del value_dict[key] return value_dict, extra
def _convert_from_python(self, value_dict, state): chained = self.chained_validators[:] chained.reverse() finished = [] for validator in chained: __traceback_info__ = ( 'for_python chained_validator %s (finished %s)') % ( validator, ', '.join(map(repr, finished)) or 'none') finished.append(validator) value_dict = validator.from_python(value_dict, state) self.assert_dict(value_dict, state) new = {} errors = {} unused = self.fields.keys() if state is not None: previous_key = getattr(state, 'key', None) previous_full_dict = getattr(state, 'full_dict', None) state.full_dict = value_dict try: __traceback_info__ = None for name, value in value_dict.iteritems(): __traceback_info__ = 'for_python in %s' % name try: unused.remove(name) except ValueError: if not self.allow_extra_fields: raise Invalid( self.message('notExpected', state, name=repr(name)), value_dict, state) if not self.filter_extra_fields: new[name] = value else: if state is not None: state.key = name try: new[name] = self.fields[name].from_python(value, state) except Invalid, e: errors[name] = e del __traceback_info__ for name in unused: validator = self.fields[name] if state is not None: state.key = name try: new[name] = validator.from_python(None, state) except Invalid, e: errors[name] = e
def _convert_to_python(self, value_dict, state): if not value_dict: if self.if_empty is not NoDefault: return self.if_empty value_dict = {} for validator in self.pre_validators: value_dict = validator.to_python(value_dict, state) self.assert_dict(value_dict, state) new = {} errors = {} unused = self.fields.keys() if state is not None: previous_key = getattr(state, 'key', None) previous_full_dict = getattr(state, 'full_dict', None) state.full_dict = value_dict try: for name, value in value_dict.items(): try: unused.remove(name) except ValueError: if not self.allow_extra_fields: raise Invalid( self.message('notExpected', state, name=repr(name)), value_dict, state) if not self.filter_extra_fields: new[name] = value continue validator = self.fields[name] # are iterators (list, tuple, set, etc) allowed? if self._value_is_iterator(value) and not getattr( validator, 'accept_iterator', False): errors[name] = Invalid( self.message('singleValueExpected', state), value_dict, state) if state is not None: state.key = name try: new[name] = validator.to_python(value, state) except Invalid, e: errors[name] = e for name in unused: validator = self.fields[name] try: if_missing = validator.if_missing except AttributeError: if_missing = NoDefault if if_missing is NoDefault: if self.ignore_key_missing: continue if self.if_key_missing is NoDefault: try: message = validator.message('missing', state) except KeyError: message = self.message('missingValue', state) errors[name] = Invalid(message, None, state) else: if state is not None: state.key = name try: new[name] = validator.to_python( self.if_key_missing, state) except Invalid, e: errors[name] = e else: new[name] = validator.if_missing
for validator in self.chained_validators: if (not hasattr(validator, 'validate_partial') or not getattr( validator, 'validate_partial_form', False)): continue try: validator.validate_partial(value_dict, state) except Invalid, e: sub_errors = e.unpack_errors() if not isinstance(sub_errors, dict): # Can't do anything here continue merge_dicts(errors, sub_errors) if errors: raise Invalid(format_compound_error(errors), value_dict, state, error_dict=errors) for validator in self.chained_validators: new = validator.to_python(new, state) return new finally: if state is not None: state.key = previous_key state.full_dict = previous_full_dict def _convert_from_python(self, value_dict, state): chained = self.chained_validators[:] chained.reverse()