[Python-Dev] Re: PEP 654 -- Exception Groups and except* : request for feedback for SC submission

2021-03-04 Thread Irit Katriel via Python-Dev
On Thu, Mar 4, 2021 at 1:38 AM Glenn Linderman 
wrote:

> On 3/3/2021 2:49 PM, Irit Katriel via Python-Dev wrote:
>
> That's an interesting idea.
>
> Do you mean that one exception gets handled and the rest of the group is
> reraised? Or discarded?
>
> The value of sys.exc_info() (and the e in "except T as e:") needs to be a
> single naked exception. So if there is more than one match in the group we
> would need to pick one (let's say the first in DFS order).
>
> If we do this, then we have this situation. Before ExceptionGroups, you
> got to choose which of the exceptions you have is the most important, and
> you raised only that one. Now you raise a bunch of them and the order of
> the except clauses in caller's code determines which one of them counts and
> which ones are discarded. What do you make of that?
>
>
> You _could_ implement it as you said, but remember, you that with this
> idea, you are changing how except clauses work—so instead of making the
> order of the except clauses determine which one counts most, you could
> instead do something else.
>
> One alternative idea would be to take the "first in DFS order" and see if
> it matches any of the except clauses, and if so, process that one.  If not,
> then pick the next, and see if it matches, until one is found that matches,
> and can be processed.
>


Or we could make it explicit:

add an optional arg to ExceptionGroup like
ExceptionGroup("eg", list_of_exceptions, singleton=None)

In the example of atexit, where currently it raises only the last exception
from your callbacks, it will instead raise

ExceptionGroup("atexit errors", all_exceptions, singleton=last_exception)

Then except* works as before, ignoring the singleton.  But except matches
the singleton.

And there's no magic where you can be surprised about which exception
except chose to look at.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/LWIDPI5ZTXAPO4ATKBYRVZPUWHWVLSNT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Seeking review: Reinstate ability to run python.org locally with local PEPs repo

2021-03-04 Thread David Foster
The PEPs repo [1] has a README [2] with instructions for configuring a local 
installation of the python.org website such that you can develop PEPs locally 
and see how they will appear on python.org locally. However the README's 
instructions reference a python.org configuration setting (PEP_REPO_PATH) that 
appears to no longer exist.

So I reimplemented support for the PEP_REPO_PATH setting for local python.org 
installations and have a pull request out for review at [3] which has been 
seeking a reviewer for about 2 weeks. Is there someone on this list (or at some 
other particular location) who would be willing to give me a review?

[1]: https://github.com/python/peps
[2]: https://github.com/python/peps/blob/master/README.rst
[3]: https://github.com/python/pythondotorg/pull/1735

-- 
David Foster | Seattle, WA, USA
Contributor to TypedDict support for mypy
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/VYX5NIW2EDA7ZCKCURTK74U6RTQ6RGT3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 654 -- Exception Groups and except* : request for feedback for SC submission

2021-03-04 Thread Baptiste Carvello
Le 03/03/2021 à 23:49, Irit Katriel via Python-Dev a écrit :
> 
> On Wed, Mar 3, 2021 at 10:39 PM Greg Ewing  > wrote:
> 
> [...]
> In other words, the only difference between except and
> except* would be that multiple except* clauses can be run,
> whereas only one except clause will run (the first one that
> matches something in the ExceptionGroup).
> 
> Is there any good reason not to do things that way?
> 
> That's an interesting idea. 
> 
> Do you mean that one exception gets handled and the rest of the group is
> reraised? Or discarded?
> [...]

Hi,

I'll take a shoot at this, just to see how it tastes… So, let's say:

When an exception group reaches a set of traditional "except" clauses,
those are examined one after the other, in the order they are in the
code. That way, exceptions matched by several clauses will cause the
first one to run, same as today.

A subgroup is built with the subset of exceptions matched by the
examined clause, as the PEP specifies for "except*". If this subgroup is
None, the clause is not selected, and the next clause, if any, is
examined. On the contrary, if the subgroup contains at least one matched
exception, the clause is selected and no other clause will run (again,
same as today). Exceptions not part of the subgroup are discarded.

The clause body is then run just once (so the boss only gets one email
about KeyboardInterrupt). If the clause uses the "as" form, the "as"
variable is bound to one exception in the subgroup, which one is
unspecified (at least for now). The other ones are discarded, except if
a bare "raise" is reached (below).

If a bare "raise" is reached while executing the body, the selected
subgroup propagates out of the "try-except" construct. Justification:
the whole group cannot propagate, because today a bare "raise" cannot
reraise exceptions of a type not matched by the clause. However, if a
single-type exception group is handled similar to a single exception in
traditional "except" clauses, it is acceptable to let it propagate.

So you would have:

try:
g=BaseExceptionGroup(
[ValueError(), KeyboardInterrupt(), KeyboardInterrupt()])
raise g
except RuntimeError:   # doesn't match
log_the_error()
except  KeyboardInterrupt as e: # builds s=g.subgroup(KeyboardInterrupt)
email_the_boss(e)   # tells the boss of any one error
raise   # reraises s
except BaseException:   # would match, but doesn't run
launch_nuclear_attack()

# BaseExceptionGroup([KeyboardInterrupt(), KeyboardInterrupt()])
# propagates further, a traditional "except KeyboardInterrupt"
# would catch it. The ValueError is discarded.

An interesting feature would be: when the matching clause has no "as",
"except" behaves the same as "except*", apart from the fact that only
one clause may run.

Cheers,
Baptiste
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/EXC6BQVHQXUXBHIEWHLSLU6FY7SJKIF3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 654 -- Exception Groups and except* : request for feedback for SC submission

2021-03-04 Thread Sven R. Kunze

Hi Irit,

makes sense. So, in case of a *mixed-type ExceptionGroup,* SystemExit 
wins and forces the program to exit.



Could you add your reasoning to the PEP?


This would help future readers and illustrates the chain of thoughts. It 
might be obvious to you but from the outside it is really a long 
journey. I actually liked your wording below and the explicitly writing 
down the consequence I mentioned makes it very clear why this 
complication exists.


Best,
Sven

On 03.03.21 21:13, Irit Katriel wrote:


Hi Sven,

This is all about the popularity of "except Exception".

Look at the hierarchy of builtin exceptions: 
https://docs.python.org/3/library/exceptions.html#exception-hierarchy 



Most exceptions are subclasses of Exception. There are a few which are 
not, because they typically mean "this process should exit" so you 
should not usually handle them in your code. People use "except 
Exception" as a way to "catch almost everything, but not the critical 
stuff like SystemExit".


If we make ExceptionGroup be a BaseException, then "except Exception" 
doesn't catch it. So we make it a subclass of Exception. But then we 
can't make it wrap things like SystemExit, which people expect will 
not be caught by "except Exception".  So we add BaseExceptionGroup, 
which is a subclass of BaseException and therefore is not caught by 
"except Exception", so it can wrap SystemExit.


Why is the choice automated?  Because it can be. You look at what 
you're wrapping. If it's all subclasses of Exception, then it can be 
ExceptionGroup. If there are BaseExceptions, then it needs to be 
BaseExceptionGroup. There is no reason to ever do anything else.


I hope that makes sense.


On Wed, Mar 3, 2021 at 7:32 PM Sven R. Kunze > wrote:


Hey Irit,

find my 3 answers below:

On 03.03.21 13:17, Irit Katriel wrote:
> Hi Sven,
>
> I like your formatting suggestion, thanks. I will do something
like that.

You're welcome.

>
> I'm not sure I understand your question. ExceptionGroup is a
subclass
> of Exception (which is a subclass of BaseException). So
ExceptionGroup
> is caught by "except Exception" or "except BaseException".

1) So I understand "try-except BaseException" (cf.
concurrent.futures)
will work without fixes (i.e. produce the same results).


