Skip to content

Commit af0adfa

Browse files
author
Sylvain MARIE
committed
Numpy True can be used (again) as a success condition in validation functions. Fixed #53
1 parent 80ed5df commit af0adfa

File tree

5 files changed

+57
-30
lines changed

5 files changed

+57
-30
lines changed

valid8/base.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,48 @@ def get_callable_names(validation_callables # type: Iterable[ValidationCallable
9999
SUCCESS_CONDITIONS = 'in {None, True}' # was used in some error messages
100100

101101

102-
def result_is_success(validation_result # type: Any
103-
):
104-
# type: (...) -> bool
105-
"""
106-
Helper function to check if some results returned by a validation function mean success or failure.
102+
try:
103+
import numpy as np
104+
except ImportError:
105+
NP_TRUE = None # not available - use None as it is already a success condition
107106

108-
The result should be True or None for a validation to be considered valid. Note that this is
109-
quite different from the standard python truth value test (where None is equivalent to False), but it seems
110-
more adapted to an intuitive usage, where a function that returns silently without any output means a
111-
successful validation.
107+
def result_is_success(validation_result # type: Any
108+
):
109+
# type: (...) -> bool
110+
"""
111+
Helper function to check if some results returned by a validation function mean success or failure.
112112
113-
:param validation_result:
114-
:return:
115-
"""
116-
# WARNING: if you change this definition, do not forget to do a search on all occurences of `result_is_success` in
117-
# the code base, and replace all inlined versions accordingly
118-
return (validation_result is None) or (validation_result is True)
113+
The result should be True or None for a validation to be considered valid. Note that this is
114+
quite different from the standard python truth value test (where None is equivalent to False), but it seems
115+
more adapted to an intuitive usage, where a function that returns silently without any output means a
116+
successful validation.
117+
118+
:param validation_result:
119+
:return:
120+
"""
121+
# WARNING: if you change this definition, do not forget to do a search on all occurences of `result_is_success`
122+
# in the code base, and replace all inlined versions accordingly
123+
return (validation_result is None) or (validation_result is True)
124+
else:
125+
NP_TRUE = np.bool_(True)
126+
127+
def result_is_success(validation_result # type: Any
128+
):
129+
# type: (...) -> bool
130+
"""
131+
Helper function to check if some results returned by a validation function mean success or failure.
132+
133+
The result should be True or None for a validation to be considered valid. Note that this is
134+
quite different from the standard python truth value test (where None is equivalent to False), but it seems
135+
more adapted to an intuitive usage, where a function that returns silently without any output means a
136+
successful validation.
137+
138+
:param validation_result:
139+
:return:
140+
"""
141+
# WARNING: if you change this definition, do not forget to do a search on all occurences of `result_is_success`
142+
# in the code base, and replace all inlined versions accordingly
143+
return (validation_result is None) or (validation_result is True) or (validation_result is NP_TRUE)
119144

120145

121146
def is_error_of_type(exc, ref_type):
@@ -546,7 +571,7 @@ def raiser(x, **ctx):
546571
# perform validation
547572
res = call_it(x, **ctx)
548573
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
549-
success = (res is None) or (res is True)
574+
success = (res is None) or (res is True) or (res is NP_TRUE)
550575

551576
except ValidationFailure as f:
552577
# failures should be raised "as is"

valid8/composition.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from makefun import with_signature
66

7-
from valid8.base import ValidationFailure, get_callable_names, get_callable_name, _none_accepter, _none_rejecter, pop_kwargs
7+
from valid8.base import ValidationFailure, get_callable_names, get_callable_name, _none_accepter, _none_rejecter, \
8+
pop_kwargs, NP_TRUE
89
from valid8.common_syntax import make_validation_func_callables
910

1011

@@ -109,7 +110,7 @@ def play_all_validators(self, validators, value, **ctx):
109110
try:
110111
res = validator(value, **ctx)
111112
# if result_is_success(res): <= DO NOT REMOVE THIS COMMENT
112-
if (res is None) or (res is True):
113+
if (res is None) or (res is True) or (res is NP_TRUE):
113114
successes.append(name)
114115
else:
115116
failures[validator] = res
@@ -169,7 +170,7 @@ def and_v_(x, **ctx):
169170
# one validator was unhappy > raise
170171
raise AtLeastOneFailed(validation_funcs, x, ctx, cause=e)
171172
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
172-
if (res is not None) and (res is not True):
173+
if (res is not None) and (res is not True) and (res is not NP_TRUE):
173174
# one validator was unhappy > raise
174175
raise AtLeastOneFailed(validation_funcs, x, ctx)
175176

@@ -210,7 +211,7 @@ def not_v_(x, **ctx):
210211
try:
211212
res = validation_func(x, **ctx)
212213
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
213-
if (res is not None) and (res is not True): # inverse the result
214+
if (res is not None) and (res is not True) and (res is not NP_TRUE): # inverse the result
214215
return True
215216

216217
except ValidationFailure:
@@ -265,7 +266,7 @@ def or_v_(x, **ctx):
265266
try:
266267
res = validator(x, **ctx)
267268
# if result_is_success(res): <= DO NOT REMOVE THIS COMMENT
268-
if (res is None) or (res is True):
269+
if (res is None) or (res is True) or (res is NP_TRUE):
269270
# we can return : one validator was happy
270271
return True
271272
except Exception:
@@ -316,7 +317,7 @@ def xor_v_(x, **ctx):
316317
try:
317318
res = val_func(x, **ctx)
318319
# if result_is_success(res): <= DO NOT REMOVE THIS COMMENT
319-
if (res is None) or (res is True):
320+
if (res is None) or (res is True) or (res is NP_TRUE):
320321
ok_validators.append(val_func)
321322
except Exception:
322323
pass

valid8/entry_points.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@
2828
use_typing = False
2929

3030
from valid8.utils.string_tools import end_with_dot
31-
from valid8.base import get_callable_name, _none_accepter, _none_rejecter, RootException, failure_raiser, ValidationFailure, \
32-
HelpMsgMixIn, is_error_of_type, HelpMsgFormattingException, should_be_hidden_as_cause, raise_, pop_kwargs
31+
from valid8.base import get_callable_name, _none_accepter, _none_rejecter, RootException, failure_raiser, \
32+
ValidationFailure, HelpMsgMixIn, is_error_of_type, HelpMsgFormattingException, should_be_hidden_as_cause, raise_, \
33+
pop_kwargs, NP_TRUE
3334
from valid8.common_syntax import make_validation_func_callables
3435
from valid8.composition import _and_
3536

@@ -702,7 +703,7 @@ def is_valid(self,
702703

703704
# return a boolean indicating if success or failure
704705
# return result_is_success(res): <= DO NOT REMOVE THIS COMMENT
705-
return (res is None) or (res is True)
706+
return (res is None) or (res is True) or (res is NP_TRUE)
706707

707708
except Exception:
708709
# caught exception means failure > return False

valid8/entry_points_inline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from linecache import getline
55

6-
from valid8.base import ValueIsNone, raise_, ValidationFailure, InvalidType, InvalidValue
6+
from valid8.base import ValueIsNone, raise_, ValidationFailure, InvalidType, InvalidValue, NP_TRUE
77
from valid8.entry_points import Validator, ValidationError, NonePolicy, assert_valid
88
from valid8.validation_lib.types import HasWrongType, IsWrongType
99
from valid8.validation_lib.collections import NotInAllowedValues, TooLong, TooShort, WrongLength, DoesNotContainValue, \
@@ -442,7 +442,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
442442
res = exc_val or self.eye.outcome
443443

444444
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
445-
if res is not None and res is not True:
445+
if (res is not None) and (res is not True) and (res is not NP_TRUE):
446446
# ValidationFailure: *** We should raise a Validation Error ***
447447

448448
# extract the source file and line number where exit happened

valid8/validation_lib/collections.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
pass
66

77
from valid8.composition import and_
8-
from valid8.base import ValidationFailure, get_callable_name
8+
from valid8.base import ValidationFailure, get_callable_name, NP_TRUE
99

1010

1111
class Empty(ValidationFailure, ValueError):
@@ -303,7 +303,7 @@ def on_all_val(x):
303303
validation_outcome=e)
304304

305305
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
306-
if (res is not None) and (res is not True):
306+
if (res is not None) and (res is not True) and (res is not NP_TRUE):
307307
# one element of x was not valid > raise
308308
# raise ValidationFailure('on_all_(' + str(validation_func) + '): failed for input '
309309
# 'element [' + str(idx) + ']: ' + str(x_elt))
@@ -357,7 +357,7 @@ def on_each_val(x # type: Tuple
357357
validation_outcome=e)
358358

359359
# if not result_is_success(res): <= DO NOT REMOVE THIS COMMENT
360-
if (res is not None) and (res is not True):
360+
if (res is not None) and (res is not True) and (res is not NP_TRUE):
361361
# one validation_function was unhappy > raise
362362
raise InvalidItemInSequence(wrong_value=elt,
363363
validation_func=validation_function_func,

0 commit comments

Comments
 (0)