Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!bcyclone01.am1.xlned.com!bcyclone01.am1.xlned.com!newsfeed.xs4all.nl!newsfeed4a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'syntax': 0.04; 'say,': 0.05; 'list?': 0.07; 'matches': 0.07; 'none:': 0.07; 'plenty': 0.07; 'suppose': 0.07; 'versions,': 0.07; 'advance': 0.07; 'string': 0.09; 'difference,': 0.09; 'except:': 0.09; 'expected.': 0.09; 'iterate': 0.09; 'logic': 0.09; 'naturally': 0.09; 'pretend': 0.09; 'try:': 0.09; 'violates': 0.09; 'python': 0.11; 'def': 0.12; "wouldn't": 0.14; '#no': 0.16; '(),': 0.16; '(before': 0.16; 'behaviour.': 0.16; 'clause.': 0.16; 'clauses': 0.16; 'defaulting': 0.16; 'distinct': 0.16; 'empty,': 0.16; 'empty.': 0.16; 'excellent,': 0.16; 'ought': 0.16; 'really?': 0.16; 'rules.': 0.16; 'sense,': 0.16; 'sequence,': 0.16; 'subclasses': 0.16; 'surprising': 0.16; 'syntax,': 0.16; 'true:': 0.16; 'tuple': 0.16; 'tuple,': 0.16; 'tuple.': 0.16; 'exception': 0.16; 'sat,': 0.16; 'all.': 0.16; 'wrote:': 0.18; 'items.': 0.19; '>>>': 0.22; 'putting': 0.22; 'saying': 0.22; 'header:User- Agent:1': 0.23; 'instead.': 0.24; 'logical': 0.24; "shouldn't": 0.24; 'versions': 0.24; '(or': 0.24; 'equivalent': 0.26; 'this:': 0.26; 'pass': 0.26; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'correct': 0.29; 'am,': 0.29; 'raise': 0.29; "doesn't": 0.30; 'errors': 0.30; 'statement': 0.30; "i'm": 0.30; 'code': 0.31; '>>>>': 0.31; 'catching': 0.31; "d'aprano": 0.31; 'exceptions': 0.31; 'omitted': 0.31; 'steven': 0.31; 'yourself.': 0.31; 'lists': 0.32; 'languages': 0.32; '(i.e.': 0.33; 'not.': 0.33; 'older': 0.33; 'could': 0.34; 'problem': 0.35; 'subject:with': 0.35; "can't": 0.35; 'agree': 0.35; 'except': 0.35; 'skip:s 30': 0.35; 'something': 0.35; 'case,': 0.35; 'no,': 0.35; 'objects': 0.35; 'but': 0.35; 'there': 0.35; '2.6': 0.36; 'in:': 0.36; 'leads': 0.36; 'sequence': 0.36; 'next': 0.36; 'possible': 0.36; 'should': 0.36; 'behind': 0.37; 'changing': 0.37; 'example,': 0.37; 'turn': 0.37; 'list': 0.37; 'list.': 0.37; 'being': 0.38; 'expected': 0.38; 'implement': 0.38; 'needed': 0.38; 'to:addr:python-list': 0.38; 'fact': 0.38; 'pm,': 0.38; 'anything': 0.39; 'expect': 0.39; 'aside': 0.39; 'sure': 0.39; 'to:addr:python.org': 0.39; 'skip:* 10': 0.61; 'course': 0.61; "you're": 0.61; 'email addr:gmail.com': 0.63; 'real': 0.63; 'more': 0.64; 'different': 0.65; 'charset:windows-1252': 0.65; 'effectively': 0.66; 'design.': 0.68; 'received:74.208': 0.68; 'repeat': 0.74; 'behavior': 0.77; "'for'": 0.84; '2015': 0.84; 'bare': 0.84; 'collection.': 0.84; 'everything,': 0.84; 'everything.': 0.84; 'perspective.': 0.84; 'presumably': 0.84; 'process...': 0.84; 'received:74.208.4.194': 0.84; 'subject:..': 0.84; 'angel': 0.91; 'items,': 0.91; 'write:': 0.91 Date: Sat, 11 Apr 2015 06:24:38 -0400 From: Dave Angel User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: python-list@python.org Subject: Re: try..except with empty exceptions References: <64a75c32-e0ab-4ce0-9373-358c2669fe6e@googlegroups.com> <785010c0-6bcc-46d7-b7e0-0ed062fabbc7@googlegroups.com> <55287c0d$0$13000$c3e8da3$5496439d@news.astraweb.com> <5528c906$0$12994$c3e8da3$5496439d@news.astraweb.com> <5528F400.106@davea.name> In-Reply-To: <5528F400.106@davea.name> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:ypchqYx9tfrGDqvIcTyA4RSJX9BkLW34ANsee/x38Is30oGthyy rUmcY+iXOlZRbdv79MF+Kss3l83cGqDCrYweISTASuGl9Uea4Z1CzLeouVHrfnaZUStCy9c 340EIAfPMC03OiEC9v71mlsNeiIOXaWZ2mzGDUQW/c4x53ezRC0HDfO6cPqP5Rt8qqgh3Uv 9YuOfG23dFYO2mxKROPaQ== X-UI-Out-Filterresults: notjunk:1; X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 223 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1428747891 news.xs4all.nl 2958 [2001:888:2000:d::a6]:46672 X-Complaints-To: abuse@xs4all.nl X-Received-Bytes: 11569 X-Received-Body-CRC: 1297397654 Xref: csiph.com comp.lang.python:88815 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