From: Armin Rigo <arigo@tunes.org> To: Michael Hudson <mwh@python.net> Subject: Re: [pypy-dev] [gmane.comp.python.pypy] deep breakage
Hello Michael,
On Sat, Jun 07, 2003 at 08:38:32PM +0100, Michael Hudson wrote:
try: "x" + 1 except TypeError, e: raise e
because here 'e' gets bound to a *string* and then this is what's reraised.
This is of course false. e gets a TypeError instance (or at least that's what it does in CPython, and what it should do).
This is the same problem as in CPython. Most failing internal operations call PyErr_SetString(), which causes a string to be used as the exception value.
No, as the argument to the exception constructor.
The hack is that when the user code reaches an 'except' clauses the exception is "normalized", which translates the pair "TypeError class + string" into the pair "TypeError class + TypeError instance".
Right, and for all practical purposes, raise TypeError, "foo" is the same as raise TypeError("foo")
We might either choose to mimic this behavior or clean it up a bit, e.g. by always using internally a single object as the exception instance.
That's fine. CPython uses the pair so that for certain exceptions raised *internally* (by C code, not by raise statements) the instantiation is never done if the exception is caught and cleared by C code further down the stack. For example, when iterating over a built-in sequence, the StopIteration exception is raised but never instantiated.
String exceptions are being deprecated, but still we could reasonably emulate them, say by inventing a StringException class. This would isolate the hacky parts around this specific class (like setting sys.exc_type to something else than current_exception.__class__ for this particular case).
I would not even bother. String exceptions are strongly deprecated part of the language. --Guido van Rossum (home page: http://www.python.org/~guido/)