Le mardi 16 janvier 2018 11:24:34 UTC+1, Steven D'Aprano a écrit :
That's not a bug, or even a problem ("wrong"), it is the very purpose of assert. Assertions are intended to allow the end user to disable the checks.
If you, the developer, don't want a check to be disabled, then you shouldn't call it an assertion and use assert.
That is exactly what I'm saying. It seems that we both agree that applicative value validation is different from asserts, and that assert should not be used for applicative value validation. For this reason, I do not suggest to go in the direction the OP is mentioning but rather to explicitly separate the 2 concepts by creating a new statement for value validation.
The problem with a statement called "validate" is that it will break a huge number of programs that already include functions and methods using that name.
You definitely make a point here. But that would be the case for absolutely *any* language evolution as soon as the proposed statements are plain old english words. Should it be a show-stopper ? I dont think so.
But apart from the use of a keyword, we already have a way to do almost exactly what you want:
if not expression: raise ValidationError(message)
after defining some appropriate ValidationError class. And it is only a few key presses longer than the proposed:
validate expression, ValidationError, message
This is precisely what is not good in my opinion: here you do not separate <validation means> from <validation intent>. Of course if <validation means> is just a "x > 0" statement, it works, but now what if you rely on a 3d-party provided validation function (or even yours) such as e.g. "is_foo_compliant" ?
if not is_foo_compliant(x): raise ValidationError(message)
What if this third part method raises an exception instead of returning False in some cases ?
try: if not is_foo_compliant(x): raise ValidationError(message) except: raise MyValidationError(message)
What if you want to compose this third party function with *another* one that returns False but not exceptions ? Say, with an OR ? (one or the other should work). Yields:
try: if not is_foo_compliant(x): raise ValidationError(message) except: if not is_bar_compliant(x): raise MyValidationError(message)
It starts to be quite ugly, messy... while the applicative intent is clear and could be expressed directly as:
validate is_foo_compliant(x) or is_bar_compliant(x) ValidationError(message)
The goal is really to let developers express their applicative intent =(what should be checked and what is the outcome if anything goes wrong), and give them confidence that the statement will always fail the same way, whatever the failure modes /behaviour of the checkers used in the statement. This is what valid8 https://smarie.github.io/python-valid8/ proposes today with assert_valid, but obviously again having it built-in in the language would be much more concise. Note that the class and function decorators (@validate_arg, @validate_field...) would remain useful anyway.