Let's get to the fundamental problem with this. It is DWIM magic, and 
you haven't (as far as I have seen) yet specified how we are supposed to 
use it or predict how it is supposed to work.

Here is your syntax again:

> >     def a_potentially_recursive_function(some, args) with 
> > ExceptionWeCareAbout:
> >         some.user_code()
> >         code_we_assume_is_safe()
> >         if args.something and some_condition:
> >             raise ExceptionWeCareAbout  # Line (A)
> >
> > How does the compiler know that *only* ExceptionWeCareAbout originating
> > in Line (A) should be re-raised, and any other location turned into
> > RuntimeError?
>
> Same way Rust decides whether to propagate or unwrap a Result: you
> *must* tell the compiler.

How do I tell the compiler? There is no sign in your syntax that Line
(A) is special or different from the rest of the lines in the function.

> > What if I factor out those last two lines and make it:
> >
> >     def a_potentially_recursive_function(some, args) with 
> > ExceptionWeCareAbout:
> >         some.user_code()
> >         code_we_assume_is_safe()
> >         check_condition_or_raise(args.something, some_condition)
> >
> > How does the compiler decide to re-raise exceptions originating in the
> > last line but not the first two?
>
> In this case, it explicitly doesn't.

So by refactoring a conditional raise (if condition: raise) into a
function, I completely change the meaning of the code? That's just
great. Not.


> You explicitly told it the last line doesn't raise any exceptions that
> contribute to your API's exception surface.

I did? I wasn't aware that I told the interpeter *explicitly* anything
about the last line. How does this work?

That's what I'm trying to understand about your proposal: I write a
function, and stick "with ExceptionName" into the function declaration
line:

    def function(some, args) with ExceptionWeCareAbout:

and then write a block of code under that declaration, and *somehow* in
some completely unspecified way the compiler Does What I Mean by
deciding that *some* of those lines which raise ExceptionWeCareAbout it
should let the exception through while *other* lines that raise the same
exception should be guarded against ExceptionWeCareAbout and have them
raise RuntimeError instead.

And I have no idea how it decides which lines are guarded and which are
not. You tell me that I explicitly instructed the compiler which
lines should be guarded, but I don't know how I did it.


> You *must* use try: check_condition_or_raise(args.something,
> some_condition) except ExceptionWeCareAbout: raise

But that's not what the pre-refactoring code had. All I did was move:

    # The original version, before refactoring.
    if args.something and some_condition:
        raise ExceptionWeCareAbout

into a named function and call that. In the original code, I didn't have
to explicitly catch the exception and then immediately re-raise it:

    # This was never used.
    try:
        if args.something and some_condition:
            raise ExceptionWeCareAbout
    except ExceptionWeCareAbout:
        raise

But now you are telling me that if I move the `if... raise` lines into a
function I have to also wrap it in a try...except, catch the exception,
and immediately and unconditionally re-raise it.

This behaviour may be clear to *you* but I cannot read your mind. Unless 
you actually tell me how the compiler knows which part of the block need 
to be guarded and which parts don't, I have no clue how this is 
happening except "the compiler magically infers what I want it to do".



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

Reply via email to