Re: [Python-ideas] Runtime assertion with no overhead when not active

By 'self-contained', I meant that using the assert keyword and its expression is sufficient. An inline assertive expression as the one you describe does not fulfill this assert requirement. My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime. The syntax example I gave illustrated what I meant by syntax aware. De : Serhiy Storchaka Envoyé : samedi 5 mai à 15:10 Objet : Re: [Python-ideas] Runtime assertion with no overhead when not active À : python-ideas@python.org 05.05.18 15:54, Eloi Gaudry пише: > I meant avoiding the overhead of the expression evaluation enclosed in the assert itself, not the active/disabled state (that comes at virtually no cost). > ex: >>>> runtime_assert( { i:None for i in range( 10000000 ) } ) > > By using the syntax you describe ('boolean and not expr'), you loose all the benefit of the Python grammar: > - self-contained Could you please explain what you mean? > - able to catch semantic/syntax bugs > > ex: >>>> f=1 >>>> runtime_assert( f==1 ) >>>> runtime_assert( f=1 ) > File "", line 1 > runtime_assert( f=1 ) > ^ > SyntaxError: invalid syntax Until inline assignment expression is implemented, this is an error too: >>> if debug and not f=1: File "", line 1 if debug and not f=1: ^ SyntaxError: invalid syntax _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

05.05.18 18:04, Eloi Gaudry пише:
Sufficient for what? And why writing with using the existing syntax is not sufficient?
My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime.
The main property of the assert statement is that has a zero overhead in non-debug run. If you remove this property, it will be not the assert statement, and you will not need a special syntax support for writing this runtime check.
The syntax example I gave illustrated what I meant by syntax aware.
It doesn't illustrate why a new syntax is necessary. Or I can't understand this illustration.

I didn't mean to replace the current (debug) assert but I wanted to add another one that would allow to be switch on or off on production builds. The need for a new keyword (not syntax) comes from this difference. I cannot think of another example that would convince you of the benefit of having a specific keyword for such a runtime assert. I do believe that having such a feature in non-debug build is more than interesting but indeed needed. At some point, there should be a trade-off between to relying on a simple keyword/mechanism (for a runtime assert) versus the development cost of adding such a feature and maintaining it. Anyway, thanks for your feedback Serhiy, it helps. ________________________________ From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> on behalf of Serhiy Storchaka <storchaka@gmail.com> Sent: Saturday, May 5, 2018 17:44 To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active 05.05.18 18:04, Eloi Gaudry пише:
Sufficient for what? And why writing with using the existing syntax is not sufficient?
My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime.
The main property of the assert statement is that has a zero overhead in non-debug run. If you remove this property, it will be not the assert statement, and you will not need a special syntax support for writing this runtime check.
The syntax example I gave illustrated what I meant by syntax aware.
It doesn't illustrate why a new syntax is necessary. Or I can't understand this illustration. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

On Mon, 7 May 2018 at 06:28 Serhiy Storchaka <storchaka@gmail.com> wrote:
My question is how is this different to running with -O which leaves the assert statement out of the bytecode and so you avoid any run-time cost of the statement entirely?

On Mon, 2018-05-07 at 16:56 +0000, Brett Cannon wrote:
Not so much different, except that: - the switch won't need to be on the command line - the 2 different asserts would be considered differently by developers/users : * debug assert, for helping developing a new features, used with debug- builds * runtime assert, for ensuring correctness and/or diagnosing issue with production/release-builds on-site.

On 5/8/2018 9:50 AM, Eloi Gaudry wrote:
I think what's confusing to me (and maybe others) is that we haven't seen your vision on how this would look in Python code. An example that would throw runtime assertions and the same example where it wouldn't (after a global switch is set?) would be helpful. Eric

On Tue, 2018-05-08 at 09:58 -0400, Eric V. Smith wrote:
Eric, I can only agree to your comment. As a matter of fact, I have only used the case where the runtime assert is activated through an extension. In this case, adding a set method is simple : in our framework, we would set the variable Py_RuntimeAssertFlag to 1, depending on some command line parameters, or settings found in a configuration file). In pure python, if something as having a method registered in __builtins__ make sense, it could be used to trigger the assertive behavior. In this example, let's assume that you may want to perform some basic check on a given file in diagnostics mode:
__builtins__.set_runtime_assert( True )

