Skip to content

Commit 0d4b879

Browse files
author
Sylvain MARIE
committed
Using the fastest string formatting method everywhere possible (except in help messages templates of validation exceptions)
1 parent 3eba6d7 commit 0d4b879

14 files changed

Lines changed: 81 additions & 82 deletions

valid8/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -576,11 +576,11 @@ def raiser(x, **ctx):
576576
# they will appear anyway !
577577
# ---
578578
# if help_msg or failure_type:
579-
# raiser.__name__ = 'failure_raiser({}, {})'.format(get_callable_name(validation_callable),
580-
# help_msg or failure_type.__name__)
579+
# raiser.__name__ = 'failure_raiser(%s, %s)' % (get_callable_name(validation_callable),
580+
# help_msg or failure_type.__name__)
581581
# else:
582582
# ---
583-
# raiser.__name__ = 'failure_raiser({})'.format(get_callable_name(validation_callable))
583+
# raiser.__name__ = 'failure_raiser(%s)' % get_callable_name(validation_callable)
584584
raiser.__name__ = get_callable_name(validation_callable)
585585
# Note: obviously this can hold as long as we do not check the name of this object in any other context than
586586
# raising errors. If we want to support this, then creating a callable object with everything in the fields will be
@@ -657,7 +657,7 @@ def accept_none(x, **ctx):
657657
# value is None: skip validation
658658

659659
# set a name so that the error messages are more user-friendly
660-
accept_none.__name__ = 'skip_on_none({})'.format(get_callable_name(validation_callable))
660+
accept_none.__name__ = 'skip_on_none(%s)' % get_callable_name(validation_callable)
661661

662662
return accept_none
663663

@@ -689,7 +689,7 @@ def reject_none(x, **ctx):
689689
raise ValueIsNone(wrong_value=x)
690690

691691
# set a name so that the error messages are more user-friendly ==> NO ! here we want to see the checker
692-
reject_none.__name__ = 'reject_none({})'.format(get_callable_name(validation_callable))
692+
reject_none.__name__ = 'reject_none(%s)' % get_callable_name(validation_callable)
693693

694694
return reject_none
695695

valid8/composition.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def and_v_(x, **ctx):
175175

176176
return True
177177

178-
and_v_.__name__ = 'and({})'.format(get_callable_names(validation_funcs))
178+
and_v_.__name__ = 'and(%s)' % get_callable_names(validation_funcs)
179179
return and_v_
180180

181181

@@ -225,7 +225,7 @@ def not_v_(x, **ctx):
225225
# if we're here that's a failure
226226
raise DidNotFail(validation_func=validation_func, wrong_value=x, validation_outcome=res)
227227

228-
not_v_.__name__ = 'not({})'.format(get_callable_name(validation_func))
228+
not_v_.__name__ = 'not(%s)' % get_callable_name(validation_func)
229229
return not_v_
230230

231231

@@ -275,7 +275,7 @@ def or_v_(x, **ctx):
275275
# no validator accepted: gather details and raise
276276
raise AllValidatorsFailed(validation_func, x, ctx)
277277

278-
or_v_.__name__ = 'or({})'.format(get_callable_names(validation_func))
278+
or_v_.__name__ = 'or(%s)' % get_callable_names(validation_func)
279279
return or_v_
280280

281281

@@ -334,7 +334,7 @@ def xor_v_(x, **ctx):
334334
# no validation function happy, fail
335335
raise AllValidatorsFailed(validation_func, x, ctx)
336336

337-
xor_v_.__name__ = 'xor({})'.format(get_callable_names(validation_func))
337+
xor_v_.__name__ = 'xor(%s)' % get_callable_names(validation_func)
338338
return xor_v_
339339

340340