> BaseExceptionGroup is a subclass only of BaseException so it is
caught
> by "except BaseException" but not "except Exception". And
> ExceptionGroup is allowed to wrap only Exceptions while
BaseException
> can wrap Exceptions and and BaseExceptions. Makes sense?


2) Can you add motivating examples for "BaseExceptionGroup vs
ExceptionGroup" in the PEP? Right now, I only see what the
consequences
are but not why it was done this way.

3) Can you explain (and show the reasoning behind) this automatic
choice
in the PEP? Sounds a bit like hidden magic to me.


Referring to: "The difference between them is that ExceptionGroup can
only wrap Exception subclasses while BaseExceptionGroup can wrap any
BaseException subclass. A factory method that inspects the nested
exceptions and selects between ExceptionGroup and BaseExceptionGroup
makes the choice automatic."


Best
Sven


PS:

the reason why I was a bit puzzled by the
BaseExceptionGroup/ExceptionGroup issue is that:
- if it doesn't matter (so we do it automatically, because we do not
want to bother anybody), why do we need ExceptionGroup at all,
BaseExceptionGroup seems more flexible?
- if it does matter, why is the choice automatic and what if it
was the
wrong choice?


___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/NYBCJCQWEH3T4VMURSAP7S6AZKSFN2C7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 654 -- Exception Groups and except* : request for feedback for SC submission

