Skip to content

Commit

Permalink
Merge pull request #56 from marcellarius/no-null-type-conversion
Browse files Browse the repository at this point in the history
No null type conversion
  • Loading branch information
sloria committed Aug 18, 2015
2 parents a2f163d + db76dd4 commit 0c15aba
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
8 changes: 6 additions & 2 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,17 @@ def test_validated_long_type(self):
arg = Arg(type_=long_type)
assert arg.validated('foo', 42) == 42

def test_validated_string_conversion_null(self):
arg = Arg(type_=str)
assert arg.validated('foo', None) is None

def test_validated_unknown_type(self):
arg = Arg(type_=UUID)
assert (arg.validated('foo', '12345678123456781234567812345678') ==
UUID('12345678-1234-5678-1234-567812345678'))
with pytest.raises(ValidationError) as excinfo:
arg.validated('foo', None)
assert 'Expected type "UUID" for foo, got "null"' in str(excinfo)
arg.validated('foo', '123xyz') # An invalid UUID
assert 'Expected type "UUID" for foo, got "string"' in str(excinfo)

def test_custom_error(self):
arg = Arg(type_=int, error='not an int!')
Expand Down
28 changes: 23 additions & 5 deletions webargs/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,27 @@ def noop(x):
class Arg(object):
"""A request argument.
When a value for an Arg is found in the request, it is processed by the ``validated``
method, which performs type conversion and any validation functions on this
Arg object.
The validation is performed as follows:
1. Any ``use`` functions are run to transform the value prior to type conversion.
2. If the value is not ``None`` then type conversion will take place, transforming the
value using the `type\_` parameter
3. Any validation functions are run. If a function returns ``False`` or raises a
:exc:`ValidationError` then validation for this Arg will stop and an error will
be raised.
In the case of a nested Arg dictionary, the validation functions are run before
the nested arguments are processed.
:param type\_: Value type or nested `Arg` dictionary. If the former,
the parsed value will be coerced this type. If the latter, the parsed
value will be validated and converted according to the nested `Arg` dict.
If ``None``, no type conversion will be performed.
If the parsed value, or the `type\_` parameter is ``None``, no type conversion
will be performed.
:param default: Default value for the argument. Used if the value is not found
on the request. May be a callable.
:param required: If truthy, the :meth:`Parser.handle_error`
Expand Down Expand Up @@ -233,10 +250,11 @@ def _validate(self, name, value):
if ret is None and self.type in __non_nullable_types__:
raise ValidationError(self.error or msg, arg_name=name)

try:
ret = self.type(ret)
except (ValueError, TypeError):
raise ValidationError(self.error or msg, arg_name=name)
if ret is not None:
try:
ret = self.type(ret)
except (ValueError, TypeError):
raise ValidationError(self.error or msg, arg_name=name)

# Then call validation functions
for validator in self.validators:
Expand Down

0 comments on commit 0c15aba

Please sign in to comment.