How to name Exceptions that aren't Errors

Discussion in 'Python' started by Leo Breebaart, Apr 7, 2005.

  1. I've recently become rather fond of using Exceptions in Python to
    signal special conditions that aren't errors, but which I feel
    are better communicated up the call stack via the exception
    mechanism than via e.g. return values.

    For instance, I'm thinking of methods such as:


    def run(self):
    """ Feed the input file to the simulator. """

    for linenr, line in enumerate(self.infile):
    try:
    current_values = self.parse_line(linenr, line)
    ==> except CommentLineException:
    continue
    results = self.do_one_simulation_step(current_values)
    self.process_simulation_results(results)


    which I use in order to discard comments from a file I'm parsing
    line-by-line.

    My question is twofold. First, I know that many programmers are
    violently opposed to using exceptions in this fashion, i.e. for
    anything other than, well, exceptional circumstances. But am I
    correct in thinking that in Python this usage is actually
    considered quite normal, and not frowned upon? Is my snippet
    above indeed sufficiently Pythonic?

    Second, purely as a question of aesthetics, I was wondering if
    the folks here might have any opinions about actual naming
    conventions for the exception classes used in this fashion.

    'CommentLineError' would clearly be wrong, but using the
    'Exception' prefix seems a bit redundant and pointless too. I
    suppose I could just call the exception "CommentLine" and leave
    it at that, but I don't know, maybe there's something better I'm
    overlooking.

    Any suggestions?

    --
    Leo Breebaart <>
     
    Leo Breebaart, Apr 7, 2005
    #1
    1. Advertising

  2. Leo Breebaart

    Steve Holden Guest

    Leo Breebaart wrote:
    > I've recently become rather fond of using Exceptions in Python to
    > signal special conditions that aren't errors, but which I feel
    > are better communicated up the call stack via the exception
    > mechanism than via e.g. return values.
    >

    Absolutely.

    > For instance, I'm thinking of methods such as:
    >
    >
    > def run(self):
    > """ Feed the input file to the simulator. """
    >
    > for linenr, line in enumerate(self.infile):
    > try:
    > current_values = self.parse_line(linenr, line)
    > ==> except CommentLineException:
    > continue
    > results = self.do_one_simulation_step(current_values)
    > self.process_simulation_results(results)
    >
    >
    > which I use in order to discard comments from a file I'm parsing
    > line-by-line.
    >

    This specific example assumes that it isn't possible to easily determine
    by examination that the line is a comment, otherwise it's more readably
    re-cast as

    for linenr, line in enumerate(self.infile):
    if not isComment(line):
    current_values = self.parse_line(linenr, line)
    results = self.do_one_simulation_step(current_values)
    self.process_simulation_results(results)

    but the general point is still a valid one, so I'll assume you just
    grabbed something that was readily to hand.

    > My question is twofold. First, I know that many programmers are
    > violently opposed to using exceptions in this fashion, i.e. for
    > anything other than, well, exceptional circumstances. But am I
    > correct in thinking that in Python this usage is actually
    > considered quite normal, and not frowned upon? Is my snippet
    > above indeed sufficiently Pythonic?
    >

    Well, you will doubtless get as many opinions as you consult
    programmers, but in general there's much more tolerance in the Python
    world for such programming methods, and indeed much more tolerance
    generally than in some communities I've been a part of.

    > Second, purely as a question of aesthetics, I was wondering if
    > the folks here might have any opinions about actual naming
    > conventions for the exception classes used in this fashion.
    >
    > 'CommentLineError' would clearly be wrong, but using the
    > 'Exception' prefix seems a bit redundant and pointless too. I
    > suppose I could just call the exception "CommentLine" and leave
    > it at that, but I don't know, maybe there's something better I'm
    > overlooking.
    >

    Here you could be guided by the standard hierarchy, quoted here from the
    2.4 documentation:

    Exception
    +-- SystemExit
    +-- StopIteration
    +-- StandardError
    | +-- KeyboardInterrupt
    | +-- ImportError
    | +-- EnvironmentError
    | | +-- IOError
    | | +-- OSError
    | | +-- WindowsError
    | +-- EOFError
    | +-- RuntimeError
    | | +-- NotImplementedError
    | +-- NameError
    | | +-- UnboundLocalError
    | +-- AttributeError
    | +-- SyntaxError
    | | +-- IndentationError
    | | +-- TabError
    | +-- TypeError
    | +-- AssertionError
    | +-- LookupError
    | | +-- IndexError
    | | +-- KeyError
    | +-- ArithmeticError
    | | +-- OverflowError
    | | +-- ZeroDivisionError
    | | +-- FloatingPointError
    | +-- ValueError
    | | +-- UnicodeError
    | | +-- UnicodeEncodeError
    | | +-- UnicodeDecodeError
    | | +-- UnicodeTranslateError
    | +-- ReferenceError
    | +-- SystemError
    | +-- MemoryError
    +---Warning
    +-- UserWarning
    +-- DeprecationWarning
    +-- PendingDeprecationWarning
    +-- SyntaxWarning
    +-- OverflowWarning (not generated in 2.4; won't exist in 2.5)
    +-- RuntimeWarning
    +-- FutureWarning

    > Any suggestions?
    >

    Obviously *Error and *Warning predominate, but I would suggest it's
    largely a matter of code readability. I've even used an exception called
    Continue to overcome an irksome restriction in the language (you used
    not to be able to continue a loop from an except clause).

    As long as the intent of the code is obvious to the casual reader I
    suspect it's very unlikely you'll get complaints.

    except CommentLine:
    pass

    seems reasonably comprehensible, so time spent arguing about it would be
    better devoted to a discussion of the number of angels that could dance
    on the head of a pin.

    regards
    Steve
    --
    Steve Holden +1 703 861 4237 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
     
    Steve Holden, Apr 7, 2005
    #2
    1. Advertising

  3. Leo Breebaart

    F. Petitjean Guest

    Le 7 Apr 2005 19:23:21 GMT, Leo Breebaart a écrit :
    > I've recently become rather fond of using Exceptions in Python to
    > signal special conditions that aren't errors, but which I feel
    > are better communicated up the call stack via the exception
    > mechanism than via e.g. return values.
    >
    > For instance, I'm thinking of methods such as:
    >
    >
    > def run(self):
    > """ Feed the input file to the simulator. """
    >
    > for linenr, line in enumerate(self.infile):
    > try:
    > current_values = self.parse_line(linenr, line)
    >==> except CommentLineException:
    > continue
    > results = self.do_one_simulation_step(current_values)
    > self.process_simulation_results(results)
    >
    >
    > which I use in order to discard comments from a file I'm parsing
    > line-by-line.
    >

    [snip]
    > 'Exception' prefix seems a bit redundant and pointless too. I
    > suppose I could just call the exception "CommentLine" and leave
    > it at that, but I don't know, maybe there's something better I'm
    > overlooking.

    You are overlooking the fact the flow of information is pretty much
    linear. The comments lines can be safely ignored (filtered out) on the
    fly.
    enumerate filter-out
    infile(producer) --------> linenr, line -----------> linenr, line --->
    >
    > Any suggestions?

    From your parse_line() method extract the logic to detect a comment line
    put this code in a predicate function and use itertools.ifilter(pred,
    iterable). Much more explicit. parse_line() is simplified. The client
    code run() does not have to deal with bogus inputs anymore if you feed
    it with the filtered out stream.
    >
     
    F. Petitjean, Apr 7, 2005
    #3
  4. Leo Breebaart

    Max Guest

    Leo Breebaart wrote:
    > I've recently become rather fond of using Exceptions in Python to
    > signal special conditions that aren't errors, but which I feel
    > are better communicated up the call stack via the exception
    > mechanism than via e.g. return values.
    >


    Ummm... yeah, I quite agree.

    LOOK EVERYONE, it's Leo Breebart. This guys famous in the alternative
    universe of alt.fan.pratchett.

    You are the same Leo Breebart, right?

    Well done, APF9 is excellent. But what did we expect.

    --Max
     
    Max, Apr 7, 2005
    #4
  5. Leo Breebaart

    Aahz Guest

    In article <>,
    Leo Breebaart <> wrote:
    >
    >My question is twofold. First, I know that many programmers are
    >violently opposed to using exceptions in this fashion, i.e. for
    >anything other than, well, exceptional circumstances. But am I correct
    >in thinking that in Python this usage is actually considered quite
    >normal, and not frowned upon? Is my snippet above indeed sufficiently
    >Pythonic?


    Consider the use of StopIteration for ``for`` loops, and you will be
    Enlightened.
    --
    Aahz () <*> http://www.pythoncraft.com/

    "The joy of coding Python should be in seeing short, concise, readable
    classes that express a lot of action in a small amount of clear code --
    not in reams of trivial code that bores the reader to death." --GvR
     
    Aahz, Apr 7, 2005
    #5
  6. Max <rabkin@mweb[DOT]co[DOT]za> writes:

    > LOOK EVERYONE, it's Leo Breebart. You are the same Leo
    > Breebart, right?


    Breeb*aa*rt. But otherwise, yeah -- I do frequent more than just
    one newsgroup. :)


    > This guys famous in the alternative universe of
    > alt.fan.pratchett.


    I doubt anybody here cares! Who was it that said: "On the
    Internet, everyone's famous to fifteen other people"...?

    Anyways, regardless of any feeble claims to notoriety I may have
    in alternate universes, here in Python country I am but a humble
    grasshopper wot has only been programming in Python for slightly
    over a year now.

    *Dutch* grasshopper, though. Does that help any?

    --
    Leo Breebaart <>
     
    Leo Breebaart, Apr 7, 2005
    #6
  7. On Thu, 07 Apr 2005 15:40:24 -0400, Steve Holden <> wrote:

    >Leo Breebaart wrote:
    >> I've recently become rather fond of using Exceptions in Python to
    >> signal special conditions that aren't errors, but which I feel
    >> are better communicated up the call stack via the exception
    >> mechanism than via e.g. return values.
    >>

    >Absolutely.
    >
    >> For instance, I'm thinking of methods such as:
    >>
    >>
    >> def run(self):
    >> """ Feed the input file to the simulator. """
    >>
    >> for linenr, line in enumerate(self.infile):
    >> try:
    >> current_values = self.parse_line(linenr, line)
    >> ==> except CommentLineException:
    >> continue
    >> results = self.do_one_simulation_step(current_values)
    >> self.process_simulation_results(results)
    >>
    >>
    >> which I use in order to discard comments from a file I'm parsing
    >> line-by-line.


    It also possible for exception arguments to deliver a result, rather
    than indicate something rejected. E.g., you can terminate a recursive
    search via an exception. If no exception occurs, you have gone through
    the entire search space and not met the solution criterion.

    Regards,
    Bengt Richter
     
    Bengt Richter, Apr 8, 2005
    #7
  8. Leo Breebaart

    Roy Smith Guest

    Leo Breebaart <> wrote:

    > I've recently become rather fond of using Exceptions in Python to
    > signal special conditions that aren't errors, but which I feel
    > are better communicated up the call stack via the exception
    > mechanism than via e.g. return values.
    >
    > For instance, I'm thinking of methods such as:
    >
    >
    > def run(self):
    > """ Feed the input file to the simulator. """
    >
    > for linenr, line in enumerate(self.infile):
    > try:
    > current_values = self.parse_line(linenr, line)
    > ==> except CommentLineException:
    > continue
    > results = self.do_one_simulation_step(current_values)
    > self.process_simulation_results(results)


    I know this isn't the question you asked, but I would have written a little
    generator function which hides the comment processing in a lower level:

    def nonCommentLines (file):
    for lineNumber, line in enumerate (file):
    if not line.startswith('#'):
    yield lineNumber, line

    for lineNumber, line in nonCommentLines (sys.stdin):
    current_values = self.parse_line(linenr, line)
    results = self.do_one_simulation_step(current_values)
    self.process_simulation_results(results)

    This assumes you don't mind your line numbers starting from zero, but your
    version has the same behavior.

    > My question is twofold. First, I know that many programmers are
    > violently opposed to using exceptions in this fashion, i.e. for
    > anything other than, well, exceptional circumstances. But am I
    > correct in thinking that in Python this usage is actually
    > considered quite normal, and not frowned upon? Is my snippet
    > above indeed sufficiently Pythonic?


    I think my code is clearer, but I wouldn't go so far as to say I'm
    violently opposed to your code. I save violent opposition for really
    important matters like which text editor you use.

    I suspect if you showed your code to a C++ guy, he might be violently
    opposed. In C++, exceptions are perceived to be more heavyweight than they
    are in Python. Some of this is just perception (perhaps colored by
    historical issues with older C++ compilers not handling exceptions well),
    some of it is real. Just the other day, a colleague of mine was telling me
    about a bug in his code. It happened because he had failed to write a copy
    constructor for an exception class he wrote. The mind boggles how anybody
    can get anything useful done in a language like that. But I digress.

    In Python, exceptions seem to be the much more accepted way of doing
    things. You often see:

    try:
    value = dictionary[key]
    except KeyError:
    whatever

    instead of:

    if dictionary.has_key (key):
    value = dictionary[key]
    else:
    whatever

    While in C++, the "if" version would be far more common.

    > Second, purely as a question of aesthetics, I was wondering if
    > the folks here might have any opinions about actual naming
    > conventions for the exception classes used in this fashion.


    If you look at the list of standard exceptions (import exceptions and do a
    dir() on it), you'll see things like KeyboardInterrupt, StopIteration, and
    SystemExit. If the name fits, raise it.
     
    Roy Smith, Apr 8, 2005
    #8
  9. Leo Breebaart

    Steve Holden Guest

    Roy Smith wrote:
    [...]
    > I think my code is clearer, but I wouldn't go so far as to say I'm
    > violently opposed to your code. I save violent opposition for really
    > important matters like which text editor you use.


    +1 QOTW

    regards
    Steve
    --
    Steve Holden +1 703 861 4237 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
     
    Steve Holden, Apr 8, 2005
    #9
  10. Steve Holden wrote:
    > I've even used an exception called Continue to overcome an irksome
    > restriction in the language (you used not to be able to continue a
    > loop from an except clause).


    Out of curiosity, how could you use an exception to do that? I would
    think you would need to catch it and then use "continue", which wouldn't
    be possible because of the restriction you were trying to work around in
    the first place.
     
    Leif K-Brooks, Apr 8, 2005
    #10
  11. Leif K-Brooks wrote:
    > Steve Holden wrote:
    >
    >> I've even used an exception called Continue to overcome an irksome
    >> restriction in the language (you used not to be able to continue a
    >> loop from an except clause).

    >
    >
    > Out of curiosity, how could you use an exception to do that? I would
    > think you would need to catch it and then use "continue", which wouldn't
    > be possible because of the restriction you were trying to work around in
    > the first place.


    Here is a stupid way to calculate a 3-element median:

    class Success(Exception): pass

    def median_if_sorted(x,y,z):
    if x >= y >= z:
    raise Success(y)
    def median(a, b, c):
    try:
    median_if_sorted(a, b, c)
    median_if_sorted(c, b, a)
    median_if_sorted(a, c, b)
    median_if_sorted(c, a, b)
    median_if_sorted(b, a, c)
    median_if_sorted(b, c, a)
    except Success, instance:
    result, = instance.args
    return result
    else:
    raise ValueError, 'Nothing found'

    --Scott David Daniels
     
    Scott David Daniels, Apr 8, 2005
    #11
  12. Leo Breebaart

    Steve Holden Guest

    Leif K-Brooks wrote:
    > Steve Holden wrote:
    >
    >> I've even used an exception called Continue to overcome an irksome
    >> restriction in the language (you used not to be able to continue a
    >> loop from an except clause).

    >
    >
    > Out of curiosity, how could you use an exception to do that? I would
    > think you would need to catch it and then use "continue", which wouldn't
    > be possible because of the restriction you were trying to work around in
    > the first place.


    As long as the exception-handling code doesn't break then the loop
    automatically continues, so the trick was (IIRC) to have a loop body
    that essentially looked like this:

    for item in somelist:
    try:
    {loop body}
    except Continue:
    pass

    Then exceptions caught inside the loop body (which obviously had nested
    try: clauses) could raise Continue inside their except: clause to
    restart the loop at the next iteration.

    regards
    Steve
    --
    Steve Holden +1 703 861 4237 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
     
    Steve Holden, Apr 8, 2005
    #12
  13. On 7 Apr 2005 21:20:19 GMT, rumours say that Leo Breebaart
    <> might have written:

    [Max about Leo]
    >> This guys famous in the alternative universe of
    >> alt.fan.pratchett.


    The little imp stopped moving the memory blocks around as soon as it
    heard the distinct click of the name "Breebart"[1] falling into place.


    [1] "Breeb*aa*rt" you say. Ok then, double click.


    >I doubt anybody here cares!


    I WAS EXPECTING TO MEET THEE IN ALT.FAN.PRATCHETT.
    --
    TZOTZIOY, I speak England very best.
    "Be strict when sending and tolerant when receiving." (from RFC1958)
    I really should keep that in mind when talking with people, actually...
     
    Christos TZOTZIOY Georgiou, Apr 15, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Goldin

    Errors, errors, errors

    Mark Goldin, Jan 17, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    1,027
    Mark Goldin
    Jan 17, 2004
  2. Ahmed Moustafa
    Replies:
    5
    Views:
    30,122
    Chris Smith
    Jul 14, 2004
  3. Aaron W. LaFramboise
    Replies:
    4
    Views:
    364
  4. John Nagle
    Replies:
    11
    Views:
    535
    John Nagle
    Apr 27, 2007
  5. yawnmoth
    Replies:
    97
    Views:
    4,800
    Bent C Dalager
    Feb 27, 2009
Loading...

Share This Page