On Wed, May 16, 2018 at 08:29:00AM +0000, Eloi Gaudry wrote:
Is there some interest in the proposal or should I finally close this thread ?
I'm definitely interested in the concept, not the suggested syntax or semantics. -- Steve

On Wed, May 16, 2018 at 01:27:50PM +0000, Eloi Gaudry wrote:
The syntax is the minor point: you give is an ungainly name, "runtime_assert", and your proposed PEP shows it requiring parentheses as if it were an ordinary function. The bigger problem is the semantics. As I already said in an earlier email, you don't explain what "runtime_assert_active" is (is it a per-module global variable? a single application-wide super-global? a local variable? something else?) or how we are supposed to set it. That too is an ungainly name, and the fact that there's only *one* such flag (whether it is per module or not) makes this proposal useless for my needs. Another problem is that your runtime_assert *prints* the error message instead of raising an exception, and there's no way to customise the message. But the most important reason is that I'm not really interested in adding a new keyword for this. I would much prefer to explore ways to allow ordinary functions to receive arguments and be able to delay evaluation of those arguments until needed. -- Steve

On Thu, May 17, 2018 at 5:46 PM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
if __runtime_assert__ and long_expensive_calculation: raise AssertionError There's minimal run-time cost, but you lose the convenience of having the expression shown in the error's message. There is, however, a lot of text to this. So if it could be wrapped up, that would be useful. Hence the idea of exploring ways of doing this: def rtassert(expr): if not __runtime_assert__: return if expr.eval(): return raise AssertionError(expr.text) rtassert(&long_expensive_calculation) where the ampersand (or something of the sort) means "pass this expression along unevaluated". The only way to do this currently is with a lambda function, but they don't get their texts captured. It'd take either syntactic support, or something like MacroPy, to make this happen. ChrisA

On Thu, May 17, 2018 at 07:46:41AM +0000, Eloi Gaudry wrote:
On Thu, 2018-05-17 at 03:09 +1000, Steven D'Aprano wrote:
Sorry, I had forgetten the extension answer: Include/pydebug.h : int Py_RuntimeAssertFlag = 1; Your_extension/main.c : SetFlag(Py_RuntimeAssertFlag); and I had missed your answer to have a builtin. In any case, I don't think that having only a single flag for the entire Python application is sufficiently useful to bother with this. At the *absolute least* I would expect individual modules to be able to independently enable or disable their own "runtime assertions".
What would then be solution for implementing the runtime_assert with the current python api ? A lambda ?
Earlier in this thread I mentioned that I had a few thoughts on that, and I was exploring those ideas. I asked for anyone interested to contact me off list. Basically I am looking at how we could get delayed evaluation of expressions, which has a number of good use-cases. (So far I have four: this is only one of them.) And yes, wrapping the expression in a function (lambda) seems like the most promising approach. -- Steve

On Tue, May 08, 2018 at 09:58:51AM -0400, Eric V. Smith wrote:
In Eloi's first post in this thread, he gave the example: runtime_assert( expr ) Although it is written as a function call, he refers to it as a statement, so I guess he means: runtime_assert expr He says that would compile to the equivalent of: if runtime_assert_active and expr: print(RuntimeAssertionError()) but he gives no idea of what runtime_assert_active is (is it a per-module global variable? a single application-wide super-global? a local variable? something else?) or how we are supposed to set it. Nor does he explain why failed assertions merelt *print* an error message, rather than raising an exception. -- Steve

On Tue, May 08, 2018 at 07:37:55AM +0000, Eloi Gaudry wrote:
I don't think that is a useful distinction to make. I use `assert` all the time, and I have never once cared whether it is a "debug build" or a "production build". I use assert in my code, and then people (including me) can use it with whatever build of Python they like. I don't even know which builds of Python I'm running. My *guess* is that the OS-provided Python is probably a non-debug build, and the ones I've compiled from source will be whatever the default build settings are, but I don't know what that is or how to find out. And if there was some sort of runtime_assert that could be enabled and disabled individually, why wouldn't I use it with debug builds as well as non-debug builds? -- Steve

