Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally
Guido van Rossum <[EMAIL PROTECTED]> writes: > [Steven Bethard] >> I have a feeling that it might actually be easier to continue to >> document try/except and try/finally separately and then just give the >> semantics of try/except/finally in terms of the other semantics. Take >> a look at the Java Language Specification[1] (pages 399-401) if you >> want to see how nastly documenting try/except/finally can get. And >> they don't even have an else clause! ;-) > > Fine with me. > > Can I go ahead and approve this now While I see the cost of this PEP being pretty small, I see the benefit the same way too. > before someone proposes to add a new keyword? Heh. Cheers, mwh -- If i don't understand lisp, it would be wise to not bray about how lisp is stupid or otherwise criticize, because my stupidity would be archived and open for all in the know to see. -- Xah, comp.lang.lisp ___ 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] Merging PEP 310 and PEP 340-redux?
On 5/11/05, Guido van Rossum <[EMAIL PROTECTED]> wrote: > I realize that the pushback was against looping, but whereas in the > PEP 340 proposal general exception handling comes out naturally, it > feels as an ugly wart in the modified PEP 310 proposal. > > Plus I think the use cases are much weaker (even PEP 340 doesn't have > many use cases for exception handling -- the only one is the > auto-retry example). Accepted, but I still feel that the templates should explicitly include the try...finally, rather than simply having the yield mark the split. The examples seem more readable that way. Explicit is better than implicit, and all that... Paul. ___ 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] Merging PEP 310 and PEP 340-redux?
On Wed, 11 May 2005, Guido van Rossum wrote: > [Steven Bethard] > > exc = () > > try: > > try: > > BLOCK1 > > except: > > exc = sys.exc_info() > > finally: > > stmt_exit(*exc) > > > > would this make any of the examples impossible to write? All you have > > to do to suppress an exception is to not reraise it in __exit__. > > But this use case would contain a trap for the unwary user who is > writing an __exit__ method -- they have to remember to re-raise an > exception if it was passed in, but that's easy to forget (and slightly > tricky since you have to check the arg count or whether the first > argument is not None). Then wouldn't it be simplest to separate normal exit from exceptional exit? That is, split __exit__ into __except__ and __finally__. If __except__ is defined, then it handles the exception, otherwise the exception is raised normally. > class locking: > def __init__(self, lock): self.lock = lock > def __enter__(self): self.lock.acquire() > def __exit__(self, *args): self.lock.release() Having __exit__ take varargs is a signal to me that it mashes together what really are two different methods. -- ?!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] Merging PEP 310 and PEP 340-redux?
Steven Bethard wrote:
> On 5/11/05, Nick Coghlan <[EMAIL PROTECTED]> wrote:
>
>>The gist is that the alternative is to require an __exit__() method to raise
>>TerminateBlock in order to suppress an exception.
>
> So I didn't see any examples that really needed TerminateBlock to
> suppress an exception.
Yeah, I figured out a tidier way to handle it after reading Phillip's message
earlier today. My idea is similar to your second solution, but with an early
exit via break, continue or return still indicated to the __exit__() method via
TerminateBlock so that examples like transaction() continue to do the right
thing:
the_stmt = EXPR1
stmt_enter = getattr(the_stmt, "__enter__", None)
stmt_exit = getattr(the_stmt, "__exit__", None)
if stmt_enter is None or stmt_exit is None:
raise TypeError("User defined statement template required")
terminate = True
VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause
try:
try:
BLOCK1
except TerminateBlock:
raise # Disallow suppression of TerminateBlock
except:
terminate = False
if not stmt_exit(*sys.exc_info()):
raise
else:
terminate = False
stmt_exit()
finally:
if terminate:
try:
stmt_exit(TerminateBlock, None, None)
except TerminateBlock:
pass
Version 1.5 uses these updated semantics, and the suggested generator
__exit__()
method semantics are adjusted appropriately. I've also added a paragraph in
Open
Issues about removing the ability to suppress exceptions as Guido has
suggested.
However, I'm hoping his objections are based on the assorted horrible
mechanisms
I used in versions before this one - he is quite right that forcing every
__exit__() method to reraise exceptions was a rather ugly wart.
The new version also fixes a typo in the auto_retry example that a couple of
people pointed out, and adds a non-exception related example from Arnold deVos.
The URL is the same as before:
http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html
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] a patch to inspect and a non-feature request
Well, I logged into Sourceforge with the idea of filing my feature request about copying functions, and then my eye went on my previous submissions. It seems it takes some time to fix non-critical bugs, isn't it? ;) Two years ago, I discovered a bug with pydoc for classes containing "super" objects: >>> class C(object): ...pass >>> C.s = super(C) >>> help(C) # aargh!! I filed that bug 25 months ago and it is still there (actually Brett Cannot fixed it but then somebody else broke his patch). Clearly nobody uses this feature and the bug fixing is not at all urgent still it disturbs me, so I have worked out a patch. Actually, the problem is not in pydoc but in inspect, that treats super objects as methods, whereas they should be treated as data. Here is the patch: $ diff -c /home/micheles/python/dist/src/Lib/inspect.py inspect.py *** /home/micheles/python/dist/src/Lib/inspect.py Thu May 12 13:05:10 2005 --- inspect.py Thu May 12 13:06:55 2005 *** *** 77,83 and not hasattr(object, "__set__") # else it's a data descriptor and not ismethod(object) # mutual exclusion and not isfunction(object) ! and not isclass(object)) def isdatadescriptor(object): """Return true if the object is a data descriptor. --- 77,84 and not hasattr(object, "__set__") # else it's a data descriptor and not ismethod(object) # mutual exclusion and not isfunction(object) ! and not isclass(object) ! and not isinstance(object, super)) def isdatadescriptor(object): """Return true if the object is a data descriptor. It changes the code of ismethoddescriptor to make sure that super objects are not treated as methods. BTW, I have downloaded the CVS version of Python and run test_inspect against the patch and it is working. However, introspection tools have the tendency to be very fragile (especially with the rate of changes in Python) and it is possible that this fix would break something else. Let The Powers That Be to decide. The test suite should be augmented with a test such >>> inspect.ismethoddescriptor(C.s) False In my experience super is a huge can of worms and actually I have a non-feature request about the descriptor aspect of super: I would like super's __get__ method and the possibily to call super with just one argument to be removed in Python 3000. They are pretty much useless (yes I know of "autosuper") and error prone. Michele Simionato ___ 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] Pre-PEP: Unifying try-except and try-finally
> > Can I go ahead and approve this now > > While I see the cost of this PEP being pretty small, I see the benefit > the same way too. Sure. Let me approve it and we'll see if someone cares enough to implement it. -- --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] Merging PEP 310 and PEP 340-redux?
On 5/12/05, Nick Coghlan <[EMAIL PROTECTED]> wrote: > Yeah, I figured out a tidier way to handle it after reading Phillip's message > earlier today. My idea is similar to your second solution, but with an early > exit via break, continue or return still indicated to the __exit__() method > via > TerminateBlock so that examples like transaction() continue to do the right > thing: Do they? I don't write enough transactional code, but I would have thought that break, continue or return would have been a normal, expected exit from the do-statement and therefore should do a db.commit(), not a db.rollback(). Do you think you could add an example of how the transaction do-statement would be used in such a way that these would be the desired semantics? Thanks, 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] a patch to inspect and a non-feature request
On 5/12/05, Michele Simionato <[EMAIL PROTECTED]> wrote: > In my experience super is a huge can of worms and actually I have a > non-feature > request about the descriptor aspect of super: I would like super's > __get__ method > and the possibily to call super with just one argument to be removed > in Python 3000. +1 while super doesn't work with "meta-attributes" and classmethods: py> class B(object): ... "The B type" ... @classmethod ... def m(cls): ... print "B.m" ... py> class C(B): ... @classmethod ... def m(cls): ... print "C.m" ... cls._sup.m() ... py> C._sup = super(C) py> super(C, C).__doc__ 'The B type' py> super(C, C).__name__ Traceback (most recent call last): File "", line 1, in ? AttributeError: 'super' object has no attribute '__name__' py> C().m() C.m Traceback (most recent call last): File "", line 1, in ? File "", line 5, in m AttributeError: 'super' object has no attribute 'm' 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
[Python-Dev] Merging PEP 310 and PEP 340-redux?
In http://mail.python.org/pipermail/python-dev/2005-May/053652.html Nick wrote: terminate = True VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause try: try: BLOCK1 except TerminateBlock: raise # Disallow suppression of TerminateBlock except: terminate = False if not stmt_exit(*sys.exc_info()): raise else: terminate = False stmt_exit() finally: if terminate: try: stmt_exit(TerminateBlock, None, None) except TerminateBlock: pass This seems confusing to me, as if it were saying "OK, I don't want to finalize this, so I'll set terminate to false, but then finalize anyhow." Would "terminated=False" (and getting set later to True) still meet your requirements? Or even "finalized=False"? I realize that the spelling of finalise is a bugaboo, but presumably this is really a hidden variable, instead of something that the user must type. Or have I misunderstood that as well? -jJ ___ 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] Merging PEP 310 and PEP 340-redux?
A quick response to various small issues...
- Benji York proposes that file and lock objects (for example) could
have suitable __enter__ and __exit__ methods (__enter__ would have
to return self). Right!
- Greg Ewing (I believe) wants 'do' instead of 'with' for the
keyword. I think I like 'with' better, especially combining it with
Benji's proposal. IMO this reads better with 'with' than with 'do':
with open("/etc/passwd") as f:
for line in f:
...
- Steve Bethard has this example:
stmt = EXPR1
VAR1 = stmt.__enter__()
exc = () # or (None, None, None) if you prefer
try:
try:
BLOCK1
except:
exc = sys.exc_info()
finally:
if stmt.__exit__(*exc) is not None:
raise exc[0], exc[1], exc[2]
but he seems to forget that finally *always* re-raises the
exception. Anyway, I still don't care for the use case; rather than
fixing the coding bug, your time would be better spent arguing why
this functionality can't be missed.
- Eric Nieuwland asks if the VAR is still optional. Yes, it is (this
is implicit in the entire set of threads).
- Paul Moore wants the generator templates to explicitly contain
try/finally (or try/except, depending on the use case). That's much
more work though (passing exceptions into a generator is a new
feature) and is not necessary to get the "redux" version.
- Ka-ping Yee thinks we need separate entry points for the exceptional
and the normal termination case. I disagree; this would end up in
unnecessary duplication of code (or boilerplate to equate the two
methods) in most cases. The whole *point* is that finally gets to
do its clean-up act regardless of whether an exception is being
processed or not. The varargs signature to __exit__ was just me
being lazy instead of typing
def __exit__(self, t=None, v=None, tb=None): ...
- Nick is still peddling his much more complicated variant. I
recommend that he focuses on arguing use cases rather than semantic
subtleties, or else it won't get any traction (at least not with me
:-).
--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] a patch to inspect and a non-feature request
On 5/12/05, Steven Bethard <[EMAIL PROTECTED]> wrote: >super doesn't work with "meta-attributes" and classmethods: > > py> super(C, C).__name__ > Traceback (most recent call last): > File "", line 1, in ? > AttributeError: 'super' object has no attribute '__name__' Actually this is the Right Thing to do for super. It is something to be aware of, not something to change. Since __name__ is a descriptor defined in the type metaclass and not an attribute defined in the base class, super correctly does not retrieve it. It is enough to add some documentation about "super" caveats and nonobvious points. What I really dislike is super called with only one argument since it has many unpleasant surprises and not real advantages :-( Michele Simionato ___ 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] Merging PEP 310 and PEP 340-redux?
I think this is my first post to python-dev, so a mini-intro: I've
been lurking here for about 5 years, "professional" user a bit longer,
now working at Zope Corp.
Guido van Rossum wrote:
> Going for all-out simplicity, I would like to be able to write these examples:
>
> class locking:
> def __init__(self, lock): self.lock = lock
> def __enter__(self): self.lock.acquire()
> def __exit__(self, *args): self.lock.release()
>
> class opening:
> def __init__(self, filename): self.filename = filename
> def __enter__(self): self.f = open(self.filename); return self.f
> def __exit__(self, *args): self.f.close()
I've read the entire discussion, but may have missed this point, so,
correct me if I'm wrong. Wouldn't these semantics let "normal" objects
be used in a do. For example, if the file object had these methods:
def __enter__(self): return self
def __exit__(self, *args): self.close()
you could write
do file('whatever) as f:
lines = f.readlines()
Or a lock:
def __enter__(self): self.aquire(); return self
def __exit__(self, *args): self.release()
do my_lock:
a()
b()
c()
--
Benji York
Sr. Software Engineer
Zope Corporation
___
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] Merging PEP 310 and PEP 340-redux?
On 5/12/05, Guido van Rossum <[EMAIL PROTECTED]> wrote: > - Steve Bethard has this example: > > stmt = EXPR1 > VAR1 = stmt.__enter__() > exc = () # or (None, None, None) if you prefer > try: > try: > BLOCK1 > except: > exc = sys.exc_info() > finally: > if stmt.__exit__(*exc) is not None: > raise exc[0], exc[1], exc[2] > > but he seems to forget that finally *always* re-raises the > exception. Not if except catches it: py> try: ... try: ... raise Exception ... except: ... exc = sys.exc_info() ... finally: ... pass ... py> As I understand it, finally only re-raises the exception if it wasn't already caught. And I have to use an except block above to catch it so that sys.exc_info() returns something other than (None, None, None). > Anyway, I still don't care for the use case; rather than > fixing the coding bug, your time would be better spent arguing why > this functionality can't be missed. Sorry, I'm unclear. Do you not want sys.exc_info() passed to __exit__, or do you not want the with/do-statement to be allowed to suppress exceptions? Or both? My feeling is that the mechanism for suppressing exceptions is confusing, and it would probably be better to always reraise the exception. (I included it mainly to provide a middle ground between Guido's and Nick's proposals.) That is, I prefer something like: stmt = EXPR1 VAR1 = stmt.__enter__() exc = () # or (None, None, None) if you prefer try: try: BLOCK1 except: exc = sys.exc_info() finally: stmt.__exit__(*exc) raise exc[0], exc[1], exc[2] which should really read the same as Guido's suggestion: stmt = EXPR1 VAR1 = stmt.__enter__() try: BLOCK1 finally: stmt.__exit__(*sys.exc_info()) except that since sys.exc_info() returns (None, None, None) when there wasn't an except block, this won't actually work. If we don't provide some flag that an exception occurred, the transaction example doesn't work. My feeling is that if we're going to provide any flag, we might as well provide the entire 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] Merging PEP 310 and PEP 340-redux?
On 5/12/05, Benji York <[EMAIL PROTECTED]> wrote:
> if the file object had these methods:
>
> def __enter__(self): return self
> def __exit__(self, *args): self.close()
>
> you could write
>
> do file('whatever) as f:
> lines = f.readlines()
>
> Or a lock:
>
> def __enter__(self): self.aquire(); return self
> def __exit__(self, *args): self.release()
>
> do my_lock:
> a()
> b()
> c()
Ah, finally a proposal that I can understand!
But maybe the keyword should be "let":
let lock:
do_something
let open("myfile") as f:
for line in f: do_something(line)
or even, without need of "as":
let f=file("myfile") :
for line in f: do_something(line)
which I actually like more
Michele Simionato
___
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] Merging PEP 310 and PEP 340-redux?
At 07:50 AM 5/12/2005 -0700, Guido van Rossum wrote: >- Paul Moore wants the generator templates to explicitly contain > try/finally (or try/except, depending on the use case). That's much > more work though (passing exceptions into a generator is a new > feature) and is not necessary to get the "redux" version. Uh oh. Speaking on behalf of the "coroutine-y people" :), does this mean that we're not going to get the ability to pass exceptions into generators? ___ 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] Merging PEP 310 and PEP 340-redux?
[Guido van Rossum] > >- Paul Moore wants the generator templates to explicitly contain > > try/finally (or try/except, depending on the use case). That's much > > more work though (passing exceptions into a generator is a new > > feature) and is not necessary to get the "redux" version. [Phillip J. Eby] > Uh oh. Speaking on behalf of the "coroutine-y people" :), does this mean > that we're not going to get the ability to pass exceptions into generators? That would be a separate proposal (PEP 288 or PEP 325). The do/with statement with its __enter__ and __exit__ APIs is entirely independent from generators. Having shown a few non-generator do/with wrappers I'm not so sure there's a lot of need for generators here; especially since generators will always have that round-peg-square-hole feeling when they're used in a non-looping context. But I still want to leave the door open for using generators as do/with-templates, hence my modification of PEP 310 (otherwise we could just accept PEP 310 as is and be done with it). For coroutines, see PEP 342. -- --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
[Python-Dev] "with" use case: exception chaining
> - Ka-ping Yee thinks we need separate entry points for the exceptional > and the normal termination case. I disagree; this would end up in > unnecessary duplication of code (or boilerplate to equate the two > methods) in most cases. The whole *point* is that finally gets to > do its clean-up act regardless of whether an exception is being > processed or not. Okay, let me back up for a second. My suggestion responded to your reply to Steve Bethard's example about exception handling. The point of the suggestion is that *if* we are going to let "with" do exception handling, it should be done in a separate method. I didn't mean to imply that __finally__ should be skipped. This brings us back to the question of whether "with" should be able to handle exceptions. On this, you wrote: > For try/finally we have a large body of use cases that just scream for > abstraction. I'm not convinced that we have the same for try/except. So let's look at some use cases. I've thought of two; the first one is nice and simple, and the second one is messier so i'll discuss it in a separate message. Example 1: Exception Chaining. As has been previously discussed, the information from an exception can be lost when the handling of the exception runs into a problem. It is often helpful to preserve the original reason for the problem. Suppose, by convention, that the "reason" attribute on exception objects is designated for this purpose. The assignment of this attribute can be conveniently abstracted using a "with" clause as follows: try: # ... risky operation ... except: with reason(sys.exc_info()): # ... cleanup ... The "with reason" construct would be implemented like this: class reason: def __init__(self, etype, evalue, etb): self.reason = etype, evalue, etb def __except__(self, etype, evalue, etb): evalue.reason = self.reason raise etype, evalue, etb (Other possible names for "reason" might be "cause" or "context".) -- ?!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
[Python-Dev] "with" use case: replacing a file
Here's another use case to think about. Example 2: Replacing a File. Suppose we want to reliably replace a file. We require that either: (a) The file is completely replaced with the new contents; or (b) the filesystem is unchanged and a meaningful exception is thrown. We'd like to be able to write this conveniently as: with replace(filename) as file: ... file.write(spam) ... file.write(eggs) ... To make sure the file is never only partially written, we rely on the filesystem to rename files atomically, so the basic steps (without error handling) look like this: tempname = filename + '.tmp' file = open(tempname, 'w') ... file.write(spam) ... file.close() os.rename(tempname, filename) We would like to make sure the temporary file is cleaned up and no filehandles are left open. Here's my analysis of all the execution paths we need to cover: 1. +open +write +close +rename 2. +open +write +close -rename ?remove 3. +open +write -close ?remove 4. +open -write +close ?remove 5. +open -write -close ?remove 6. -open (In this list, + means success, - means failure, ? means don't care.) When i add error handling, i get this: tempname = filename + '.tmp' file = open(tempname, 'w') # okay to let exceptions escape problem = None try: try: ... file.write(spam) ... except: problem = sys.exc_info() raise problem finally: try: file.close() except Exception, exc: problem, problem.reason = exc, problem if not problem: try: os.rename(tempname, filename) except Exception, exc: problem, problem.reason = exc, problem if problem: try: os.remove(tempname) except Exception, exc: problem, problem.reason = exc, problem raise problem In this case, the implementation of replace() doesn't require a separate __except__ method: class replace: def __init__(self, filename): self.filename = filename self.tempname = '%s.%d.%d' % (self.filename, os.getpid(), id(self)) def __enter__(self): self.file = open(self.tempname, 'w') return self def write(self, data): self.file.write(data) def __exit__(self, *problem): try: self.file.close() except Exception, exc: problem, problem.reason = exc, problem if not problem: # commit try: os.rename(tempname, filename) except Exception, exc: problem, problem.reason = exc, problem if problem: # rollback try: os.remove(tempname) except Exception, exc: problem, problem.reason = exc, problem raise problem This is all so intricate i'm not sure if i got it right. Somebody let me know if this looks right or not. (In any case, i look forward to the day when i can rely on someone else to get it right, and they only have to write it once!) -- ?!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] "with" use case: replacing a file
At 03:00 PM 5/12/2005 -0500, Ka-Ping Yee wrote: >This is all so intricate i'm not sure if i got it right. Somebody >let me know if this looks right or not. (In any case, i look forward >to the day when i can rely on someone else to get it right, and they >only have to write it once!) It looks fine, but it's not a use case for suppressing exceptions, nor was the exception-chaining example. Really, the only use case for suppressing exceptions is to, well, suppress exceptions that are being logged, shown to the user, sent via email, or just plain ignored. Guido's point, I think, is that these use cases are rare enough (yet simple and similar enough) that they don't deserve support from the cleanup facility, and instead should use a try/except block. After reviewing the cases in my own code where I might've used a 'with logged_exceptions()' or similar blocks, I think I now agree. The difference between: try: BLOCK except: logger.exception(...) and: with log_errors(logger): BLOCK doesn't seem worth the effort, especially since this pattern just doesn't occur that often, compared to resource-using blocks. What *your* use cases seem to illustrate, however, is that it's quite possible that an __exit__ might well need to contain complex error handling of its own, including the need to throw a different exception than the one that was passed in. ___ 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] "with" use case: exception chaining
[Ka-Ping Yee] > Example 1: Exception Chaining. > > As has been previously discussed, the information from an exception can > be lost when the handling of the exception runs into a problem. It is > often helpful to preserve the original reason for the problem. [example deleted] This problem is universal -- every except clause (in theory) can have this problem. I'd much rather deal with this in a systematic way in the Python VM's exception handling machinery. Modifying every potentially affected except clause to use some additional boilerplate doesn't strike me as a good solution. -- --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] "with" use case: exception chaining
On Thu, 12 May 2005, Guido van Rossum wrote: > [Ka-Ping Yee] > > Example 1: Exception Chaining. > > > > As has been previously discussed, the information from an exception can > > be lost when the handling of the exception runs into a problem. It is > > often helpful to preserve the original reason for the problem. > [example deleted] > > This problem is universal -- every except clause (in theory) can have > this problem. I'd much rather deal with this in a systematic way in > the Python VM's exception handling machinery. That's reasonable. Unless another use case comes up, i withdraw my suggestion for a separate __except__ method. I hope the examples were interesting, anyhow. -- ?!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] "with" use case: replacing a file
Phillip J. Eby wrote: > Really, the only use case for suppressing exceptions is to, well, suppress > exceptions that are being logged, shown to the user, sent via email, or > just plain ignored. Guido's point, I think, is that these use cases are > rare enough (yet simple and similar enough) that they don't deserve support > from the cleanup facility, and instead should use a try/except block. Particularly since the *action* can be factored out into a do statement - it's only the *suppression* that has to be reproduced inline. That is: try: do standard_reaction(): pass except MyException: pass > After reviewing the cases in my own code where I might've used a 'with > logged_exceptions()' or similar blocks, I think I now agree. I think I'm convinced, too. The only actual use case in the PEP is auto_retry, and that can be more obviously written with a try/except block inside the loop: for retry in reversed(xrange(num_attempts)): try: make_attempt() break except IOError: if not retry: raise Not as pretty perhaps, but the control flow is far easier to see. Steven has also convinced me that break, continue and return should look like normal exits rather than exceptions. This should bring my next PEP draft back to something resembling Guido's option 3 - the __exit__() method still gets passed the contents of sys.exc_info(), it just can't do anything about it other than raise a different exception. Cheers, Nick. P.S. The points regarding non-local flow control in Joel Spolsky's latest Joel on Software article (especially the links at the end) may have had something to do with my change of heart. . . -- 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] Tidier Exceptions
It occurred to me as i was messing around with handling and re-raising exceptions that tossing around these (type, value, traceback) triples is irritating and error-prone. How about just passing around a single value? All we'd have to do is put the traceback in value.traceback. Implementation: - "raise Class" and "raise Class, string" automatically set the .traceback attribute on the new instance of Class. - "raise instance" automatically sets the .traceback attribute on the instance unless it already has one. The behaviour of "except" and "sys.exc_*" could remain unchanged. "raise t, v, tb" would eventually be deprecated in favour of "raise v". -- ?!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
[Python-Dev] Chained Exceptions
Suppose exceptions have an optional "context" attribute, which is
set when the exception is raised in the context of handling another
exception. Thus:
def a():
try:
raise AError
except:
raise BError
yields an exception which is an instance of BError. This instance
would have as its "context" attribute an instance of AError.
Or, in a more complex case:
def compute():
try:
1/0
except Exception, exc:
log(exc)
def log(exc):
try:
file = open('error.log') # oops, forgot 'w'
print >>file, exc
file.close()
except:
display(exc)
def display(exc):
print 'Aaaack!', ex# oops, misspelled 'exc'
Today, this just gives you a NameError about 'ex'.
With the suggested change, you would still get a NameError about 'ex';
its 'context' attribute would show that it occurred while handling an
IOError on error.log; and this IOError would have a 'context' attribute
containing the original ZeroDivisionError that started it all.
What do you think?
-- ?!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] Tidier Exceptions
[Ka-Ping Yee] > It occurred to me as i was messing around with handling and re-raising > exceptions that tossing around these (type, value, traceback) triples > is irritating and error-prone. > > How about just passing around a single value? All we'd have to do is > put the traceback in value.traceback. I proposed the same thing a while back (during the early hours of writing PEP 340). It won't fly as long as we have string exceptions (since there's nowhere to put the traceback) but once those are dead I like it a lot. -- --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] Chained Exceptions
[Ka-Ping Yee] > Suppose exceptions have an optional "context" attribute, which is > set when the exception is raised in the context of handling another > exception. Thus: > > def a(): > try: > raise AError > except: > raise BError > > yields an exception which is an instance of BError. This instance > would have as its "context" attribute an instance of AError. [...] I like the idea, but I'm not sure about the consequences, and I'm not sure how it can be defined rigorously. Would it only happen when something *in* an except clause raises an exception? Which piece of code would be responsible for doing this? Try to come up with a precise specification and we'll talk. -- --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] Tidier Exceptions
Guido van Rossum wrote: > [Ka-Ping Yee] > >>It occurred to me as i was messing around with handling and re-raising >>exceptions that tossing around these (type, value, traceback) triples >>is irritating and error-prone. >> >>How about just passing around a single value? All we'd have to do is >>put the traceback in value.traceback. > > > I proposed the same thing a while back (during the early hours of > writing PEP 340). > > It won't fly as long as we have string exceptions (since there's > nowhere to put the traceback) but once those are dead I like it a lot. > Seems like, especially if we require inheritance from a base exception class in Python 3000, exceptions should have standard 'arg' and 'traceback' attributes with a possible 'context' attribute (or always a 'context' attribute set to None if not a chained exception). I don't think there is other data normally associated with exceptions is there? I really need to get off my ass one of these days and just write a PEP targeted for Python 3000 with base inheritance, standard attributes (including exception chains), reworking the built-in exception inheritance hierarchy, and whether bare 'except' statements should go or only catch certain exceptions. Could probably stand to break it up until multiple PEPs, though. =) -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] Chained Exceptions
Guido van Rossum wrote: > [Ka-Ping Yee] > >>Suppose exceptions have an optional "context" attribute, which is >>set when the exception is raised in the context of handling another >>exception. Thus: >> >>def a(): >>try: >>raise AError >>except: >>raise BError >> >>yields an exception which is an instance of BError. This instance >>would have as its "context" attribute an instance of AError. > > [...] > > I like the idea, but I'm not sure about the consequences, and I'm not > sure how it can be defined rigorously. Would it only happen when > something *in* an except clause raises an exception? Which piece of > code would be responsible for doing this? > > Try to come up with a precise specification and we'll talk. > If a new exception is raised (e.g., not a bare 'raise') while a current exception is active (e.g., sys.exc_info() would return something other than a tuple of None), then the new exception is made the active exception and the now old exception is assigned to the new exception's context attribute to be the old exception. -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] Chained Exceptions
On Thu, 12 May 2005, Brett C. wrote: > Guido van Rossum wrote: > > Try to come up with a precise specification and we'll talk. > > If a new exception is raised (e.g., not a bare 'raise') while a current > exception is active (e.g., sys.exc_info() would return something other > than a tuple of None), then the new exception is made the active exception > and the now old exception is assigned to the new exception's context > attribute to be the old exception. Yeah, i think that's basically all there is to it. I'll go have a peek at the interpreter to see if i'm forgetting something. -- ?!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] Chained Exceptions
[Brett C.] > If a new exception is raised (e.g., not a bare 'raise') while a current > exception is active (e.g., sys.exc_info() would return something other than a > tuple of None), then the new exception is made the active exception and the > now > old exception is assigned to the new exception's context attribute to be the > old exception. Define "raise". Does that involve a raise statement? What about 1/0? What if you call a method that executes 1/0? What if that method catches that exception? What about the StopIteration conceptually raised by next() called by the for-loop implementation? (Often it doesn't get instantiated at all when the next() method belongs to a built-in iterator.) I believe there are (at least) two use cases: (1) I catch some low-level exception (e.g. socket.error) and turn it into a high-level exception (e.g. an HTTPRequestFailed exception). (2) I write some exception handling code and somehow a bug in the handler (or an uncooperative environment, e.g. a full disk) causes the exception handling code to trip over an exception. I'm fairly certain (but not 100%) that Ping meant to include both use cases. -- --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] Tidier Exceptions
[Brett C.] > Seems like, especially if we require inheritance from a base exception class > in > Python 3000, exceptions should have standard 'arg' and 'traceback' attributes > with a possible 'context' attribute (or always a 'context' attribute set to > None if not a chained exception). > > I don't think there is other data normally associated with exceptions is > there? I despise the "arg" argument -- I like Java's "message" concept better. > I really need to get off my ass one of these days and just write a PEP > targeted > for Python 3000 with base inheritance, standard attributes (including > exception > chains), reworking the built-in exception inheritance hierarchy, and whether > bare 'except' statements should go or only catch certain exceptions. Could > probably stand to break it up until multiple PEPs, though. =) +1. I think these things are sufficiently closely related to keep them all in one PEP. -- --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] Chained Exceptions
On Thu, 12 May 2005, Guido van Rossum wrote:
> Define "raise". Does that involve a raise statement?
Not necessarily; it could be a raise statement or an inadvertently
triggered exception, such as in the example code i posted.
> What about 1/0?
That counts.
> What if you call a method that executes 1/0?
That counts too.
> What if that method catches that exception?
Did you mean something like this?
def handle():
try:
open('spamspamspam')
except:
catchit()
# point A
...
def catchit():
try:
1/0
except:
pass
Then there's no exception to propagate, so it doesn't matter.
Once we're get to point A, the division by zero is long forgotten.
> What about the StopIteration conceptually
> raised by next() called by the for-loop implementation?
It's "caught" by the for-loop, so to speak, so it never gets out.
Conceptually, the for-loop expands to:
while 1:
try:
item = it.next()
except StopIteration:
break
# body of loop goes here
The 'break' can't possibly cause an exception, so the StopIteration
exception isn't retained.
> I believe there are (at least) two use cases:
>
> (1) I catch some low-level exception (e.g. socket.error) and turn it
> into a high-level exception (e.g. an HTTPRequestFailed exception).
>
> (2) I write some exception handling code and somehow a bug in the
> handler (or an uncooperative environment, e.g. a full disk) causes the
> exception handling code to trip over an exception.
>
> I'm fairly certain (but not 100%) that Ping meant to include both use cases.
Yes, though i did not expect to provide any mechanism for distinguishing
the two cases. Do you think such a mechanism would be necessary?
-- ?!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] Tidier Exceptions
On Thu, 12 May 2005, Brett C. wrote: > whether bare 'except' statements should go or only catch certain exceptions. Maybe bare 'except' should be spelled 'except *'. I don't think it can be removed altogether because sometimes you just need to be able to do magic, but it can be made a little more explicit. With the asterisk, it's greppable, and editors can find it or highlight it. I like the parallel to 'import *' (frowned upon, but sometimes useful if you really know what you are doing). -- ?!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] Chained Exceptions
At 07:36 PM 5/12/2005 -0500, Ka-Ping Yee wrote: >On Thu, 12 May 2005, Brett C. wrote: > > Guido van Rossum wrote: > > > Try to come up with a precise specification and we'll talk. > > > > If a new exception is raised (e.g., not a bare 'raise') while a current > > exception is active (e.g., sys.exc_info() would return something other > > than a tuple of None), then the new exception is made the active exception > > and the now old exception is assigned to the new exception's context > > attribute to be the old exception. > >Yeah, i think that's basically all there is to it. I'll go have a peek >at the interpreter to see if i'm forgetting something. I think the main problem is going to be that (IIUC), Python doesn't "know" when you've exited an 'except:' clause and are therefore no longer handling the exception. sys.exc_info() still gives you the exception you just caught. I think that a lot of the questions Guido brought up are directly related to this. Also, what about code like this: try: doSomething() except SomeError: pass doSomethingElse() Should exceptions raised by doSomethingElse()' be treated as having the SomeError as their context, if it was raised? If I understand correctly, the interpreter cannot currently distinguish between this, and the case where an error is raised inside the 'except' clause. ___ 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] Tidier Exceptions
[Ka-Ping Yee] > Maybe bare 'except' should be spelled 'except *'. -1. > I don't think it can be removed altogether because sometimes you just > need to be able to do magic, but it can be made a little more explicit. Assuming a single root of the exception tree, you can spell it explicitly as "except Exception" or perhaps (if that's not the root) "except Raisable" (cf. Java's Throwable). > With the asterisk, it's greppable, and editors can find it or highlight > it. I like the parallel to 'import *' (frowned upon, but sometimes > useful if you really know what you are doing). How is "except:" less greppable? And is *args also frowned upon? -- --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] Tidier Exceptions
On Thu, 12 May 2005, Guido van Rossum wrote: > How is "except:" less greppable? Duh. I'm slow today. -- ?!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] Chained Exceptions
[Phillip J. Eby] > I think the main problem is going to be that (IIUC), Python doesn't "know" > when you've exited an 'except:' clause and are therefore no longer > handling the exception. But the compiler knows and could insert code to maintain this state. > sys.exc_info() still gives you the exception you > just caught. I think that a lot of the questions Guido brought up are > directly related to this. Right. > Also, what about code like this: > > try: > doSomething() > except SomeError: > pass > > doSomethingElse() > > Should exceptions raised by doSomethingElse()' be treated as having the > SomeError as their context, if it was raised? > > If I understand correctly, the interpreter cannot currently distinguish > between this, and the case where an error is raised inside the 'except' > clause. Indeed the interpreter currently doesn't distinguish between these, but I think it ought to for the purposes of this proposal. -- --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] Chained Exceptions
[Guido]
> > What if that method catches that exception?
[Ka-Ping Yee]
> Did you mean something like this?
>
> def handle():
> try:
> open('spamspamspam')
> except:
> catchit()
> # point A
> ...
>
> def catchit():
> try:
> 1/0
> except:
> pass
>
> Then there's no exception to propagate, so it doesn't matter.
> Once we're get to point A, the division by zero is long forgotten.
But at what point does the attaching happen? If I catch the
ZeroDivisionException inside catchit() and inspects its context
attribute, does it reference the IOError instance raised by
open('spamspamspam')? This could potentially cause a lot of extra
work: when an inner loop that raises and catches lots of exceptions is
invoked in the context of having caught an exception at some outer
level, the inner loop keeps attaching the outer exception to each
exception raised.
> Yes, though i did not expect to provide any mechanism for distinguishing
> the two cases. Do you think such a mechanism would be necessary?
No, I was just trying to figure out what you meant when you said
"raise". It's clear now.
--
--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] Merging PEP 310 and PEP 340-redux?
Guido van Rossum wrote: > Going for all-out simplicity, I would like to be able to write these examples: > > class locking: > def __init__(self, lock): self.lock = lock > def __enter__(self): self.lock.acquire() > def __exit__(self, *args): self.lock.release() > > class opening: > def __init__(self, filename): self.filename = filename > def __enter__(self): self.f = open(self.filename); return self.f > def __exit__(self, *args): self.f.close()\ > > And do EXPR as VAR: BLOCK would mentally be translated into > > itr = EXPR > VAR = itr.__enter__() > try: BLOCK > finally: itr.__exit__(*sys.exc_info()) # Except sys.exc_info() isn't > defined by finally If it's this simple, it should be possible to write something that combines the acquisition of multiple resources in a single statement. For example: with combining(opening(src_fn), opening(dst_fn, 'w')) as src, dst: copy(src, dst) I think the following class would do it. class combining: def __init__(self, *resources): self.resources = resources self.entered = 0 def __enter__(self): results = [] try: for r in self.resources: results.append(r.__enter__()) self.entered += 1 return results except: # exit resources before re-raising the exception self.__exit__() raise def __exit__(self, *args): last_exc = None # exit only the resources successfully entered to_exit = self.resources[:self.entered] while to_exit: r = to_exit.pop() try: r.__exit__(*args) except: # re-raise the exception after exiting the others last_exc = sys.exc_info() if last_exc is not None: raise last_exc[0], last_exc[1], last_exc[2] Would that work? 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] Chained Exceptions
On May 12, 2005, at 6:32 PM, Ka-Ping Yee wrote: > Suppose exceptions have an optional "context" attribute, which is > set when the exception is raised in the context of handling another > exception. Thus: > > def a(): > try: > raise AError > except: > raise BError > > yields an exception which is an instance of BError. This instance > would have as its "context" attribute an instance of AError. > I think it's a bad idea to have this happen automatically. Many times if an exception is raised in the except clause, that doesn't necessarily imply it's related to the original exception. It just means there's a bug in the exception handler. Take the divide by 0 example: try: doABunchOfStuff() except: 1/0 If you're going to do anything useful with the chained exception information (such as have it printed by the default exception printer), it'd be best to not print a bunch of irrelevant backtraces for all exceptions up the stack. The reason that doABunchOfStuff failed is not important. What is important is only that you had a divide by 0. In my mind it's much better to be explicit about your intentions, via something like: try: raise AError except Raiseable, e: raise BError(cause=e) Of course you can already do similar with current python, it just can't be spelled as nicely, and the default traceback printer won't use the info: try: raise AError except: newException = BError() newException.cause=sys.exc_info() raise newException James ___ 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] Merging PEP 310 and PEP 340-redux?
[Shane Hathaway] > If it's this simple, it should be possible to write something that > combines the acquisition of multiple resources in a single statement. > For example: > > with combining(opening(src_fn), opening(dst_fn, 'w')) as src, dst: > copy(src, dst) Yeah (and I don't see anything wrong with your implementation of combining either), but even if that existed I think I'd prefer to just write with opening(src_fn) as src: with opening(dst_fn) as dst: copy(src, dst) See Ma, no magic! :-) -- --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] Chained Exceptions
James Y Knight wrote: > Of course you can already do similar with current python, it just > can't be spelled as nicely, and the default traceback printer won't > use the info: > > try: >raise AError > except: >newException = BError() >newException.cause=sys.exc_info() >raise newException Well, one thing you can do is (somewhat evil ;) :: import sys try: raise AError, 'message' except: exc_type, exc_value, exc_traceback - sys.exc_info() raise BError, exc_value, exc_traceback with the result: Traceback (most recent call last): File ... raise AError, 'message' BError: message So you store the original exception as the argument to the new exception (so it's accessible). This has the nice side effect that message is displayed in the traceback - but the type has changed. Whilst in the above example, it's particularly evil, in the case where the original exception came from a function call and you want to translate the type it works very nicely. 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] Chained Exceptions
[James Y Knight ] > I think it's a bad idea to have this happen automatically. Many times > if an exception is raised in the except clause, that doesn't > necessarily imply it's related to the original exception. It just > means there's a bug in the exception handler. Yeah, but especially in that case I think it would be nice if the traceback printed by the system (if all this doesn't get caught at an outer level) could show both the traceback from the handler and the traceback that it was trying to handle -- I've had many occasions where a trivial bug in the handler blew away the original traceback which was shy enough to make repeating it a pain. -- --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
[Python-Dev] the current behavior of try: ... finally:
All this talk about try: ... finally: and exceptions reminded me of a curious behavior I discovered a while back, i.e. that finally can swallow your exceptions. This is a contrived example, but shows the point: def divide1(n1, n2): try: result = n1/n2 finally: print "cleanup" result = "Infinity\n" return result # the exception is swallowed away def divide2(n1, n2): try: result = n1/n2 finally: print "cleanup" result = "Infinity\n" return result # the exception is NOT swallowed away print divide1(10, 0) # no-exception print divide2(10, 0) # error If there is an indentation error in "divide2" and the return line is too indented the exceptions get swallowed by the finally clause. I am not sure if this is good or bad, but sure it surprised me that a finally clause could hide my exception. Michele Simionato ___ 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] the current behavior of try: ... finally:
Michele Simionato wrote: > def divide1(n1, n2): > try: > result = n1/n2 > finally: > print "cleanup" > result = "Infinity\n" > return result # the exception is swallowed away What would you prefer to have happen in this case? Or do you think return (and break and continue) should be disallowed in a finally? -- 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] Tidier Exceptions
Guido van Rossum wrote: > It won't fly as long as we have string exceptions (since there's > nowhere to put the traceback) but once those are dead I like it a lot. Are there plans as to when string exceptions will be exterminated? Surely the only places they're used now are in some very old library modules. -- 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] Tidier Exceptions
Brett C. wrote: > Seems like, especially if we require inheritance from a base exception class > in > Python 3000, exceptions should have standard 'arg' and 'traceback' attributes > with a possible 'context' attribute (or always a 'context' attribute set to > None if not a chained exception). Instead of an 'args' attribute, I'd suggest that the constructor take keyword arguments and store them in corresponding attributes. Then interested parties could retrieve them by name instead of having to remember their positions in the args tuple of the exception class concerned. -- 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] Merging PEP 310 and PEP 340-redux?
Guido van Rossum wrote:
> - Greg Ewing (I believe) wants 'do' instead of 'with' for the
> keyword. I think I like 'with' better, especially combining it with
> Benji's proposal. IMO this reads better with 'with' than with 'do':
>
> with open("/etc/passwd") as f:
> for line in f:
> ...
I don't think I like the idea of giving the file object
itself __enter__ and __exit__ methods, because it doesn't
ensure that the opening and closing are done as a pair.
It would permit the following kind of mistake:
f = open("somefile")
with f:
do_something()
with f:
do_something_else()
which our proposed construct, if it is any good, should
be able to prevent.
Also I don't at all agree that "with open(...)" reads
better; on the contrary, it seems ungrammatical.
Especially when compared with the very beautiful
"do opening(...)", which I would be disappointed
to give up.
I still also have reservations about "with" on the
grounds that we're making it mean something very
different to what it means in most other languages
that have a "with".
--
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] Merging PEP 310 and PEP 340-redux?
Michele Simionato wrote:
> let lock:
>do_something
>
> let open("myfile") as f:
> for line in f: do_something(line)
This is getting even further into the realm
of gibberish to my ear.
> let f=file("myfile") :
> for line in f: do_something(line)
To anyone with a Lisp or funcional background, that
looks like nothing more than a local variable
binding.
--
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] the current behavior of try: ... finally:
On 5/13/05, Greg Ewing <[EMAIL PROTECTED]> wrote: > Michele Simionato wrote: > > > def divide1(n1, n2): > > try: > > result = n1/n2 > > finally: > > print "cleanup" > > result = "Infinity\n" > > return result # the exception is swallowed away > > What would you prefer to have happen in this case? > > Or do you think return (and break and continue) should > be disallowed in a finally? > Honestly, I don't know. This is why I ask here ;) Michele Simionato ___ 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] the current behavior of try: ... finally:
It did surprise me also. Because I've come to Python from Delphi. There are no return statement in Delphi. I also write some c++, the language has no finally-statement. This problem probably python exclusive. I think it's not too difficult to get used to it. This behavior is fine for me. ___ 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
