[Python-ideas] Repurpose `assert' into a general-purpose check

Paul Moore p.f.moore at gmail.com
Tue Nov 28 08:46:59 EST 2017


On 28 November 2017 at 13:36, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On 28 November 2017 at 15:41, Steven D'Aprano <steve at pearwood.info> wrote:
>> On Tue, Nov 28, 2017 at 05:12:36AM +0300, Ivan Pozdeev via Python-ideas wrote:
>>> Unlike C, Python does the aforementioned checks all the time, i.e. it's
>>> effectively always in "debug mode".
>>
>> Apart from -O which disables assertions. But in any case, the best use
>> of assertions is not checking things which the interpreter is going to
>> do anyway, but checking things which the interpreter can not and does
>> not check automatically: your program logic. There is no way that the
>> Python interpreter is going to do this check automatically, unless I
>> write the assertion:
>>
>> assert 0 <= r < abs(y)
>>
>> That is copied straight out of one of my functions.
>
> I'll make the same observation I usually do each time one of these
> threads comes up:
>
> * I'm opposed to making assert substantially different from the way it works now
> * I'm in favour of adding a new "ensure()" builtin that encapsulates
> the check-and-raise logic
>
> The reasons I prefer this approach:
>
> - assert is a statement *solely* so that the compiler can optimise it
> out. If it's not optional,
>   it doesn't need to be a statement any more
> - if the existing assert statements are left alone, there are no
> performance or compatibility
>   concerns for folks that rely on the current behaviour
> - if it's a function, it doesn't need to be called "assert", it can use the more
>   imperative term "ensure" (meaning "ensure this condition is true
> before continuing")
> - if it's a function, it can easily be emulated on old versions via
> compatibility libraries
> - "ensure() is required, assert is optional" is a better answer to
> complaints about
>   assertions being optional than suggesting "if cond: raise AssertionError(msg)"
>   as a reasonable alternative to "assert cond, msg"
> - if it's a function, we get access to all the regular function
> machinery, so we're
>   not restricted to positional-only arguments the way the assert statement is
>
> My initial proposed behaviour for the function:
>
>     def ensure(cond, msg=None, exc_type=RuntimeError):
>         """Raise an exception if the given condition is not true"""
>         if not cond:
>             if msg is None:
>                 frame = sys._getframe(1)
>                 line = frame.f_lineno
>                 modname = frame.f_globals.get("__name__", "<unknown module>")
>                 msg = f"Condition not met on line {line:d} in {modname!r}"
>             raise exc_type(msg)
>
> Cheers,
> Nick.
>
> P.S. No, I'm not offering to write that PEP myself, I'd just be in
> favour of the idea if someone else were to write it :)

+1 on everything Nick said.

Paul


More information about the Python-ideas mailing list