On Wed, 2018-05-09 at 01:34 +1000, Steven D'Aprano wrote: > On Tue, May 08, 2018 at 07:37:55AM +0000, Eloi Gaudry wrote: > > > * debug assert, for helping developing a new features, used with > > debug- > > builds > > * runtime assert, for ensuring correctness and/or diagnosing issue > > with > > production/release-builds on-site. > > I don't think that is a useful distinction to make. > > I use `assert` all the time, and I have never once cared whether it > is a > "debug build" or a "production build". I use assert in my code, and > then > people (including me) can use it with whatever build of Python they > like. I do understand your point but I don't share your opinion. I think that is a difference between: - the current 'assert' which usage seems (to me) to focus on development correctness (I think of it as the C-assert enabled in any C program in debug build ) - the runtime_assert that I submitted on the list, which would be focusing on usage correctness (hence runtime), and easily disabled at runtime (when the python command line options parsing is not an option, for instance when the python interpreter is not python itself and/or when the consumer/extension wants to behave differently). > I don't even know which builds of Python I'm running. My *guess* is > that > the OS-provided Python is probably a non-debug build, and the ones > I've > compiled from source will be whatever the default build settings > are, > but I don't know what that is or how to find out. > > And if there was some sort of runtime_assert that could be enabled > and > disabled individually, why wouldn't I use it with debug builds as > well > as non-debug builds? There would be no reason why, but you would benefit from being able to easily activate/deactivate the runtime assert.

On Wed, May 9, 2018 at 1:51 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
What's the difference between "development correctness" and "usage correctness"? Does the latter depend on user input at run time? I still don't understand the distinction you're trying to make here. ChrisA

My choice of words might not be the best, yes. I do see to different meanings and/or context for the historical assert and the one I propose: 1/ the first one would be something saying that, as a developer, when writing
assert (expr) in my python code, I mean that all my unit tests and real life tests I could think of should succeed the test. I do mean "don't go further, I might not know where you come from or where you intend to go or why you are behaving as such, but you failed to meet this and/or this criteria/condition".
2/ the second one is there to activate some other checks, not while developing, just at runtime when the user uses my extension and want to get some diagnostics/enforcing checks to happen, because he/she is using something I couldn't think of in the first place, something that would not have been checked before. Yes, those checks might be considered as identical in a language sense, but then : as an extension/interpreter writer, why should I only rely on the debug assert available today? Why would it not make sense to offer another assert, semantically different, aiming at runtime checks issues and this time where control is indeed by the consumer/the extension? -----Original Message----- From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> On Behalf Of Chris Angelico Sent: Tuesday, May 8, 2018 7:38 PM To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active On Wed, May 9, 2018 at 1:51 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
What's the difference between "development correctness" and "usage correctness"? Does the latter depend on user input at run time? I still don't understand the distinction you're trying to make here. ChrisA

On Wed, May 9, 2018 at 5:27 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
No, they're not identical. The first one is an assertion; the second is simply an 'if' and a 'raise'. It doesn't need any special syntax - all you need is standard exception creation. def average(values): if not values: raise ValueError("Cannot calculate average of empty collection") This should not be an assertion, "run-time" or otherwise. You never want to disable it. ChrisA

08.05.18 18:34, Steven D'Aprano пише:
There are different means of "debug build". It may mean that binaries are build with enabling runtime checks in C code. When you build from sources you will get a non-debug build by default. You need to pass a special option --with-pydebug to ./configure for getting a debug build. The OS-provided Python is a non-debug build too. It may means that the "assert" statement in Python code is not a no-op and the building __debug__ constant is True. Python is ran in debug mode by default. You have to pass the -O option to the python command for running Python in non-debug mode. ISTM the OP uses the term "debug build" in this meaning. Finally, a special "development mode" mode was introduced in 3.7. It is enabled by the command line option -X dev. It switches on several expensive runtime checks in C code (if they are not switched off by compiling binaries in "release build" in the first meaning). https://docs.python.org/3.8/whatsnew/3.7.html#new-development-mode-x-dev All these things are virtually orthogonal and can be combined arbitrary.

On Mon, May 7, 2018 at 6:24 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
I just don't understand why you need a new keyword for writing runtime checks.
Oh, that's pretty clear. The OP wants to be able to turn these checks off with some flag he can set/clear at runtime, and when it's off he doesn't want to incur the overhead of evaluating the check. The assert statement has the latter property, but you have to use -O to turn it off. He basically wants a macro so that runtime_assert(<expr>) expands to if <controlling flag> and (<expr>): raise AssertionError In Lisp this would be easy. :-) -- --Guido van Rossum (python.org/~guido)

