PEP 654 except* formatting
![](https://secure.gravatar.com/avatar/268ecf5b8a9a200b1ec33a1a165ae828.jpg?s=120&d=mm&r=g)
We wonder if people have a view on which of the following is clearer/better: 1. except *E as e: // except *(E1, E2) as e: 2. except* E as e: // except* (E1, E2) as e: (The difference is in the whitespace around the *). At the moment * is a separate token so both are allowed, but we could change that (e.g., make except* a token), and in any case we need to settle on a convention that we use in documentation, etc. It is also not too late to opt for a completely different syntax if a better one is suggested.
![](https://secure.gravatar.com/avatar/4092f24df6ef679499c0a914a76bd4e6.jpg?s=120&d=mm&r=g)
On 03/10/2021 16:54, Thomas Grainger wrote:
I don't think X[Y | Z] is close to any syntax match currently allows. But... I have long thought that the interpreter's exception matching abilities were underused by the language. Maybe this is an opportunity for something else interesting, in general? The problem being, besides the general extra complexity, that the match statement's variable capture semantics are different to the `as name` syntax already used by the except statement.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
We’ll, typically you don’t explicitly mention ExceptionGroup — it’s implied by the ‘except*’ syntax. Introducing match semantics probably wouldn’t open up new functionality, you can already write ‘except (E1, E2):’. On Sun, Oct 3, 2021 at 09:00 Thomas Grainger <tagrain@gmail.com> wrote:
-- --Guido (mobile)
![](https://secure.gravatar.com/avatar/4092f24df6ef679499c0a914a76bd4e6.jpg?s=120&d=mm&r=g)
On 03/10/2021 16:47, Irit Katriel via Python-Dev wrote:
1. except *E as e: // except *(E1, E2) as e: 2. except* E as e: // except* (E1, E2) as e:
I vote #2, because `except *(e1, e2) as e:` could imply that this is splatting an arbitrary expression there - it looks like it will match any number of dynamically chosen exception types.
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Tue, Oct 5, 2021 at 10:51 AM Patrick Reader <_@pxeger.com> wrote:
But it only looks like splatting because you changed it from `(E1, E2)` to `(e1, e2)` where Title Case names will look like a matched type and lower case names will look like destination names. So, given these will be class names and 99.9% Title Case, Option 1 does not really fail under your suggested confusion here.
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Tue, Oct 05, 2021 at 11:17:25AM -0400, Calvin Spealman wrote:
It's the asterisk `*`, not the case of the names, that makes it look like sequence unpacking. Sequence unpacking works on sequences of types or other names that start with capital letters. There is no difference between unpacking a tuple of classes with a capital letter and a tuple of classes with names that start with lower case letters: a, b, c = *(ValueError, TypeError, Exception) a, b, c = *(int, float, str) Shockingly, we can even use mixed case and unusual naming conventions! obj, Module = (None, sys) *wink*
![](https://secure.gravatar.com/avatar/d995b462a98fea412efa79d17ba3787a.jpg?s=120&d=mm&r=g)
On Sun, 3 Oct 2021 at 16:55, Irit Katriel via Python-Dev <python-dev@python.org> wrote:
I prefer (1). I never liked C declarations where the * was attached to the type rather than the variable, and I have the same dislike here.
At the moment * is a separate token so both are allowed, but we could change that (e.g., make except* a token), and in any case we need to settle on a convention that we use in documentation, etc.
Having said the above, it's a matter of taste/preference, so I think that allowing both is the correct thing to do.
It is also not too late to opt for a completely different syntax if a better one is suggested.
Let's stick with "except *". It doesn't seem productive to have another round of bikeshedding at this point, unless there's a really compelling technical reason (i.e., something significantly more than mere bikeshedding). Paul
![](https://secure.gravatar.com/avatar/d91ce240d2445584e295b5406d12df70.jpg?s=120&d=mm&r=g)
except* looks like the exception statement has a footnote, which isn't wrong. *(E1, E2) looks like they are being unpacked, which is wrong. -jJ
![](https://secure.gravatar.com/avatar/24b80e6028805be74bebd77879301855.jpg?s=120&d=mm&r=g)
I agree that *(E1, E2) looks like unpacking, how about except *E1 as error: ... except (*E1, *E2) as error: ... even better would be if we could drop the braces: except *E1, *E2 as error: ...
![](https://secure.gravatar.com/avatar/53c166c5e1f0eef9ff4eb4d0b6ec9371.jpg?s=120&d=mm&r=g)
It seems like, for this to work, "group" would have to become a keyword. This would play havoc with a lot of existing code. I can't tell you how many times I've used the identifier "group" in my code, particularly when dealing with regular expressions. Even making it a soft keyword, a la "await" in 3.5, would lead to ambiguity: group = KeyboardInterrupt try: while True: print("thou can only defeat me with Ctrl-C") except group as error: print("lo, thou hast defeated me") //arry/ On 10/6/21 2:12 AM, Barry Warsaw wrote:
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 6 Oct 2021, at 12:06, Larry Hastings <larry@hastings.org> wrote:
It seems like, for this to work, "group" would have to become a keyword.
No, just like `match` and `case` didn't have to.
This would play havoc with a lot of existing code.
Extraordinary claims require extraordinary evidence, Larry. I maintain this will be entirely backwards compatible.
Two things: 1. This is a convoluted example, I bet $100 you won't find such an `except group` statement in any code predating my e-mail 🤠 Sure, sometimes (very rarely) it's useful to gather exceptions in a variable. But I'm pretty sure `group` won't be the name chosen for it. 2. While non-obvious, the example is not ambiguous. There can only be one parsing rule fitting this: 'except' expression 'as' NAME ':' Note how this is different from: 'except' 'group' expression 'as' NAME ':' There could be confusion if except-star, whatever its name is going to be, supported an empty "catch all" variant like `except:`. Thankfully, this is explicitly listed as a no-go in PEP 654. So `except group:` remains unambiguous. We can even make its error message smarter than the default NameError, since -- as I claim -- it's terribly unlikely somebody would mean to name their dynamic exception collection "group". - Ł
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Haha, let's see if we can write a Mersienne twister all inside an except statement 👨🏻🔬 Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory! In practice, however, PEG is satisfied with the first rule that matches entirely, so this is a matter of choosing correct precedence. In this case, it seems it would make sense for "old-style" except to come first because your (convoluted! 🤠) example is potentially useful, whereas "except +TimeoutError:" is pure nonsense. I will prototype a PR for this just so we can play with it. - Ł
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Łukasz Langa wrote:
Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory!
Another option (to remove the ambiguity) could be to move the “group” after the expression. Bonus points for reading more clearly: except MemoryError group as e: … except (KeyError, IndexError) group as e: … except some + expression group as e: … And edge-cases like this still work normally: except some + group as e: …
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Wed, Oct 6, 2021 at 12:01 PM Brandt Bucher <brandtbucher@gmail.com> wrote:
I like the clarity of this a lot. +100
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Oct 6, 2021 at 9:01 AM Brandt Bucher <brandtbucher@gmail.com> wrote:
Argh. This would be very easy to overlook. As the senior author of PEP 654 I am going to go with "except*". Since it was shown that "except group" has ambiguous edge cases the proposals have gotten worse, which to me is a good sign that we need to stop. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Łukasz Langa wrote:
Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory!
The ambiguity with function calls, though, is probably a dealbreaker: except group (E1, E2) as e: … except group(E1, E2) as e: … See my other message for an alternative (putting “group” after the expression). Brandt
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Ding ding, we have a winner. This single-handedly kills the "except group" syntax proposal.
See my other message for an alternative (putting “group” after the expression).
It's interesting but at this point not so clearly better than except* to my eyes. Unless everybody else loves it, I don't think we'll go there. - Ł
![](https://secure.gravatar.com/avatar/53c166c5e1f0eef9ff4eb4d0b6ec9371.jpg?s=120&d=mm&r=g)
On 10/6/21 2:34 PM, Łukasz Langa wrote:
My claim is that making "group" a hard-coded keyword, visible at all times, and thus no longer permitting use of "group" as an identifier, would play havoc with a lot of existing code. I don't think it's an extraordinary claim to say that "group" is a reasonably popular identifier. For example, I offer the 1,117 uses of the word "group" in the Python 3.10.0 Lib/ directory tree. (I admit I didn't review them all to see which ones were actual identifiers, and which ones were in strings or documentation.) If the proposal is to add it as some "it's only a keyword in this context" magic thing, a la how "async"/"await" were "soft keywords" in 3.5, and if we otherwise would permit the word "group" to be used as an identifier in perpetuity--okay, it won't cause this problem.
I concede I don't completely understand PEP 654 yet, much less the counter-proposals flying around right now. But it does seem like "except group" has the potential to be ambiguous, given that "group" is a reasonably popular identifier. //arry/
![](https://secure.gravatar.com/avatar/61a537f7b31ecf682e3269ea04056e94.jpg?s=120&d=mm&r=g)
I don't like `except group` or any variant with soft keywords. I'll list a few reasons here: 1. `try: .. except group:` is a valid syntax today. And it will continue to be valid syntax. Having both `try: .. except group:` (catch exception `group`) and `try: .. except group E:` (catch exceptions of E into a group) in the same grammar worries me. 1a. It can be especially confusing if someone has a local/global variable called `group`. 1b. Or, for example, if a user forgets to type `E` and leaves just `except group` it would fallback to the regular try..except behavior. And it would be a runtime error ("group" is undefined). 1c. This will be all even more complicated because syntax highlighters in IDEs and on sites like GitHub will likely just always highlight `except group` as a pair of keywords (even in `except group:` variant). 2. I'm not sure I like the "sound" of it. IMO it would make more sense to write `except all E`, but `all()` is a built-in and so this would be at odds with (1). 3. This is a niche feature. People who use async/await will get used to `except*` in no time. `except*` is also about unpacking in some metaphysical sense (looks similar enough to `*args` in function signatures to me) so I think it reads just fine. So I'm -1 on `except group` or any variant that uses soft keywords. If the SC considers making `group` a proper keyword I can possibly change my mind on this. Yury On Tue, Oct 5, 2021 at 6:28 PM Barry Warsaw <barry@python.org> wrote:
-- Yury
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 6 Oct 2021, at 18:05, Yury Selivanov <yselivanov.ml@gmail.com> wrote:
I don't like `except group` or any variant with soft keywords.
As Brandt just commented, this proposal is a no go due to confusion with function calls. I'll respond below anyway because looking through it was an interesting experience
This is a valid point, also raised by Pablo over WhatsApp (which happens to work today!). The particular hairy example has to do with your next point so let's go there first...
1b. Or, for example, if a user forgets to type `E` and leaves just `except group` it would fallback to the regular try..except behavior. And it would be a runtime error ("group" is undefined).
Right. Worse yet, this wouldn't be a runtime error UNLESS user code raises an exception within that try: block. Otherwise Python would happily take the unbound name and run with it:
When you raise:
During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 3, in <module> NameError: name 'group' is not defined This is pretty confusing and in my eyes disqualifies the "except group" proposal. Pablo also claims it would be very hard to generate good error messages due to this and I can see why. My initial idea here was to modify this received `NameError` just like we do in other cases with the new "Did you mean" helper:
We could potentially do something similar to generate better error messages for "except group" confusion, right? Only we can't if `group` happens to be bound as a name in a reachable scope which Larry points out is a popular name. In this scenario any syntax errors would end up with terribly confusing TypeErrors or AttributeErrors and so on. This is unacceptable.
1c. This will be all even more complicated because syntax highlighters in IDEs and on sites like GitHub will likely just always highlight `except group` as a pair of keywords (even in `except group:` variant).
This would a minor annoyance but definitely true.
2. I'm not sure I like the "sound" of it. IMO it would make more sense to write `except all E`, but `all()` is a built-in and so this would be at odds with (1).
That I disagree with. "except KeyError" reads like "except if there's a KeyError". "except group KeyError" reads like "except if there's a group of KeyErrors". And if you said, "except group KeyError as eg", an ExceptionGroup with KeyErrors would be exactly what you're getting under `eg`.
3. This is a niche feature. People who use async/await will get used to `except*` in no time. `except*` is also about unpacking in some metaphysical sense (looks similar enough to `*args` in function signatures to me) so I think it reads just fine.
Agreed. Except-star will be fine, too.
So I'm -1 on `except group` or any variant that uses soft keywords. If the SC considers making `group` a proper keyword I can possibly change my mind on this.
Making `group` a proper keyword is a no go. With Brandt's arguments, the entire idea is a no go. It's a bummer but I have to agree with the concerns raised. - Ł
![](https://secure.gravatar.com/avatar/be200d614c47b5a4dbb6be867080e835.jpg?s=120&d=mm&r=g)
On 10/6/2021 5:05 PM, Yury Selivanov wrote:
For the record (and I'm sure I'm not the only one), I'm -100 on making it a proper keyword. That would be disastrous (e.g. re.Match.group() becomes unusable). A soft keyword, punctuation, or magic builtin are the only possibilities here. "except all ..." is viable, since it's already a builtin that isn't useful as "except all:". But if that's the case, "except ExceptionGroup" is equally viable (with perhaps "except ExceptionGroup[Specific, Type]" for filtering?) I'm not going to argue against "except *", as that's already been accepted. But any alternative needs to: * break the same amount of existing code (i.e. none) * be equally/more readable and discoverable Since "except *" breaks *no* existing code, that's a pretty easy thing to check for in any alternative. But since "*" here has no precedent (as we've seen in this discussion), virtually any alternative is going to be more readable. So enjoy bikeshedding, everyone :) Please don't break any of our code. Cheers, Steve
![](https://secure.gravatar.com/avatar/77c28d84086eaacc4f606416ea70434d.jpg?s=120&d=mm&r=g)
Just my two small cents: soft keywords have a cost as they make everything around them more complicated in the parser. For example, creating custom error messages around soft keywords is one or two levels of magnitude more complicated as sometimes you need to parse segments of syntactically invalid code, with some generality (like "starts with this token and then anything can follow until this other token"). Soft keywords also make highlighters' life more complicated as it has already been discussed. And just to be clear: I am not saying they are bad, just that they are not free of cost.
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Sun, Oct 03, 2021 at 04:47:57PM +0100, Irit Katriel via Python-Dev wrote:
We wonder if people have a view on which of the following is clearer/better:
1. except *E as e: // except *(E1, E2) as e:
That looks like you're unpacking the tuple (E1, E2), and that's just misleading and wrong.
2. except* E as e: // except* (E1, E2) as e:
That looks like it is the "except" keyword which is special, not the tuple. If we're going to have yet another meaning for star (multiplication, replication, unpacking, powers, wildcard imports...) then I vote for 2. But Thomas Grainger's comment about match semantics got me thinking. I think his suggestion is a bit too verbose, but how do people feel about borrowing the vertical line and using it like this: except| E as e: except| (E1, E2) as e: Again, it's attached to the except keyword, to indicate that it's the keyword which is special, not a unary prefix operator on the E. The vertical line is suggestive of grouping something with a box around it: +-----------------+ | group of things | +-----------------+ and of the lines used in tracebacks shown in the PEP. So the output helps remind you of the syntax. -- Steve
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Interestingly, IIRC this was the original intention: `except *E as e` means you're unpacking E from some group. I agree this is a somewhat convoluted analogy and it breaks down in the presence of a tuple of exception names.
2. except* E as e: // except* (E1, E2) as e:
But Thomas Grainger's comment about match semantics got me thinking.
Uh oh ;-)
-1 If I could read the vertical line as a pipe character, the expression would read "except or E as e". But I can't read it that way anyway. Instead, all I see is a lowercase EXCEPTL. My idea is this: try: ... except group E as e: ... except group E1, T2 as e: ... Should be doable given the magical match-case contextual keywords precedent. This looks nice and is explicit, since you will always get an ExceptionGroup instance under `e`. But I know it's a bit late for bikeshedding this thing so if we want to be conservative and stick to the current syntactical options already defined in PEP 654, I'm voting Option 2 (given the awkwardness of the *(E1, E2) example). - Ł
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:28 AM Irit Katriel via Python-Dev < python-dev@python.org> wrote:
We're going around in circles. We considered 'catch' early on, but decided against it since, comparing 'except E' and 'catch E', there would be no good way to tell which is the recommended one (and the same would apply to another single keyword like 'handle'). At least with 'except*', it's easy to remember that this is a modified version of 'except', so it's probably meant for a special case. I also think that the bar should be pretty high before we reopen the *syntax* -- the PEP was approved without anyone (neither the SC, nor Nathaniel, nor anyone else) providing any feedback on the use of 'except *'. So I think it's a bit late to be bikeshedding the syntax. This thread was meant to solicit feedback on how to *format* it: does the space go before or after the '*'. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Sun, Oct 03, 2021 at 11:34:55AM -0700, Guido van Rossum wrote:
`except* E`, otherwise it looks like unpacking E. Done! Bikeshedding is over! *wink* All joking aside, my preference is to put the star on the except, not the exceptions. I don't think I have anything more to say that hasn't already been said, so I'll bow out now. -- Steve
![](https://secure.gravatar.com/avatar/2dde9ab55441548a981af3e43639fcbd.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:40 PM Steven D'Aprano <steve@pearwood.info> wrote:
I think it's worth noting that the following is already legal: Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.
Indeed, when I first learned that you could do this (a few years ago IIRC), my first thought was to unpack the "exceptions" tuple with a star. It wasn't until I tried that and got a SyntaxError that I tried it the way shown here and it worked. Allowing `except *E` for this new feature would take that helpful-to-a-beginner SyntaxError and turn it into a subtle and unhelpful bug. Therefore my vote is for requiring `except* E` and keeping `except *E` as a SyntaxError.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 9:20 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
Therefore my vote is for requiring `except* E` and keeping `except *E` as a SyntaxError.
You can't do that with our current lexer+parser. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/d995b462a98fea412efa79d17ba3787a.jpg?s=120&d=mm&r=g)
On Mon, 4 Oct 2021 at 07:16, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Agreed. Having "except*" be a single token, distinguished from the pair of tokens "except" "*" only by the presence of whitespace, would be extremely confusing. And yes, I am aware that 3.as_integer_ratio() and 3. as_integer_ratio() are syntax errors, whereas 3 .as_integer_ratio() and 3 . as_integer_ratio() are valid. IMO, that's *also* very confusing, and serves as a warning to not do that again, and not as an example of how it's OK and we can do more of that... Paul
![](https://secure.gravatar.com/avatar/2dde9ab55441548a981af3e43639fcbd.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 1:24 AM Guido van Rossum <guido@python.org> wrote:
Then what is the purpose of this thread? I understood from the OP that the question was which to allow and which to prohibit. If it's impossible to require either or prohibit either because the lexer/parser can't tell the difference, then it's going to end up as a never-ending style argument just like C pointers, so what are we even discussing? (Other than an entirely different syntax, of course, which now seems like the logical way to go if we can't enforce a single way to do it with the original proposal.)
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
The question was about which style to *recommend* (a la PEP-8). On Mon, Oct 4, 2021 at 8:03 AM Jonathan Goble <jcgoble3@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 12:07 PM Guido van Rossum <guido@python.org> wrote:
The question was about which style to *recommend* (a la PEP-8).
I think the very fact that it can't (or is difficult) be enforced, and so in the wild we'll likely see variations that could lead to confusion, is enough reason to find an alternative syntax.
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/1fee087d7a1ca17c8ad348271819a8d5.jpg?s=120&d=mm&r=g)
On Mon, 4 Oct 2021 12:18:35 -0400 Calvin Spealman <cspealma@redhat.com> wrote:
How so? If style checkers are already able to check whitespace around operators, they should be to check whitespace in this instance as well. Do you suggest that PEP 8 violations should be detected by the Python parser itself?
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 12:48 PM Antoine Pitrou <antoine@python.org> wrote:
1) I was basing the "can't enforce" on Guido's " You can't do that with our current lexer+parser." 2) Of course PEP 8 violations shouldn't be checked by the parser. That's why they're PEP 8 and not syntax rules. However, this doesn't look like style. This syntax is modifying either the `except` keyword for the exception type associated with it. Which does it modify? That the asterisk can be on either side of the whitespace feels very odd, in general but especially for Python syntax. That's why I'd opt for a variation that is either unambiguously attached to the left or right, or which is not connected to either, like the very clear `except group E` proposal. _______________________________________________
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/be200d614c47b5a4dbb6be867080e835.jpg?s=120&d=mm&r=g)
On 10/4/2021 5:47 PM, Antoine Pitrou wrote:
No, but if it isn't decided by *us*, it'll be decided by whoever contributes it to Black first. To me, the "*name" looks most similar to how we write "*args" in a function definition, so I'd go for that. We don't currently modify[1] keywords with punctuation, and that's what "except*" looks like, and "except * E" looks like a binary operator and/or grit on the screen. Cheers, Steve [1]: Meaning to "give it a different meaning in particular context", not _literally_ modify in any permanent sense.
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Mon, Oct 04, 2021 at 07:31:10PM +0100, Steve Dower wrote:
To me, the "*name" looks most similar to how we write "*args" in a function definition, so I'd go for that.
That's exactly why we *shouldn't* go for that option. That is going to confuse a lot of people that it is sequence unpacking. See for example Jonathon Goble's experience here: https://mail.python.org/archives/list/python-dev@python.org/message/2TBZZSMZ...
We don't currently modify[1] keywords with punctuation,
Star imports are a possible exception. But there we have no way of confusing the meaning.
When I saw the `except*` syntax first suggested, I was a little surprised because it did seem rather unusual for Python. But I grew up with FORTH where function names contain punctuation all the time, so I didn't think too much of it. I expected that the keyword literally would be `except*` and nothing but `except*`. If I had realised that the star would be free to wander around and that the syntax actually was r"except[ \t]*\*[ \t]*", I would have said something much earlier :-( -- Steve
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Mon, Oct 04, 2021 at 09:03:54AM -0700, Guido van Rossum wrote:
The question was about which style to *recommend* (a la PEP-8).
Quote: "At the moment * is a separate token so both are allowed, but we could change that (e.g., make except* a token)" If that is mistaken, that's fine, no harm done, but those of us who thought that enforcing one or the other form was on the table didn't imagine it :-) -- Steve
![](https://secure.gravatar.com/avatar/7f37d34f3bb0e91890c01450f8321524.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 10:47 AM Łukasz Langa <lukasz@langa.pl> wrote:
+1 on the `except* E` Option 2 syntax. It better conveys its uniqueness and non-relation to other meanings of *. Someone mentioned allowing both and letting people decide. Whatever is chosen, please not that. There should be only one way to write this. That avoids style arguments when no auto-formatter is involved. -gps
![](https://secure.gravatar.com/avatar/01aa7d6d4db83982a2f6dd363d0ee0f3.jpg?s=120&d=mm&r=g)
On Oct 3, 2021, at 10:42, Łukasz Langa <lukasz@langa.pl> wrote:
Speaking just for myself, the `except *` syntax always bothered me, but I couldn’t come up with anything better and it wasn’t enough for me to vote against PEP 654. `except group` is nicer though, and I would be in favor of that, or something like it. We could of course bike shed on the syntax forever. The PSC did vote to accept the PEP but we left room for changes while during the 3.11 cycle. -Barry
![](https://secure.gravatar.com/avatar/d6b9415353e04ffa6de5a8f3aaea0553.jpg?s=120&d=mm&r=g)
On 10/4/2021 9:57 AM, Ammar Askar wrote:
I agree for same reasons. And avoids more bikeshedding. I checked and if 'except group' is added to keyword.kwlist *before* 'except', the pair is recognized as a keyword phrase by IDLE's syntax highlighter without any change. ('except\s*group' would take care of variable spacing) -- Terry Jan Reedy
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Irit Katriel wrote:
It is also not too late to opt for a completely different syntax if a better one is suggested.
Honestly, I’ve never been a fan of the PEP’s proposed star syntax. If we’re okay adding a soft keyword, though, something like “except each” could help communicate the meaning of the blocks a bit more explicitly. I’m pretty sure that grammar would be unambiguous in all cases.
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:48 AM Irit Katriel via Python-Dev < python-dev@python.org> wrote:
It is difficult to understand why any special syntax is needed at all. ExceptionGroup is still an exception class like any other, isn't it? Why wouldn't the existing syntax suffice?
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 4 Oct 2021, at 15:00, Calvin Spealman <cspealma@redhat.com> wrote:
It is difficult to understand why any special syntax is needed at all. ExceptionGroup is still an exception class like any other, isn't it? Why wouldn't the existing syntax suffice?
This is covered at length in the PEP. Those sections specifically address this: https://www.python.org/dev/peps/pep-0654/#extend-except-to-handle-exception-... <https://www.python.org/dev/peps/pep-0654/#extend-except-to-handle-exception-...> https://www.python.org/dev/peps/pep-0654/#programming-without-except <https://www.python.org/dev/peps/pep-0654/#programming-without-except> - Ł
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
Rob Cliffe is having problems posting to the Python-Dev list, so he posted an alternative suggestion to the Python-Ideas list: https://mail.python.org/archives/list/python-ideas@python.org/message/6KQUQB... Rob's idea is to use "except for ..." with exception groups, instead of a new keyword or symbol. -- Steve
![](https://secure.gravatar.com/avatar/4092f24df6ef679499c0a914a76bd4e6.jpg?s=120&d=mm&r=g)
On 03/10/2021 16:54, Thomas Grainger wrote:
I don't think X[Y | Z] is close to any syntax match currently allows. But... I have long thought that the interpreter's exception matching abilities were underused by the language. Maybe this is an opportunity for something else interesting, in general? The problem being, besides the general extra complexity, that the match statement's variable capture semantics are different to the `as name` syntax already used by the except statement.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
We’ll, typically you don’t explicitly mention ExceptionGroup — it’s implied by the ‘except*’ syntax. Introducing match semantics probably wouldn’t open up new functionality, you can already write ‘except (E1, E2):’. On Sun, Oct 3, 2021 at 09:00 Thomas Grainger <tagrain@gmail.com> wrote:
-- --Guido (mobile)
![](https://secure.gravatar.com/avatar/4092f24df6ef679499c0a914a76bd4e6.jpg?s=120&d=mm&r=g)
On 03/10/2021 16:47, Irit Katriel via Python-Dev wrote:
1. except *E as e: // except *(E1, E2) as e: 2. except* E as e: // except* (E1, E2) as e:
I vote #2, because `except *(e1, e2) as e:` could imply that this is splatting an arbitrary expression there - it looks like it will match any number of dynamically chosen exception types.
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Tue, Oct 5, 2021 at 10:51 AM Patrick Reader <_@pxeger.com> wrote:
But it only looks like splatting because you changed it from `(E1, E2)` to `(e1, e2)` where Title Case names will look like a matched type and lower case names will look like destination names. So, given these will be class names and 99.9% Title Case, Option 1 does not really fail under your suggested confusion here.
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Tue, Oct 05, 2021 at 11:17:25AM -0400, Calvin Spealman wrote:
It's the asterisk `*`, not the case of the names, that makes it look like sequence unpacking. Sequence unpacking works on sequences of types or other names that start with capital letters. There is no difference between unpacking a tuple of classes with a capital letter and a tuple of classes with names that start with lower case letters: a, b, c = *(ValueError, TypeError, Exception) a, b, c = *(int, float, str) Shockingly, we can even use mixed case and unusual naming conventions! obj, Module = (None, sys) *wink*
![](https://secure.gravatar.com/avatar/d995b462a98fea412efa79d17ba3787a.jpg?s=120&d=mm&r=g)
On Sun, 3 Oct 2021 at 16:55, Irit Katriel via Python-Dev <python-dev@python.org> wrote:
I prefer (1). I never liked C declarations where the * was attached to the type rather than the variable, and I have the same dislike here.
At the moment * is a separate token so both are allowed, but we could change that (e.g., make except* a token), and in any case we need to settle on a convention that we use in documentation, etc.
Having said the above, it's a matter of taste/preference, so I think that allowing both is the correct thing to do.
It is also not too late to opt for a completely different syntax if a better one is suggested.
Let's stick with "except *". It doesn't seem productive to have another round of bikeshedding at this point, unless there's a really compelling technical reason (i.e., something significantly more than mere bikeshedding). Paul
![](https://secure.gravatar.com/avatar/d91ce240d2445584e295b5406d12df70.jpg?s=120&d=mm&r=g)
except* looks like the exception statement has a footnote, which isn't wrong. *(E1, E2) looks like they are being unpacked, which is wrong. -jJ
![](https://secure.gravatar.com/avatar/24b80e6028805be74bebd77879301855.jpg?s=120&d=mm&r=g)
I agree that *(E1, E2) looks like unpacking, how about except *E1 as error: ... except (*E1, *E2) as error: ... even better would be if we could drop the braces: except *E1, *E2 as error: ...
![](https://secure.gravatar.com/avatar/53c166c5e1f0eef9ff4eb4d0b6ec9371.jpg?s=120&d=mm&r=g)
It seems like, for this to work, "group" would have to become a keyword. This would play havoc with a lot of existing code. I can't tell you how many times I've used the identifier "group" in my code, particularly when dealing with regular expressions. Even making it a soft keyword, a la "await" in 3.5, would lead to ambiguity: group = KeyboardInterrupt try: while True: print("thou can only defeat me with Ctrl-C") except group as error: print("lo, thou hast defeated me") //arry/ On 10/6/21 2:12 AM, Barry Warsaw wrote:
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 6 Oct 2021, at 12:06, Larry Hastings <larry@hastings.org> wrote:
It seems like, for this to work, "group" would have to become a keyword.
No, just like `match` and `case` didn't have to.
This would play havoc with a lot of existing code.
Extraordinary claims require extraordinary evidence, Larry. I maintain this will be entirely backwards compatible.
Two things: 1. This is a convoluted example, I bet $100 you won't find such an `except group` statement in any code predating my e-mail 🤠 Sure, sometimes (very rarely) it's useful to gather exceptions in a variable. But I'm pretty sure `group` won't be the name chosen for it. 2. While non-obvious, the example is not ambiguous. There can only be one parsing rule fitting this: 'except' expression 'as' NAME ':' Note how this is different from: 'except' 'group' expression 'as' NAME ':' There could be confusion if except-star, whatever its name is going to be, supported an empty "catch all" variant like `except:`. Thankfully, this is explicitly listed as a no-go in PEP 654. So `except group:` remains unambiguous. We can even make its error message smarter than the default NameError, since -- as I claim -- it's terribly unlikely somebody would mean to name their dynamic exception collection "group". - Ł
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Haha, let's see if we can write a Mersienne twister all inside an except statement 👨🏻🔬 Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory! In practice, however, PEG is satisfied with the first rule that matches entirely, so this is a matter of choosing correct precedence. In this case, it seems it would make sense for "old-style" except to come first because your (convoluted! 🤠) example is potentially useful, whereas "except +TimeoutError:" is pure nonsense. I will prototype a PR for this just so we can play with it. - Ł
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Łukasz Langa wrote:
Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory!
Another option (to remove the ambiguity) could be to move the “group” after the expression. Bonus points for reading more clearly: except MemoryError group as e: … except (KeyError, IndexError) group as e: … except some + expression group as e: … And edge-cases like this still work normally: except some + group as e: …
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Wed, Oct 6, 2021 at 12:01 PM Brandt Bucher <brandtbucher@gmail.com> wrote:
I like the clarity of this a lot. +100
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Oct 6, 2021 at 9:01 AM Brandt Bucher <brandtbucher@gmail.com> wrote:
Argh. This would be very easy to overlook. As the senior author of PEP 654 I am going to go with "except*". Since it was shown that "except group" has ambiguous edge cases the proposals have gotten worse, which to me is a good sign that we need to stop. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Łukasz Langa wrote:
Joking aside, since we allow any expression after 'except' 'group' then this is indeed ambiguous. In theory!
The ambiguity with function calls, though, is probably a dealbreaker: except group (E1, E2) as e: … except group(E1, E2) as e: … See my other message for an alternative (putting “group” after the expression). Brandt
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Ding ding, we have a winner. This single-handedly kills the "except group" syntax proposal.
See my other message for an alternative (putting “group” after the expression).
It's interesting but at this point not so clearly better than except* to my eyes. Unless everybody else loves it, I don't think we'll go there. - Ł
![](https://secure.gravatar.com/avatar/53c166c5e1f0eef9ff4eb4d0b6ec9371.jpg?s=120&d=mm&r=g)
On 10/6/21 2:34 PM, Łukasz Langa wrote:
My claim is that making "group" a hard-coded keyword, visible at all times, and thus no longer permitting use of "group" as an identifier, would play havoc with a lot of existing code. I don't think it's an extraordinary claim to say that "group" is a reasonably popular identifier. For example, I offer the 1,117 uses of the word "group" in the Python 3.10.0 Lib/ directory tree. (I admit I didn't review them all to see which ones were actual identifiers, and which ones were in strings or documentation.) If the proposal is to add it as some "it's only a keyword in this context" magic thing, a la how "async"/"await" were "soft keywords" in 3.5, and if we otherwise would permit the word "group" to be used as an identifier in perpetuity--okay, it won't cause this problem.
I concede I don't completely understand PEP 654 yet, much less the counter-proposals flying around right now. But it does seem like "except group" has the potential to be ambiguous, given that "group" is a reasonably popular identifier. //arry/
![](https://secure.gravatar.com/avatar/61a537f7b31ecf682e3269ea04056e94.jpg?s=120&d=mm&r=g)
I don't like `except group` or any variant with soft keywords. I'll list a few reasons here: 1. `try: .. except group:` is a valid syntax today. And it will continue to be valid syntax. Having both `try: .. except group:` (catch exception `group`) and `try: .. except group E:` (catch exceptions of E into a group) in the same grammar worries me. 1a. It can be especially confusing if someone has a local/global variable called `group`. 1b. Or, for example, if a user forgets to type `E` and leaves just `except group` it would fallback to the regular try..except behavior. And it would be a runtime error ("group" is undefined). 1c. This will be all even more complicated because syntax highlighters in IDEs and on sites like GitHub will likely just always highlight `except group` as a pair of keywords (even in `except group:` variant). 2. I'm not sure I like the "sound" of it. IMO it would make more sense to write `except all E`, but `all()` is a built-in and so this would be at odds with (1). 3. This is a niche feature. People who use async/await will get used to `except*` in no time. `except*` is also about unpacking in some metaphysical sense (looks similar enough to `*args` in function signatures to me) so I think it reads just fine. So I'm -1 on `except group` or any variant that uses soft keywords. If the SC considers making `group` a proper keyword I can possibly change my mind on this. Yury On Tue, Oct 5, 2021 at 6:28 PM Barry Warsaw <barry@python.org> wrote:
-- Yury
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 6 Oct 2021, at 18:05, Yury Selivanov <yselivanov.ml@gmail.com> wrote:
I don't like `except group` or any variant with soft keywords.
As Brandt just commented, this proposal is a no go due to confusion with function calls. I'll respond below anyway because looking through it was an interesting experience
This is a valid point, also raised by Pablo over WhatsApp (which happens to work today!). The particular hairy example has to do with your next point so let's go there first...
1b. Or, for example, if a user forgets to type `E` and leaves just `except group` it would fallback to the regular try..except behavior. And it would be a runtime error ("group" is undefined).
Right. Worse yet, this wouldn't be a runtime error UNLESS user code raises an exception within that try: block. Otherwise Python would happily take the unbound name and run with it:
When you raise:
During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 3, in <module> NameError: name 'group' is not defined This is pretty confusing and in my eyes disqualifies the "except group" proposal. Pablo also claims it would be very hard to generate good error messages due to this and I can see why. My initial idea here was to modify this received `NameError` just like we do in other cases with the new "Did you mean" helper:
We could potentially do something similar to generate better error messages for "except group" confusion, right? Only we can't if `group` happens to be bound as a name in a reachable scope which Larry points out is a popular name. In this scenario any syntax errors would end up with terribly confusing TypeErrors or AttributeErrors and so on. This is unacceptable.
1c. This will be all even more complicated because syntax highlighters in IDEs and on sites like GitHub will likely just always highlight `except group` as a pair of keywords (even in `except group:` variant).
This would a minor annoyance but definitely true.
2. I'm not sure I like the "sound" of it. IMO it would make more sense to write `except all E`, but `all()` is a built-in and so this would be at odds with (1).
That I disagree with. "except KeyError" reads like "except if there's a KeyError". "except group KeyError" reads like "except if there's a group of KeyErrors". And if you said, "except group KeyError as eg", an ExceptionGroup with KeyErrors would be exactly what you're getting under `eg`.
3. This is a niche feature. People who use async/await will get used to `except*` in no time. `except*` is also about unpacking in some metaphysical sense (looks similar enough to `*args` in function signatures to me) so I think it reads just fine.
Agreed. Except-star will be fine, too.
So I'm -1 on `except group` or any variant that uses soft keywords. If the SC considers making `group` a proper keyword I can possibly change my mind on this.
Making `group` a proper keyword is a no go. With Brandt's arguments, the entire idea is a no go. It's a bummer but I have to agree with the concerns raised. - Ł
![](https://secure.gravatar.com/avatar/be200d614c47b5a4dbb6be867080e835.jpg?s=120&d=mm&r=g)
On 10/6/2021 5:05 PM, Yury Selivanov wrote:
For the record (and I'm sure I'm not the only one), I'm -100 on making it a proper keyword. That would be disastrous (e.g. re.Match.group() becomes unusable). A soft keyword, punctuation, or magic builtin are the only possibilities here. "except all ..." is viable, since it's already a builtin that isn't useful as "except all:". But if that's the case, "except ExceptionGroup" is equally viable (with perhaps "except ExceptionGroup[Specific, Type]" for filtering?) I'm not going to argue against "except *", as that's already been accepted. But any alternative needs to: * break the same amount of existing code (i.e. none) * be equally/more readable and discoverable Since "except *" breaks *no* existing code, that's a pretty easy thing to check for in any alternative. But since "*" here has no precedent (as we've seen in this discussion), virtually any alternative is going to be more readable. So enjoy bikeshedding, everyone :) Please don't break any of our code. Cheers, Steve
![](https://secure.gravatar.com/avatar/77c28d84086eaacc4f606416ea70434d.jpg?s=120&d=mm&r=g)
Just my two small cents: soft keywords have a cost as they make everything around them more complicated in the parser. For example, creating custom error messages around soft keywords is one or two levels of magnitude more complicated as sometimes you need to parse segments of syntactically invalid code, with some generality (like "starts with this token and then anything can follow until this other token"). Soft keywords also make highlighters' life more complicated as it has already been discussed. And just to be clear: I am not saying they are bad, just that they are not free of cost.
![](https://secure.gravatar.com/avatar/d91ce240d2445584e295b5406d12df70.jpg?s=120&d=mm&r=g)
Yury Selivanov wrote:
If anything, that makes "except all E" less of a problem; the built-in all is not an exception, so any current meaning would be, at the least, a dodgy renaming of a built-in to something unrelated -- in which case a reader *should* already be suspicious. -jJ
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Sun, Oct 03, 2021 at 04:47:57PM +0100, Irit Katriel via Python-Dev wrote:
We wonder if people have a view on which of the following is clearer/better:
1. except *E as e: // except *(E1, E2) as e:
That looks like you're unpacking the tuple (E1, E2), and that's just misleading and wrong.
2. except* E as e: // except* (E1, E2) as e:
That looks like it is the "except" keyword which is special, not the tuple. If we're going to have yet another meaning for star (multiplication, replication, unpacking, powers, wildcard imports...) then I vote for 2. But Thomas Grainger's comment about match semantics got me thinking. I think his suggestion is a bit too verbose, but how do people feel about borrowing the vertical line and using it like this: except| E as e: except| (E1, E2) as e: Again, it's attached to the except keyword, to indicate that it's the keyword which is special, not a unary prefix operator on the E. The vertical line is suggestive of grouping something with a box around it: +-----------------+ | group of things | +-----------------+ and of the lines used in tracebacks shown in the PEP. So the output helps remind you of the syntax. -- Steve
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
Interestingly, IIRC this was the original intention: `except *E as e` means you're unpacking E from some group. I agree this is a somewhat convoluted analogy and it breaks down in the presence of a tuple of exception names.
2. except* E as e: // except* (E1, E2) as e:
But Thomas Grainger's comment about match semantics got me thinking.
Uh oh ;-)
-1 If I could read the vertical line as a pipe character, the expression would read "except or E as e". But I can't read it that way anyway. Instead, all I see is a lowercase EXCEPTL. My idea is this: try: ... except group E as e: ... except group E1, T2 as e: ... Should be doable given the magical match-case contextual keywords precedent. This looks nice and is explicit, since you will always get an ExceptionGroup instance under `e`. But I know it's a bit late for bikeshedding this thing so if we want to be conservative and stick to the current syntactical options already defined in PEP 654, I'm voting Option 2 (given the awkwardness of the *(E1, E2) example). - Ł
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:28 AM Irit Katriel via Python-Dev < python-dev@python.org> wrote:
We're going around in circles. We considered 'catch' early on, but decided against it since, comparing 'except E' and 'catch E', there would be no good way to tell which is the recommended one (and the same would apply to another single keyword like 'handle'). At least with 'except*', it's easy to remember that this is a modified version of 'except', so it's probably meant for a special case. I also think that the bar should be pretty high before we reopen the *syntax* -- the PEP was approved without anyone (neither the SC, nor Nathaniel, nor anyone else) providing any feedback on the use of 'except *'. So I think it's a bit late to be bikeshedding the syntax. This thread was meant to solicit feedback on how to *format* it: does the space go before or after the '*'. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Sun, Oct 03, 2021 at 11:34:55AM -0700, Guido van Rossum wrote:
`except* E`, otherwise it looks like unpacking E. Done! Bikeshedding is over! *wink* All joking aside, my preference is to put the star on the except, not the exceptions. I don't think I have anything more to say that hasn't already been said, so I'll bow out now. -- Steve
![](https://secure.gravatar.com/avatar/2dde9ab55441548a981af3e43639fcbd.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:40 PM Steven D'Aprano <steve@pearwood.info> wrote:
I think it's worth noting that the following is already legal: Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.
Indeed, when I first learned that you could do this (a few years ago IIRC), my first thought was to unpack the "exceptions" tuple with a star. It wasn't until I tried that and got a SyntaxError that I tried it the way shown here and it worked. Allowing `except *E` for this new feature would take that helpful-to-a-beginner SyntaxError and turn it into a subtle and unhelpful bug. Therefore my vote is for requiring `except* E` and keeping `except *E` as a SyntaxError.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 9:20 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
Therefore my vote is for requiring `except* E` and keeping `except *E` as a SyntaxError.
You can't do that with our current lexer+parser. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/d995b462a98fea412efa79d17ba3787a.jpg?s=120&d=mm&r=g)
On Mon, 4 Oct 2021 at 07:16, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Agreed. Having "except*" be a single token, distinguished from the pair of tokens "except" "*" only by the presence of whitespace, would be extremely confusing. And yes, I am aware that 3.as_integer_ratio() and 3. as_integer_ratio() are syntax errors, whereas 3 .as_integer_ratio() and 3 . as_integer_ratio() are valid. IMO, that's *also* very confusing, and serves as a warning to not do that again, and not as an example of how it's OK and we can do more of that... Paul
![](https://secure.gravatar.com/avatar/2dde9ab55441548a981af3e43639fcbd.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 1:24 AM Guido van Rossum <guido@python.org> wrote:
Then what is the purpose of this thread? I understood from the OP that the question was which to allow and which to prohibit. If it's impossible to require either or prohibit either because the lexer/parser can't tell the difference, then it's going to end up as a never-ending style argument just like C pointers, so what are we even discussing? (Other than an entirely different syntax, of course, which now seems like the logical way to go if we can't enforce a single way to do it with the original proposal.)
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
The question was about which style to *recommend* (a la PEP-8). On Mon, Oct 4, 2021 at 8:03 AM Jonathan Goble <jcgoble3@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 12:07 PM Guido van Rossum <guido@python.org> wrote:
The question was about which style to *recommend* (a la PEP-8).
I think the very fact that it can't (or is difficult) be enforced, and so in the wild we'll likely see variations that could lead to confusion, is enough reason to find an alternative syntax.
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/1fee087d7a1ca17c8ad348271819a8d5.jpg?s=120&d=mm&r=g)
On Mon, 4 Oct 2021 12:18:35 -0400 Calvin Spealman <cspealma@redhat.com> wrote:
How so? If style checkers are already able to check whitespace around operators, they should be to check whitespace in this instance as well. Do you suggest that PEP 8 violations should be detected by the Python parser itself?
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Mon, Oct 4, 2021 at 12:48 PM Antoine Pitrou <antoine@python.org> wrote:
1) I was basing the "can't enforce" on Guido's " You can't do that with our current lexer+parser." 2) Of course PEP 8 violations shouldn't be checked by the parser. That's why they're PEP 8 and not syntax rules. However, this doesn't look like style. This syntax is modifying either the `except` keyword for the exception type associated with it. Which does it modify? That the asterisk can be on either side of the whitespace feels very odd, in general but especially for Python syntax. That's why I'd opt for a variation that is either unambiguously attached to the left or right, or which is not connected to either, like the very clear `except group E` proposal. _______________________________________________
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/be200d614c47b5a4dbb6be867080e835.jpg?s=120&d=mm&r=g)
On 10/4/2021 5:47 PM, Antoine Pitrou wrote:
No, but if it isn't decided by *us*, it'll be decided by whoever contributes it to Black first. To me, the "*name" looks most similar to how we write "*args" in a function definition, so I'd go for that. We don't currently modify[1] keywords with punctuation, and that's what "except*" looks like, and "except * E" looks like a binary operator and/or grit on the screen. Cheers, Steve [1]: Meaning to "give it a different meaning in particular context", not _literally_ modify in any permanent sense.
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Mon, Oct 04, 2021 at 07:31:10PM +0100, Steve Dower wrote:
To me, the "*name" looks most similar to how we write "*args" in a function definition, so I'd go for that.
That's exactly why we *shouldn't* go for that option. That is going to confuse a lot of people that it is sequence unpacking. See for example Jonathon Goble's experience here: https://mail.python.org/archives/list/python-dev@python.org/message/2TBZZSMZ...
We don't currently modify[1] keywords with punctuation,
Star imports are a possible exception. But there we have no way of confusing the meaning.
When I saw the `except*` syntax first suggested, I was a little surprised because it did seem rather unusual for Python. But I grew up with FORTH where function names contain punctuation all the time, so I didn't think too much of it. I expected that the keyword literally would be `except*` and nothing but `except*`. If I had realised that the star would be free to wander around and that the syntax actually was r"except[ \t]*\*[ \t]*", I would have said something much earlier :-( -- Steve
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Mon, Oct 04, 2021 at 09:03:54AM -0700, Guido van Rossum wrote:
The question was about which style to *recommend* (a la PEP-8).
Quote: "At the moment * is a separate token so both are allowed, but we could change that (e.g., make except* a token)" If that is mistaken, that's fine, no harm done, but those of us who thought that enforcing one or the other form was on the table didn't imagine it :-) -- Steve
![](https://secure.gravatar.com/avatar/7f37d34f3bb0e91890c01450f8321524.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 10:47 AM Łukasz Langa <lukasz@langa.pl> wrote:
+1 on the `except* E` Option 2 syntax. It better conveys its uniqueness and non-relation to other meanings of *. Someone mentioned allowing both and letting people decide. Whatever is chosen, please not that. There should be only one way to write this. That avoids style arguments when no auto-formatter is involved. -gps
![](https://secure.gravatar.com/avatar/01aa7d6d4db83982a2f6dd363d0ee0f3.jpg?s=120&d=mm&r=g)
On Oct 3, 2021, at 10:42, Łukasz Langa <lukasz@langa.pl> wrote:
Speaking just for myself, the `except *` syntax always bothered me, but I couldn’t come up with anything better and it wasn’t enough for me to vote against PEP 654. `except group` is nicer though, and I would be in favor of that, or something like it. We could of course bike shed on the syntax forever. The PSC did vote to accept the PEP but we left room for changes while during the 3.11 cycle. -Barry
![](https://secure.gravatar.com/avatar/d6b9415353e04ffa6de5a8f3aaea0553.jpg?s=120&d=mm&r=g)
On 10/4/2021 9:57 AM, Ammar Askar wrote:
I agree for same reasons. And avoids more bikeshedding. I checked and if 'except group' is added to keyword.kwlist *before* 'except', the pair is recognized as a keyword phrase by IDLE's syntax highlighter without any change. ('except\s*group' would take care of variable spacing) -- Terry Jan Reedy
![](https://secure.gravatar.com/avatar/2f030aadc9b778ceda33bad2b0141c76.jpg?s=120&d=mm&r=g)
Irit Katriel wrote:
It is also not too late to opt for a completely different syntax if a better one is suggested.
Honestly, I’ve never been a fan of the PEP’s proposed star syntax. If we’re okay adding a soft keyword, though, something like “except each” could help communicate the meaning of the blocks a bit more explicitly. I’m pretty sure that grammar would be unambiguous in all cases.
![](https://secure.gravatar.com/avatar/0ba23f0a211079fb3e219acfaa9e432d.jpg?s=120&d=mm&r=g)
On Sun, Oct 3, 2021 at 11:48 AM Irit Katriel via Python-Dev < python-dev@python.org> wrote:
It is difficult to understand why any special syntax is needed at all. ExceptionGroup is still an exception class like any other, isn't it? Why wouldn't the existing syntax suffice?
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
![](https://secure.gravatar.com/avatar/dbae42afc5ab53e05f3c61d36b9ee7d4.jpg?s=120&d=mm&r=g)
On 4 Oct 2021, at 15:00, Calvin Spealman <cspealma@redhat.com> wrote:
It is difficult to understand why any special syntax is needed at all. ExceptionGroup is still an exception class like any other, isn't it? Why wouldn't the existing syntax suffice?
This is covered at length in the PEP. Those sections specifically address this: https://www.python.org/dev/peps/pep-0654/#extend-except-to-handle-exception-... <https://www.python.org/dev/peps/pep-0654/#extend-except-to-handle-exception-...> https://www.python.org/dev/peps/pep-0654/#programming-without-except <https://www.python.org/dev/peps/pep-0654/#programming-without-except> - Ł
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
Rob Cliffe is having problems posting to the Python-Dev list, so he posted an alternative suggestion to the Python-Ideas list: https://mail.python.org/archives/list/python-ideas@python.org/message/6KQUQB... Rob's idea is to use "except for ..." with exception groups, instead of a new keyword or symbol. -- Steve
participants (31)
-
Ammar Askar
-
Antoine Pitrou
-
Barry Scott
-
Barry Warsaw
-
Brandt Bucher
-
Calvin Spealman
-
Damian Shaw
-
Ethan Furman
-
Glenn Linderman
-
Greg Ewing
-
Gregory P. Smith
-
Guido van Rossum
-
Irit Katriel
-
Jim J. Jewett
-
Jonathan Goble
-
Larry Hastings
-
Mark Shannon
-
MRAB
-
Pablo Galindo Salgado
-
Patrick Reader
-
Paul Moore
-
Petr Viktorin
-
Rob Cliffe
-
sascha.schlemmer@me.com
-
Steve Dower
-
Steven D'Aprano
-
Terry Reedy
-
Thomas Grainger
-
Victor Stinner
-
Yury Selivanov
-
Łukasz Langa