TLDR: One-line exception triage for better error handling with lambda-like syntax:
# initial proposed syntax; '^except' is a single token
t = father["smell"]
^except KeyError: return "elder berries"
In my 2 decades with Python across gaming, social media, and aerospace, a very common issue I’ve run into is exception-laziness caused most frequently by aesthetic aversions.
The “try first, ask later” use of exceptions tends to be unpopular because it produces so much boilerplate, reminding me of go’s
result, err := camelot()
if err != nil {
runaway()
}
Back to Python, it is also a frequent, common cause of simple bad engineering where people are lazy about dealing with exceptions because they don’t want to write four lines of code - let someone else handle it.
Let’s take a most trivial example, index checking, to underline how this starts badly and scales worse:
# real-world preferred
if (h := data.get("hello")) and (w := data.get("world")):
# properly pythonically, while retaining ability to
# deal with which key was affected most reasonably
try:
h := data["hello"]
except KeyError:
...
try:
w := data["world"]
except KeyError:
...
The second aversion is nesting and displacement:
try:
with open("coconuts.pickle", "rb") as jar:
try:
header = pickle.load(jar)
except Pickle.UnpickleError as e:
...
... other operations allowing exceptions to fall to the top
except FileNotFoundError as e:
...
except PermissionError as e:
...
except ValueError as e:
...
hang on mr elipsis writer - what code is THIS responding to?
People are frequently averse to localizing exception handling because it’s just plain annoying to try and say “oh if I get a key error here”.
the above example would become:
with open("coconuts.pickle", "rb") as jar:
^except FileNotFoundError: return "Brave Sir Robin, run away"
^except PermissionError: return "Go away you silly, English, kniggit"
header = pickle.load(jar)
^except Pickle.UnpickleError as e: return "YOUR father smells of herring"
try: # the others are validly a single block with common handlers
...
except ValueError as e:
I suspect initially it needs to be available in very limited contexts: single-statement lines
horse = (Coconut(), Coconut()); horse.ride()
^except # <- error
and not inside compounds
x = {
"x": 1,
"y": getDatabase(),
^except # <- error
"z": getDatabase() # <- user omitted comma thinking that was the issue
^except # <- error
...
y = [
getHorse("Coconut"),
^except # <- error, with or without the comma
]
May be later we’ll want it available in [edit] comprehensions but that can be revisited as an improvement.
I suspect we should also prohibit it from use on multi-value with statements:
# ok
with open("nudge", "wb") as out:
^except PermissionErrora s e: return RuntimeError("can't write arthur's file")
# not ok
with Connect("db") as db, open("nudge", "wb") as out:
^except ...
# because the user could also have written that across multiple lines.