On Tue, May 8, 2018 at 12:29 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
That seems premature. There is not even a hint of agreement that such a feature would be useful *in general* (I'm not doubting your situation) and worth our limited volunteer developer resources to maintain, document etc. for decades to come. -- --Guido van Rossum (python.org/~guido)

This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging. My logging example would be log( control_flag, msg_expr ) expanding to: if <control_flag>: log_function( <msg_expr> ) Barry

On 10 May 2018 at 17:55, Barry Scott <barry@barrys-emacs.org> wrote:
Logging is the example that came to mind for me as well - https://docs.python.org/3/howto/logging.html#optimization discusses the "logging.isEnabledFor" API, and how it can be used to avoid the overhead of expensive state queries when the result log message would just be discarded anyway. Generally speaking though, the spelling for that kind of lazy evaluation is to accept a zero-argument callable, which can then be used with "lambda: " at the call site: runtime_assert(lambda: <expr>) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, May 10, 2018 at 08:55:44AM +0100, Barry Scott wrote:
This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging.
I'm working on an idea for delayed evaluation of expressions, and I think your idea of logging below would make an excellent use-case.
The idea isn't yet ready for Python-Ideas, but if you're interested feel free to contact me off-list. -- Steve

I currently use the form <control_flag> and log_function( <msg_expr> ) where <control_flag> is some module variable, usually "DEBUG". I do this because it is one line, and it ensures the log_function parameters are not evaluated. *IF* runtime assertions had a switch so they have no overhead when not active, how much faster can it get? How expensive is the <control_flag> check? On 2018-05-10 03:55, Barry Scott wrote:

The check is made against a boolean value in the C extension, I don't think that it offers a significant speed-up against the pure python code. but it offers a simpler (reduced, global) assertion syntax though. ________________________________ From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> on behalf of Kyle Lahnakoski <klahnakoski@mozilla.com> Sent: Tuesday, June 5, 2018 7:25:45 PM To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active I currently use the form <control_flag> and log_function( <msg_expr> ) where <control_flag> is some module variable, usually "DEBUG". I do this because it is one line, and it ensures the log_function parameters are not evaluated. *IF* runtime assertions had a switch so they have no overhead when not active, how much faster can it get? How expensive is the <control_flag> check? On 2018-05-10 03:55, Barry Scott wrote: My logging example would be log( control_flag, msg_expr ) expanding to: if <control_flag>: log_function( <msg_expr> ) Barry This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging.

05.05.18 18:04, Eloi Gaudry пише:
Sufficient for what? And why writing with using the existing syntax is not sufficient?
My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime.
The main property of the assert statement is that has a zero overhead in non-debug run. If you remove this property, it will be not the assert statement, and you will not need a special syntax support for writing this runtime check.
The syntax example I gave illustrated what I meant by syntax aware.
It doesn't illustrate why a new syntax is necessary. Or I can't understand this illustration.

I didn't mean to replace the current (debug) assert but I wanted to add another one that would allow to be switch on or off on production builds. The need for a new keyword (not syntax) comes from this difference. I cannot think of another example that would convince you of the benefit of having a specific keyword for such a runtime assert. I do believe that having such a feature in non-debug build is more than interesting but indeed needed. At some point, there should be a trade-off between to relying on a simple keyword/mechanism (for a runtime assert) versus the development cost of adding such a feature and maintaining it. Anyway, thanks for your feedback Serhiy, it helps. ________________________________ From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> on behalf of Serhiy Storchaka <storchaka@gmail.com> Sent: Saturday, May 5, 2018 17:44 To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active 05.05.18 18:04, Eloi Gaudry пише:
Sufficient for what? And why writing with using the existing syntax is not sufficient?
My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime.
The main property of the assert statement is that has a zero overhead in non-debug run. If you remove this property, it will be not the assert statement, and you will not need a special syntax support for writing this runtime check.
The syntax example I gave illustrated what I meant by syntax aware.
It doesn't illustrate why a new syntax is necessary. Or I can't understand this illustration. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

On Mon, 7 May 2018 at 06:28 Serhiy Storchaka <storchaka@gmail.com> wrote:
My question is how is this different to running with -O which leaves the assert statement out of the bytecode and so you avoid any run-time cost of the statement entirely?

On Mon, 2018-05-07 at 16:56 +0000, Brett Cannon wrote:
Not so much different, except that: - the switch won't need to be on the command line - the 2 different asserts would be considered differently by developers/users : * debug assert, for helping developing a new features, used with debug- builds * runtime assert, for ensuring correctness and/or diagnosing issue with production/release-builds on-site.

On 5/8/2018 9:50 AM, Eloi Gaudry wrote:
I think what's confusing to me (and maybe others) is that we haven't seen your vision on how this would look in Python code. An example that would throw runtime assertions and the same example where it wouldn't (after a global switch is set?) would be helpful. Eric

On Tue, 2018-05-08 at 09:58 -0400, Eric V. Smith wrote:
Eric, I can only agree to your comment. As a matter of fact, I have only used the case where the runtime assert is activated through an extension. In this case, adding a set method is simple : in our framework, we would set the variable Py_RuntimeAssertFlag to 1, depending on some command line parameters, or settings found in a configuration file). In pure python, if something as having a method registered in __builtins__ make sense, it could be used to trigger the assertive behavior. In this example, let's assume that you may want to perform some basic check on a given file in diagnostics mode:
__builtins__.set_runtime_assert( True )

