
Quoth Greg Ewing: [...]
I know that's the way it *is*, but I can't see any reason why the interpreter couldn't defer instantiation if it wanted to. It should be an optimisation that any part of the implementation is free to make if the programmer hasn't explicitly instantiated before raising.
The interpreter certainly could do that, but imho it would be a Bad Thing. Forgive my long-windedness, but: Imho, it's bad enough that raise MyError, 'foo' raise MyError('foo') are two ways of saying the same thing; that's merely confusing. But having the interpreter defer instantiation in the former case would make them a much worse pair -- two subtly different ways of saying almost the same thing, where the difference is one you almost never care about. I cringe. To be more concrete, if exception instantiation might be deferred and might not occur at all, then (off the top of my head): 1. Logging code in an exception's __init__ might be called, might not. 2. sys._getframe tricks in an exception's __init__ might work, might not. (And exceptions are just the kind of infrastructure- level thing where such tricks are most likely to be useful, imho. You might, for example, want to grab a copy of all the locals of the function which raised the exception, for error reporting. Sure you could use the traceback, if you can get ahold of it somehow, but everywhere *else* this kind of machinery uses sys._getframe, so...) 3. Implementations of __new__ in which the created object is not of the requested class would make the exception type depend on whether instantiation was deferred or not, affecting whether and when it gets caught. Perhaps these aren't showstoppers, but I really like it when optimizations are completely transparent. Besides, almost all raise statements report errors which prevent normal processing, and so have no use for such an optimization anyway. And even when using exceptions for control flow on performance- critical paths, you can avoid paying the instantiation cost in inner loops by other, simpler, means -- e.g., create one instance of your FancyControlFlow exception up front and raise that one object as needed. There's also some (surmountable) implementation issues: Suppose we enter an except block without instantiating the exception; what are the values of sys.exc_type etc. then? Are they possibly denormalized? Or do we remove sys.exc_{type, value, traceback} entirely, and have calling sys.exc_info() cause instantiation? If explicit instantiation were standard, and the implicit instantiation syntax were now being proposed with deferred-and- skipped-if-possible semantics, I might just be -0 YAGNI on it. In that scenario, this syntax would be something weird that programmers would only use if they knew they needed it. But the actual circumstance is, to judge by the stdlib, that implicit instantiation is today the de facto standard way to raise an exception. Thus adding such semantics now would give the normal form weird behaviour to enable an optimization which is useful only in specialized circumstances -- which puts me firmly in the -1 AAAGH! camp. All of the above is intended for pure Python only. If the tradeoffs are much different in Pyrex, I'd like to hear more details. [...]
But something else has occurred to me. If we're going to require exception classes to be derived from Exception, then there's no ambiguity anyway, [...]
For old-style classes, there's no ambiguity now, either. But yes, requiring inheritance from Exception seems to eliminate any instance/class ambiguities for future new-style exceptions too. (It also avoids certain other problems; see Alex's persuasive arguments in c.l.py around the beginning of May, mentioned elsewhere in this thread.) PEP 317 isn't primarily concerned with that ambiguity, of course; more with the loss of clarity in present-day everyday code.
[...] because you can't have an object which is both a subclass of Exception and an instance of a subclass of Exception. (At least not without pulling some sort of bizarre trick, and I don't much care what happens to anyone who does that.-)
Couldn't agree more. -- Steven Taschuk staschuk@telusplanet.net "Its force is immeasurable. Even Computer cannot determine it." -- _Space: 1999_ episode "Black Sun"