Re: [Python-Dev] PEP 343 - Abstract Block Redux
Guido van Rossum wrote: > [Fredrik Lundh] > >>unlike the original design, all you get from this is >>the ability to add try/finally blocks to your code >>without ever writing a try/finally-clause (neither >>in your code or in the block controller). that >>doesn't strike me as especially pythonic. > > Would it be better if we pulled back in the generator exit handling > from PEP 340? That's a pretty self-contained thing, and would let you > write try/finally around the yield. That would be good, in my opinion. I updated PEP 3XX to use this idea: http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html With that update (to version 1.6), PEP 3XX is basically PEP 343, but injecting exceptions that occur into the template generator's internal frame instead of invoking next(). The rest of the PEP is then about dealing with the implications of allowing yield inside try/finally statements. The Rejected Options section tries to look at all the alternatives brought up in the various PEP 310, 340 and 343 discussions, and explain why PEP 3XX chooses the way it does. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Loading compiled modules under MSYS/MingGW?
Hey all- Simple question. I'm working on getting Python support enabled for the Gimp under Win32. I've set up and successfully compiled the Gimp under a MSYS/MinGW enviroment, using both python.org Python 2.3 and ActivePython 2.3 (I need to stick to 2.3 due to support issues with the packaging software I'm using) Both versions of Python give me the same problem when I try to load the "gimpfu" module (used for accessing Gimp functions from within Python programs) Sample Script: import sys sys.path.insert(1, '/local/lib/gimp/2.0/python/') import gimpfu print "cool" Execution: $ ./test Traceback (most recent call last): File "./test", line 7, in ? import gimpfu File "E:\msys\1.0\local\lib\gimp\2.0\python\gimpfu.py", line 65, in ? import gimp ImportError: No module named gimp Directory listing: $ ls /local/lib/gimp/2.0/python/ gimpenums.py gimpmodule.a gimpprocbrowsermodule.a gimpui.py gimpfu.py gimpmodule.la gimpprocbrowsermodule.la pygimp-logo.png gimpfu.pycgimpplugin.py gimpshelf.py ...Python is finding gimpfu.py, but doesn't see "gimpmodule.[a,la]" .. this directory listing is similar to what you would find under a linux compilation, except linux also creates a "gimpmodule.so" library file. Am I missing something obvious? Is this a question better suited to MinGW/MSYS mailing lists, or perhaps the Gimp list? If so, what's the right kind of question(s) I need to be asking? It seems to me that the compile is going through just fine, but somethings not getting built correctly and Python can't see that module. Cheers in advance, Steve Castellotti ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Nick Coghlan wrote:
> That would be good, in my opinion. I updated PEP 3XX to use this idea:
> http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html
>
> With that update (to version 1.6), PEP 3XX is basically PEP 343, but
> injecting
> exceptions that occur into the template generator's internal frame instead of
> invoking next().
>
> The rest of the PEP is then about dealing with the implications of allowing
> yield inside try/finally statements.
You might add to the PEP the following example, which could really
improve the process of building GUIs in Python:
class MyFrame(Frame):
def __init__(self):
with Panel():
with VerticalBoxSizer():
self.text = TextEntry()
self.ok = Button('Ok')
Indentation improves the readability of code that creates a hierarchy.
Shane
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Shane Hathaway wrote: > Here is example A, a non-looping block statement using "try": > > text = 'diamond' > for fn in filenames: > try opening(fn) as f: > if text in f.read(): > print 'I found the text in %s' % fn > break That's a pretty way to write it! Would it be possible to extend the 'try' syntax in this way? It would certainly stress the fact that this construct includes exception handling. --eric ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343: Resource Composition and Idempotent __exit__
Ka-Ping Yee wrote: > - The generator style in PEP 340 is the easiest to compose and > reuse, but its implementation is the most complex to understand. The latest version of my PEP 3XX aims to get (most of) the power of PEP 340, with the easy comprehensibility of PEP 310. What magic it requires is almost entirely contained in the statement_template decorator. It can be looked at as PEP 340 without the looping or ability to suppress exceptions, or as PEP 343, with PEP 340's style of using generators to write templates. It falls into the category where __enter__ and __exit__ are paired, as it uses the same expansion as Shane describes (an exception in __enter__ means that __exit__ is never executed). > To evaluate these options, we could look at a few scenarios where we're > trying to write a resource wrapper for some lock objects. Each lock > object has two methods, .acquire() and .release(). > > Scenario 1. You have two resource objects and you want to acquire both. > > Scenario 2. You want a single resource object that acquires two locks. > > Scenario 3. Your resource object acquires one of two locks depending > on some runtime condition. For your three scenarios, PEP 3XX usage and implementation are as you describe for PEP 343. PEP 343 itself doesn't work as you describe, as it still prohibits yielding inside a try/finally block (and, by extension, inside a with statement, as that is just syntactic sugar for a particular type of try/finally). Scenario 1 (two locks, handled manually): PEP 3XX actually recommends supplying __enter__ and __exit__ directly on lock objects, so no additional 'resource' wrapper is required: with lock1: with lock2: BLOCK And the relevant lock methods are: def __enter__(self): self.acquire() def __exit__(self, *exc): self.release() However, if that didn't happen, and an external wrapper was needed, it could be optimally implemented as: class Resource(object): def __init__(self, lock): self.lock = lock def __enter__(self): self.lock.acquire() def __exit__(self, *exc): self.lock.release() Or less efficiently as: @statement_template def Resource(lock): lock.acquire() try: yield finally: lock.release() Scenario 2 (two locks, handled by resource): Used as: with DoubleResource(lock1, lock2): BLOCK Implemented as: @statement_template def DoubleResource(resource1, resource2): with resource1: with resource2: yield Scenario 3 (runtime choice of lock): Used as: with ConditionalResource(condition, lock1, lock2): BLOCK Implemented as: @statement_template def ConditionalResource(condition, resource1, resource2): if condition: with resource1: yield else: with resource2: yield Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Shane Hathaway wrote: > Guido van Rossum wrote: > > > > Consider an application where you have to acquire *two* locks regularly: > > > You really have to write it like this: Shane, you've already solved this one more elegantly: def lockBoth(): return combining(lock1.locking(), lock2.locking()) using the combining function you wrote earlier, which I assume will make it into the library. - Anders ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On 5/14/05, Brett C. <[EMAIL PROTECTED]> wrote: > Nick's was obviously directly against looping, but, with no offense to Nick, > how many other people were against it looping? It never felt like it was a > screaming mass with pitchforks but more of a "I don't love it, but I can deal" > crowd. Agreed. That's certainly how I felt originally. There were a *lot* of nice features with PEP 340. The initial discussion had a lot of people enthusiastic about all the neat things they could do with it. That's disappeared now, in a long series of attempts to "fix" the looping issue. No-one is looking at PEP 343, or Nick's PEP 3XX, and saying "hey, that's neat - I can do XXX with that!". This makes me feel that we've thrown out the baby with the bathwater. (Yes, I know PEP 342 is integral to many of the neat features, but I get the impression that PEP 342 is being lost - later iterations of the other two PEPs are going out of their way to avoid assuming PEP 324 is implemented...) Looping is definitely a wart. Looping may even be a real problem in some cases. There may be cases where an explicit try...finally remains better, simply to avoid an unwanted looping behaviour. But I'll live with that to get back the enthusiasm for a new feature that started all of this. Much better than the current "yes, I guess that's good enough" tone to the discussion. Paul. PS Guido - next time you get a neat idea like PEP 340, just code it and check it in. Then we can just badger you to fix the code, rather than using up all your time on discussion before there's an implementation :-) ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On 5/15/05, Nick Coghlan <[EMAIL PROTECTED]> wrote: > http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html >From there I see the semantics: VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause exc = (None, None, None) try: try: BLOCK1 except: exc = sys.exc_info() finally: stmt_exit(*exc) Don't you want a "raise" after the "exc = sys.exc_info()"? STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Loading compiled modules under MSYS/MingGW?
"Steve Castellotti" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Simple question. I'm working on getting Python [2.3] support enabled > for the Gimp under Win32. ... >Am I missing something obvious? Is this a question better suited to > MinGW/MSYS mailing lists, or perhaps the Gimp list? Since this is a question about using past Python [2.3], while this is a list for developing future Pythons [2.5+], the Python part of your question would better be directed to comp.lang.python or the corresponding mailing list. Whether the other lists would be any better, I have no opinion. Terry J. Reedy ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Shane Hathaway <[EMAIL PROTECTED]> wrote:
>
> Nick Coghlan wrote:
> > That would be good, in my opinion. I updated PEP 3XX to use this idea:
> > http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html
> >
> > With that update (to version 1.6), PEP 3XX is basically PEP 343, but
> > injecting
> > exceptions that occur into the template generator's internal frame instead
> > of
> > invoking next().
> >
> > The rest of the PEP is then about dealing with the implications of allowing
> > yield inside try/finally statements.
>
> You might add to the PEP the following example, which could really
> improve the process of building GUIs in Python:
>
> class MyFrame(Frame):
> def __init__(self):
> with Panel():
> with VerticalBoxSizer():
> self.text = TextEntry()
> self.ok = Button('Ok')
>
> Indentation improves the readability of code that creates a hierarchy.
I've generally been fairly ambiguous about the entire PEP 310/340/343
issue. While resource allocation and release is quite useful, not a
whole heck of a lot of my code has to deal with it.
But after seeing this sketch of an example for its use in GUI
construction; I must have it!
+1 for:
- 'do' keyword (though 'try' being reused scratches the 'no new keyword'
itch for me, and is explicit about "I won't loop")
- PEP 343
- try/finally + @do_template with generators
- Josiah
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Paul Moore wrote: > On 5/14/05, Brett C. <[EMAIL PROTECTED]> wrote: > >>Nick's was obviously directly against looping, but, with no offense to Nick, >>how many other people were against it looping? It never felt like it was a >>screaming mass with pitchforks but more of a "I don't love it, but I can deal" >>crowd. > > > Agreed. That's certainly how I felt originally. > Oh good. So I am not nuts. =) > There were a *lot* of nice features with PEP 340. The initial > discussion had a lot of people enthusiastic about all the neat things > they could do with it. That's disappeared now, in a long series of > attempts to "fix" the looping issue. No-one is looking at PEP 343, or > Nick's PEP 3XX, and saying "hey, that's neat - I can do XXX with > that!". This makes me feel that we've thrown out the baby with the > bathwater. (Yes, I know PEP 342 is integral to many of the neat > features, but I get the impression that PEP 342 is being lost - later > iterations of the other two PEPs are going out of their way to avoid > assuming PEP 324 is implemented...) > My feelings exactly. I was really happy and excited when it seemed like everyone really liked PEP 340 sans a few disagreements on looping and other things. Having a huge chunk of people get excited and liking a proposal was a nice contrast to the whole decorator debate. > Looping is definitely a wart. Looping may even be a real problem in > some cases. There may be cases where an explicit try...finally remains > better, simply to avoid an unwanted looping behaviour. > Which I think is actually fine if they do just use a try/finally if it fits the situation better. > But I'll live with that to get back the enthusiasm for a new feature > that started all of this. Much better than the current "yes, I guess > that's good enough" tone to the discussion. > Ditto. -Brett ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On 5/15/05, Paul Moore <[EMAIL PROTECTED]> wrote: > There were a *lot* of nice features with PEP 340. The initial > discussion had a lot of people enthusiastic about all the neat things > they could do with it. That's disappeared now, in a long series of > attempts to "fix" the looping issue. Having done the python-dev summary on this topic, I think the initial "enthusiasm" you were seeing included a lot of "what if we did it this way?" or "what if we extended this further in another way?" kind of stuff. When PEP 340 finally came out (around the end of the month), the more extreme ideas were discarded. So in some sense, PEP 340 was the reason for the lack of "enthusiasm"; with the semantics laid out, people were forced to deal with a specific implementation instead of a variety of wild suggestions. > No-one is looking at PEP 343, or > Nick's PEP 3XX, and saying "hey, that's neat - I can do XXX with > that!". This makes me feel that we've thrown out the baby with the > bathwater. I'd be surprised if you can find many examples that PEP 340 can do that PEP 3XX can't. The only real looping example we had was auto_retry, and there's a reasonably simple solution to that in PEP 3XX. You're not going to see anyone saying "hey that's neat - I can do XXX with that!" because PEP 3XX doesn't add anything. But for 95% of the cases, it doesn't take anything away either. > (Yes, I know PEP 342 is integral to many of the neat > features, but I get the impression that PEP 342 is being lost - later > iterations of the other two PEPs are going out of their way to avoid > assuming PEP 324 is implemented...) Not very far out of their way. I split off PEP 342 from the original PEP 340, and it was ridiculously easy for two reasons: * the concepts are very orthogonal; the only thing really used from it in any of PEP 340 was the "yield" means "yield None" thing * there weren't *any* examples of using the "continue EXPR" syntax. PEP 342 is still lacking in this spot If you want to get people enthused about PEP 342 again (which is the right way to make sure it gets excepted), what would really help is a bunch of good examples of how it could be used. > Looping is definitely a wart. Looping may even be a real problem in > some cases. There may be cases where an explicit try...finally remains > better, simply to avoid an unwanted looping behaviour. > > But I'll live with that to get back the enthusiasm for a new feature > that started all of this. Much better than the current "yes, I guess > that's good enough" tone to the discussion. I'm convinced that such a tone is inevitable after 30 days and over 700 messages on *any* topic. ;-) Ok, back to summarizing this fortnight's 380+ PEP 340 messages. ;-) STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Steven Bethard wrote: > On 5/15/05, Nick Coghlan <[EMAIL PROTECTED]> wrote: > >>http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html > > >>From there I see the semantics: > > VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause > exc = (None, None, None) > try: > try: > BLOCK1 > except: > exc = sys.exc_info() > finally: > stmt_exit(*exc) > > Don't you want a "raise" after the "exc = sys.exc_info()"? Oops. . . yeah, that must have gotten lost somewhere along the way. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Paul Moore wrote: > Looping is definitely a wart. Looping may even be a real problem in > some cases. There may be cases where an explicit try...finally remains > better, simply to avoid an unwanted looping behaviour. I agree PEP 343 throws away too much that was good about PEP 340 - that's why I'm still updating PEP 3XX as the discussion continues. But is there anything PEP 340 does that PEP 3XX doesn't, other than letting you suppress exceptions? The only example the latest version of PEP 3XX drops since the original PEP 340 is auto_retry - and that suffers from the hidden control flow problem, so I doubt Guido would permit it, even *if* the new statement was once again a loop. And if the control flow in response to an exception can't be affected, it becomes even *harder* to explain how the new statement differs from a standard for loop. > But I'll live with that to get back the enthusiasm for a new feature > that started all of this. Much better than the current "yes, I guess > that's good enough" tone to the discussion. I think the current tone is more due to the focus on addressing problems with all of the suggestions - that's always going to dampen enthusiasm. Every PEP 340 use case that doesn't involve suppressing exceptions (i.e. all of them except auto_retry) can be written under the current PEP 3XX using essentially *identical* generator code (the only difference is the statement_template decorator at the top of the generator definition) Pros of PEP 3XX 1.6 vs PEP 340: - control flow is easier to understand - can use inside loops without affecting break/continue - easy to write enter/exit methods directly on classes - template generators can be reused safely - iterator generator resource management is dealt with Cons of PEP 3XX 1.6 vs PEP 340: - no suppression of exceptions (see first pro, though) Of course, I may be biased :) Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On Sun, 15 May 2005, Shane Hathaway wrote:
> You might add to the PEP the following example, which could really
> improve the process of building GUIs in Python:
>
> class MyFrame(Frame):
> def __init__(self):
> with Panel():
> with VerticalBoxSizer():
> self.text = TextEntry()
> self.ok = Button('Ok')
I don't understand how this would be implemented. Would a widget
function like 'TextEntry' set the parent of the widget according to
some global 'parent' variable? If so, how would 'Panel' know that
its parent is supposed to be the 'MyFrame' object?
-- ?!ng
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Shane Hathaway wrote: > PEP 340 is very nice, but it became less appealing to me when I saw > what it would do to "break" and "continue" statements. Absolutely. I really liked PEP 340, but two things stood out to me as being flawed: 1. Looping - it took a while for me to realise this was bugging me - the unintuitive behaviour of break and continue clarified it for me. 2. Not re-raising exceptions automatically. I actually proposed at one point that any exception should be re-raised at the end of the iterator finalisation unless another exception was raised (not StopIteration, etc). I still continue to support this. It also deals with the control-flow issue (being hidden). PEP 3XX has some other nice things. I have two opposing views on for-loops supporting finalisation of iterators though: 1. for-loops should support finalisation. However, in that case every iterator should be finalisable by default, and you should have to go out of your way to prevent it (or prevent forced exhaustion of the iterator). I think there's zero chance of this proposal being accepted ;) 2. for-loops should not support finalisation at all, and if you want finalisation semantics you need to enclose the for-loop in a do/with statement. I think the most important thing is that the semantics must be absolutely clear to someone looking at the code for the first time, without knowing the particulars of the statement being used. To me that suggests that the following 3 factors are the most important: 1. Non-looping semantics. Looping semantics require me to think more about the actual behaviour in the presence of break/continue. 2. An exception raised in the body of the statement must be propagated outside of the statement. I'm willing to accept another exception being raised in its place, but in that case I think it would be a good idea to chain the exceptions in some way. In any case, if the body of the statement terminates abnormally, it should not be possible for the statement to change that abnormal exit. 3. There should be a single statement (other than try...finally) that has finalisation semantics i.e. for-loop doesn't. Tim Delaney ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Ka-Ping Yee <[EMAIL PROTECTED]> wrote:
>
> On Sun, 15 May 2005, Shane Hathaway wrote:
> > You might add to the PEP the following example, which could really
> > improve the process of building GUIs in Python:
> >
> > class MyFrame(Frame):
> > def __init__(self):
> > with Panel():
> > with VerticalBoxSizer():
> > self.text = TextEntry()
> > self.ok = Button('Ok')
>
> I don't understand how this would be implemented. Would a widget
> function like 'TextEntry' set the parent of the widget according to
> some global 'parent' variable? If so, how would 'Panel' know that
> its parent is supposed to be the 'MyFrame' object?
It would actually take a bit more to make work properly.
If those objects were aware of the resource allocation mechanism, they
could add and remove themselves from a context stack as necessary. In
the case of things like VerticalBoxSizer, save the current self
dictionary on entrance, then check for changes on exit, performing an
Add with all the new objects. Or, so that it doesn't change the way
wxPython works with other versions of Python, everything could be
wrapped, perhaps using something like...
class MyFrame(Frame):
def __init__(self):
with new_context(self):
with parented(Panel, self) as panel:
with unparented(VerticalBoxSizer, 'Add') as panel.sizer:
self.text = TextEntry(panel)
self.ok = Button(panel, 'Ok')
There would be a little more work involved to generate a reasonable API
for this, but it is all possible.
- Josiah
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
[Nick Coghlan] > > http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html [Steven Bethard] > there I see the semantics: > > VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause > exc = (None, None, None) > try: > try: > BLOCK1 > except: > exc = sys.exc_info() > finally: > stmt_exit(*exc) > > Don't you want a "raise" after the "exc = sys.exc_info()"? I have the same question for Nick. Interestingly, assuming Nick meant that "raise" to be there, PEP 3XX and PEP 343 now have the same translation. In rev 1.10 I moved the __enter__ call out of the try-block again. Having it inside was insane: when __enter__ fails, it should do its own cleanup rather than expecting __exit__ to clean up after a partial __enter__. But some of the claims from PEP 3XX seem to be incorrect now: Nick claims that a with-statement can abstract an except clause, but that's not the case; an except clause causes the control flow to go forward (continue after the whole try statement) but the with-statement (with the "raise" added) always acts like a finally-clause, which implicitly re-raises the exception. So, in particular, in this example: with EXPR1: 1/0 print "Boo" the print statement is unreachable and there's nothing clever you can put in an __exit__ method to make it reachable. Just like in this case: try: 1/0 finally: BLOCK1 print "Boo" there's nothing that BLOCK1 can to to cause the print statement to be reached. This claim in PEP 3XX may be a remnant from a previous version; or it may be that Nick misunderstands how 'finally' works. Anyway, I think we may be really close at this point, if we can agree on an API for passing exceptions into generators and finalizing them, so that the generator can be written using a try/finally around the yield statement. Of course, it's also possible that Nick did *not* mean for the missing "raise" to be there. But in that case other claims from his PEP become false, so I'm assuming with Steven here. Nick? -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
At 08:18 AM 5/16/2005 +1000, Nick Coghlan wrote: >Paul Moore wrote: > > Looping is definitely a wart. Looping may even be a real problem in > > some cases. There may be cases where an explicit try...finally remains > > better, simply to avoid an unwanted looping behaviour. > >I agree PEP 343 throws away too much that was good about PEP 340 - that's why >I'm still updating PEP 3XX as the discussion continues. Could you please stop calling it PEP 3XX and go ahead and submit it as a real PEP? Either that, or post its URL *every* time you mention it, because at this point I don't know where to go to read it, and the same applies for each new person to enter the discussion. Thanks. ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Ka-Ping Yee wrote:
> On Sun, 15 May 2005, Shane Hathaway wrote:
>
>>You might add to the PEP the following example, which could really
>>improve the process of building GUIs in Python:
>>
>>class MyFrame(Frame):
>>def __init__(self):
>>with Panel():
>>with VerticalBoxSizer():
>>self.text = TextEntry()
>>self.ok = Button('Ok')
>
>
> I don't understand how this would be implemented. Would a widget
> function like 'TextEntry' set the parent of the widget according to
> some global 'parent' variable? If so, how would 'Panel' know that
> its parent is supposed to be the 'MyFrame' object?
Try this version, which I sent to Nick earlier:
class MyFrame(Frame):
def __init__(self):
with Panel(self):
with VerticalBoxSizer(self):
self.text = TextEntry(self)
self.ok = Button(self, 'Ok')
The 'self' parameter tells the component to add itself to the current
parent inside the Frame. The current parent is a temporary variable set
by 'with' statements. Outside any 'with' statement, the current parent
is the frame.
There is only a little magic. Maybe someone can find an even less
magical pattern, but it's a lot easier to read and write than the status
quo:
class MyFrame(Frame):
def __init__(self):
p = Panel()
self.add(p)
sizer = VerticalBoxSizer(p)
p.add(sizer)
self.text = TextEntry()
sizer.add(self.text)
self.ok = Button('Ok')
sizer.add(self.ok)
Shane
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
It's been interesting watching all the loops this discussion has gone through. I'm not sure the following is compatible with the current proposals, but maybe it will spur some ideas or help rule out something. There have been several examples of problems with opening several resources inside an enter method and how to resolve them in the case of an incomplete entry. So it seams to me, each resource needs to be handled separately, but that doesn't mean you can't use them as a group. So I was wondering if something like the following is feasible? # open-close pairing def opening(filename, mode): def openfile(): f = open(filename, mode) try: yield f finally: f.close() return openfile with opening(file1,m),opening(file2,m),opening(file3,m) as f1,f2,f3: # do stuff with files The 'with' (or whatever) statement would need a little more under the hood, but it might simplify handling multiple resources. This also reduces nesting in cases such as locking and opening. Both must succeed before the block executes. And if something goes wrong, the "with" statement knows and can handle each resource. The point is, each resource needs to be a whole unit, opening multiple files in one resource handler is probably not a good idea anyway. Regards, _Ron Adam ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Guido van Rossum wrote: > [...] But some of the claims from PEP 3XX seem to be incorrect now: Nick > claims that a with-statement can abstract an except clause, but that's > not the case; [...] Sorry for being a lurker, but can I try and expand this point. The options: - If we don't allow the except clause in the generator, the exception can't be examined there. - If we do allow the except clause we must (IMO) also allow the generator to suppress the exception. It would be surprising behaviour if an a caught exception was re-raised without an explicit raise statement. An argument: Despite the control-flow-macros-are-harmful discussion, I see nothing wrong with a block controller swallowing its block's exceptions because: - In most proposals it can raise its own exception in place of the block's exception anyway. - In the following example there is nothing surprising if controller() swallows block()'s exception: def block(): # do stuff raise E controller(block) Perhaps we don't want the block controller statement to have as much power over its block as controller() has over block() above. But handling an exception is not so radical is it? - Arnold. ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Phillip J. Eby wrote: > This makes it seem awkward for e.g. "do self.__lock", which doesn't > make any sense. But the extra call needed to make it "do > locking(self.__lock)" seems sort of gratuitous. How about do holding(self.__lock): ... > It makes me wonder if "with" or "using" or some similar word that works > better with nouns might be more appropriate ... For > example, a Decimal Context object might implement __enter__ by setting > itself as the thread-local context, and __exit__ by restoring the previous > context."do aDecimalContext" doesn't make much sense, but "with > aDecimalContext" or "using aDecimalContext" reads quite nicely. It doesn't work so well when you don't already have an object with one obvious interpretation of what you want to do 'with' it, e.g. you have a pathname and you want to open a file. I've already argued against giving file objects __enter__ and __exit__ methods. And I'm -42 on giving them to strings. :-) -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Guido van Rossum wrote: >>Also, one question: will the "do protocol" be added to built-in "resource" >>types? That is, locks, files, sockets, and so on? > > One person proposed that and it was shot down by Greg Ewing. I think > it's better to require a separate wrapper. It depends on whether the resource is "reusable". It would be okay for locks since you can lock and unlock the same lock as many times as you want, but files and sockets can only be used once, so there has to be something else around them. ALthough if we use 'do', we might want to use wrappers anyway for readability, even if they're not semantically necessary. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
A additional comment (or 2) on my previous message before I go back to lurk mode. If the recommended use of each resource template is kept to a single resource, then each enter and exit can be considered a whole block of code that will either pass or fail. You can then simplify the previous template to just: # open-close pairing def opening(filename, mode): def openfile(): f = open(filename, mode) yield f f.close() return openfile with opening(file1,m),opening(file2,m),opening(file3,m) as f1,f2,f3: # do stuff with files The with statement will need to catch any opening errors at the start in case one of the opening resources fails. Close any opened resources, then re raise the first exception. The with statement will also need to catch any uncaught exceptions in the block, close any opened resources, then re raise the exception. And again when closing, it will need to catch any exceptions that occur until it has tried to close all open resources, then re raise the first exception. Although it's possible to have more than one exception occur, it should always raise the first most one as any secondary exceptions may just be a side effect of the first one. The programmer has the option to surround the 'with' block with a try except if he want to catch any exceptions raised. He should also be able to put try excepts before the yield, and after the yield, or in the block. (But not surrounding the yield, I think.) Of course he may cause himself more problems than not, but that should be his choice, and maybe he thought of some use. This might be an acceptable use case of try-except in the enter section. def openfile(firstfile, altfile, mode): try: f = open(firstfile, mode) except: f = open(altfile, mode) yield f f.close() return openfile This is still a single open resource (if it succeeds) so should work ok. Alternate closing could be possible, maybe retrying the close several time before raising it and letting the 'with' handle it. Cheers, _Ron ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Fredrik Lundh wrote: > try with opening(file) as f: > body > except IOError: > deal with the error (you have to do this anyway) You don't usually want to do it right *there*, though. More likely you'll have something further up that deals with a variety of possible errors. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On Sun, 15 May 2005, Guido van Rossum wrote: > In rev 1.10 I moved the __enter__ call out of the > try-block again. Having it inside was insane: when __enter__ fails, it > should do its own cleanup rather than expecting __exit__ to clean up > after a partial __enter__. No, it wasn't insane. You had a good reason for putting it there. The question is what style of implementation you want to encourage. If you put __enter__ inside, then you encourage idempotent __exit__, which makes resource objects easier to reuse. If you put __enter__ outside, that allows the trivial case to be written a little more simply, but also makes it hard to reuse. -- ?!ng ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
On 5/15/05, Nick Coghlan <[EMAIL PROTECTED]> wrote: > http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html In reading over PEP 3XX again, it struck me that I'd been having a really hard time grasping exactly when I needed to use the "needs_finish" decorator. Am I right in saying that I should use the "needs_finish" decorator every time I have a "yield" inside a with-statement or a try/finally? Are there other situations where I might need the "needs_finish" decorator? If it's true that I need the "needs_finish" decorator every time I have a "yield" inside a with-statement or a try/finally, I'd be inclined to do this automatically. That is, since a yield inside a with-statement or try/finally can be determined lexically (heck, we do it now to disallow it), generators that have such code should be automatically wrapped with the "needs_finish" decorator, i.e. they should automatically acquire a __finish__ method. If I've misunderstood, and there are other situations when "needs_finish" is required, it'd be nice to see some more examples. STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Steven Bethard wrote: > If I've misunderstood, and there are other situations when > "needs_finish" is required, it'd be nice to see some more examples. The other cases are where you want to do something in response to an exception, but not otherwise:: def gen(): try: yield except: print 'Got exception:', sys.exc_info() raise Personally, I think they're rare enough that you could use a decorator in those cases, but still have:: def gen(): try: yield finally: pass automatically make the generator conform to the do/with protocol. Tim Delaney ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Guido van Rossum wrote: > But then the reason for separating VAR from EXPR becomes unclear. > Several people have mentioned that they thought this was "a good idea > on its own", but without giving additional use cases. Without the > ability to write the acquire/release template as a generator, the big > question is, "why not just PEP 310" ? Here's another use case: In PyGUI, in order to abstract the various ways that different platforms deal with drawing contexts, my widgets currently have a method widget.with_canvas(func) where you define func as def func(canvas): # do drawing operations on the canvas The canvas is a separate object from the widget so that it's harder to make the mistake of trying to draw to the widget outside of the appropriate context. The with-statement form of this would be with widget.canvas() as c: # do drawing operations on c Keeping the VAR and EXPR separate in this case better reflects the semantics of the original with_canvas() function. The canvas is strictly a local object produced as a result of executing the __enter__ method, which helps ensure that the correct protocol is followed -- if you haven't called __enter__, you don't have a canvas, so you can't do any drawing. On the other hand, this leads to some awkwardness in the naming conventions. The canvas() method, despite its name, doesn't actually return a canvas, but another object which, when used in the right way, produces a canvas. In general, the names of methods for use in a with-statement will need to be named according to the object which is bound to the VAR, rather than what they actually return. I'm not sure whether this is a problem or not. There's already a similar situation with generators, which are more usefully named according to what they yield, rather than what they return when considered as a function. I just feel a bit uncomfortable giving my widgets a function called canvas() that doesn't return a canvas. The alternative is that the canvas() method *does* return a canvas, with __enter__ and __exit__ methods, and the rule that you have to use the appropriate protocol before you can use it. This would avoid most of the aforementioned problems. So I think I may have just talked myself out of what I was originally intending to argue! -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Nick Coghlan wrote:
> The naming convention for 'do' is shown in the current PEP 343. The issue
> I've
> noticed with it is that *functions* read well, but methods don't because
> things
> get out of sequence. That is, "do locking(the_lock)" reads well, but "do
> the_lock.locking()" does not.
>
> Whereas, using 'with', it can be written either way, and still read
> reasonably
> well ("with locked(the_lock)", "with the_lock.locked()").
>
> The 'with' keyword also reads better if objects natively support use in
> 'with'
> blocks ("with the_lock", "with the_file").
>
> Guido's concern regarding file objects being reused inappropriately can be
> dealt
> with in the file __enter__ method:
>
>def __enter__(self):
>if self.closed:
>raise RuntimeError, "Cannot reopen closed file handle"
>
> For files, it may then become the common practice to keep pathnames around,
> rather than open file handles. When you actually needed access to the file,
> the
> existing "open" builtin would suffice:
>
>with open(filename, "rb") as f:
>for line in f:
>print line
I think I'm starting to agree. Currently about +0.6 in
favour of 'with' now, especially if this is to be
almost exclusively a resource-acquisition statement,
as all our use cases seem to be.
--
Greg Ewing, Computer Science Dept, +--+
University of Canterbury, | A citizen of NewZealandCorp, a |
Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. |
[EMAIL PROTECTED] +--+
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Guido van Rossum wrote: > PEP 340 is still my favorite, but it seems there's too much opposition > to it, I'm not opposed to PEP 340 in principle, but the ramifications seemed to be getting extraordinarily complicated, and it seems to be hamstrung by various backwards-compatibility constraints. E.g. it seems we can't make for-loops work the way they should in the face of generator finalisation or we break old code. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - Abstract Block Redux
Brett C. wrote: > Nick's was obviously directly against looping, but, with no offense to Nick, > how many other people were against it looping? It never felt like it was a > screaming mass with pitchforks but more of a "I don't love it, but I can deal" > crowd. My problem with looping was that, with it, the semantics of a block statement would be almost, but not quite, exactly like those of a for-loop, which seems to be flying in the face of TOOWTDI. And if it weren't for the can't-finalise-generators-in-a-for-loop backward compatibility problem, the difference would be even smaller. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list [email protected] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
