Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #88772 > unrolled thread
| Started by | Pavel S <pavel@schon.cz> |
|---|---|
| First post | 2015-04-10 01:48 -0700 |
| Last post | 2015-04-10 18:56 -0700 |
| Articles | 20 on this page of 24 — 11 participants |
Back to article view | Back to comp.lang.python
try..except with empty exceptions Pavel S <pavel@schon.cz> - 2015-04-10 01:48 -0700
Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-10 18:58 +1000
Re: try..except with empty exceptions sohcahtoa82@gmail.com - 2015-04-10 12:31 -0700
Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 11:42 +1000
Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 22:23 -0400
Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 19:38 -0700
Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 23:46 -0400
Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 21:17 -0700
Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 21:39 -0700
Re: try..except with empty exceptions Cameron Simpson <cs@zip.com.au> - 2015-04-11 19:27 +1000
Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 21:00 +1000
Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-11 21:21 +1000
Re: try..except with empty exceptions Ian Kelly <ian.g.kelly@gmail.com> - 2015-04-11 12:49 -0600
Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-12 06:04 +1000
Re: try..except with empty exceptions Chris Angelico <rosuav@gmail.com> - 2015-04-12 06:05 +1000
Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 17:11 +1000
Re: try..except with empty exceptions Serhiy Storchaka <storchaka@gmail.com> - 2015-04-11 11:22 +0300
Re: try..except with empty exceptions Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-11 20:47 +1000
Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-11 06:14 -0400
Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-11 06:24 -0400
Re: try..except with empty exceptions Ian Foote <ian@feete.org> - 2015-04-11 15:20 +0100
Re: try..except with empty exceptions Terry Reedy <tjreedy@udel.edu> - 2015-04-11 04:58 -0400
Re: try..except with empty exceptions Dave Angel <davea@davea.name> - 2015-04-10 16:27 -0400
Re: try..except with empty exceptions Rustom Mody <rustompmody@gmail.com> - 2015-04-10 18:56 -0700
Page 1 of 2 [1] 2 Next page →
| From | Pavel S <pavel@schon.cz> |
|---|---|
| Date | 2015-04-10 01:48 -0700 |
| Subject | try..except with empty exceptions |
| Message-ID | <64a75c32-e0ab-4ce0-9373-358c2669fe6e@googlegroups.com> |
Hi,
I noticed interesting behaviour. Since I don't have python3 installation here, I tested that on Python 2.7.
Well known feature is that try..except block can catch multiple exceptions listed in a tuple:
exceptions = ( TypeError, ValueError )
try:
a, b = None
except exceptions, e:
print 'Catched error:', e
However when exceptions=(), then try..except block behaves as no try..except block.
exceptions = ()
try:
a, b = None # <--- the error will not be catched
except exceptions, e:
print 'Catched error:', e
I found use case for it, e.g. when I want to have a method with 'exceptions' argument:
def catch_exceptions(exceptions=()):
try:
do_something()
except exceptions:
do_something_else()
catch_exceptions() # catches nothing
catch_exceptions((TypeError,)) # catches TypeError
I believe that behaviour is not documented. What you think?
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-04-10 18:58 +1000 |
| Message-ID | <mailman.198.1428656305.12925.python-list@python.org> |
| In reply to | #88772 |
On Fri, Apr 10, 2015 at 6:48 PM, Pavel S <pavel@schon.cz> wrote:
> Hi,
>
> I noticed interesting behaviour. Since I don't have python3 installation here, I tested that on Python 2.7.
>
> Well known feature is that try..except block can catch multiple exceptions listed in a tuple:
>
> However when exceptions=(), then try..except block behaves as no try..except block.
>
> exceptions = ()
>
> try:
> a, b = None # <--- the error will not be catched
> except exceptions, e:
> print 'Catched error:', e
>
> I believe that behaviour is not documented. What you think?
It's no different from any other except clause that doesn't match. An
empty tuple of exception types can never match any actual exception
thrown, so it'll be like skipping that except block. It doesn't need
to be specifically documented, as it's a natural consequence of the
use of the empty tuple there.
However, even though it's perfectly plausible as regards language
definition, I would hesitate to use it in production code. I'm not
sure this makes your code any better.
Side point: Even though you're not using Python 3 (where it's
mandatory), I would recommend using the "as" syntax with except
clauses:
exceptions = ()
try:
a, b = None
except exceptions as e:
print("Can't happen")
Writing your code to be compatible with both 2.7 and 3.x will make the
eventual port easier.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2015-04-10 12:31 -0700 |
| Message-ID | <785010c0-6bcc-46d7-b7e0-0ed062fabbc7@googlegroups.com> |
| In reply to | #88772 |
On Friday, April 10, 2015 at 1:48:22 AM UTC-7, Pavel S wrote: > Hi, > > I noticed interesting behaviour. Since I don't have python3 installation here, I tested that on Python 2.7. > > Well known feature is that try..except block can catch multiple exceptions listed in a tuple: > > > exceptions = ( TypeError, ValueError ) > > try: > a, b = None > except exceptions, e: > print 'Catched error:', e > > > However when exceptions=(), then try..except block behaves as no try..except block. > > > exceptions = () > > try: > a, b = None # <--- the error will not be catched > except exceptions, e: > print 'Catched error:', e > > > I found use case for it, e.g. when I want to have a method with 'exceptions' argument: > > > def catch_exceptions(exceptions=()): > try: > do_something() > except exceptions: > do_something_else() > > > catch_exceptions() # catches nothing > catch_exceptions((TypeError,)) # catches TypeError > > > I believe that behaviour is not documented. What you think? It isn't document because it is expected. Why would the exception get caught if you're not writing code to catch it? If you write a function and pass it a tuple of exceptions to catch, I'm not sure why you would expect it to catch an exception not in the tuple. Just because the tuple is empty doesn't mean that it should catch *everything* instead. That would be counter-intuitive.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-04-11 11:42 +1000 |
| Message-ID | <55287c0d$0$13000$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88785 |
On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote:
> It isn't document because it is expected. Why would the exception get
> caught if you're not writing code to catch it? If you write a function
> and pass it a tuple of exceptions to catch, I'm not sure why you would
> expect it to catch an exception not in the tuple. Just because the tuple
> is empty doesn't mean that it should catch *everything* instead. That
> would be counter-intuitive.
Really? I have to say, I expected it.
try:
spam()
except This, That:
# Implicitly a tuple of two exceptions.
pass
Compare:
try:
spam()
except:
# Implicitly an empty tuple.
pass
I'm not surprised that it fails, especially in Python 2 before
the "except ... as err" syntax was available, but the OP is not alone in
thinking that an empty tuple should catch everything.
I'm fairly dubious about catching everything, that sounds like a good way to
hide bugs, but if you need to catch everything, using Exception is the
usual way to do it.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-04-10 22:23 -0400 |
| Message-ID | <mailman.211.1428718999.12925.python-list@python.org> |
| In reply to | #88792 |
On 04/10/2015 09:42 PM, Steven D'Aprano wrote: > On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote: > >> It isn't document because it is expected. Why would the exception get >> caught if you're not writing code to catch it? If you write a function >> and pass it a tuple of exceptions to catch, I'm not sure why you would >> expect it to catch an exception not in the tuple. Just because the tuple >> is empty doesn't mean that it should catch *everything* instead. That >> would be counter-intuitive. > > Really? I have to say, I expected it. > > I'm astounded at your expectation. That's like saying a for loop on an empty list ought to loop on all possible objects in the universe. The tuple lists those exceptions you're interested in, and they are tried, presumably in order, from that collection. If none of those match, then the logic will advance to the next except clause. If the tuple is empty, then clearly none will match. > try: > spam() > except This, That: > # Implicitly a tuple of two exceptions. > pass > > > Compare: > > try: > spam() > except: > # Implicitly an empty tuple. No, an omitted item is not the same as an empty tuple. If it were, then we wouldn't have the problem of bare excepts, which are so tempting to novices. There's plenty of precedent in many languages for a missing item being distinct from anything one could actually supply. When there's no tuple specified, it's a different syntax, and the semantics are specified separately. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-04-10 19:38 -0700 |
| Message-ID | <d1e58c04-9c96-4fb8-a9ce-f56b9cdcd273@googlegroups.com> |
| In reply to | #88797 |
On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote: > On 04/10/2015 09:42 PM, Steven D'Aprano wrote: > > On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote: > > > >> It isn't document because it is expected. Why would the exception get > >> caught if you're not writing code to catch it? If you write a function > >> and pass it a tuple of exceptions to catch, I'm not sure why you would > >> expect it to catch an exception not in the tuple. Just because the tuple > >> is empty doesn't mean that it should catch *everything* instead. That > >> would be counter-intuitive. > > > > Really? I have to say, I expected it. > > > > > > I'm astounded at your expectation. That's like saying a for loop on an > empty list ought to loop on all possible objects in the universe. To work, this analogy should also have two python syntaxes like this: "Normal" for-loop: for var in iterable: suite "Empty" for-loop: for: suite [Sorry Steven… didn't notice you were agreeing with me… a rare privilege 😁 ]
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-04-10 23:46 -0400 |
| Message-ID | <mailman.212.1428724013.12925.python-list@python.org> |
| In reply to | #88798 |
On 04/10/2015 10:38 PM, Rustom Mody wrote:
> On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote:
>> On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
>>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote:
>>>
>>>> It isn't document because it is expected. Why would the exception get
>>>> caught if you're not writing code to catch it? If you write a function
>>>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>>>> expect it to catch an exception not in the tuple. Just because the tuple
>>>> is empty doesn't mean that it should catch *everything* instead. That
>>>> would be counter-intuitive.
>>>
>>> Really? I have to say, I expected it.
>>>
>>>
>>
>> I'm astounded at your expectation. That's like saying a for loop on an
>> empty list ought to loop on all possible objects in the universe.
>
> To work, this analogy should also have two python syntaxes like this:
>
> "Normal" for-loop:
> for var in iterable:
> suite
>
> "Empty" for-loop:
> for:
> suite
>
That tells me nothing about your opinions. What did you mean by the
phrase "to work"? My analogy already works. The for loop on an empty
list loops zero times. Just like try/except on an empty tuple catches
zero exception types.
As for the separate syntax, that might be an acceptable extension to
Python. But it already has a convention for an infinite loop, which is
while True:
I'm pretty sure do{} works as an infinite loop in C, but perhaps I'm
remembering some other language where you could omit the conditional.
--
DaveA
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-04-10 21:17 -0700 |
| Message-ID | <571a2fb7-ee1b-4144-9d90-26a96c767ec5@googlegroups.com> |
| In reply to | #88799 |
On Saturday, April 11, 2015 at 9:17:16 AM UTC+5:30, Dave Angel wrote: > On 04/10/2015 10:38 PM, Rustom Mody wrote: > > On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote: > >> On 04/10/2015 09:42 PM, Steven D'Aprano wrote: > >>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote: > >>> > >>>> It isn't document because it is expected. Why would the exception get > >>>> caught if you're not writing code to catch it? If you write a function > >>>> and pass it a tuple of exceptions to catch, I'm not sure why you would > >>>> expect it to catch an exception not in the tuple. Just because the tuple > >>>> is empty doesn't mean that it should catch *everything* instead. That > >>>> would be counter-intuitive. > >>> > >>> Really? I have to say, I expected it. > >>> > >>> > >> > >> I'm astounded at your expectation. That's like saying a for loop on an > >> empty list ought to loop on all possible objects in the universe. > > > > To work, this analogy should also have two python syntaxes like this: > > > > "Normal" for-loop: > > for var in iterable: > > suite > > > > "Empty" for-loop: > > for: > > suite > > > > That tells me nothing about your opinions. What did you mean by the > phrase "to work"? Your analogy is "for loop on an empty list ought to loop on all possible objects in the universe" This seemingly works as a demo of a ridiculous expectation because there is only one pattern of for-loop for var in iterable: In the case of exceptions we have two patterns except e-tuple: and except: with the second having a wildly different semantics from the first
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-04-10 21:39 -0700 |
| Message-ID | <01bae820-c75c-4879-b009-3a6f0ad50a41@googlegroups.com> |
| In reply to | #88800 |
On Saturday, April 11, 2015 at 9:47:36 AM UTC+5:30, Rustom Mody wrote: > On Saturday, April 11, 2015 at 9:17:16 AM UTC+5:30, Dave Angel wrote: > > On 04/10/2015 10:38 PM, Rustom Mody wrote: > > > On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote: > > >> On 04/10/2015 09:42 PM, Steven D'Aprano wrote: > > >>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote: > > >>> > > >>>> It isn't document because it is expected. Why would the exception get > > >>>> caught if you're not writing code to catch it? If you write a function > > >>>> and pass it a tuple of exceptions to catch, I'm not sure why you would > > >>>> expect it to catch an exception not in the tuple. Just because the tuple > > >>>> is empty doesn't mean that it should catch *everything* instead. That > > >>>> would be counter-intuitive. > > >>> > > >>> Really? I have to say, I expected it. > > >>> > > >>> > > >> > > >> I'm astounded at your expectation. That's like saying a for loop on an > > >> empty list ought to loop on all possible objects in the universe. > > > > > > To work, this analogy should also have two python syntaxes like this: > > > > > > "Normal" for-loop: > > > for var in iterable: > > > suite > > > > > > "Empty" for-loop: > > > for: > > > suite > > > > > > > That tells me nothing about your opinions. What did you mean by the > > phrase "to work"? > > Your analogy is "for loop on an empty list ought to loop on all possible > objects in the universe" > This seemingly works as a demo of a ridiculous expectation > because there is only one pattern of for-loop > for var in iterable: > > In the case of exceptions we have two patterns > except e-tuple: > and > except: > with the second having a wildly different semantics from the first IOW: OP is surprised that except (): is a no-op The real surprise is that except: is valid syntax with questionable semantics
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2015-04-11 19:27 +1000 |
| Message-ID | <mailman.217.1428744459.12925.python-list@python.org> |
| In reply to | #88798 |
On 10Apr2015 19:38, Rustom Mody <rustompmody@gmail.com> wrote: >On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote: >> On 04/10/2015 09:42 PM, Steven D'Aprano wrote: >> > On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote: >> >> It isn't document because it is expected. Why would the exception get >> >> caught if you're not writing code to catch it? If you write a function >> >> and pass it a tuple of exceptions to catch, I'm not sure why you would >> >> expect it to catch an exception not in the tuple. Just because the tuple >> >> is empty doesn't mean that it should catch *everything* instead. That >> >> would be counter-intuitive. >> > >> > Really? I have to say, I expected it. >> >> I'm astounded at your expectation. That's like saying a for loop on an >> empty list ought to loop on all possible objects in the universe. > >To work, this analogy should also have two python syntaxes like this: > >"Normal" for-loop: >for var in iterable: > suite > >"Empty" for-loop: >for: > suite Well, to throw an anaolgy in the mix, the shell has a bare for syntax. list='a b c' for x in $list do echo $x done echoes a, b and c as you might expect. This: for x do echo $x done echoes the command line arguments. (Which is extremely useful.) But as with Python, the missing iteration means a _default_ source of iteration, not _no_ iteration. To continue the analogy, this: list= for x in $list do echo $x done echoes nothing. As I would hope Steven would expect. Importantly, in both Python and the shell you have a way to specify "nothing". If the empty tuple were to mean "catch everything" then there would not be a way to express "catch nothing". Bad bad bad! Consider this a proof that Python's current meanings for bare except and "except ()" are sensible, using a proof by contradiction. Cheers, Cameron Simpson <cs@zip.com.au>
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-04-11 21:00 +1000 |
| Message-ID | <5528feec$0$13002$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88813 |
On Sat, 11 Apr 2015 07:27 pm, Cameron Simpson wrote:
> If the empty tuple were to mean "catch everything" then there would not be
> a way to express "catch nothing". Bad bad bad!
# Catch everything:
try:
spam()
except:
pass
# Catch nothing:
spam()
:-)
> Consider this a proof that Python's current meanings for bare except and
> "except ()" are sensible, using a proof by contradiction.
Given that Python 3 does not allow you to raise things which don't inherit
from BaseException, I wish that bare except clauses were dropped
altogether. In Python 3, the equivalent to "catch everything" is
spelled "except BaseException", which I think would be a lot less
attractive to beginners than bare "except:".
But I digress.
Yes, I agree that Python's behaviour here is better than the alternative.
Having "except ()" catch nothing is consistent with the behaviour with
other tuples, so I'm okay with that. But it still surprised me :-)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-04-11 21:21 +1000 |
| Message-ID | <mailman.220.1428751263.12925.python-list@python.org> |
| In reply to | #88818 |
On Sat, Apr 11, 2015 at 9:00 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > Yes, I agree that Python's behaviour here is better than the alternative. > Having "except ()" catch nothing is consistent with the behaviour with > other tuples, so I'm okay with that. But it still surprised me :-) It's worth noting that there's another false parallel here. Grouping nothing creates something. x = 1 # x is an integer x = (1) # ditto x = (((((((((1))))))))) # LITHP Okay, so adding parentheses does nothing, right? Right. x = # syntax error x = () # empty tuple "Parentheses around nothing" is NOT the same as "nothing". So if you compare against this, then it makes perfect sense for "except :" and "except ():" to be distinctly different. But I agree, it would be very nice if Python 3 could have abolished the truly confusing part of this, where "except:" catches everything. Forcing people to spell it "except BaseException:" would fix all of this. How hard is it to deprecate and then remove that, same as string exceptions were removed? You know what, I'm moving that to -ideas. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-04-11 12:49 -0600 |
| Message-ID | <mailman.228.1428778155.12925.python-list@python.org> |
| In reply to | #88818 |
[Multipart message — attachments visible in raw view] — view raw
On Apr 11, 2015 5:06 AM, "Steven D'Aprano" < steve+comp.lang.python@pearwood.info> wrote: > > Yes, I agree that Python's behaviour here is better than the alternative. > Having "except ()" catch nothing is consistent with the behaviour with > other tuples, so I'm okay with that. But it still surprised me :-) There's another alternative that I haven't seen suggested yet. An empty tuple could be considered an indication of a programming error and raise a chained ValueError.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-04-12 06:04 +1000 |
| Message-ID | <mailman.229.1428782701.12925.python-list@python.org> |
| In reply to | #88818 |
On Sun, Apr 12, 2015 at 4:49 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote: > On Apr 11, 2015 5:06 AM, "Steven D'Aprano" > <steve+comp.lang.python@pearwood.info> wrote: >> >> Yes, I agree that Python's behaviour here is better than the alternative. >> Having "except ()" catch nothing is consistent with the behaviour with >> other tuples, so I'm okay with that. But it still surprised me :-) > > There's another alternative that I haven't seen suggested yet. An empty > tuple could be considered an indication of a programming error and raise a > chained ValueError. Not really a lot of point. Just as with isinstance, an empty tuple simply matches nothing. Why go to the effort of rejecting it? ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-04-12 06:05 +1000 |
| Message-ID | <mailman.230.1428782737.12925.python-list@python.org> |
| In reply to | #88818 |
On Sun, Apr 12, 2015 at 6:04 AM, Chris Angelico <rosuav@gmail.com> wrote: > On Sun, Apr 12, 2015 at 4:49 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote: >> On Apr 11, 2015 5:06 AM, "Steven D'Aprano" >> <steve+comp.lang.python@pearwood.info> wrote: >>> >>> Yes, I agree that Python's behaviour here is better than the alternative. >>> Having "except ()" catch nothing is consistent with the behaviour with >>> other tuples, so I'm okay with that. But it still surprised me :-) >> >> There's another alternative that I haven't seen suggested yet. An empty >> tuple could be considered an indication of a programming error and raise a >> chained ValueError. > > Not really a lot of point. Just as with isinstance, an empty tuple > simply matches nothing. Why go to the effort of rejecting it? (At least, I assume you're not putting a literal empty tuple in. This would be useful only in cases where the tuple is provided dynamically.) ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-04-11 17:11 +1000 |
| Message-ID | <5528c906$0$12994$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88797 |
On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:
> On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote:
>>
>>> It isn't document because it is expected. Why would the exception get
>>> caught if you're not writing code to catch it? If you write a function
>>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>>> expect it to catch an exception not in the tuple. Just because the
>>> tuple
>>> is empty doesn't mean that it should catch *everything* instead. That
>>> would be counter-intuitive.
>>
>> Really? I have to say, I expected it.
>>
>>
>
> I'm astounded at your expectation. That's like saying a for loop on an
> empty list ought to loop on all possible objects in the universe.
Not really.
If we wrote:
for x in:
# Missing sequence leads to an infinite loop
*then* your analogy would be excellent, but it isn't. With for loops, we
iterate over each item in the sequence, hence an empty sequence means we
don't iterate at all.
But with try...except, an empty exception list means to catch *everything*,
not nothing:
try: ...
except a,b,c: # catches a, b, c
try: ...
except a,b: # catches a, b
try: ...
except a: # catches a
try: ...
except: # catches EVERYTHING, not nothing
Putting (a, b, c) into a tuple shouldn't make a difference, and it doesn't,
unless the tuple is empty. That surprised me.
t = a, b, c
try:
except t: # same as except a,b,c
t = a, b
try:
except t: # same as except a,b
t = a,
try:
except t: # same as except a
t = ()
try:
except t: # NOT THE SAME as bare except.
I can see the logic behind the current behaviour. If you implement except
clauses like this pseudo-code:
for exc in exceptions:
if raised_exception matches exc: catch it
then an empty tuple will naturally lead to nothing being caught. That
doesn't mean it isn't surprising from the perspective that an empty
exception list (i.e. a bare except) should be analogous to an empty tuple.
> The tuple lists those exceptions you're interested in, and they are
> tried, presumably in order, from that collection. If none of those
> match, then the logic will advance to the next except clause. If the
> tuple is empty, then clearly none will match.
Yes, that makes sense, and I agree that it is reasonable behaviour from one
perspective. But its also reasonable to treat "except ():" as analogous to
a bare except.
[...]
>> try:
>> spam()
>> except:
>> # Implicitly an empty tuple.
>
> No, an omitted item is not the same as an empty tuple.
You are correct about Python as it actually is, but it could have been
designed so that except (): was equivalent to a bare except.
> If it were, then
> we wouldn't have the problem of bare excepts, which are so tempting to
> novices. There's plenty of precedent in many languages for a missing
> item being distinct from anything one could actually supply.
Let us put aside the fact that some people misuse bare excepts, and allow
that there are some uses for it. Now, in Python 2.6 and later, you can
catch everything by catching BaseException. But in older versions, you
could raise strings as well, and the only way to catch everything is with a
bare except.
If you want to write a function that takes a list of things to catch,
defaulting to "everything", in Python 2.6+ we can write:
def spam(things_to_catch=BaseException):
try:
do_stuff()
except things_to_catch:
handle_exception()
but in older versions you have to write this:
def spam(things_to_catch=None):
if things_to_catch is None:
try:
do_stuff()
except:
handle_exception()
else:
try:
do_stuff()
except things_to_catch:
handle_exception()
This violates Don't Repeat Yourself. Any time you have "a missing item being
distinct from anything one could actually supply", you have a poor design.
Anyway, in modern Python (2.6 onwards), now that string exceptions are gone,
you can supply something to catch everything. Or nothing, for that matter:
BaseException # catch everything
Exception # catch errors
(A, B, C) # Just A, B or C or their subclasses
A # Just A (or its subclasses)
() # Catch nothing.
so I suppose that having an empty tuple mean "catch nothing" is better than
having it catch everything.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Serhiy Storchaka <storchaka@gmail.com> |
|---|---|
| Date | 2015-04-11 11:22 +0300 |
| Message-ID | <mailman.215.1428740547.12925.python-list@python.org> |
| In reply to | #88806 |
On 11.04.15 10:11, Steven D'Aprano wrote: > Anyway, in modern Python (2.6 onwards), now that string exceptions are gone, > you can supply something to catch everything. Or nothing, for that matter: > > BaseException # catch everything Not everything. >>> class A: pass ... >>> try: raise A ... except BaseException: pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> __main__.A: <__main__.A instance at 0xb707982c>
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-04-11 20:47 +1000 |
| Message-ID | <5528fbdb$0$13010$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88809 |
On Sat, 11 Apr 2015 06:22 pm, Serhiy Storchaka wrote: > On 11.04.15 10:11, Steven D'Aprano wrote: >> Anyway, in modern Python (2.6 onwards), now that string exceptions are >> gone, you can supply something to catch everything. Or nothing, for that >> matter: >> >> BaseException # catch everything > > Not everything. > > >>> class A: pass > ... > >>> try: raise A > ... except BaseException: pass > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > __main__.A: <__main__.A instance at 0xb707982c> Hmmm, I thought that starting from 2.6 exceptions had to inherit from BaseException. Thanks for the correction. [steve@ando ~]$ python2.7 -c "class A: pass raise A()" Traceback (most recent call last): File "<string>", line 2, in <module> __main__.A: <__main__.A instance at 0xb7ebb1ac> [steve@ando ~]$ python3.3 -c "class A: pass raise A()" Traceback (most recent call last): File "<string>", line 2, in <module> TypeError: exceptions must derive from BaseException Ahah! So it's 3.x only that catching BaseException should catch everything. In 2.6, Python stopped supporting string exceptions: [steve@ando ~]$ python2.6 -c "raise 'spam'" Traceback (most recent call last): File "<string>", line 1, in <module> TypeError: exceptions must be old-style classes or derived from BaseException, not str (glad that at least I remembered that part correctly!) -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-04-11 06:14 -0400 |
| Message-ID | <mailman.218.1428747278.12925.python-list@python.org> |
| In reply to | #88806 |
On 04/11/2015 03:11 AM, Steven D'Aprano wrote: > On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote: > >> On 04/10/2015 09:42 PM, Steven D'Aprano wrote: >>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote: >>> >>>> It isn't document because it is expected. Why would the exception get >>>> caught if you're not writing code to catch it? If you write a function >>>> and pass it a tuple of exceptions to catch, I'm not sure why you would >>>> expect it to catch an exception not in the tuple. Just because the >>>> tuple >>>> is empty doesn't mean that it should catch *everything* instead. That >>>> would be counter-intuitive. >>> >>> Really? I have to say, I expected it. >>> >>> >> >> I'm astounded at your expectation. That's like saying a for loop on an >> empty list ought to loop on all possible objects in the universe. > > Not really. > > If we wrote: > > for x in: > # Missing sequence leads to an infinite loop > > *then* your analogy would be excellent, but it isn't. With for loops, we > iterate over each item in the sequence, hence an empty sequence means we > don't iterate at all. > > But with try...except, an empty exception list means to catch *everything*, > not nothing: No an empty exception list means to catch nothing. A *missing* exception list means catch everything, but that's a different syntax > > try: ... > except a,b,c: # catches a, b, c > > try: ... > except a,b: # catches a, b > > try: ... > except a: # catches a try: ... except (a,) #catches a try: ... except () #catches nothing, as expected > > try: ... > except: # catches EVERYTHING, not nothing > Different syntax. No reason for it to pretend that it's being given an empty tuple or list. > > Putting (a, b, c) into a tuple shouldn't make a difference, and it doesn't, > unless the tuple is empty. That surprised me. > > t = a, b, c > try: > except t: # same as except a,b,c > > t = a, b > try: > except t: # same as except a,b > > t = a, > try: > except t: # same as except a > > t = () > try: > except t: # NOT THE SAME as bare except. Of course not. It's empty, so it catches nothing. Just like 'for' > > > I can see the logic behind the current behaviour. If you implement except > clauses like this pseudo-code: > > > for exc in exceptions: > if raised_exception matches exc: catch it > > > then an empty tuple will naturally lead to nothing being caught. That > doesn't mean it isn't surprising from the perspective that an empty > exception list (i.e. a bare except) should be analogous to an empty tuple. Why should it?? It's a different syntax, with different rules. Perhaps it should have been consistent, but then it's this statement that's surprising, not the behavior with an empty tuple. > > >> The tuple lists those exceptions you're interested in, and they are >> tried, presumably in order, from that collection. If none of those >> match, then the logic will advance to the next except clause. If the >> tuple is empty, then clearly none will match. > > Yes, that makes sense, and I agree that it is reasonable behaviour from one > perspective. But its also reasonable to treat "except ():" as analogous to > a bare except. > > [...] >>> try: >>> spam() >>> except: >>> # Implicitly an empty tuple. >> >> No, an omitted item is not the same as an empty tuple. > > You are correct about Python as it actually is, but it could have been > designed so that except (): was equivalent to a bare except. Only by changing the bare except behavior. > > >> If it were, then >> we wouldn't have the problem of bare excepts, which are so tempting to >> novices. There's plenty of precedent in many languages for a missing >> item being distinct from anything one could actually supply. > > Let us put aside the fact that some people misuse bare excepts, and allow > that there are some uses for it. Now, in Python 2.6 and later, you can > catch everything by catching BaseException. But in older versions, you > could raise strings as well, and the only way to catch everything is with a > bare except. > > If you want to write a function that takes a list of things to catch, > defaulting to "everything", in Python 2.6+ we can write: > > def spam(things_to_catch=BaseException): > try: > do_stuff() > except things_to_catch: > handle_exception() > > > but in older versions you have to write this: > > def spam(things_to_catch=None): > if things_to_catch is None: > try: > do_stuff() > except: > handle_exception() > else: > try: > do_stuff() > except things_to_catch: > handle_exception() > > > This violates Don't Repeat Yourself. Any time you have "a missing item being > distinct from anything one could actually supply", you have a poor design. Yep, and it happens all the time. For example, mylist[a,b,-1] What value can I use for b to mean the whole list? There are others more grotesque, but I can't think of any at this moment. > > Anyway, in modern Python (2.6 onwards), now that string exceptions are gone, > you can supply something to catch everything. Or nothing, for that matter: > > BaseException # catch everything > Exception # catch errors > (A, B, C) # Just A, B or C or their subclasses > A # Just A (or its subclasses) > () # Catch nothing. > > so I suppose that having an empty tuple mean "catch nothing" is better than > having it catch everything. > Just like with all(()) and any(()), there's a logical way and an illogical way. An empty list means no items, not all possible items. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-04-11 06:24 -0400 |
| Message-ID | <mailman.219.1428747891.12925.python-list@python.org> |
| In reply to | #88806 |
On 04/11/2015 06:14 AM, Dave Angel wrote:
> On 04/11/2015 03:11 AM, Steven D'Aprano wrote:
>> On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:
>>
>>> On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
>>>> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82@gmail.com wrote:
>>>>
>>>>> It isn't document because it is expected. Why would the exception get
>>>>> caught if you're not writing code to catch it? If you write a
>>>>> function
>>>>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>>>>> expect it to catch an exception not in the tuple. Just because the
>>>>> tuple
>>>>> is empty doesn't mean that it should catch *everything* instead. That
>>>>> would be counter-intuitive.
>>>>
>>>> Really? I have to say, I expected it.
>>>>
>>>>
>>>
>>> I'm astounded at your expectation. That's like saying a for loop on an
>>> empty list ought to loop on all possible objects in the universe.
>>
>> Not really.
>>
>> If we wrote:
>>
>> for x in:
>> # Missing sequence leads to an infinite loop
>>
>> *then* your analogy would be excellent, but it isn't. With for loops, we
>> iterate over each item in the sequence, hence an empty sequence means we
>> don't iterate at all.
>>
>> But with try...except, an empty exception list means to catch
>> *everything*,
>> not nothing:
>
> No an empty exception list means to catch nothing. A *missing*
> exception list means catch everything, but that's a different syntax
>>
>> try: ...
>> except a,b,c: # catches a, b, c
>>
>> try: ...
>> except a,b: # catches a, b
>>
>> try: ...
>> except a: # catches a
>
> try: ...
> except (a,) #catches a
>
> try: ...
> except () #catches nothing, as expected
>
>>
>> try: ...
>> except: # catches EVERYTHING, not nothing
>>
>
> Different syntax. No reason for it to pretend that it's being given an
> empty tuple or list.
>
>>
>> Putting (a, b, c) into a tuple shouldn't make a difference, and it
>> doesn't,
>> unless the tuple is empty. That surprised me.
>>
>> t = a, b, c
>> try:
>> except t: # same as except a,b,c
>>
>> t = a, b
>> try:
>> except t: # same as except a,b
>>
>> t = a,
>> try:
>> except t: # same as except a
>>
>> t = ()
>> try:
>> except t: # NOT THE SAME as bare except.
>
> Of course not. It's empty, so it catches nothing. Just like 'for'
>
>>
>>
>> I can see the logic behind the current behaviour. If you implement except
>> clauses like this pseudo-code:
>>
>>
>> for exc in exceptions:
>> if raised_exception matches exc: catch it
>>
>>
>> then an empty tuple will naturally lead to nothing being caught. That
>> doesn't mean it isn't surprising from the perspective that an empty
>> exception list (i.e. a bare except) should be analogous to an empty
>> tuple.
>
> Why should it?? It's a different syntax, with different rules. Perhaps
> it should have been consistent, but then it's this statement that's
> surprising, not the behavior with an empty tuple.
>
>>
>>
>>> The tuple lists those exceptions you're interested in, and they are
>>> tried, presumably in order, from that collection. If none of those
>>> match, then the logic will advance to the next except clause. If the
>>> tuple is empty, then clearly none will match.
>>
>> Yes, that makes sense, and I agree that it is reasonable behaviour
>> from one
>> perspective. But its also reasonable to treat "except ():" as
>> analogous to
>> a bare except.
>>
>> [...]
>>>> try:
>>>> spam()
>>>> except:
>>>> # Implicitly an empty tuple.
>>>
>>> No, an omitted item is not the same as an empty tuple.
>>
>> You are correct about Python as it actually is, but it could have been
>> designed so that except (): was equivalent to a bare except.
>
> Only by changing the bare except behavior.
>
>>
>>
>>> If it were, then
>>> we wouldn't have the problem of bare excepts, which are so tempting to
>>> novices. There's plenty of precedent in many languages for a missing
>>> item being distinct from anything one could actually supply.
>>
>> Let us put aside the fact that some people misuse bare excepts, and allow
>> that there are some uses for it. Now, in Python 2.6 and later, you can
>> catch everything by catching BaseException. But in older versions, you
>> could raise strings as well, and the only way to catch everything is
>> with a
>> bare except.
>>
>> If you want to write a function that takes a list of things to catch,
>> defaulting to "everything", in Python 2.6+ we can write:
>>
>> def spam(things_to_catch=BaseException):
>> try:
>> do_stuff()
>> except things_to_catch:
>> handle_exception()
>>
>>
>> but in older versions you have to write this:
>>
>> def spam(things_to_catch=None):
>> if things_to_catch is None:
>> try:
>> do_stuff()
>> except:
>> handle_exception()
>> else:
>> try:
>> do_stuff()
>> except things_to_catch:
>> handle_exception()
>>
>>
>> This violates Don't Repeat Yourself. Any time you have "a missing item
>> being
>> distinct from anything one could actually supply", you have a poor
>> design.
>
> Yep, and it happens all the time. For example, mylist[a,b,-1] What
> value can I use for b to mean the whole list?
>
> There are others more grotesque, but I can't think of any at this moment.
>
>>
>> Anyway, in modern Python (2.6 onwards), now that string exceptions are
>> gone,
>> you can supply something to catch everything. Or nothing, for that
>> matter:
>>
>> BaseException # catch everything
>> Exception # catch errors
>> (A, B, C) # Just A, B or C or their subclasses
>> A # Just A (or its subclasses)
>> () # Catch nothing.
>>
>> so I suppose that having an empty tuple mean "catch nothing" is better
>> than
>> having it catch everything.
>>
>
> Just like with all(()) and any(()), there's a logical way and an
> illogical way. An empty list means no items, not all possible items.
>
A better analogy:
if item in mytuple:
process...
If mytuple is (), should this somehow turn into the equivalent of
if True:
of course not. If mytuple is an empty tuple, then the if never succeeds.
In this case, just like with the real try/except (before 2.6), if you
need to effectively make an infinite tuple, so that all possible items
would match, you'd need different syntax:
#No syntax needed for this case, we don't care what item is
process...
--
DaveA
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web