Re: [Python-ideas] [Python-Dev] What's the status of PEP 505: None-aware operators?

I like much of the thinking in Random's approach. But I still think None isn't quite special enough to warrant it's own syntax. However, his '(or None: name.strip()[4:].upper())' makes me realize that what is being asked in all the '?(', '?.', '?[' syntax ideas is a kind of ternary expression. Except the ternary isn't based on whether a predicate holds, but rather on whether an exception occurs (AttributeError, KeyError, TypeError). And the fallback in the ternary is always None rather than being general. I think we could generalize this to get something both more Pythonic and more flexible. E.g.: val = name.strip()[4:].upper() except None This would just be catching all errors, which is perhaps too broad. But it *would* allow a fallback other than None: val = name.strip()[4:].upper() except -1 I think some syntax could be possible to only "catch" some exceptions and let others propagate. Maybe: val = name.strip()[4:].upper() except (AttributeError, KeyError): -1 I don't really like throwing a colon in an expression though. Perhaps some other word or symbol could work instead. How does this read: val = name.strip()[4:].upper() except -1 in (AttributeError, KeyError) Where the 'in' clause at the end would be optional, and default to 'Exception'. I'll note that what this idea DOES NOT get us is: val = timeout ?? local_timeout ?? global_timeout Those values that are "possibly None" don't raise exceptions, so they wouldn't apply to this syntax. Yours, David... On Wed, Nov 29, 2017 at 9:03 AM, Random832 <random832@fastmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Nov 29, 2017, at 12:40, David Mertz <mertz@gnosis.cx> wrote:
I don’t know whether I like any of this <wink> but I think a more natural spelling would be: val = name.strip()[4:].upper() except (AttributeError, KeyError) as -1 which could devolve into: val = name.strip()[4:].upper() except KeyError as -1 or: val = name.strip()[4:].upper() except KeyError # Implicit `as None` I would *not* add any spelling for an explicit bare-except equivalent. You would have to write: val = name.strip()[4:].upper() except Exception as -1 Cheers, -Barry

On 11/29/2017 01:02 PM, Barry Warsaw wrote:
Of all the proposed spellings for the idea, this one feels most "normal" to me, too (I'm -0 on the idea as a whole).
Wouldn't that really need to be this instead, for a true 'except:' equivalence: val = name.strip()[4:].upper() except BaseException as -1 Tres. -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com

On Wed, Nov 29, 2017, at 12:40, David Mertz wrote:
I did say, though, that it should only "catch" errors arising from operations that are lexically within the block. Seeing this, I got an idea in my head of a feature set that (along with expression syntax that has already been suggested), could together fulfill this need and provide more generality. --- Conditional exception catching --- "except [ExceptionTypes] [as name] [when condition]" as a syntax to only catch if [condition] is true. the byte code appears to already evaluate an arbitrary condition, it just currently only ever uses it to check types with the special "exception match" compare_op. We could use "if" as the keyword for conditions instead of "when", but I'm not sure if that creates ambiguity with proposed except-expression syntax when a conditional operator might also be used. I don't know if this has been proposed before. C# and VB have it, as do some C and Javascript implementations. I don't know if it would be equivalent or subtly different from re-raising if the condition is false, but even if so it would make it much easier to implement this sort of logic in an expression. --- Lexical exceptions --- Have at least some exceptions (say, AttributeError) carry enough information to allow for an exception catching statement to only catch when the exception was caused by the current code, not a function being called. I don't have much idea of how exactly this could work - something to do with the stack trace, maybe? A complicating factor might be that we may want to e.g. catch an AttributeError that comes from a raise statement within a __getattribute__ function, but not from an attribute lookup within such a function. This could be implemented in a function to be used with the above conditional feature, rather than made another keyword. --- None-specific exceptions --- Create a NoneError class to act as a second base class for subclasses of TypeError and AttributeError used when the value causing the error was None. I don't know if the exception catching machinery allows for multiple inheritance, if not, the conditional exception catching feature could be used to use a regular type check instead of the special exception match check [i.e. except as e when isinstance(e, NoneError)] None might not be special enough to warrant its own syntax, but I think it is special enough for this.

On Nov 29, 2017, at 12:40, David Mertz <mertz@gnosis.cx> wrote:
I don’t know whether I like any of this <wink> but I think a more natural spelling would be: val = name.strip()[4:].upper() except (AttributeError, KeyError) as -1 which could devolve into: val = name.strip()[4:].upper() except KeyError as -1 or: val = name.strip()[4:].upper() except KeyError # Implicit `as None` I would *not* add any spelling for an explicit bare-except equivalent. You would have to write: val = name.strip()[4:].upper() except Exception as -1 Cheers, -Barry

On 11/29/2017 01:02 PM, Barry Warsaw wrote:
Of all the proposed spellings for the idea, this one feels most "normal" to me, too (I'm -0 on the idea as a whole).
Wouldn't that really need to be this instead, for a true 'except:' equivalence: val = name.strip()[4:].upper() except BaseException as -1 Tres. -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com

On Wed, Nov 29, 2017, at 12:40, David Mertz wrote:
I did say, though, that it should only "catch" errors arising from operations that are lexically within the block. Seeing this, I got an idea in my head of a feature set that (along with expression syntax that has already been suggested), could together fulfill this need and provide more generality. --- Conditional exception catching --- "except [ExceptionTypes] [as name] [when condition]" as a syntax to only catch if [condition] is true. the byte code appears to already evaluate an arbitrary condition, it just currently only ever uses it to check types with the special "exception match" compare_op. We could use "if" as the keyword for conditions instead of "when", but I'm not sure if that creates ambiguity with proposed except-expression syntax when a conditional operator might also be used. I don't know if this has been proposed before. C# and VB have it, as do some C and Javascript implementations. I don't know if it would be equivalent or subtly different from re-raising if the condition is false, but even if so it would make it much easier to implement this sort of logic in an expression. --- Lexical exceptions --- Have at least some exceptions (say, AttributeError) carry enough information to allow for an exception catching statement to only catch when the exception was caused by the current code, not a function being called. I don't have much idea of how exactly this could work - something to do with the stack trace, maybe? A complicating factor might be that we may want to e.g. catch an AttributeError that comes from a raise statement within a __getattribute__ function, but not from an attribute lookup within such a function. This could be implemented in a function to be used with the above conditional feature, rather than made another keyword. --- None-specific exceptions --- Create a NoneError class to act as a second base class for subclasses of TypeError and AttributeError used when the value causing the error was None. I don't know if the exception catching machinery allows for multiple inheritance, if not, the conditional exception catching feature could be used to use a regular type check instead of the special exception match check [i.e. except as e when isinstance(e, NoneError)] None might not be special enough to warrant its own syntax, but I think it is special enough for this.
participants (6)
-
Barry Warsaw
-
Chris Angelico
-
David Mertz
-
Eric V. Smith
-
Random832
-
Tres Seaver