[Python-ideas] Arguments to exceptions
Neil Girdhar
mistersheik at gmail.com
Thu Jul 6 14:26:41 EDT 2017
This is a good example. I like this idea. I think that a good place to
start would be setting the right example in the standard library:
IndexError could have the offending index, KeyError the offending key,
TypeError the offending type, etc.
On Monday, July 3, 2017 at 3:49:23 PM UTC-4, Jeff Walker wrote:
>
> Paul,
> I think you are fixating too much on Ken's example. I think I
> understand what he
> is saying and I agree with him. It is a problem I struggle with routinely.
> It occurs in
> the following situations:
>
> 1. You are handling an exception that you are not raising. This could be
> because
> Python itself is raising the exception, as in Ken's example, or it
> could be raised
> by some package you did not write.
> 2. You need to process or transform the message in some way.
>
> Consider this example:
>
> import json
>
>
>
> >>> s = '{"abc": 0, "cdf: 1}'
>
>
>
> >>> try:
>
> ... d = json.loads(s)
>
> ... except Exception as e:
>
> ... print(e)
>
> ... print(e.args)
> Unterminated string starting at: line 1 column 12 (char 11)
> ('Unterminated string starting at: line 1 column 12 (char 11)',)
>
> Okay, I have caught an exception for which I have no control over how the
> exception was raised. Now, imagine that I am writing an application that
> highlights
> json errors in place. To do so, I would need the line and column numbers
> to
> highlight the location of the error, and ideally I'd like to strip them
> from the base
> message and just show that. You can see from my second print statement
> that
> the line and column numbers were not passed as separate arguments. Thus
> I need to parse the error message to extract them. Not a difficult job,
> but fragile.
> Any change to the error message could break my code.
>
> I don't know what this code smell is that people keep referring to, but to
> me,
> that code would smell.
>
> Jeff
>
>
> > On 3 July 2017 at 09:59, Ken Kundert <python... at shalmirane.com
> <javascript:>> wrote:
> > > I think in trying to illustrate the existing behavior I made things
> more
> > > confusing than they needed to be. Let me try again.
> > >
> > > Consider this code.
> > >
> > > >>> import Food
> > > >>> try:
> > > ... import meals
> > > ... except NameError as e:
> > > ... name = str(e).split("'")[1] # <-- fragile code
> > > ... from difflib import get_close_matches
> > > ... candidates = ', '.join(get_close_matches(name, Food.foods,
> 1, 0.6))
> > > ... print(f'{name}: not found. Did you mean {candidates}?')
> > >
> > > In this case *meals* instantiates a collection of foods. It is a
> Python file,
> > > but it is also a data file (in this case the user knows Python, so
> Python is
> > > a convenient data format). In that file thousands of foods may be
> instantiated.
> > > If the user misspells a food, I would like to present the available
> > > alternatives. To do so, I need the misspelled name. The only way I
> can get it
> > > is by parsing the error message.
> >
> > As Steven pointed out, this is a pretty good example of a code smell.
> > My feeling is that you may have just proved that Python isn't quite as
> > good a fit for your data file format as you thought - or that your
> > design has flaws. Suppose your user had a breakfast menu, and did
> > something like:
> >
> > if now < lunchtim: # Should have been "lunchtime"
> >
> > Your error handling will be fairly confusing in that case.
> >
> > > That is the problem. To write the error handler, I need the
> misspelled name.
> > > The only way to get it is to extract it from the error message. The
> need to
> > > unpack information that was just packed suggests that the packing was
> done too
> > > early. That is my point.
> >
> > I don't have any problem with *having* the misspelled name as an
> > attribute to the error, I just don't think it's going to be as useful
> > as you hope, and it may indeed (as above) encourage people to use it
> > without thinking about whether there might be problems with using
> > error handling that way.
> >
> > > Fundamentally, pulling the name out of an error message is a really
> bad coding
> > > practice because it is fragile. The code will likely break if the
> formatting or
> > > the wording of the message changes. But given the way the exception
> was
> > > implemented, I am forced to choose between two unpleasant choices:
> pulling the
> > > name from the error message or not giving the enhanced message at all.
> >
> > Or using a different approach. ("Among our different approaches...!"
> > :-)) Agreed that's also an unpleasant choice at this point.
> >
> > > What I am hoping to do with this proposal is to get the Python
> developer
> > > community to see that:
> > > 1. The code that handles the exception benefits from having access to
> the
> > > components of the error message. In the least it can present the
> message to
> > > the user is the best possible way. Perhaps that means enforcing a
> particular
> > > style, or presenting it in the user's native language, or perhaps
> it means
> > > providing additional related information as in the example above.
> >
> > I see it as a minor bug magnet, but not really a problem in principle.
> >
> > > 2. The current approach to exceptions follows the opposite philosophy,
> > > suggesting that the best place to construct the error message is at
> the
> > > source of the error. It inadvertently puts obstacles in place that
> make it
> > > difficult to customize the message in the handler.
> >
> > It's more about implicitly enforcing the policy of "catch errors over
> > as small a section of code as practical". In your example, you're
> > trapping NameError from anywhere in a "many thousands" of line file.
> > That's about as far from the typical use of one or two lines in a try
> > block as you can get.
> >
> > > 3. Changing the approach in the BaseException class to provide the
> best of both
> > > approaches provides considerable value and is both trivial and
> backward
> > > compatible.
> >
> > A small amount of value in a case we don't particularly want to
> encourage.
> > Whether it's trivial comes down to implementation - I'll leave that to
> > whoever writes the PR to demonstrate. (Although if it *is* trivial, is
> > it something you could write a PR for?)
> >
> > Also, given that this would be Python 3.7 only, would people needing
> > this functionality (only you have expressed a need so far) be OK with
> > either insisting their users go straight to Python 3.7, or including
> > backward compatible code for older versions?
> >
> > Overall, I'm -0 on this request (assuming it is trivial to implement -
> > I certainly don't feel it's worth significant implementation effort).
> >
> > Paul
> _______________________________________________
> Python-ideas mailing list
> Python... at python.org <javascript:>
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170706/935cc572/attachment.html>
More information about the Python-ideas
mailing list