> Your magic template has apparently turned positional-or-keyword
parameters into keyword-only.  This means that every exception class that
you’d normally construct with positional args today (which apparently
includes even your example, since that’s what you did in version 1 and 2)
now requires keyword boilerplate on every line where you construct one.
And, since you generally construct and use a class many times, but only
define it once, that’s adding a lot more boilerplate than it’s saving.

In my mind, you're filling in a format string, so of course you're going to
give the values by name. But I can see how that would seem like a step
backwards compared to an exception with positional arguments. And yes,
taking arguments in the order they appear in the string is too much magic
and not intuitive.

> Also, even in the definition, while you are saving one line, you’re doing
it by replacing a standard idiom used all over Python that has an obvious
meaning, which nobody ever forgets how to write, with magic involving a
special name that’s unlike anything else in the stdlib, which many people
will forget how to write, forcing them to look up the docs or find an
example whenever they add the first new exception to a new module.

That seems overly pessimistic. If you can remember to extend a class, it's
not too much of a stretch to remember what aspect of it that you're
defining.

> Also, this doesn’t fill in the exception’s stored args. Is there a way to
fix that without requiring more boilerplate? Remember, stored args are
positional, not keywords. So, even if you can come up with some magic
(e.g., parsing the format string to sort the keywords in the order of first
appearance), that only helps the interpreter, not a human reader who sees
exc.args[2] in an except clause for an exception created with three keyword
args and has to guess which one is #2. Without explicitly listing the args
in order somewhere, how do you solve that? And is there a way to list the
named args of a function in order that’s less boilerplate than (but just as
understandable as) a def statement?

I don't see why you would want to access arguments by their position. Why
wouldn't you access them by name? ie: exc.action
The user-defined exceptions in the Python documentation don't pass
arguments to the base class either:
https://docs.python.org/3/tutorial/errors.html#user-defined-exceptions


So let's go ahead and assume my implementation is flawed. The fact that
people prefer to copy their format strings all over their projects implies
that the current exception scheme is suboptimal. Can we agree on that? If
not, there's no need to continue this discussion.

On Thu, Aug 8, 2019 at 4:12 PM Andrew Barnert <abarn...@yahoo.com> wrote:

> On Aug 8, 2019, at 08:52, Ryan Fox <r...@rcfox.ca> wrote:
> >
> > >>> class MyException(Exception):
> > ...     def __init__(self, action, context):
> > ...         super().__init__(f'Bad thing happened during {action} in
> {context}')
> > >>> raise MyException(current_action, current_context)
>
> ...
>
> > Version 2 looks simple enough to do, but all of the repetitious
> boilerplate adds up when several exception types need to be defined. (And
> it's even worse when you want all of your code to include typing
> annotations.) Most people don't bother.
> >
> > My proposal is a new exception class as the preferred base for
> user-defined exceptions:
> >
> > >>> class MyException(ExceptionTemplate):
> > ...    message = 'Bad thing happened during {action} in {context}'
> > >>> raise MyException(action=current_action, context=current_context)
>
> Does this really save boilerplate?
>
> Your magic template has apparently turned positional-or-keyword parameters
> into keyword-only.  This means that every exception class that you’d
> normally construct with positional args today (which apparently includes
> even your example, since that’s what you did in version 1 and 2) now
> requires keyword boilerplate on every line where you construct one. And,
> since you generally construct and use a class many times, but only define
> it once, that’s adding a lot more boilerplate than it’s saving.
>
> Also, even in the definition, while you are saving one line, you’re doing
> it by replacing a standard idiom used all over Python that has an obvious
> meaning, which nobody ever forgets how to write, with magic involving a
> special name that’s unlike anything else in the stdlib, which many people
> will forget how to write, forcing them to look up the docs or find an
> example whenever they add the first new exception to a new module.
>
> Also, this doesn’t fill in the exception’s stored args. Is there a way to
> fix that without requiring more boilerplate? Remember, stored args are
> positional, not keywords. So, even if you can come up with some magic
> (e.g., parsing the format string to sort the keywords in the order of first
> appearance), that only helps the interpreter, not a human reader who sees
> exc.args[2] in an except clause for an exception created with three keyword
> args and has to guess which one is #2. Without explicitly listing the args
> in order somewhere, how do you solve that? And is there a way to list the
> named args of a function in order that’s less boilerplate than (but just as
> understandable as) a def statement?
>
>
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/7R7OHZ5N7GZ3H77OOJMUXQTOMRY2BBFY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to