Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #110765 > unrolled thread
| Started by | Victor Savu <victor.nicolae.savu@gmail.com> |
|---|---|
| First post | 2016-06-29 10:01 +0000 |
| Last post | 2016-06-30 00:59 -0400 |
| Articles | 9 — 6 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: "for/while ... break(by any means) ... else" make sense? Victor Savu <victor.nicolae.savu@gmail.com> - 2016-06-29 10:01 +0000
Re: "for/while ... break(by any means) ... else" make sense? Steven D'Aprano <steve@pearwood.info> - 2016-06-30 10:27 +1000
Re: "for/while ... break(by any means) ... else" make sense? Chris Angelico <rosuav@gmail.com> - 2016-06-30 11:28 +1000
Re: "for/while ... break(by any means) ... else" make sense? Rustom Mody <rustompmody@gmail.com> - 2016-06-29 19:26 -0700
Re: "for/while ... break(by any means) ... else" make sense? Random832 <random832@fastmail.com> - 2016-06-30 00:00 -0400
Re: "for/while ... break(by any means) ... else" make sense? Steven D'Aprano <steve@pearwood.info> - 2016-06-30 14:12 +1000
Re: "for/while ... break(by any means) ... else" make sense? Chris Angelico <rosuav@gmail.com> - 2016-06-30 14:40 +1000
Re: "for/while ... break(by any means) ... else" make sense? Zachary Ware <zachary.ware+pylist@gmail.com> - 2016-06-29 23:47 -0500
Re: "for/while ... break(by any means) ... else" make sense? Random832 <random832@fastmail.com> - 2016-06-30 00:59 -0400
| From | Victor Savu <victor.nicolae.savu@gmail.com> |
|---|---|
| Date | 2016-06-29 10:01 +0000 |
| Subject | Re: "for/while ... break(by any means) ... else" make sense? |
| Message-ID | <mailman.101.1467194475.2358.python-list@python.org> |
There are many posts trying to explain the else after for or while. Here is my take on it: There are three ways of getting out of a (for/while) loop: throw, break or the iterator gets exhausted. The question is, how cab we tell which way we exited? For the throw, we have the except clause. This leaves us to differentiatr between break and normal exhaustion of the iterator. This is that the else clause is for: we enter the body iff the loop iterator was exhausted. A lot of discussion goes around the actual keyword used: else. Opinions may differ, but I for one would have chosen 'then' as a keyword to mark something that naturally happens as part of the for statement but after the looping is over; assuming break jumps out of the entire statement, it makes sense that it skips the 'then' body as well. (In the same way, I prefer 'catch' to 'except' as a correspondent to 'throw', but all of this is just bikeshedding). At a language design level, the decision was made to reuse one of the existing keywords and for better or worse, 'else' was chosen, which can be thought of as having no relation to the other use of the same keyword in the 'if' statement. The only rationale behind this was to save one keyword. The search analogy often used for justifying 'else' is (to me) totally bogus, since the same argument can be used to support replacing the keyword 'for' by the keyword 'find' and have looping only as a side-effect of a search. I hope this gives you some sense of closure. Best, VS
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-06-30 10:27 +1000 |
| Message-ID | <57746765$0$1593$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #110765 |
On Wed, 29 Jun 2016 08:01 pm, Victor Savu wrote:
> There are many posts trying to explain the else after for or while. Here
> is my take on it:
>
> There are three ways of getting out of a (for/while) loop: throw, break or
> the iterator gets exhausted.
- reaching the end of the loop
- raise (not throw)
- return (if inside a function)
- calling os.abort()
- calling os._exit()
- break
So at least six ways.
> The question is, how cab we tell which way we exited?
I'm not really sure that is the right question to ask, but okay, let's
continue and see where this goes.
> For the throw, we have the except clause.
Which `except` clause?
`except` is not part of the for statement, it is completely independent.
There may, or may not, be an `except` clause anywhere in your code.
In either case, the `raise` behaves like a GOTO, jumping to the nearest
`except` clause (if any). That may be inside the loop:
for x in seq:
try:
do_something(x)
except Error:
...
or outside the loop:
try:
for x in seq:
do_something(x)
except Error:
...
or there may be no except clause at all, and control is transferred to the
top-level error handler (if any) or to the Python interpreter, which then
prints a stack trace and exits.
> This leaves us to
> differentiatr between break and normal exhaustion of the iterator.
Following `return`, the function returns and transfer returns to the
caller's code.
Following os.abort(), the interpreter exits in the hardest, quickest manner
possible.
Following os._exit(), the interpreter exits without doing any normal cleanup
or processing.
In those two cases, we cannot run any Python code after the function is
called, so the question of distinguishing them from ending the loop
normally doesn't come up. Nevertheless, they do exit the loop.
> This is
> that the else clause is for: we enter the body iff the loop iterator was
> exhausted.
The way I would put it is that we enter the body of the `else` statement
when the loop reaches the end. That applies to both `while` and `for`
loops, and it applies to looping over sequences using the sequence protocol
instead of the iterator protocol. It applies to empty sequences (the loop
reaches the end immediately). And it even applies to infinite loops: if the
loop never ends, the `else` statement never runs.
And most importantly, if we transfer control out of the `for` statement
using *any* other mechanism (break, return, raise, os.abort, ...) then the
`else` statement never runs because we have jumped past it.
> I for one would have chosen 'then' as a keyword to mark
> something that naturally happens as part of the for statement but after
> the looping is over;
I agree with this.
> assuming break jumps out of the entire statement, it
> makes sense that it skips the 'then' body as well.
And this.
> (In the same way, I
> prefer 'catch' to 'except' as a correspondent to 'throw',
There is no "throw" in Python, there is "raise".
> but all of this
> is just bikeshedding). At a language design level, the decision was made
> to reuse one of the existing keywords and for better or worse, 'else' was
> chosen, which can be thought of as having no relation to the other use of
> the same keyword in the 'if' statement. The only rationale behind this was
> to save one keyword.
Agreed.
--
Steven
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-06-30 11:28 +1000 |
| Message-ID | <mailman.116.1467250108.2358.python-list@python.org> |
| In reply to | #110791 |
On Thu, Jun 30, 2016 at 10:27 AM, Steven D'Aprano <steve@pearwood.info> wrote: > Following os.abort(), the interpreter exits in the hardest, quickest manner > possible. os.kill(os.getpid(), 9) Now THAT is the hardest way to abort. You ain't comin' back from this one! ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2016-06-29 19:26 -0700 |
| Message-ID | <b014e209-b2a6-4921-9e22-8473f7e50e21@googlegroups.com> |
| In reply to | #110793 |
On Thursday, June 30, 2016 at 6:58:42 AM UTC+5:30, Chris Angelico wrote: > On Thu, Jun 30, 2016 at 10:27 AM, Steven D'Aprano wrote: > > Following os.abort(), the interpreter exits in the hardest, quickest manner > > possible. > > os.kill(os.getpid(), 9) > > Now THAT is the hardest way to abort. You ain't comin' back from this one! Is it? | On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, | SIGSEGV, or SIGTERM. A ValueError will be raised in any other case. from https://docs.python.org/3.5/library/signal.html 9 may still work?? Dunno...
[toc] | [prev] | [next] | [standalone]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2016-06-30 00:00 -0400 |
| Message-ID | <mailman.118.1467259216.2358.python-list@python.org> |
| In reply to | #110796 |
On Wed, Jun 29, 2016, at 22:26, Rustom Mody wrote: > > os.kill(os.getpid(), 9) > > > > Now THAT is the hardest way to abort. You ain't comin' back from > > this one! > > Is it? > > | On Windows, signal() can only be called with SIGABRT, SIGFPE, > | SIGILL, SIGINT, SIGSEGV, or SIGTERM. A ValueError will be raised in > | any other case. And SIGBREAK (it being missing from this list is a doc bug). > from https://docs.python.org/3.5/library/signal.html > > 9 may still work?? Dunno... That's signal, not kill. You can call kill on Windows with any integer. Only CTRL_C_EVENT and CTRL_BREAK_EVENT (which aren't, AIUI, equal to SIGINT and SIGBREAK, which is unfortunate for cross-platform code) do anything interesting, the rest call TerminateProcess with the given value.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-06-30 14:12 +1000 |
| Message-ID | <57749c30$0$1598$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #110793 |
On Thu, 30 Jun 2016 11:28 am, Chris Angelico wrote: > On Thu, Jun 30, 2016 at 10:27 AM, Steven D'Aprano <steve@pearwood.info> > wrote: >> Following os.abort(), the interpreter exits in the hardest, quickest >> manner possible. > > os.kill(os.getpid(), 9) > > Now THAT is the hardest way to abort. You ain't comin' back from this one! The docs say it will abort in the hardest way possible, by dumping core or equivalent. I *think* I recall seeing os.abort() actually segfault at some point, but I can't replicate that now. I tried to find the actual implementation of os.abort(), but I couldn't work out where it was or what it does. Can somebody enlighten me? -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-06-30 14:40 +1000 |
| Message-ID | <mailman.119.1467261623.2358.python-list@python.org> |
| In reply to | #110805 |
On Thu, Jun 30, 2016 at 2:12 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> On Thu, 30 Jun 2016 11:28 am, Chris Angelico wrote:
>
>> On Thu, Jun 30, 2016 at 10:27 AM, Steven D'Aprano <steve@pearwood.info>
>> wrote:
>>> Following os.abort(), the interpreter exits in the hardest, quickest
>>> manner possible.
>>
>> os.kill(os.getpid(), 9)
>>
>> Now THAT is the hardest way to abort. You ain't comin' back from this one!
>
> The docs say it will abort in the hardest way possible, by dumping core or
> equivalent. I *think* I recall seeing os.abort() actually segfault at some
> point, but I can't replicate that now.
>
> I tried to find the actual implementation of os.abort(), but I couldn't work
> out where it was or what it does. Can somebody enlighten me?
My expectation is that it'd be something like this:
def abort():
if sys.platform == 'windows':
some_win32_api_call()
signal.signal(signal.SIGABRT, signal.SIG_DFL)
kill(getpid(), signal.SIGABRT)
Certainly, after a call to os.abort() under Linux, the process is
recorded as having terminated with signal 6 (SIGABRT), and the
intended purpose of that signal is "abort the process abnormally,
possibly dumping core".
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Zachary Ware <zachary.ware+pylist@gmail.com> |
|---|---|
| Date | 2016-06-29 23:47 -0500 |
| Message-ID | <mailman.120.1467262104.2358.python-list@python.org> |
| In reply to | #110805 |
On Wed, Jun 29, 2016 at 11:12 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> On Thu, 30 Jun 2016 11:28 am, Chris Angelico wrote:
>
>> On Thu, Jun 30, 2016 at 10:27 AM, Steven D'Aprano <steve@pearwood.info>
>> wrote:
>>> Following os.abort(), the interpreter exits in the hardest, quickest
>>> manner possible.
>>
>> os.kill(os.getpid(), 9)
>>
>> Now THAT is the hardest way to abort. You ain't comin' back from this one!
>
> The docs say it will abort in the hardest way possible, by dumping core or
> equivalent. I *think* I recall seeing os.abort() actually segfault at some
> point, but I can't replicate that now.
>
> I tried to find the actual implementation of os.abort(), but I couldn't work
> out where it was or what it does. Can somebody enlighten me?
Right here: https://hg.python.org/cpython/file/default/Modules/posixmodule.c#l10528
Here's the entire implementation of os.abort:
{
abort();
/*NOTREACHED*/
Py_FatalError("abort() called from Python code didn't abort!");
return NULL;
}
abort(3) is a standard C function, see the manpage. If execution
somehow makes it past the abort() call, Python does its best to make
sure it really doesn't by calling Py_FatalError, which dumps a scary
message to stderr along with any traceback it can get its hands on,
then calls abort() again. I tried setting a signal handler for
SIGABRT (I tried `signal.signal(signal.SIGABRT, print)`), but it
didn't trigger a Py_FatalError call on OSX or Linux.
On Windows, abort() causes the "some.exe has stopped working" dialog
to pop up and "search for solutions". Similarly, the Crash Reporter
pops up on OSX.
--
Zach
[toc] | [prev] | [next] | [standalone]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2016-06-30 00:59 -0400 |
| Message-ID | <mailman.123.1467262795.2358.python-list@python.org> |
| In reply to | #110805 |
On Thu, Jun 30, 2016, at 00:12, Steven D'Aprano wrote: > I tried to find the actual implementation of os.abort(), but I > couldn't work out where it was or what it does. Can somebody > enlighten me? It's in posixmodule.c, it calls abort(), which is a standard C function, equivalent to killing the process with SIGABRT. The core dump behavior is defined as the default signal behavior as SIGABRT in POSIX. Windows has its own additional behavior for the abort function: https://msdn.microsoft.com/en-us/library/k089yyh0.aspx It's not a "segfault", but both behaviors (core dump on unix, and error reporting popup on windows) are reminiscent of it, so that may be what you're thinking of.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web