On Thu, Sep 30, 2021 at 11:03 AM Soni L. <fakedme...@gmail.com> wrote:
>
> So uh, this is a hardly at all fleshed out idea, but one thing we really
> don't like about python is having to do stuff like this so as to not
> swallow exceptions:
>
> def a_potentially_recursive_function(some, args):
>   """
>   Does stuff and things.
>   Raises ExceptionWeCareAbout under so and so conditions.
>   """
>   try: some.user_code() except ExceptionWeCareAbout as exc: raise
> RuntimeError from exc
>   code_we_assume_is_safe()
>   if args.something and some_condition:
>     raise ExceptionWeCareAbout
>
> It'd be nice if there was a way to... make this easier to deal with.
> Perhaps something where, something like this:
>
> def a_potentially_recursive_function(some, args) with ExceptionWeCareAbout:
>   """
>   Does stuff and things.
>   Raises ExceptionWeCareAbout under so and so conditions.
>   """
>   some.user_code()
>   code_we_assume_is_safe()
>   if args.something and some_condition:
>     raise ExceptionWeCareAbout
>
> becomes:
>
> def a_potentially_recursive_function(some, args):
>   """
>   Does stuff and things.
>   Raises ExceptionWeCareAbout under so and so conditions.
>   """
>   try:
>     some.user_code()
>     code_we_assume_is_safe()
>     if args.something and some_condition:
>       let_exception_through = True
>       raise ExceptionWeCareAbout
>   except ExceptionWeCareAbout as exc:
>     if let_exception_through:
>       raise
>     else:
>       raise RuntimeError from exc
>
> (or equivalent)
>
> and something like:
>
> def foo() with Bar:
>   try: baz() except Bar: raise
>
> becomes:
>
> def foo():
>   try:
>     try:
>       baz()
>     except Bar:
>       allow_exception = True
>       raise
>   except Bar as exc:
>     if allow_exception:
>       raise
>     else:
>       raise RuntimeError from exc
>
> (thus allowing explicit exception propagation)
>
> Additionally, note that it would only apply to the raise itself -
> something like `raise may_raise_the_same_error()` would desugar as if:
>
> exception = may_raise_the_same_error()
> allow_exception = True
> raise exception
>
> Obviously this doesn't solve exception handling, doesn't require the
> caller to catch the exceptions, etc etc. It does, however, encourage
> better exception hygiene. Chances are something like this would
> significantly reduce the amount of swallowed exceptions, if it gets
> widely adopted. We know something like this would've saved us a lot of
> trouble, so we're sharing the idea in the hopes it can, in the future,
> help others.

Can you give a realistic example of how this works, and how you could
accidentally leak the exact same exception that you'd be intentionally
raising? It looks to me like you possibly should be splitting the
function into the recursive part and the setup part, where only the
setup is capable of raising that exception.

I've seen a LOT of bad Python code caused by an assumption that
"recursion" must always mean "calling the external API". A much better
model, in a lot of cases, is:

def _somefunc_recursive(x, y, z):
    ...
    _somefunc_recursive(x, y + 1, z - 1)

def somefunc(x, y, z=4):
    ...
    _somefunc_recursive(x, y, z)
    return someresult

ChrisA
_______________________________________________
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/XDLYGFSLSHRUV6RVCK65XHF46M3PEXBW/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to