On Tue, Nov 28, 2017 at 6:08 PM Ivan Pozdeev via Python-ideas <python-ideas@python.org> wrote:
On 28.11.2017 16:36, Nick Coghlan wrote:

> On 28 November 2017 at 15:41, Steven D'Aprano <steve@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
Another benefit of a statement vs function is only evaluating the
error-related arguments when there's an error

I'm not sure what the use case is, but it could be implemented easily as

    ensure(not hasattr(e, "exception")) or raise e.exception

... had "raise" been an expression, an idea repeatedly rejected here. It's still implementable with a "throw()" function.

> - 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 :)


Python-ideas mailing list
Code of Conduct: http://python.org/psf/codeofconduct/