valid8/entry_points.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ def __init__(self,
472472
quite different from the standard python truth value test (where None is equivalent to False), but it seems more
473473
adapted to an intuitive usage, where a function that returns silently without any output means 'no problem
474474
there, move one'. Users defining their own base validation functions may wish to raise instances or subclasses
475-
of `ValidationFailure` to provide more user-friendly details and unique failure identifiers. Raw mini_lambda expressions
476-
are supported and are automatically transformed to functions.
475+
of `ValidationFailure` to provide more user-friendly details and unique failure identifiers. Raw mini_lambda
476+
expressions are supported and are automatically transformed to functions.
477477
478478
For example:
479479
@@ -500,10 +500,12 @@ def my_validator(x):
500500
```
501501
502502
Users may perform composition on base validation functions used in a `Validator`:
503+
503504
- either explicitly using the various operators provided in valid8.composition (`and_`, `or_`, `xor_`,
504-
`failure_raiser()`, `skip_on_none()`, `fail_on_none()`...)
505+
`failure_raiser()`, `skip_on_none()`, `fail_on_none()`...)
506+
505507
- or implicitly using the syntax defined in `ValidationFuncs`: i.e. a list means an implicit `and_()` and a
506-
tuple means an implicit `failure_raiser()`
508+
tuple means an implicit `failure_raiser()`
507509
508510
It is possible to provide values for `help_msg` and `error_type` in the constructor so as to reuse them in any
509511
subsequent call to `assert_valid`. See `assert_valid` for details about those fields
@@ -534,8 +536,8 @@ def my_validator(x):
534536
kw_context_args = kwargs
535537

536538
if help_msg is None and error_type is None and len(kw_context_args) > 0:
537-
raise ValueError("Keyword context arguments have been provided but help_msg and error_type have not: {}"
538-
"".format(kw_context_args))
539+
raise ValueError("Keyword context arguments have been provided but `help_msg` and `error_type` have not: %s"
540+
% kw_context_args)
539541

540542
self.none_policy = none_policy if none_policy is not None else NonePolicy.VALIDATE
541543

@@ -572,14 +574,17 @@ def __repr__(self):
572574
# type: (...) -> str
573575
""" Overrides the default string representation for Validator instances """
574576

575-
info = self.get_additional_info_for_repr()
576-
return "{validator_type}<{additional_info}validation_function={main_val_function}, none_policy={none_policy}," \
577-
" exc_type={exc_type}>" \
578-
"".format(additional_info=(info + ', ') if len(info) > 0 else '',
579-
validator_type=type(self).__name__,
580-
main_val_function=self.get_main_function_name(),
581-
none_policy=get_none_policy_text(self.none_policy),
582-
exc_type=self.error_type.__name__)
577+
_info = self.get_additional_info_for_repr()
578+
additional_info = (_info + ', ') if len(_info) > 0 else ''
579+
580+
validator_type = type(self).__name__
581+
main_val_function = self.get_main_function_name()
582+
none_policy = get_none_policy_text(self.none_policy)
583+
exc_type = self.error_type.__name__
584+
585+
return "%s<%s" \
586+
"validation_function=%s, none_policy=%s, exc_type=%s>" \
587+
% (validator_type, additional_info, main_val_function, none_policy, exc_type)
583588

584589
def get_additional_info_for_repr(self):
585590
# type: (...) -> str

valid8/entry_points_annotations.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def get_what_txt(self):
4747
Overrides the base behaviour defined in ValidationError in order to add details about the function.
4848
:return:
4949
"""
50-
return 'input [{var}] for function [{func}]'.format(var=self.get_variable_str(),
51-
func=self.validator.get_validated_func_display_name())
50+
return 'input [%s] for function [%s]' % (self.get_variable_str(),
51+
self.validator.get_validated_func_display_name())
5252

5353

5454
class OutputValidationError(ValidationError):
@@ -67,7 +67,7 @@ def get_what_txt(self):
6767
Overrides the base behaviour defined in ValidationError in order to add details about the function.
6868
:return:
6969
"""
70-
return 'output of function [{func}]'.format(func=self.validator.get_validated_func_display_name())
70+
return 'output of function [%s]' % self.validator.get_validated_func_display_name()
7171

7272

7373
class ClassFieldValidationError(ValidationError):
@@ -85,8 +85,8 @@ def get_what_txt(self):
8585
Overrides the base behaviour defined in ValidationError in order to add details about the class field.
8686
:return:
8787
"""
88-
return 'field [{field}] for class [{clazz}]'.format(field=self.get_variable_str(),
89-
clazz=self.validator.get_validated_class_display_name())
88+
return 'field [%s] for class [%s]' % (self.get_variable_str(),
89+
self.validator.get_validated_class_display_name())
9090

9191
def get_variable_str(self):
9292
""" Utility method to get the variable value or 'var_name=value' if name is not None """
@@ -147,7 +147,7 @@ def __init__(self,
147147
error_type=error_type, help_msg=help_msg, **kw_context_args)
148148

149149
def get_additional_info_for_repr(self):
150-
return 'validated_function={func}'.format(func=get_callable_name(self.validated_func))
150+
return 'validated_function=%s' % get_callable_name(self.validated_func)
151151

152152
def get_validated_func_display_name(self):
153153
"""
@@ -330,8 +330,8 @@ def _get_name_for_errors(self,
330330
return self.validated_field_name
331331

332332
def get_additional_info_for_repr(self):
333-
return 'validated_class_field={clazz}.{field}'.format(clazz=self.get_validated_class_display_name(),
334-
field=self.validated_field_name)
333+
return 'validated_class_field=%s.%s' % (self.get_validated_class_display_name(),
334+
self.validated_field_name)
335335

336336
def get_validated_class_display_name(self):
337337
"""
@@ -645,14 +645,14 @@ def decorate_cls_with_validation(cls,
645645
elif (hasattr(var, '__get__') and callable(var.__get__)) \
646646
or (hasattr(var, '__delete__') and callable(var.__delete__)):
647647
# this is a descriptor but it does not have any setter method: impossible to validate
648-
raise ValueError("Class field '{}' is a valid class descriptor for class '{}' but it does not implement "
648+
raise ValueError("Class field '%s' is a valid class descriptor for class '%s' but it does not implement "
649649
"__set__ so it is not possible to add validation to it. See "
650-
"https://docs.python.org/3.6/howto/descriptor.html".format(field_name, cls.__name__))
650+
"https://docs.python.org/3.6/howto/descriptor.html" % (field_name, cls.__name__))
651651

652652
else:
653653
# this is not a descriptor: unsupported
654-
raise ValueError("Class field '{}.{}' is not a valid class descriptor, see "
655-
"https://docs.python.org/3.6/howto/descriptor.html".format(cls.__name__, field_name))
654+
raise ValueError("Class field '%s.%s' is not a valid class descriptor, see "
655+
"https://docs.python.org/3.6/howto/descriptor.html" % (cls.__name__, field_name))
656656

657657
else:
658658
# ** No class field with that name exist
@@ -682,8 +682,8 @@ def decorate_cls_with_validation(cls,
682682
# (for __setattr__ see https://stackoverflow.com/questions/15750522/class-properties-and-setattr/15751159)
683683

684684
# finally raise an error
685-
raise ValueError("@validate_field definition exception: field '{}' can not be found in class '{}', and it "
686-
"is also not an input argument of the __init__ method.".format(field_name, cls.__name__))
685+
raise ValueError("@validate_field definition exception: field '%s' can not be found in class '%s', and it "
686+
"is also not an input argument of the __init__ method." % (field_name, cls.__name__))
687687

688688
return cls
689689

valid8/entry_points_inline.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ def validate(name, # type: str
319319
else:
320320
# basic (and not enough) check to verify that there was no typo leading an argument to be put in kw_context_args
321321
if error_type is None and help_msg is None and len(kw_context_args) > 0:
322-
raise ValueError("Keyword context arguments have been provided but help_msg and error_type are not: {}"
323-
"".format(kw_context_args))
322+
raise ValueError("Keyword context arguments have been provided but `help_msg` and `error_type` have not: %s"
323+
% kw_context_args)
324324

325325

326326
_QUICK_VALIDATOR = _QuickValidator()
@@ -461,8 +461,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):
461461
try:
462462
wrapped_block_lines = self._get_wrapped_lines(exit_file_path, exit_line_nb)
463463
except Exception as e:
464-
warn('Error while inspecting source code at {}. No details will be added to the resulting '
465-
'exception. Caught {}'.format(exit_file_path, e))
464+
warn('Error while inspecting source code at %s. No details will be added to the resulting '
465+
'exception. Caught %s' % (exit_file_path, e))
466466
else:
467467
if exc_val is not None:
468468
# -- There was an exception, we dont know where: output the full code in self.main_function.name

valid8/tests/helpers/utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ def append_all_custom_variants(base_function, custom_boolean_testers, custom_fai
99
:return:
1010
"""
1111
if 'custom_boolean' in base_function.__name__:
12-
print('{} uses custom boolean checkers'.format(base_function.__name__))
12+
print('%s uses custom boolean checkers' % base_function.__name__)
1313
for cust in custom_boolean_testers:
1414
dest_list.append(create_custom_function(base_function, cust))
1515

1616
elif 'custom_raiser' in base_function.__name__:
17-
print('{} uses custom failure raisers'.format(base_function.__name__))
17+
print('%s uses custom failure raisers' % base_function.__name__)
1818
for cust in custom_failure_raisers:
1919
dest_list.append(create_custom_function(base_function, cust))
2020

2121
else:
22-
print('{} uses ALL custom functions'.format(base_function.__name__))
22+
print('%s uses ALL custom functions' % base_function.__name__)
2323
for cust in custom_boolean_testers + custom_failure_raisers:
2424
dest_list.append(create_custom_function(base_function, cust))
2525

2626

2727
def create_custom_function(base_function, cust):
2828
def cust_f(t):
29-
print('calling function {} with custom func {}'.format(base_function.__name__, cust.__name__))
29+
print('calling function %s with custom func %s' % (base_function.__name__, cust.__name__))
3030
return base_function(t, cust)
3131

3232
cust_f.__name__ = base_function.__name__.replace('custom', 'custom_' + cust.__name__)

valid8/tests/readme/examples/test_example3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
ex3_functions = []
2222
for ex3_func in ex3_functions_init:
2323
if 'custom' not in ex3_func.__name__:
24-
print('{} does not use custom function'.format(ex3_func.__name__))
24+
print('%s does not use custom function' % ex3_func.__name__)
2525
ex3_functions.append(ex3_func)
2626
else:
2727
# create as many functions as there are custom functions to use

valid8/tests/readme/test_readme_examples.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ def test_readme_examples_4():
1818

1919
for i, v in enumerate(l):
2020
# each item is a tuple of size 2
21-
validate('l[{}]'.format(i), l[i], instance_of=tuple, length=2)
21+
validate('l[%s]'% i, l[i], instance_of=tuple, length=2)
2222
# the first element is a float between 0 and 1
23-
validate('l[{}][0]'.format(i), l[i][0], instance_of=Real, min_value=0, max_value=1)
23+
validate('l[%s][0]'% i, l[i][0], instance_of=Real, min_value=0, max_value=1)
2424
# the second element is a lowercase string of size 3
25-
validate('l[{}][1]'.format(i), l[i][1], instance_of=str, length=3, equals=l[i][1].lower())
25+
validate('l[%s][1]'% i, l[i][1], instance_of=str, length=3, equals=l[i][1].lower())
2626

2727
# ---- inline 2
2828
from valid8 import validator
@@ -71,7 +71,7 @@ def check_valid_tuple(tup):
7171
# then validate (and use) the contents
7272
for i, v in enumerate(l):
7373
# each item is a valid tuple
74-
with validation('l[{}]'.format(i), l[i]):
74+
with validation('l[%s]'% i, l[i]):
7575
check_valid_tuple(l[i])
7676

7777
# here you can actually USE the current item

valid8/tests/readme/test_readme_usage.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def test_tutorial():
1313
# 1. age: finite
1414
def hello(age):
1515
assert isfinite(age)
16-
print('Hello, {}-years-old fella !'.format(age))
16+
print('Hello, %s-years-old fella !' % age)
1717

1818
hello(21)
1919
with pytest.raises(AssertionError):
@@ -26,7 +26,7 @@ def hello(age):
2626
def hello(age):
2727
# assert_valid('age', age, isfinite)
2828
validate('age', age, custom=isfinite)
29-
print('Hello, {}-years-old fella !'.format(age))
29+
print('Hello, %s-years-old fella !' % age)
3030

3131
hello(21)
3232
with pytest.raises(ValidationError) as exc_info:
@@ -45,7 +45,7 @@ def hello(age):
4545
from valid8.validation_lib import between
4646
def hello(age):
4747
assert_valid('age', age, [isfinite, between(0, 150)])
48-
print('Hello, {}-years-old fella !'.format(age))
48+
print('Hello, %s-years-old fella !' % age)
4949

5050
hello(21)
5151
with pytest.raises(ValidationError) as exc_info:
@@ -61,7 +61,7 @@ def hello(age):
6161
from mini_lambda import x, Int
6262
def hello(age):
6363
assert_valid('age', age, [isfinite, between(0, 150), Int(x) == x])
64-
print('Hello, {}-years-old fella !'.format(age))
64+
print('Hello, %s-years-old fella !' % age)
6565

6666
with pytest.raises(ValidationError) as exc_info:
6767
hello(12.5)
@@ -281,7 +281,7 @@ def is_multiple_of(ref):
281281
def is_multiple_of_ref(x):
282282
return x % ref == 0
283283

284-
is_multiple_of_ref.__doc__ = "Checks that x is a multiple of {}".format(ref)
284+
is_multiple_of_ref.__doc__ = "Checks that x is a multiple of %s" % ref
285285
is_multiple_of_ref.__name__ = "is_multiple_of_" + str(ref)
286286
return is_multiple_of_ref
287287

@@ -298,10 +298,10 @@ def create_base_functions_2():
298298
# (recommended) raising an exception
299299
def gt_0(x):
300300
if not (x >= 0):
301-
raise ValueError('x is not greater than 0, x={}.'.format(x))
301+
raise ValueError('x is not greater than 0, x=%s.' % x)
302302
def gt_1(x):
303303
if x < 1:
304-
raise ValidationFailure(x, 'x is not greater than 1, x={}.'.format(x))
304+
raise ValidationFailure(x, 'x is not greater than 1, x=%s.' % x)
305305

306306
# (not recommended) relying on assert, only valid in 'debug' mode
307307
def gt_2(x):
@@ -310,7 +310,7 @@ def gt_2(x):
310310
# returning details
311311
def gt_3(x):
312312
if x < 3:
313-
return 'x is not greater than 3, x={}'.format(x)
313+
return 'x is not greater than 3, x=%s' % x
314314

315315
return gt_0, gt_1, gt_2, gt_3
316316

@@ -353,7 +353,7 @@ def gt_ex1(x):
353353
if x >= 1:
354354
return True
355355
else:
356-
raise ValidationFailure(x, 'x >= 1 does not hold for x={}'.format(x))
356+
raise ValidationFailure(x, 'x >= 1 does not hold for x=%s' % x)
357357

358358
def gt_assert2(x):
359359
"""(not recommended) relying on assert, only valid in 'debug' mode"""

valid8/tests/test_entry_points_annotations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ def test_validate_custom_validators_with_exception():
288288
def gt_ex1(x):
289289
""" A validator raising a custom exception in case of failure """
290290
if not x >= 1:
291-
raise ValidationFailure(x, 'x >= 1 does not hold for x={val}'.format(val=x))
291+
raise ValidationFailure(x, 'x >= 1 does not hold for x=%s' % x)
292292

293293
def is_mod(ref):
294294
""" A validator generator, with parameters and which raises a custom exception """

0 commit comments

Comments
 (0)