On Wed, May 16, 2018 at 08:29:00AM +0000, Eloi Gaudry wrote:
Is there some interest in the proposal or should I finally close this thread ?
I'm definitely interested in the concept, not the suggested syntax or semantics. -- Steve

On Wed, May 16, 2018 at 01:27:50PM +0000, Eloi Gaudry wrote:
The syntax is the minor point: you give is an ungainly name, "runtime_assert", and your proposed PEP shows it requiring parentheses as if it were an ordinary function. The bigger problem is the semantics. As I already said in an earlier email, you don't explain what "runtime_assert_active" is (is it a per-module global variable? a single application-wide super-global? a local variable? something else?) or how we are supposed to set it. That too is an ungainly name, and the fact that there's only *one* such flag (whether it is per module or not) makes this proposal useless for my needs. Another problem is that your runtime_assert *prints* the error message instead of raising an exception, and there's no way to customise the message. But the most important reason is that I'm not really interested in adding a new keyword for this. I would much prefer to explore ways to allow ordinary functions to receive arguments and be able to delay evaluation of those arguments until needed. -- Steve

On Thu, May 17, 2018 at 5:46 PM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
if __runtime_assert__ and long_expensive_calculation: raise AssertionError There's minimal run-time cost, but you lose the convenience of having the expression shown in the error's message. There is, however, a lot of text to this. So if it could be wrapped up, that would be useful. Hence the idea of exploring ways of doing this: def rtassert(expr): if not __runtime_assert__: return if expr.eval(): return raise AssertionError(expr.text) rtassert(&long_expensive_calculation) where the ampersand (or something of the sort) means "pass this expression along unevaluated". The only way to do this currently is with a lambda function, but they don't get their texts captured. It'd take either syntactic support, or something like MacroPy, to make this happen. ChrisA

On Thu, May 17, 2018 at 07:46:41AM +0000, Eloi Gaudry wrote:
On Thu, 2018-05-17 at 03:09 +1000, Steven D'Aprano wrote:
Sorry, I had forgetten the extension answer: Include/pydebug.h : int Py_RuntimeAssertFlag = 1; Your_extension/main.c : SetFlag(Py_RuntimeAssertFlag); and I had missed your answer to have a builtin. In any case, I don't think that having only a single flag for the entire Python application is sufficiently useful to bother with this. At the *absolute least* I would expect individual modules to be able to independently enable or disable their own "runtime assertions".
What would then be solution for implementing the runtime_assert with the current python api ? A lambda ?
Earlier in this thread I mentioned that I had a few thoughts on that, and I was exploring those ideas. I asked for anyone interested to contact me off list. Basically I am looking at how we could get delayed evaluation of expressions, which has a number of good use-cases. (So far I have four: this is only one of them.) And yes, wrapping the expression in a function (lambda) seems like the most promising approach. -- Steve

