msg196181 - (view) |
Author: (deleted250130) |
Date: 2013-08-26 06:11 |
On a try/except-block if an exception raises (for example KeyboardInterrupt) the except block could cause another exception and if this block tries to catch it too the nested except block could cause another exception again. This goes into an unlimited recursion. In the attachments is an example of such a problem (race_condition_fast.py). But as it is called a "race condition" it is nearly impossible to reproduce it by a human. For this case I have adjusted the example (race_condition_slow.py). The third CTRL + C will cause a KeyboardInterrupt. |
|
|
msg196182 - (view) |
Author: Ezio Melotti (ezio.melotti) *  |
Date: 2013-08-26 06:29 |
> The third CTRL + C will cause a KeyboardInterrupt. This is expected. The first ctrl+c interrupts the first sleep and goes in the second try, executing the second sleep. The second ctrl+c interrupts the second sleep and goes in the second except where it finds the third sleep. Here a third ctrl+c will interrupt the sleep and since this line is not in a try block nothing will catch the KeyboardInterrupt. Are you saying that if the user keeps hitting ctrl+c you would need an endless chain of nested try/except in order to catch them all? |
|
|
msg196183 - (view) |
Author: (deleted250130) |
Date: 2013-08-26 06:32 |
> Are you saying that if the user keeps hitting ctrl+c you would need an endless chain of nested try/except in order to catch them all? Correct. For example if I want to show the user the message "Aborted" instead of a huge exception if he hits CTRL + C another KeyboardInterrupt could appear. |
|
|
msg196215 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2013-08-26 15:47 |
Then you catch KeyboardInterrupt and present your alternate text. I'm not following what the problem is. In particular, once you've caught KeyboardInterrupt, a second ctl-C *should* cause a normal program break, otherwise you've locked the user into a infinite loop he can't get out of if your program logic is wrong. |
|
|
msg196221 - (view) |
Author: (deleted250130) |
Date: 2013-08-26 16:16 |
The problem is simple: It is not possible to catch every exception in an application. Even if you try to print a message and exit on an exception it is always possible that the user will see a traceback. |
|
|
msg196225 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2013-08-26 16:48 |
I wonder if you could achieve what you want (which I always hope programs I use never do[*]) by writing your own signal handler. In any case, I don't believe there is a bug here. This is working as designed. [*] There are many times I have found myself leaning on ctl-C on autorepeat hoping that the ctl-c will happen at a point where the application isn't catching it, so that I can get the darn thing to abort. I realize you are proposing to do this only to then do the abort...but what if there is a bug in your code? I'd *much* rather see a traceback than have to fall back to 'kill'. At least with the traceback I know the interpreter has had a chance to clean up. |
|
|
msg196265 - (view) |
Author: (deleted250130) |
Date: 2013-08-27 06:48 |
> but what if there is a bug in your code? Bugs in a python application can be fixed by the user while a specific behavior of the interpreter can't. Maybe you are also thinking in the wrong direction. Nobody wants a solution that traps the user forever. Also KeyboardInterrupt is not the only problem that is affected by this race condition (but it is the best example to demonstrate it). But I have made some thoughts about a potential solution (maybe it needs fine-tuning, depending on the python developing-policies or if I have overlooked something): The idea contains overloading on a try/except-block. We will have the old (current) except block that acts as we know it and we will have a function-like except block "except(string_message, int_exitcode):". The function-like except block is a policy for any nested exception. Instead of triggering the nested exception it will print the first argument to stderr and exit with the second argument. While the interpreter is doing this as a built-in call it disables any potential exception-triggering in this time. This solution will eliminate the race condition without catching the user in an infinite recursion. What do you think of this idea? |
|
|
msg196283 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2013-08-27 12:46 |
Unless I'm completely misunderstanding (which I don't think I am), this is not a race condition, it is how the language is designed to operate. The change you are proposing is a language-design level change that would require a PEP. The appropriate place to discuss this the is the python-ideas list. I'm going to close this issue. If you get a positive response on python-ideas, you can reopen it with a link to the discussion. |
|
|
msg196289 - (view) |
Author: (deleted250130) |
Date: 2013-08-27 13:45 |
> Unless I'm completely misunderstanding (which I don't think I am), this is not a race condition, it is how the language is designed to operate. If it is intended not to be able to catch all exceptions and prevent a traceback being showed this should be indeed a PEP. |
|
|
msg196348 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2013-08-28 05:25 |
> If it is intended not to be able to catch all exceptions > and prevent a traceback being showed this should be indeed a PEP. You may want to have a look at sys.excepthook. |
|
|
msg196376 - (view) |
Author: (deleted250130) |
Date: 2013-08-28 11:42 |
> You may want to have a look at sys.excepthook. This would not solve the race condition. |
|
|