def test_to_python(input, expected): '''tests the method to_python of the NAarrayfield Field object''' n = NArrayField() if expected == ValidationError: with pytest.raises(ValidationError): # @UndefinedVariable val = n.to_python(input) else: val = n.to_python(input) assert val == expected assert n.to_python(expected) == expected # test failing cases by providing boundary conditions: len_ = 1 if isscalar(val) else len(val) if len_ > 0: min_ = val if isscalar(val) else min(val) max_ = val if isscalar(val) else max(val) with pytest.raises(ValidationError): # @UndefinedVariable NArrayField(min_value=min_ + 1).to_python(val) with pytest.raises(ValidationError): # @UndefinedVariable NArrayField(max_value=max_ - 1).to_python(val) with pytest.raises(ValidationError): # @UndefinedVariable NArrayField(min_count=len_ + 1).to_python(val) with pytest.raises(ValidationError): # @UndefinedVariable NArrayField(max_count=len_ - 1).to_python(val) # test ok case by providing boundary conditions: val2 = \ NArrayField(max_count=len_+1, min_count=len_-1, min_value=min_-1, max_value=max_+1).to_python(val) # test ok case by providing boundary conditions as arrays (val): val2 = NArrayField(max_count=len_ + 1, min_count=len_ - 1, min_value=val, max_value=val).to_python(val) assert val2 == expected
def clean(self): cleaned_data = super(TrellisForm, self).clean() # calculate z1pt0 and z2pt5 if needed, raise in case of errors: vs30 = cleaned_data['vs30'] # surely a list with st least one element vs30scalar = isscalar(vs30) vs30s = np.array(vectorize(vs30), dtype=float) # check vs30-dependent values: for name, func in (['z1pt0', vs30_to_z1pt0_cy14], ['z2pt5', vs30_to_z2pt5_cb14]): if name not in cleaned_data or cleaned_data[name] == []: values = func(vs30s) # numpy-function cleaned_data[name] = \ float(values[0]) if vs30scalar else values.tolist() elif isscalar(cleaned_data[name]) != isscalar(vs30) or \ (not isscalar(vs30) and len(vs30) != len(cleaned_data[name])): str_ = 'scalar' if isscalar(vs30) else \ '%d-elements vector' % len(vs30) # instead of raising ValidationError, which is keyed with # '__all__' we add the error keyed to the given field name # `name` via `self.add_error`: # https://docs.djangoproject.com/en/2.0/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other error = ValidationError(_("value must be consistent with vs30 " "(%s)" % str_), code='invalid') self.add_error(name, error) return cleaned_data
def to_python(self, value): # three scenarios: iterable: take iterable # non iterable: parse [value] # string: split value into iterable values = [] is_vector = not isscalar(value) if value is not None: if not is_vector and isinstance(value, str): value = value.strip() is_vector = value[:1] == '[' if is_vector != (value[-1:] == ']'): raise ValidationError('unbalanced brackets') try: value = json.loads(value if is_vector else "[%s]" % value) except Exception: # pylint: disable=broad-except try: value = shlex.split( value[1:-1].strip() if is_vector else value) except Exception: raise ValidationError('Input syntax error') for val in vectorize(value): try: vls = self.parse(val) except ValidationError: raise except Exception as exc: raise ValidationError("%s: %s" % (str(val), str(exc))) if isscalar(vls): values.append(vls) else: # force the return value to be list even if we have 1 elm: is_vector = True values.extend(vls) # check lengths: try: self.checkrange(len(values), self.min_count, self.max_count) except ValidationError as verr: # just re-format exception stringand raise: # msg should be in the form '% not in ...', remove first '%s' msg = verr.message[verr.message.find(' '):] raise ValidationError('number of elements (%d) %s' % (len(values), msg)) # check bounds: minval, maxval = self.min_value, self.max_value minval = [minval] * len(values) if isscalar(minval) else minval maxval = [maxval] * len(values) if isscalar(maxval) else maxval for numval, mnval, mxval in zip(values, chain(minval, repeat(None)), chain(maxval, repeat(None))): self.checkrange(numval, mnval, mxval) return values[0] if (len(values) == 1 and not is_vector) else values