On Tue, May 08, 2018 at 09:58:51AM -0400, Eric V. Smith wrote:
In Eloi's first post in this thread, he gave the example: runtime_assert( expr ) Although it is written as a function call, he refers to it as a statement, so I guess he means: runtime_assert expr He says that would compile to the equivalent of: if runtime_assert_active and expr: print(RuntimeAssertionError()) but he gives no idea of what runtime_assert_active is (is it a per-module global variable? a single application-wide super-global? a local variable? something else?) or how we are supposed to set it. Nor does he explain why failed assertions merelt *print* an error message, rather than raising an exception. -- Steve

On Tue, May 08, 2018 at 07:37:55AM +0000, Eloi Gaudry wrote:
I don't think that is a useful distinction to make. I use `assert` all the time, and I have never once cared whether it is a "debug build" or a "production build". I use assert in my code, and then people (including me) can use it with whatever build of Python they like. I don't even know which builds of Python I'm running. My *guess* is that the OS-provided Python is probably a non-debug build, and the ones I've compiled from source will be whatever the default build settings are, but I don't know what that is or how to find out. And if there was some sort of runtime_assert that could be enabled and disabled individually, why wouldn't I use it with debug builds as well as non-debug builds? -- Steve

On Wed, 2018-05-09 at 01:34 +1000, Steven D'Aprano wrote: > On Tue, May 08, 2018 at 07:37:55AM +0000, Eloi Gaudry wrote: > > > * debug assert, for helping developing a new features, used with > > debug- > > builds > > * runtime assert, for ensuring correctness and/or diagnosing issue > > with > > production/release-builds on-site. > > I don't think that is a useful distinction to make. > > I use `assert` all the time, and I have never once cared whether it > is a > "debug build" or a "production build". I use assert in my code, and > then > people (including me) can use it with whatever build of Python they > like. I do understand your point but I don't share your opinion. I think that is a difference between: - the current 'assert' which usage seems (to me) to focus on development correctness (I think of it as the C-assert enabled in any C program in debug build ) - the runtime_assert that I submitted on the list, which would be focusing on usage correctness (hence runtime), and easily disabled at runtime (when the python command line options parsing is not an option, for instance when the python interpreter is not python itself and/or when the consumer/extension wants to behave differently). > I don't even know which builds of Python I'm running. My *guess* is > that > the OS-provided Python is probably a non-debug build, and the ones > I've > compiled from source will be whatever the default build settings > are, > but I don't know what that is or how to find out. > > And if there was some sort of runtime_assert that could be enabled > and > disabled individually, why wouldn't I use it with debug builds as > well > as non-debug builds? There would be no reason why, but you would benefit from being able to easily activate/deactivate the runtime assert.

On Wed, May 9, 2018 at 1:51 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
What's the difference between "development correctness" and "usage correctness"? Does the latter depend on user input at run time? I still don't understand the distinction you're trying to make here. ChrisA

My choice of words might not be the best, yes. I do see to different meanings and/or context for the historical assert and the one I propose: 1/ the first one would be something saying that, as a developer, when writing
assert (expr) in my python code, I mean that all my unit tests and real life tests I could think of should succeed the test. I do mean "don't go further, I might not know where you come from or where you intend to go or why you are behaving as such, but you failed to meet this and/or this criteria/condition".
2/ the second one is there to activate some other checks, not while developing, just at runtime when the user uses my extension and want to get some diagnostics/enforcing checks to happen, because he/she is using something I couldn't think of in the first place, something that would not have been checked before. Yes, those checks might be considered as identical in a language sense, but then : as an extension/interpreter writer, why should I only rely on the debug assert available today? Why would it not make sense to offer another assert, semantically different, aiming at runtime checks issues and this time where control is indeed by the consumer/the extension? -----Original Message----- From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> On Behalf Of Chris Angelico Sent: Tuesday, May 8, 2018 7:38 PM To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active On Wed, May 9, 2018 at 1:51 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
What's the difference between "development correctness" and "usage correctness"? Does the latter depend on user input at run time? I still don't understand the distinction you're trying to make here. ChrisA

On Wed, May 9, 2018 at 5:27 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
No, they're not identical. The first one is an assertion; the second is simply an 'if' and a 'raise'. It doesn't need any special syntax - all you need is standard exception creation. def average(values): if not values: raise ValueError("Cannot calculate average of empty collection") This should not be an assertion, "run-time" or otherwise. You never want to disable it. ChrisA

