Awsome Python - chained exceptions

Rick Johnson rantingrickjohnson at gmail.com
Wed Feb 13 03:47:58 CET 2013


On Tuesday, February 12, 2013 12:15:29 AM UTC-6, Steven D'Aprano wrote:
> [snip inflammatory remarks]
> I thought I'd present a few of Python's more
> awesome features, starting with exception contexts.

Well that's great idea, however, in order to find this very "valuable" information the searcher must not only remember an unintuitive search tag, he must also remember /exactly/ how you misspelled the unintuitive search tag! I sure hope you have more of these "Awsome Python"'s to share because i fear this one will surely be forgotten in 2 days. 

> If you've ever written an exception handler, you've probably written a
> *buggy* exception handler:
>
> def getitem(items, index):
>     # One-based indexing.
>     try:
>         return items[index-1]
>     except IndexError:
>         print ("Item at index %d is missing" % index - 1)  # Oops!
>
>
> Unfortunately, when an exception occurs inside an except or finally
> block, the second exception masks the first, and the reason for the
> original exception is lost:
>
> py> getitem(['one', 'two', 'three'], 5)  # Python 2.6
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 6, in getitem
> TypeError: unsupported operand type(s) for -: 'str' and 'int'

But that's exactly what any sane person wants to happen. And i don't know why your error messages are so vague because i got this message (using IDLE):

py> getitem([1,2,3], 5)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    getitem([1,2,3], 5)
  File "<pyshell#1>", line 5, in getitem
    print ("Item at index %d is missing" % index - 1)  # Oops!
TypeError: unsupported operand type(s) for -: 'str' and 'int'

Which (by showing the offensive line) is quite clear to me. I even tried a simplified version on the command line (to make sure IDLE was not injecting anything) and got a better exception message, but sadly without the offending line:

py> try:
...     l[10]
... except IndexError:
...     "{0}".format(blah)
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
NameError: name 'blah' is not defined

But in either case, both forms of the message i got are far more helpful than the exception you posted. Did you trim the exception in an attempt to sensationalize the problem?

But who cares about the exception message python returned when there are /so/ many abominations in this code sample. I mean, i know this is an example, but it should not be an example of "how not to code"+"ANYTHING"+"!"*10

Some of the problems include:

1. You are using the print function (so we can assume you are using Python 3.x) but then you go and use that old ugly "%" string interpolation syntax crap! when you should have used the format method of strings.

    print("Item at index {0} is missing".format(index-1)) # Oops!
    
...Oh Steven, if you only knew how we interpreted the "Oops!", more like "Doh!".

2. Your stdout message is not only confusing, it's a freaking lie! 

    "Item at index %d is missing". 
    
...Steven, i can assure you that if "list[index]" raises an IndexError, the item is NOT /missing/. Neither the item OR the index even /exist/ as far as the sequence is concerned. Contrary to your naive beliefs, Python sequences are not initialized with every possible integer index (that the current machine can represent) just sitting around twiddling their thumbs complaining of boredom whilst waiting for a value to come along they can point to; can you imagine the memory usage of such a design (flaw)?

3. Your claim that the broken code in the "exception block" masks the exception that would have been raised by the code in the "try block" is false, because if it's true, then you'd better find the fool who told Python to mask the try block in the first place!

Got any more bright ideas DeAprano? (Oh gawd that felt good!)



More information about the Python-list mailing list