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 пише:
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.
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 пише:
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.
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/
07.05.18 12:58, Eloi Gaudry пише:
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.
I just don't understand why you need a new keyword for writing runtime checks.
On Mon, 7 May 2018 at 06:28 Serhiy Storchaka <storchaka@gmail.com> wrote:
07.05.18 12:58, Eloi Gaudry пише:
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.
I just don't understand why you need a new keyword for writing runtime checks.
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:
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?
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 3:37 AM, Eloi Gaudry wrote:
On Mon, 2018-05-07 at 16:56 +0000, Brett Cannon 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?
Not so much different, except that: - the switch won't need to be on the command line
So, is the switch set in code? If so, what would that look like? Eric
On Tue, 2018-05-08 at 09:35 -0400, Eric V. Smith wrote:
On 5/8/2018 3:37 AM, Eloi Gaudry wrote:
On Mon, 2018-05-07 at 16:56 +0000, Brett Cannon 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?
Not so much different, except that: - the switch won't need to be on the command line
So, is the switch set in code? If so, what would that look like?
Eric So far, I only have the "extension" method, where a global variable is set directly from within the C-interface, as currently done with the debug assert:
Include/pydebug.h : int Py_RuntimeAssertFlag = 1; Your_extension/main.c : SetFlag(Py_RuntimeAssertFlag);
On 5/8/2018 9:50 AM, Eloi Gaudry wrote:
On Tue, 2018-05-08 at 09:35 -0400, Eric V. Smith wrote:
On 5/8/2018 3:37 AM, Eloi Gaudry wrote:
On Mon, 2018-05-07 at 16:56 +0000, Brett Cannon 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?
Not so much different, except that: - the switch won't need to be on the command line
So, is the switch set in code? If so, what would that look like?
Eric So far, I only have the "extension" method, where a global variable is set directly from within the C-interface, as currently done with the debug assert:
Include/pydebug.h : int Py_RuntimeAssertFlag = 1; Your_extension/main.c : SetFlag(Py_RuntimeAssertFlag);
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:
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
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:
def check_mounts_size(): ... return len( open( '/proc/self/mounts', 'r' ).readlines() )>1024 ... runtime_assert( len( open( '/proc/self/mounts', 'r' ).readlines()>1024 ) ) runtime_assert( check_mounts_size() )
__builtins__.set_runtime_assert( True )
runtime_assert( len( open( '/proc/self/mounts', 'r' ).readlines()>1024 ) ) Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
runtime_assert( check_mounts_size() ) Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
Is there some interest in the proposal or should I finally close this thread ? Thanks for your feedback, Eloi
_______________________________________________ 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 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, 2018-05-16 at 21:15 +1000, Steven D'Aprano wrote:
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.
Would you briefly describe a syntax that would better fit this concept ?
On Wed, May 16, 2018 at 01:27:50PM +0000, Eloi Gaudry wrote:
On Wed, 2018-05-16 at 21:15 +1000, Steven D'Aprano wrote:
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.
Would you briefly describe a syntax that would better fit this concept ?
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 Wed, May 16, 2018 at 01:27:50PM +0000, Eloi Gaudry wrote:
On Wed, 2018-05-16 at 21:15 +1000, Steven D'Aprano wrote:
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.
Would you briefly describe a syntax that would better fit this concept ?
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. I proposed to have several ways to set it (see previous answers) : one would be extension based and the other would rely on having a builtin value that one would be able to change using a set function of the
On Thu, 2018-05-17 at 03:09 +1000, Steven D'Aprano wrote: python core.
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. I agree with you on this : the main issue with my proposal is that having only one assert (function with deferred evaluation) more is not enough : we would need to cover several other scenarii such as an extension wanting to activate its own asserts without activating other extensions checks.
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. It actually raise an AssertionError. I do agree that it should allow to set/display a message though.
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.
What would then be solution for implementing the runtime_assert with the current python api ? A lambda ?
On Thu, May 17, 2018 at 5:46 PM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
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. What would then be solution for implementing the runtime_assert with the current python api ? A lambda ?
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:
I proposed to have several ways to set it (see previous answers) : one would be extension based and the other would rely on having a builtin value that one would be able to change using a set function of the python core.
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:
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.
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:
* 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 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:
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).
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:
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).
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:
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?
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 пише:
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.
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 Mon, 2018-05-07 at 10:52 -0700, Guido van Rossum wrote:
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. :-)
and he already has a diff ready for review if needed (basically very similar to the current 'assert' implementation :)
On Tue, May 8, 2018 at 12:29 AM, Eloi Gaudry <Eloi.Gaudry@fft.be> wrote:
On Mon, 2018-05-07 at 10:52 -0700, Guido van Rossum wrote:
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. :-)
and he already has a diff ready for review if needed (basically very similar to the current 'assert' implementation :)
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)
On Tue, 2018-05-08 at 07:37 -0700, Guido van Rossum wrote:
In Lisp this would be easy. :-)
and he already has a diff ready for review if needed (basically very similar to the current 'assert' implementation :)
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.
I didn't mean to push too fast, just to show how things could be implemented and maybe clarify my comments/statements.
07.05.18 20:52, Guido van Rossum пише:
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. :-)
Python is not Lisp (still). But there is the MacroPy project. And at end you always can use an external tool for code generation. For example the old good cpp.
On 7 May 2018, at 18:52, Guido van Rossum <guido@python.org> wrote:
On Mon, May 7, 2018 at 6:24 AM, Serhiy Storchaka <storchaka@gmail.com <mailto: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. :-)
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:
On 7 May 2018, at 18:52, Guido van Rossum <guido@python.org> wrote:
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. :-)
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> )
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.
My logging example would be
log( control_flag, msg_expr )
expanding to:
if <control_flag>: log_function( <msg_expr> )
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:
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.
On 2018-06-05 18:25, Kyle Lahnakoski wrote:
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.
You'd get the same result with: if <control_flag>: log_function( <msg_expr> )
*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.
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