Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #93760 > unrolled thread
| Started by | Chris Angelico <rosuav@gmail.com> |
|---|---|
| First post | 2015-07-14 00:05 +1000 |
| Last post | 2015-07-14 20:23 -0400 |
| Articles | 20 on this page of 94 — 15 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: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 00:05 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Steven D'Aprano <steve@pearwood.info> - 2015-07-14 13:20 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-14 09:26 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-14 02:34 -0600
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Grant Edwards <invalid@invalid.invalid> - 2015-07-14 14:03 +0000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-14 12:43 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Paul Rubin <no.email@nospam.invalid> - 2015-07-13 22:15 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 15:25 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Paul Rubin <no.email@nospam.invalid> - 2015-07-13 22:41 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 21:43 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 15:28 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 22:55 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 16:38 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 23:43 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 20:29 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Steven D'Aprano <steve@pearwood.info> - 2015-07-15 03:48 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-15 10:28 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-14 16:02 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 00:07 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 20:31 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-14 20:41 -0400
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-15 11:10 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-16 10:43 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-16 09:31 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-17 10:41 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-16 21:45 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-16 15:56 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 00:00 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-16 16:32 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 02:43 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Joonas Liik <liik.joonas@gmail.com> - 2015-07-16 19:50 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 03:03 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ethan Furman <ethan@stoneleaf.us> - 2015-07-16 10:04 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Joonas Liik <liik.joonas@gmail.com> - 2015-07-16 20:34 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Steven D'Aprano <steve@pearwood.info> - 2015-07-17 04:58 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Joonas Liik <liik.joonas@gmail.com> - 2015-07-16 22:14 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-17 11:41 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ethan Furman <ethan@stoneleaf.us> - 2015-07-16 12:52 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 03:49 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Joonas Liik <liik.joonas@gmail.com> - 2015-07-16 21:23 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 04:29 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-16 16:19 -0400
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-17 12:48 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-19 10:57 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 21:05 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-17 13:43 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 21:49 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-17 14:54 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-17 23:12 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-17 16:27 -0400
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-15 21:13 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-15 12:55 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-07-15 12:22 +0100
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-16 10:34 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-07-16 00:34 +0100
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) MRAB <python@mrabarnett.plus.com> - 2015-07-15 13:00 +0100
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 22:13 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-16 10:34 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 22:22 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 08:41 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 21:33 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 15:08 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-14 15:31 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-13 23:46 -0600
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 08:57 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-14 18:29 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 10:05 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-07-15 17:52 +1200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-15 09:44 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ned Batchelder <ned@nedbatchelder.com> - 2015-07-15 03:45 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-15 13:55 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-07-15 13:04 +0200
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ned Batchelder <ned@nedbatchelder.com> - 2015-07-15 04:12 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-15 14:24 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Rustom Mody <rustompmody@gmail.com> - 2015-07-16 21:28 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-07-14 08:47 +0100
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-14 02:13 -0600
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 11:33 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-14 07:15 -0600
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 20:27 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-15 08:28 -0600
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-15 17:55 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Steven D'Aprano <steve@pearwood.info> - 2015-07-15 03:34 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 20:43 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 03:52 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Steven D'Aprano <steve@pearwood.info> - 2015-07-15 04:06 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 21:37 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 04:55 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Marko Rauhamaa <marko@pacujo.net> - 2015-07-14 22:12 +0300
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-14 21:36 -0400
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-14 21:01 -0400
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Chris Angelico <rosuav@gmail.com> - 2015-07-15 13:05 +1000
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Paul Rubin <no.email@nospam.invalid> - 2015-07-14 10:54 -0700
Re: Possibly Pythonic Tail Call Optimization (TCO/TRE) Terry Reedy <tjreedy@udel.edu> - 2015-07-14 20:23 -0400
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-17 04:29 +1000 |
| Message-ID | <mailman.602.1437071389.3674.python-list@python.org> |
| In reply to | #93886 |
On Fri, Jul 17, 2015 at 4:23 AM, Joonas Liik <liik.joonas@gmail.com> wrote: > On 16 July 2015 at 20:49, Chris Angelico <rosuav@gmail.com> wrote: >> >> This sounds like a denial-of-service attack. If you can state that no >> reasonable document will ever have more than 100 levels of nesting, >> then you can equally state that cutting the parser off with a tidy >> exception if it exceeds 100 levels is safe. >> > This particular example does have that kind of smell.. my bad for > being careless with examples. > > what if its not a ddos tho, maybe its just strange data? > That's why you're allowed to change the default limit either direction. If you're guarding against a DOS, you can crank it down; if you're working with something where 1000 stack entries isn't unreasonable, you can crank it up. I honestly don't know what you'd want to do if 5000+ stack entries isn't enough, but if you're working with something *that* deeply nested, you probably know a lot more about what you're doing than I ever will. Maybe you could recompile CPython with a bigger stack? Give Jython or PyPy a try? No idea. But I'm sure it'd be possible somehow. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-07-16 16:19 -0400 |
| Message-ID | <mailman.611.1437078001.3674.python-list@python.org> |
| In reply to | #93886 |
On 7/16/2015 7:45 AM, Chris Angelico wrote:
> On Thu, Jul 16, 2015 at 5:31 PM, Antoon Pardon
> <antoon.pardon@rece.vub.ac.be> wrote:
>> Traceback are not the only or even the most useful
>> tool for debugging code. The current stack trace
>> doesn't even contain the value's of the variables
>> on the stack. So in case of Terry Reedy's example
>> that stack trace would IMO have been next to useless.
>
> Actually, they do contain all of that (at least, they do in Py3 - not
> sure about Py2 as I haven't checked). You can poke around with the
> locals at every point on the stack:
>
> def f(x):
> if x < 10: g(x+10)
> return 5
>
> def g(x):
> if x % 3: h(x + 2)
> return 7
>
> def h(x):
> return 1/x
>
> try:
> x = -12
> print(f(x))
> except ZeroDivisionError as e:
> tb = e.__traceback__
> while tb:
> fr = tb.tb_frame
> print("In function %s (%s:%d), x = %r" % (
> fr.f_code.co_name,
> fr.f_code.co_filename,
> fr.f_lineno,
> fr.f_locals["x"],
> ))
> tb = tb.tb_next
>
>
> It's all there. And it's immensely helpful.
One of the features of Idle is Debug => Stack Viewer, which, when
invoked immediately after an exception, displays a tree widget with a
node for each stack frame in the traceback. Running your code without
the extra try: except: stuff, so a traceback is displayed, I easily see
that x is -12, -2, and 0 in f, g, and h. I suspect that this feature is
not well known and is underused.
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2015-07-17 12:48 +0200 |
| Message-ID | <mailman.639.1437130103.3674.python-list@python.org> |
| In reply to | #93886 |
On 07/16/2015 06:43 PM, Chris Angelico wrote: > On Fri, Jul 17, 2015 at 12:32 AM, Antoon Pardon > <antoon.pardon@rece.vub.ac.be> wrote: > >> What is unclear about "as it is generally produced on stderr"? That you >> can do a whole lot of stuff, doesn't mean that this whole lot of stuff is >> part of what generally happens. When people on this list ask a person >> to include the stacktrace with the description of the problem, they >> don't mean something that includes the values of the variables. > True. That said, though, it's not a justification for dropping stack > frames; even in the form that's printed to stderr, there is immense > value in them. It may be possible to explicitly drop frames that a > programmer believes won't be useful, but a general and automated > dropping of tail-call information will do more harm than good. The > fact that some frameworks can show _even more_ helpful information out > of a traceback only makes this stronger. Just wondering, are traceback records of generators available? They are if an exception is raised in the generator itself, but what if an exception is raised in the loop that is driven by a generator. They don't appear in the standard stack trace. It seems a bit strange that with the immense value that is given to stack frames, that these wouldn't be available somehow. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-07-19 10:57 +1200 |
| Message-ID | <d103upF93k9U1@mid.individual.net> |
| In reply to | #94002 |
Antoon Pardon wrote: > It seems a bit strange that with the immense value that is given to > stack frames, that these wouldn't be available somehow. There was discussion recently about the idea of providing access to the frame of a suspended generator, so that debuggers can inspect the stack of an asyncio task that's not currently running. The same mechanism ought to allow the state of an arbitrary generator to be examined. You'd need to explicitly ask for it, though -- it wouldn't appear in stack traces automatically. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-17 21:05 +1000 |
| Message-ID | <mailman.641.1437131122.3674.python-list@python.org> |
| In reply to | #93886 |
On Fri, Jul 17, 2015 at 8:48 PM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> Just wondering, are traceback records of generators available? They are
> if an exception is raised in the generator itself, but what if an exception
> is raised in the loop that is driven by a generator. They don't appear in
> the standard stack trace.
Not sure what you mean here. Something like this?
def gen():
yield stuff
yield more stuff
for stuff in gen():
bomb with exception
The error didn't happen in the generator, so I wouldn't expect to see
it in the traceback. There's still room for the cause of an error to
not be in the traceback; imagine, for instance, a function that
populates a concrete list, and then you iterate over the list. If that
function sticks a None into the list and the subsequent processing is
expecting all strings, that's going to bomb, but then you have to
figure out where the None came from. If the traceback could include
that, it'd be great, but some things aren't possible. Doesn't mean
we're happy to sacrifice other functionality.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2015-07-17 13:43 +0200 |
| Message-ID | <mailman.643.1437133440.3674.python-list@python.org> |
| In reply to | #93886 |
On 07/17/2015 01:05 PM, Chris Angelico wrote: > On Fri, Jul 17, 2015 at 8:48 PM, Antoon Pardon > <antoon.pardon@rece.vub.ac.be> wrote: >> Just wondering, are traceback records of generators available? They are >> if an exception is raised in the generator itself, but what if an exception >> is raised in the loop that is driven by a generator. They don't appear in >> the standard stack trace. > Not sure what you mean here. Something like this? > > def gen(): > yield stuff > yield more stuff > > for stuff in gen(): > bomb with exception > > The error didn't happen in the generator, so I wouldn't expect to see > it in the traceback. Yes something like that. And I wouldn't expect it either but if it is not present, is it because nobody thought about it or because it is a bad idea or an idea difficult to implement? > There's still room for the cause of an error to > not be in the traceback; imagine, for instance, a function that > populates a concrete list, and then you iterate over the list. If that > function sticks a None into the list and the subsequent processing is > expecting all strings, that's going to bomb, but then you have to > figure out where the None came from. If the traceback could include > that, it'd be great, but some things aren't possible. Sure, but in this case, the generator is still active. The Runtime would be able to jump to and somehow activates it's stack record for the next value. So why would we expect it to be impossible to include this trace back record in a stack trace? > Doesn't mean > we're happy to sacrifice other functionality. Indeed, this is an independend problem. Whatever the answer here doesn't need to affect how one feels about losing trace back record because of TCO.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-17 21:49 +1000 |
| Message-ID | <mailman.644.1437133800.3674.python-list@python.org> |
| In reply to | #93886 |
On Fri, Jul 17, 2015 at 9:43 PM, Antoon Pardon <antoon.pardon@rece.vub.ac.be> wrote: > On 07/17/2015 01:05 PM, Chris Angelico wrote: >> On Fri, Jul 17, 2015 at 8:48 PM, Antoon Pardon >> <antoon.pardon@rece.vub.ac.be> wrote: >>> Just wondering, are traceback records of generators available? They are >>> if an exception is raised in the generator itself, but what if an exception >>> is raised in the loop that is driven by a generator. They don't appear in >>> the standard stack trace. >> Not sure what you mean here. Something like this? >> >> def gen(): >> yield stuff >> yield more stuff >> >> for stuff in gen(): >> bomb with exception >> >> The error didn't happen in the generator, so I wouldn't expect to see >> it in the traceback. > > Yes something like that. And I wouldn't expect it either but if it > is not present, is it because nobody thought about it or because it > is a bad idea or an idea difficult to implement? > >> There's still room for the cause of an error to >> not be in the traceback; imagine, for instance, a function that >> populates a concrete list, and then you iterate over the list. If that >> function sticks a None into the list and the subsequent processing is >> expecting all strings, that's going to bomb, but then you have to >> figure out where the None came from. If the traceback could include >> that, it'd be great, but some things aren't possible. > > Sure, but in this case, the generator is still active. The Runtime > would be able to jump to and somehow activates it's stack record > for the next value. So why would we expect it to be impossible to > include this trace back record in a stack trace? Python could also give you stack traces for any other threads that are concurrently running, on the off-chance that one of them affected it. But the only influence the generator has on the loop is to yield a value or signal termination; if an exception is thrown in the loop itself, the local name 'stuff' should have all the information about that cause. Python isn't a mind-reader, no matter how much it may look like one, and it can't know that this function's return value should be shown as part of a completely different function's stack trace. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2015-07-17 14:54 +0200 |
| Message-ID | <mailman.647.1437137656.3674.python-list@python.org> |
| In reply to | #93886 |
On 07/17/2015 01:49 PM, Chris Angelico wrote: > On Fri, Jul 17, 2015 at 9:43 PM, Antoon Pardon > <antoon.pardon@rece.vub.ac.be> wrote: > > >> Sure, but in this case, the generator is still active. The Runtime >> would be able to jump to and somehow activates it's stack record >> for the next value. So why would we expect it to be impossible to >> include this trace back record in a stack trace? > Python could also give you stack traces for any other threads that are > concurrently running, on the off-chance that one of them affected it. > But the only influence the generator has on the loop is to yield a > value or signal termination; if an exception is thrown in the loop > itself, the local name 'stuff' should have all the information about > that cause. But the local name 'stuff' may only have the information for the immediate cause. The underlying cause may be available in the generator. Suppose you have a generator that should only generate positive numbers that you use to divide some other number by. Your loop crashes because of a DivideByZeroError Sure the local name shows the dividor to be zero, but you have no information on why your generator produced a zero, but there may be a clue in the trace back record of the generator. > Python isn't a mind-reader, no matter how much it may look > like one, and it can't know that this function's return value should > be shown as part of a completely different function's stack trace. It is not a matter of mindreading. And it is not a completely different functions stack trace. It is the trace back record of a generator that is used by the process/thread that crashed. And AFAIK an active generator belongs to one specific thread. You can't have it yield a value to a different thread and you can't send it a value from an other thread. So I really see no reason to exclude the trace back records of active generators from a stack trace of a crashed thread. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-17 23:12 +1000 |
| Message-ID | <mailman.648.1437138743.3674.python-list@python.org> |
| In reply to | #93886 |
On Fri, Jul 17, 2015 at 10:54 PM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> On 07/17/2015 01:49 PM, Chris Angelico wrote:
>> On Fri, Jul 17, 2015 at 9:43 PM, Antoon Pardon
>> <antoon.pardon@rece.vub.ac.be> wrote:
>>
>>
>>> Sure, but in this case, the generator is still active. The Runtime
>>> would be able to jump to and somehow activates it's stack record
>>> for the next value. So why would we expect it to be impossible to
>>> include this trace back record in a stack trace?
>> Python could also give you stack traces for any other threads that are
>> concurrently running, on the off-chance that one of them affected it.
>> But the only influence the generator has on the loop is to yield a
>> value or signal termination; if an exception is thrown in the loop
>> itself, the local name 'stuff' should have all the information about
>> that cause.
>
> But the local name 'stuff' may only have the information for the immediate
> cause. The underlying cause may be available in the generator. Suppose
> you have a generator that should only generate positive numbers that you
> use to divide some other number by. Your loop crashes because of a DivideByZeroError
> Sure the local name shows the dividor to be zero, but you have no
> information on why your generator produced a zero, but there may be a
> clue in the trace back record of the generator.
Indeed, but there's nothing special about generators here. The same
sequence could have been a concrete list, or it could have been some
other kind of iterator (any object with __iter__ and __next__), which
won't have a stack frame. Special cases aren't special enough to warp
exception handling around.
>> Python isn't a mind-reader, no matter how much it may look
>> like one, and it can't know that this function's return value should
>> be shown as part of a completely different function's stack trace.
>
> It is not a matter of mindreading. And it is not a completely different
> functions stack trace. It is the trace back record of a generator that
> is used by the process/thread that crashed. And AFAIK an active generator
> belongs to one specific thread. You can't have it yield a value to a different
> thread and you can't send it a value from an other thread. So I really
> see no reason to exclude the trace back records of active generators
> from a stack trace of a crashed thread.
No, generators are fine across threads:
rosuav@sikorsky:~$ python3 threadgen.py
Starting!
First yielded value
Continuing!
Second yielded value
Terminating.
Traceback (most recent call last):
File "threadgen.py", line 20, in <module>
print(next(gen))
StopIteration
rosuav@sikorsky:~$ cat threadgen.py
import threading
import time
def thread():
time.sleep(0.5)
print(next(gen))
threading.Thread(target=thread).start()
def generator():rosuav@sikorsky:~$
print("Starting!")
yield "First yielded value"
print("Continuing!")
yield "Second yielded value"
print("Terminating.")
gen = generator()
print(next(gen))
time.sleep(1)
print(next(gen))
rosuav@sikorsky:~$
In fact, a generator doesn't have a stack unless it's currently
executing, so all you could get is whatever's actually inside it (that
is, if there's a deep tree of 'yield from's, you could dig up that
part of the stack). I'm not sure this would really help you very much.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-07-17 16:27 -0400 |
| Message-ID | <mailman.658.1437164908.3674.python-list@python.org> |
| In reply to | #93886 |
On 7/17/2015 7:43 AM, Antoon Pardon wrote:
> On 07/17/2015 01:05 PM, Chris Angelico wrote:
>> def gen():
>> yield stuff
>> yield more stuff
>>
>> for stuff in gen():
>> bomb with exception
>>
>> The error didn't happen in the generator, so I wouldn't expect to see
>> it in the traceback.
>
> Yes something like that. And I wouldn't expect it either but if it
> is not present, is it because nobody thought about it or because it
> is a bad idea or an idea difficult to implement?
>
>> There's still room for the cause of an error to
>> not be in the traceback; imagine, for instance, a function that
>> populates a concrete list, and then you iterate over the list. If that
>> function sticks a None into the list and the subsequent processing is
>> expecting all strings, that's going to bomb, but then you have to
>> figure out where the None came from. If the traceback could include
>> that, it'd be great, but some things aren't possible.
>
> Sure, but in this case, the generator is still active.
No more than any other object sitting around inactive. Calling a
generator function like gen above returns a generator with the generator
function, in a suspended inactive state, attached as an attribute. When
the generator.__next__ function is called, it activates its instance of
the generator function, which suspends itself again after yielding
something. At the point of the exception above, the generator next
function has returned. There could be multiple generators with
suspended generator functions sitting around. For instance:
def f():
for tup in zip(gf0, gf1, gf2, gf3, gf4, gf5):
a = tup[6] # whoops, IndexError
<unreachable code meant to do something>
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-07-15 21:13 +1200 |
| Message-ID | <d0mmguFr51gU1@mid.individual.net> |
| In reply to | #93801 |
Chris Angelico wrote: > I'm still interested in the explicit "replace current stack frame with > this call" operation. Calling it "goto" seems wrong, as most languages > with goto restrict it to _within_ a function, This just suggests to me is that most language designers are not very imaginative. :-) A tail call *is* a goto. That's how you implement one in assembly language -- you write a jump instruction instead of a call instruction. The jump doesn't have to be to the same function. Also see: https://litrev.wordpress.com/2009/07/16/lambda-the-ultimate-goto/ -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-07-15 12:55 +0300 |
| Message-ID | <87zj2xlp89.fsf@elektro.pacujo.net> |
| In reply to | #93856 |
Gregory Ewing <greg.ewing@canterbury.ac.nz>: > A tail call *is* a goto. That's how you implement one in assembly > language -- you write a jump instruction instead of a call > instruction. The jump doesn't have to be to the same function. In functional programming languages you might not even have a call stack. Instead, you specify the program execution through transformations. When you evaluate a program, you repeatedly convert the program text into new programs until no more transformations apply and the execution halts with the result of the computation. Marko
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-07-15 12:22 +0100 |
| Message-ID | <mailman.537.1436959372.3674.python-list@python.org> |
| In reply to | #93856 |
On 15/07/2015 10:13, Gregory Ewing wrote: > Chris Angelico wrote: >> I'm still interested in the explicit "replace current stack frame with >> this call" operation. Calling it "goto" seems wrong, as most languages >> with goto restrict it to _within_ a function, > > This just suggests to me is that most language designers > are not very imaginative. :-) > > A tail call *is* a goto. That's how you implement one in > assembly language -- you write a jump instruction instead > of a call instruction. The jump doesn't have to be to > the same function. > IIRC the realms of the C setjmp and longjmp. I'm just wondering out aloud if anybody has ever tried playing with cPython using these, or whether the code and/or Python itself is just too complex to allow this to even be tried, let alone succeed. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-07-16 10:34 +1200 |
| Message-ID | <d0o5fvF8q7eU1@mid.individual.net> |
| In reply to | #93866 |
Mark Lawrence wrote: > IIRC the realms of the C setjmp and longjmp. Not really the same thing. A longjmp chops the stack back, whereas a tail call avoids putting something on the stack to begin with. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-07-16 00:34 +0100 |
| Message-ID | <mailman.551.1437003310.3674.python-list@python.org> |
| In reply to | #93884 |
On 15/07/2015 23:34, Gregory Ewing wrote: > Mark Lawrence wrote: >> IIRC the realms of the C setjmp and longjmp. > > Not really the same thing. A longjmp chops the stack > back, whereas a tail call avoids putting something on > the stack to begin with. > Thanks for that :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2015-07-15 13:00 +0100 |
| Message-ID | <mailman.538.1436961652.3674.python-list@python.org> |
| In reply to | #93856 |
On 2015-07-15 12:22, Mark Lawrence wrote: > On 15/07/2015 10:13, Gregory Ewing wrote: >> Chris Angelico wrote: >>> I'm still interested in the explicit "replace current stack frame with >>> this call" operation. Calling it "goto" seems wrong, as most languages >>> with goto restrict it to _within_ a function, >> >> This just suggests to me is that most language designers >> are not very imaginative. :-) >> >> A tail call *is* a goto. That's how you implement one in >> assembly language -- you write a jump instruction instead >> of a call instruction. The jump doesn't have to be to >> the same function. >> > > IIRC the realms of the C setjmp and longjmp. I'm just wondering out > aloud if anybody has ever tried playing with cPython using these, or > whether the code and/or Python itself is just too complex to allow this > to even be tried, let alone succeed. > The problem with longjmp is that it could inadvertently bypass some clean-up code or deallocation, or, in the case of CPython, a DECREF.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-15 22:13 +1000 |
| Message-ID | <mailman.540.1436962436.3674.python-list@python.org> |
| In reply to | #93856 |
On Wed, Jul 15, 2015 at 10:00 PM, MRAB <python@mrabarnett.plus.com> wrote: > On 2015-07-15 12:22, Mark Lawrence wrote: >> >> On 15/07/2015 10:13, Gregory Ewing wrote: >>> >>> Chris Angelico wrote: >>>> >>>> I'm still interested in the explicit "replace current stack frame with >>>> this call" operation. Calling it "goto" seems wrong, as most languages >>>> with goto restrict it to _within_ a function, >>> >>> >>> This just suggests to me is that most language designers >>> are not very imaginative. :-) >>> >>> A tail call *is* a goto. That's how you implement one in >>> assembly language -- you write a jump instruction instead >>> of a call instruction. The jump doesn't have to be to >>> the same function. >>> >> >> IIRC the realms of the C setjmp and longjmp. I'm just wondering out >> aloud if anybody has ever tried playing with cPython using these, or >> whether the code and/or Python itself is just too complex to allow this >> to even be tried, let alone succeed. >> > The problem with longjmp is that it could inadvertently bypass some > clean-up code or deallocation, or, in the case of CPython, a DECREF. Which really says that TCO is impossible if you have any sort of clean-up or deallocation to be done after the call begins. The only way to truly turn your tail call into a GOTO is to do all your cleanup first. "try: return x() finally: more_code" is not a tail call, nor is it if you have "except:" in place of "finally:". ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-07-16 10:34 +1200 |
| Message-ID | <d0o5g3F8q7eU2@mid.individual.net> |
| In reply to | #93871 |
Chris Angelico wrote: > Which really says that TCO is impossible if you have any sort of > clean-up or deallocation to be done after the call begins. The only > way to truly turn your tail call into a GOTO is to do all your cleanup > first. Indeed. In compilers that implement TCO, there's quite a lot more to it than just "replace CALL with JMP". It requires rethinking your whole strategy on when to put various things on the stack and take them off again, so that by the time you get to the point of the tail call, there is nothing on the stack other than the arguments to the tail call and the ultimate return address. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-07-15 22:22 +1000 |
| Message-ID | <mailman.541.1436962945.3674.python-list@python.org> |
| In reply to | #93856 |
On Wed, Jul 15, 2015 at 7:13 PM, Gregory Ewing
<greg.ewing@canterbury.ac.nz> wrote:
> Chris Angelico wrote:
>>
>> I'm still interested in the explicit "replace current stack frame with
>> this call" operation. Calling it "goto" seems wrong, as most languages
>> with goto restrict it to _within_ a function,
>
>
> This just suggests to me is that most language designers
> are not very imaginative. :-)
>
> A tail call *is* a goto. That's how you implement one in
> assembly language -- you write a jump instruction instead
> of a call instruction. The jump doesn't have to be to
> the same function.
>
Sure it is; but then, a while loop is a goto, but we don't call them
goto loops. Ultimately, assembly language lets you treat everything
the same way - in some CPUs, a jump is an assignment to the
instruction pointer register, and is thus the same kind of operation
as any other. In real-mode Intel 80x86 Assembly, there are
unconditional and conditional jumps, where conditional jumps are
limited to the shortest possible form of jump (relative jumps within
+/- 128 bytes), but other than that, there's no distinctions between
"if" statements, "while" loops, etc, etc. (Yes, there's also
near-call, far-call, and interrupt, which push the instruction
pointer, the IP plus the code segment, and the IP, CS, and the flags
register, respectively - but then still just do a straight jump to the
other location.) But in high level languages, we differentiate all of
them, because the human who reads the code should differentiate
between them. You don't use Python's "while" statement as a sort of
"if", nor vice versa. At least, not usually...
while x < 1:
print("x is less than one!")
break
else:
print("x is one or greater!")
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-07-14 08:41 +0300 |
| Message-ID | <87bnffnvn2.fsf@elektro.pacujo.net> |
| In reply to | #93782 |
Chris Angelico <rosuav@gmail.com>: >> def quicksort(array, start, end): >> midp = partition(array, start, end) >> if midp <= (start+end)//2: >> quicksort(array, start, midp) >> quicksort(array, midp+1, end) >> else: >> quicksort(array, midp+1, end) >> quicksort(array, start, midp) > [...] > That's a prime example of recursion... but not of recursion that can > be tail-call optimized into iteration. Of course it can. The 2nd and 4th calls to quicksort can be trivially tail-call-optimized. Tail-call optimization has nothing to do with converting algorithms into iterations. It's a prosaic trick of dropping an unneeded stack frame before making a function call. > The claim that TCO means you don't need stack space for all those > levels of recursion doesn't work if you still need stack space for all > those levels of recursion *before* you get to the tail call. Nobody is making that claim. What you are questioning is what tail-call optimization would buy you in practice. Not much. The few times you run into a stack overflow, you can refactor your code pretty easily. However, when you have to do that, it feels a bit silly. Marko
[toc] | [prev] | [next] | [standalone]
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
Back to top | Article view | comp.lang.python
csiph-web