
On Thu, Feb 21, 2019 at 10:04 PM Steven D'Aprano <steve@pearwood.info> wrote:
On Thu, Feb 21, 2019 at 07:05:55PM +1100, Chris Angelico wrote:
[Ben]
Other functions also conceptually have three ways of returning: ordinary return with a value, a documented special return like KeyError, and pass-through exceptions. If the pass-through exception is KeyError, it gets conflated with the documented exceptional return, but correct code should handle them differently. It doesn't matter whether the syntax for the documented special return is "return x" or "raise KeyError(x)".
Not sure what you mean here. If the documented special return is "return x", then it's a value that's being returned. That's completely different from raising some sort of exception.
I think I understand what Ben means, because I think I've experimented with functions which do what he may be getting at.
Remember that exceptions are not necessarily errors. So you might write a function which returns a value in the standard case, but raises an exception to represent an exceptional case. If this is not an error, then the caller ought to be prepared for the exception and always catch it.
Yep, I understand that part (and mention KeyError specifically). What I don't understand is the documented special return of "return x". If there's a way to return a magic value, then it's still just a value. For the rest, yeah, there's the normal Python behaviour of signalling "nope" by raising a specific exception. And yes, leaking an exception of the same type from within that function is going to be interpreted as that "nope". That's important to the ability to refactor - you can have a helper function that raises, and then the main __getitem__ or __getattr__ or whatever will just propagate the exception. That's why "leaking" is such a hard thing to pin down. ChrisA