2021-03-04 Thread Glenn Linderman

On 3/4/2021 1:41 AM, Irit Katriel wrote:



On Thu, Mar 4, 2021 at 1:38 AM Glenn Linderman > wrote:


On 3/3/2021 2:49 PM, Irit Katriel via Python-Dev wrote:

That's an interesting idea.

Do you mean that one exception gets handled and the rest of the
group is reraised? Or discarded?

The value of sys.exc_info() (and the e in "except T as e:") needs
to be a single naked exception. So if there is more than one
match in the group we would need to pick one (let's say the first
in DFS order).

If we do this, then we have this situation. Before
ExceptionGroups, you got to choose which of the exceptions you
have is the most important, and you raised only that one. Now you
raise a bunch of them and the order of the except clauses in
caller's code determines which one of them counts and which ones
are discarded. What do you make of that?


You _could_ implement it as you said, but remember, you that with
this idea, you are changing how except clauses work—so instead of
making the order of the except clauses determine which one counts
most, you could instead do something else.

One alternative idea would be to take the "first in DFS order" and
see if it matches any of the except clauses, and if so, process
that one.  If not, then pick the next, and see if it matches,
until one is found that matches, and can be processed.



Or we could make it explicit:

add an optional arg to ExceptionGroup like
ExceptionGroup("eg", list_of_exceptions, singleton=None)

In the example of atexit, where currently it raises only the last 
exception from your callbacks, it will instead raise


ExceptionGroup("atexit errors", all_exceptions, singleton=last_exception)

Then except* works as before, ignoring the singleton. But except 
matches the singleton.


And there's no magic where you can be surprised about which exception 
except chose to look at.


I like explicit, and avoiding magic.

And this gives a compatibility story for outer loops that except: 
Exception, and even for others cases that are not recoded for 
ExceptionGroup handling.


And I guess what you are citing is a precedent from atexit, for raising 
the last one.


And I guess in cases other than atexit, when raising an ExceptionGroup, 
the coder of the new feature would still get more of a choice about 
which Exception is more important, rather than the coder of the except 
clauses.  One could quibble that if ValueError and IndexError were both 
part of the ExceptionGroup, that if the except clauses expected either 
might happen, and listed them in ValueError and IndexError order, that 
the intention might have been that ValueError was more interesting to 
the except clause coder, whereas if the group is raised with the 
IndexError as the singleton, that the group coder has the opposite 
intention. I think it is more likely that the except clause coder simply 
knew they were mutually exclusive and that the order of the clauses 
didn't matter.


Thinking about the above a bit, the only existing except clause sequence 
that would matter would be if both a base exception class and a derived 
class were both listed in the except clauses.  The derived exception 
class should be listed before the base exception class or it wouldn't 
get processed. So it is not clear that the order of the except clauses 
really indicates any priority of interest on the part of the except 
clause coder?
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/UAHFZSVVHRABZ7UQLHVLSXS53YXRIFCC/
Code of Conduct: http://python.org/psf/codeofconduct/