08.05.18 18:34, Steven D'Aprano пише:
There are different means of "debug build". It may mean that binaries are build with enabling runtime checks in C code. When you build from sources you will get a non-debug build by default. You need to pass a special option --with-pydebug to ./configure for getting a debug build. The OS-provided Python is a non-debug build too. It may means that the "assert" statement in Python code is not a no-op and the building __debug__ constant is True. Python is ran in debug mode by default. You have to pass the -O option to the python command for running Python in non-debug mode. ISTM the OP uses the term "debug build" in this meaning. Finally, a special "development mode" mode was introduced in 3.7. It is enabled by the command line option -X dev. It switches on several expensive runtime checks in C code (if they are not switched off by compiling binaries in "release build" in the first meaning). https://docs.python.org/3.8/whatsnew/3.7.html#new-development-mode-x-dev All these things are virtually orthogonal and can be combined arbitrary.

On Mon, May 7, 2018 at 6:24 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
I just don't understand why you need a new keyword for writing runtime checks.
Oh, that's pretty clear. The OP wants to be able to turn these checks off with some flag he can set/clear at runtime, and when it's off he doesn't want to incur the overhead of evaluating the check. The assert statement has the latter property, but you have to use -O to turn it off. He basically wants a macro so that runtime_assert(<expr>) expands to if <controlling flag> and (<expr>): raise AssertionError In Lisp this would be easy. :-) -- --Guido van Rossum (python.org/~guido)

On Tue, May 8, 2018 at 12:29 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
That seems premature. There is not even a hint of agreement that such a feature would be useful *in general* (I'm not doubting your situation) and worth our limited volunteer developer resources to maintain, document etc. for decades to come. -- --Guido van Rossum (python.org/~guido)

This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging. My logging example would be log( control_flag, msg_expr ) expanding to: if <control_flag>: log_function( <msg_expr> ) Barry

On 10 May 2018 at 17:55, Barry Scott <barry@barrys-emacs.org> wrote:
Logging is the example that came to mind for me as well - https://docs.python.org/3/howto/logging.html#optimization discusses the "logging.isEnabledFor" API, and how it can be used to avoid the overhead of expensive state queries when the result log message would just be discarded anyway. Generally speaking though, the spelling for that kind of lazy evaluation is to accept a zero-argument callable, which can then be used with "lambda: " at the call site: runtime_assert(lambda: <expr>) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, May 10, 2018 at 08:55:44AM +0100, Barry Scott wrote:
This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging.
I'm working on an idea for delayed evaluation of expressions, and I think your idea of logging below would make an excellent use-case.
The idea isn't yet ready for Python-Ideas, but if you're interested feel free to contact me off-list. -- Steve

I currently use the form <control_flag> and log_function( <msg_expr> ) where <control_flag> is some module variable, usually "DEBUG". I do this because it is one line, and it ensures the log_function parameters are not evaluated. *IF* runtime assertions had a switch so they have no overhead when not active, how much faster can it get? How expensive is the <control_flag> check? On 2018-05-10 03:55, Barry Scott wrote:

The check is made against a boolean value in the C extension, I don't think that it offers a significant speed-up against the pure python code. but it offers a simpler (reduced, global) assertion syntax though. ________________________________ From: Python-ideas <python-ideas-bounces+eloi.gaudry=fft.be@python.org> on behalf of Kyle Lahnakoski <klahnakoski@mozilla.com> Sent: Tuesday, June 5, 2018 7:25:45 PM To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active I currently use the form <control_flag> and log_function( <msg_expr> ) where <control_flag> is some module variable, usually "DEBUG". I do this because it is one line, and it ensures the log_function parameters are not evaluated. *IF* runtime assertions had a switch so they have no overhead when not active, how much faster can it get? How expensive is the <control_flag> check? On 2018-05-10 03:55, Barry Scott wrote: My logging example would be log( control_flag, msg_expr ) expanding to: if <control_flag>: log_function( <msg_expr> ) Barry This idea requires the same sort of machinery in python that I was hoping for to implement the short circuit logging.
participants (11)
-
Barry Scott
-
Brett Cannon
-
Chris Angelico
-
Eloi Gaudry
-
Eric V. Smith
-
Guido van Rossum
-
Kyle Lahnakoski
-
MRAB
-
Nick Coghlan
-
Serhiy Storchaka
-
Steven D'Aprano