Deprecating string exceptions

http://python.org/sf/518846 reports that new-style classes cannot be used as exceptions. I think it is desirable that this is fixed, but I also believe that it conflicts with string exceptions. So I would like to propose that string exceptions are deprecated for Python 2.3, in order to remove them in Python 2.4, simultaneously allowing arbitrary objects as exceptions. Regards, Martin

"Martin v. Loewis" wrote:
Should it be arbitrary objects or just subclasses of exception: "It is recommended that user-defined exceptions in new code be derived from Exception, although for backward compatibility reasons, this is not required. Eventually this rule will be tightened." * http://www.python.org/doc/essays/stdexceptions.html Paul Prescod

Can we safely make Exception (and hence all built-in exceptions) a new-style class? This could break user code (even when we don't enforce that exceptions are derived from Exception). --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Can we safely make Exception (and hence all built-in GvR> exceptions) a new-style class? This could break user code GvR> (even when we don't enforce that exceptions are derived from GvR> Exception). What's the advantage of making Exception a new-style class? Isn't that a separate issue from whether 1) we deprecate string exceptions, 2) whether we enforce exceptions to inherit from Exception? -Barry

Guido van Rossum <guido@python.org> writes:
I see no need to make such a change, with this change alone, I can't see risks for breaking code, either. If you would also make Exception.args a slot, there would be a rationale (efficiency), but you would also more likely break user code. Regards, Martin

Guido van Rossum <guido@python.org> writes:
For issues related to needing vs not-needing to dynamically create Java classes and corresponding security restrictions, it would be user-friendlier if Exception on Jython side would remain a classic-style class. We can give more input when we have sorted out the implementation of new-style classes subclassing (that's many month away :( ). Maybe the issues will become non-issues or not. regards.

[Samuele]
Good point. We'll be cautious. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Martin]
If that is the rule, the bug report can be closed as "not-a-bug".
I seem to have a particularly dense day. :-( What does "that" (in "If that is the rule") refer back to? --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
"user-defined exceptions be derived from Exception". It is only a recommendation in the sense that you can use arbitrary classic classes. If the rule is eventually tightened, it is ok if new-style classes are not allowed as exceptions right now. An action is only needed if you pronounce that it is desirable to allow new-style classes as exceptions - which would necessarily have a base class that is not derived from Exception. Regards, Martin

"Samuele Pedroni" <pedroni@inf.ethz.ch> writes:
The issue is more subtle: raising an instance of Z counts as raising a string, so you cannot catch with with "except Z", but you can catch it with the identical object. However, this is not the issue reported in bug #518846: Magnus Heino does not want to inherit from str, and his class does not inherit from Exception, either. Also, I believe that using your class Z as an exception class should not be supported: a "proper" exception should not just merely inherit from Exception - it should have Exception as its only root class (Z has both object and Exception as root classes). So yes, funny things can happen, but they are all accidental, and may stop happening without notice. Regards, Martin

I think that rule is too strong, and I don't see a reason for it. --Guido van Rossum (home page: http://www.python.org/~guido/)

"MvL" == Martin v Loewis <martin@v.loewis.de> writes:
MvL> Also, I believe that using your class Z as an exception class MvL> should not be supported: a "proper" exception should not just MvL> merely inherit from Exception - it should have Exception as MvL> its only root class (Z has both object and Exception as root MvL> classes). Can you explain why you think the rule should be so strict? I don't see a problem with using multiple inheritance to satisfy the "must derive" rule. -Barry

barry@zope.com (Barry A. Warsaw) writes:
The question is, whether, given class Base:pass class MyExc(Base, Exception):pass it would be valid to write try: foo() # raises MyExc except Base: pass If that ought to be allowed, I fail to see the rationale to require that exceptions be derived from Exception: The rationale could be "all exceptions are primarily instances of Exception" - yet in this case, Base is the primary class, and Exception is just a mix-in that plays no further role in this case of exception handling. If you want to allow Base in the except clause, but do allow Base as the base class of MyExc, I'd be curious what run-time semantics you'd associate with this example. Regards, Martin

The "except Base:" class would of course be illegal because Base doesn't derive from Exception. (Although the error might only be detected when MyExc is raised -- but PyChecker could do better.) But the statement "raise MyExc" would be perfectly legal, and could be caught either with "except MyExc" or "except Exception".
I have never heard of the concept "primarily an instance of". I also don't understand why that should be the rule.
the base class of MyExc, I'd be curious what run-time semantics you'd associate with this example.
See above. Before we waste more time on this, let me explain why I like the rule that all exception classes be derived from Exception. It's only a vague liking, and maybe it's not worth making it a rule. I like it because including Exception (or one of its well-known subclasses) in the base class is a clue to the reader that a particular class declaration is used as an exception. AFAIK this is the only reason why Java has a similar rule; C++ does not, and lets you throw any class. I can't see any implementation benefits from the requirement. It sounds like you can't either -- or else you would have pointed them out by now. So maybe we shouldn't bother with this rule, and then we should take the recommendation out of the documentation. But I still kind of like it, for the reason I explained in the previous paragraph. --Guido van Rossum (home page: http://www.python.org/~guido/)

[me]
One other, more practical reason to like the rule: "except Exception:" would become equivalent to "except:". The advantage is that you can then write "except Exception, e:" and catch the exception instance in a local variable without having to call sys.exc_info(). --Guido van Rossum (home page: http://www.python.org/~guido/)

On 28 Mar 2002 at 8:29, Guido van Rossum wrote:
Which, to my mind, is sufficient to justify the rule. Hmm. If the rule were (eventually) strictly enforced, could we get the C++-style "stack allocated object whose destructor releases the resource" trick working? (Which would allow killing off the recurrent "with" / "using" thread.) -- Gordon http://www.mcmillan-inc.com/

Which, to my mind, is sufficient to justify the rule.
And also to mine. (Barry, take note for the PEP. :-)
(a) I'm not sure I like to make that semantics official, since it's hard to implement e.g. in Jython. (b) I'm having another dense day. How would requiring exceptions to inherit from Exception make this easier?
(Which would allow killing off the recurrent "with" / "using" thread.)
In c.l.py? I'm not aware of it. --Guido van Rossum (home page: http://www.python.org/~guido/)

On 28 Mar 2002 at 9:43, Guido van Rossum wrote: [me, on requiring Exception as base class]
Don't blame me - I told JimH he was wasting his time <wink>!
Well, I implicitly hand-waved on a couple steps, like a total revamp of the sys.exc_* stuff. Bleh. No, I guess there's no way around the fact that that dangling reference is either a blessing or a curse, and which it is depends on circumstances external to the system.
We just had one here. Started out on hygenic macros, but ended up on hiding finally clauses. -- Gordon http://www.mcmillan-inc.com/

Guido> One other, more practical reason to like the rule: "except Guido> Exception:" would become equivalent to "except:". Just to make sure I'm not missing something (I probably am), I still think the recommended catch-all except construct should become "except StandardError:" with KeyboardInterrupt migrated to inherit from Exception instead of StandardError. Skip

I think I didn't pay attention when that was being discussed before. I definitely don't like to make "except:" mean anyting besides "catch *all* exceptions." There are too many different use cases to favor a specific non-obvious; for example, the runcode() method in class InteractiveInterpreter() in code.py needs to catch all exceptions including KeyboardInterrupt but excluding SystemExit. Also note that StopIteration and the warning categories don't derive from StandardError; but if any of these is accidentally raised, I'd want my "except:" clause to catch it! And, while sometimes it's confusing that SystemExit is caught by "except:", it's really hard to debug why your program exits without any warning or traceback when a rogue library function raises SystemExit. --Guido van Rossum (home page: http://www.python.org/~guido/)

"Guido" == Guido van Rossum <guido@python.org> writes:
>> Just to make sure I'm not missing something (I probably am), I still >> think the recommended catch-all except construct should become >> "except StandardError:" with KeyboardInterrupt migrated to inherit >> from Exception instead of StandardError. Guido> I think I didn't pay attention when that was being discussed Guido> before. I definitely don't like to make "except:" mean anyting Guido> besides "catch *all* exceptions." I agree with you. But much of the time, as http://python.org/sf/411881 demonstrates, "except:" is the wrong answer. If someone wants to catch "everything", they actually don't want to catch SystemExit or KeyboardInterrupt most of the time. That leads to code like try: fragile_code except (KeyboardInterrupt,SystemExit): raise except: handle_stuff_we_can or, with your suggestion: try: fragile_code except (KeyboardInterrupt,SystemExit): raise except Exception, e: handle_stuff_we_can How often (percentage-wise) do you see that as the catch-all construct? If KeyboardInterrupt inherited from Exception, the above could become: try: fragile_code except StandardError, e: handle_stuff_we_can which is much more likely for lazy programmers to write than the first two constructs. (Yes, the laziest people will still use "except:".) All I'm suggesting is that the recommended usage change slightly. (I guess I'd also vote that all exceptions inherit from Exception...) Guido> There are too many different use cases to favor a specific Guido> non-obvious; for example, the runcode() method in class Guido> InteractiveInterpreter() in code.py needs to catch all exceptions Guido> including KeyboardInterrupt but excluding SystemExit. Also note Guido> that StopIteration and the warning categories don't derive from Guido> StandardError; but if any of these is accidentally raised, I'd Guido> want my "except:" clause to catch it! And, while sometimes it's Guido> confusing that SystemExit is caught by "except:", it's really Guido> hard to debug why your program exits without any warning or Guido> traceback when a rogue library function raises SystemExit. A couple comments on this: * I'm not saying you can't use "except:". I'm not advocating a semantic change to the meaning of "except:". (I am suggesting that KeyboardInterrupt should not inherit from StandardError.) I'm saying that the recommended usage for application programmers should be to avoid it. * Special situations will always remain. The point I'm trying to make is that we should make it easier for application programmers to write good code. I don't think specialized standard library code should be held up as typical usage. I'd prefer to have to modify pick over the entire standard library (as I'm already doing) and have it be easier for Joe Programmer to write robust application code than for code.py to be easier to write and have JP naively write less robust code. * I would hope there are no "rogue" functions in the standard library. If so, we should fix them. As to other people's libraries, we can't do much. SystemExit is a well-defined way to exit the program. If the rogue programmer felt SystemExit was called for at that point, that's between him and the person using his code. Skip

[Skip]
You're looking at this all wrong. In the past, we've focused on saying "unqualified except is wrong". But IMO "except Exception" or "except StandardError" is just as wrong! You're still catching way more exceptions than is good for you. In the few use cases where you really *do* want to catch (almost) all exceptions, I think it's appropriate that you have to think about the exceptions (pun intended).
Sorry. I told you I hadn't read the thread the first time around.
We should fix the "except:" examples by catching a very specific error, like AttributeError, TypeError or KeyError. *Not* by catching Exception or StandardError.
* I would hope there are no "rogue" functions in the standard library.
No, but lots of users write them without thinking. E.g. this would seem a common idiom: def error(msg): print "ERROR:", msg sys.exit(1)
--Guido van Rossum (home page: http://www.python.org/~guido/)

Guido> You're looking at this all wrong. In the past, we've focused on Guido> saying "unqualified except is wrong". But IMO "except Exception" Guido> or "except StandardError" is just as wrong! You're still Guido> catching way more exceptions than is good for you. Point taken. >> * I'm not saying you can't use "except:". I'm not advocating a >> semantic change to the meaning of "except:". (I am suggesting that >> KeyboardInterrupt should not inherit from StandardError.) I'm >> saying that the recommended usage for application programmers >> should be to avoid it. Guido> Sorry. I told you I hadn't read the thread the first time around. So, do we agree on this point? Guido> We should fix the "except:" examples by catching a very specific Guido> error, like AttributeError, TypeError or KeyError. *Not* by Guido> catching Exception or StandardError. Correct. That's what the long-standing bug #411881 is about. It just deals with the standard library however, and doesn't delve into the stuff in Tools, Demos, etc. Skip

Guido> Sorry. I told you I hadn't read the thread the first time around.
So, do we agree on this point?
Yes, "except:" should catch all exceptions, and in the future (when we can enforce the rule) so should "except Exception:".
That's OK. But I don't understand why that bug would provide an argument for special-casing KeyboardInterrupt. --Guido van Rossum (home page: http://www.python.org/~guido/)

>> Correct. That's what the long-standing bug #411881 is about. It >> just deals with the standard library however, and doesn't delve into >> the stuff in Tools, Demos, etc. Guido> That's OK. But I don't understand why that bug would provide an Guido> argument for special-casing KeyboardInterrupt. It doesn't. It's just that KeyboardInterrupt is more like SystemExit than like a real error condition. Skip

"SM" == Skip Montanaro <skip@pobox.com> writes:
>> * I'm not saying you can't use "except:". I'm not advocating a >> semantic change to the meaning of "except:". (I am suggesting >> that KeyboardInterrupt should not inherit from StandardError.) >> I'm saying that the recommended usage for application >> programmers should be to avoid it. Guido> Sorry. I told you I hadn't read the thread the first time Guido> around. SM> So, do we agree on this point? There's definitely precedence for that, and I think you could argue that a KeyboardInterrupt isn't an error the same way SystemExit and StopIteration aren't errors. I worry about backwards compatibility, but I'll add this to the UPITS[1] Exception PEP (Does anybody else lament the lack of an inheritance diagram in the exceptions module documentation?) -Barry [1] Uber Py-In-The-Sky

(Does anybody else lament the lack of an inheritance diagram in the exceptions module documentation?)
I do lament it! It's a shame that the only useful diagram is hidden in a C source file. --Guido van Rossum (home page: http://www.python.org/~guido/)

----------
Now, in addition, I lament the fact that we've got two disjointly developed sets of documentation, fighting over who can be called authoritative: doc strings and the HTML docs on the web. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)

----------
Now, in addition, I lament the fact that we've got two disjointly developed sets of documentation, fighting over who can be called authoritative: doc strings and the HTML docs on the web. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)

>> >>> import exceptions >> >>> print exceptions.__doc__[1109:] Guido> Now, in addition, I lament the fact that we've got two disjointly Guido> developed sets of documentation, fighting over who can be called Guido> authoritative: doc strings and the HTML docs on the web. :-( Yeah, that's a bit of a bummer. I'm modifying libexcs.tex right now. I will add a comment to exceptions.c noting that the tex source has to be updated if the hierarchy changes. Some enterprising person could probably add a little magic to Doc/Makefile to automatically update the .tex file from the .c file, but I doubt it will change that often. I think the more correct way to do this would be to run help(exceptions) from Doc/Makefile and snatch the class hierarchy that Ping generates for use in the .tex file. I'd then advocate that the module doc string simply refer to the libref docs for the hierarchy. Skip

"Skip" == Skip Montanaro <skip@pobox.com> writes:
Skip> I'd then advocate that the module doc string simply refer to Skip> the libref docs for the hierarchy. Except that as I understand it, the libref docs are separate from the sources, and written in a different language. I know that Emacs and XEmacs manuals are continuously different from the docstrings, and the docstrings are usually more accurate for two reasons: (1) The docstrings are written by people who have just implemented the behavior described, in a form which does not require shifting mental gears. {C,Lisp} -> Texinfo is hard to get right. Requires validating-by-doc-build, so, ok, I can do that later<wink>. (2) Docstrings are a perfect forum for the "many eyes" to make small contributions, and we get a lot of them. It is counterproductive to say "this is no good without a corresponding Texinfo patch." NB. Unlike Emacs Lisp, whose definition is "emergent" from the development process, Python (as I understand it) has a more formal definition process, even for the libraries. So Skip has a good solid theoretical basis for his position IMHO. just-trying-to-confuse-you-with-facts-ly y'rs -- Institute of Policy and Planning Sciences http://turnbull.sk.tsukuba.ac.jp University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN Don't ask how you can "do" free software business; ask what your business can "do for" free software.

BAW> (Does anybody else lament the lack of an inheritance diagram in the BAW> exceptions module documentation?) Try import exceptions help(exceptions) Skip

"SM" == Skip Montanaro <skip@pobox.com> writes:
BAW> (Does anybody else lament the lack of an inheritance diagram BAW> in the exceptions module documentation?) SM> Try | import exceptions | help(exceptions) Ah, it would be nice to have this in the library reference manual. -Barry

SM> Try BAW> | import exceptions BAW> | help(exceptions) BAW> Ah, it would be nice to have this in the library reference manual. Should be checked in shortly... Skip

Skip Montanaro <skip@pobox.com> writes:
That is indeed a different issue. If you want to catch everything (including KeyboardInterrupt), you need an except: clause, in which case it is difficult to get at the exception object. Regards, Martin

Guido van Rossum wrote:
The traceback object could be part of the exception object, just like Java does it. When we have an exception that wraps another exception, both tracebacks would then be available. That's not exactly an implementation benefit, but an application benefit. -- Walter Dörwald · LivingLogic AG, Bayreuth/Germany · www.livinglogic.de

I think you can do this now, though not in a standard way: the wrapping exception would have to retrieve the traceback using sys.exc_info(), and then store it as an instance variable.
That's not exactly an implementation benefit, but an application benefit.
That's OK; I like application benefits better than implementation benefits to motivate feature! Maybe we should try to migrate to doing it this way in the future. With the traceback in the exception object, there's no need to call sys.exc_info() any more! It does mean that the exception object gets modified as it is passed along from frame to frame searching for an exception handler, accumulating traceback info. I think that's fine. If people like this idea enough, perhaps it could be PEPped? --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Maybe we should try to migrate to doing it this way in the GvR> future. With the traceback in the exception object, there's GvR> no need to call sys.exc_info() any more! GvR> If people like this idea enough, perhaps it could be PEPped? I like this idea too, and would be happy to add it to the eventual Exceptions Uber-PEP. Maybe it should be a separate PEP though? -Barry

No, just add sections to the one PEP. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
I can't see any implementation benefits from the requirement. It sounds like you can't either
If the requirement was extended to disallow multiple root classes, it would disambiguate the case of the class Z(str,Exception): It would be an error to raise an exception of class Z. Classes that only inherit from str would continue to operate as string exceptions, classes that inherit from Exception would be caught by their type - you couldn't have a class that is both. Regards, Martin

Yeah, but that's only a backwards compatibility hack. Eventually, string exceptions will be illegal, and then I don't see a good reason why exceptions couldn't derive from multiple classes. So I don't want to start with such a restriction. I'd rather continue to special-case string exceptions. There's no reason why in your example, the exception couldn't match both Exception and a string. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
There are several problems in the std library now: bdb.py:9 BdbQuit is a string exception macpath.py:173 norm_error is a string exception tabnanny.py:48 NannyNag does not derive from Exception xdrlib.py:12 ConversionError (Error) does not derive from Exception Shall I make all of these derive from Exception? Is there any potential problems with doing so? Neal

Please do. Note that the last two line numbers are off w.r.t. current CVS (the exception class is defined a few lines down) -- not sure if that's a lurking PyChecker bug or that you used an older version.
Is there any potential problems with doing so?
I don't think so. --Guido van Rossum (home page: http://www.python.org/~guido/)

Legal, but not particularly useful. Anyway, I think that "derives from Exception" overrules "derives from str" here, so this should be allowed. Note that currently it creates a new-style class and thus it doesn't work. --Guido van Rossum (home page: http://www.python.org/~guido/)

But if you try "except Exception:" or "except Z:" instead, it doesn't work. Very surprising. --Guido van Rossum (home page: http://www.python.org/~guido/)

Well, in the long run I would like all classes to be new-style classes, so at that point at the latest, exceptions will have to follow. Long before that moment, I would like to encourage people to use new-style classes for everything, and that should include exceptions. (Also, at some point before the end state, the default for a class statement would become to create a new-style class rather than a classic class.) This is somewhat separate from enforcing the "exceptions must derive from Exception" rule. We should start warning about string exceptions as well as about class exceptions not deriving from Exception soon. Whether Exception should become a new-style class before, after or at the same time as full enforcement of that rule is an open issue. (Barry, are you taking notes for the transition-to-all-exceptions- deriving-from-Exception PEP?) --Guido van Rossum (home page: http://www.python.org/~guido/)

Can you explain this conflict? Couldn't this be worked around by making an exception for strings?
I think string exceptions are used enough that we should deprecate them on a slower schedule. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
Currently, if you write try: raise "Hallo" except str: pass the exception will pass through. If "new-style classes" (aka types) are allowed, then the string /should/ be caught.
I think string exceptions are used enough that we should deprecate them on a slower schedule.
If you follow Paul's rationale (exceptions should inherit from Exception), then the bug report could be closed, and no action would be needed until Exception becomes a type. Regards, Martin

Gotcha. But I could easily accept a bw compatibility rule that says you can't have a subclass of str (that's not also a subclass of Exception) in the except clause until string exceptions have been removed from the language. All of this is irrelevant though, because...
Fair enough; go ahead and close the bug. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
>> So I would like to propose that string exceptions are >> deprecated for Python 2.3, in order to remove them in Python >> 2.4, simultaneously allowing arbitrary objects as exceptions. GvR> I think string exceptions are used enough that we should GvR> deprecate them on a slower schedule. Is there any controversy that string exceptions should, eventually, be deprecated? If not, then let's come up with a road map for deprecating them, even if their use doesn't raise a deprecation warning in Python 2.3. -Barry

Good point. I do want to start deprecating them, but slowly because they're used so much. Maybe you can draft a brief PEP? --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
>> Is there any controversy that string exceptions should, >> eventually, be deprecated? If not, then let's come up with a >> road map for deprecating them, even if their use doesn't raise >> a deprecation warning in Python 2.3. GvR> Good point. I do want to start deprecating them, but slowly GvR> because they're used so much. Maybe you can draft a brief GvR> PEP? Will do. I'd like to cover the following: - roadmap for deprecating string exceptions (i.e. when will we issue DeprecationWarnings, when will they become illegal). - roadmap for requiring exceptions to inherit from Exception (or discussion on whether this is still a goal). - impact of the transition to new-style classes everywhere on the exception rules. That might be too broad or too narrow -- I'm up for suggestions! -Barry

GvR> I think string exceptions are used enough that we should deprecate GvR> them on a slower schedule. BAW> Is there any controversy that string exceptions should, eventually, BAW> be deprecated? Taking a quick peek at my own code, the only place I see that strings are raised is in code that works with ZServer (e.g. "raise 'redirect'"). I was not speedy to get rid of string exceptions in my own code, but except for external compatibility, I think they are all gone now. Does Zope (clearly the 800-pound gorilla in most backward compatibility discussions) still use them heavily? Skip

Zope 2 uses them heavily. But I doubt it will ever need Python 2.4; more likely, it will settle on Python 2.1.3 (if/when that is released). In Zope 3, string exceptions are officially out of grace. (I don't know if there are any left, but if so, they will be removed soon enough.) --Guido van Rossum (home page: http://www.python.org/~guido/)

"SM" == Skip Montanaro <skip@pobox.com> writes:
SM> Taking a quick peek at my own code, the only place I see that SM> strings are raised is in code that works with ZServer SM> (e.g. "raise 'redirect'"). ---------------^^^^^^^^^^^^^^^ That's kind of scary Skip! I.e. I belive the following is /not/ guaranteed to work in any version of Python that I'm aware of: try: raise 'foo' except 'foo': print 'foo caught' because 'foo' is not (necessarily) 'foo'. Much better to use: FOOEXC = 'foo' try: raise FOOEXC except FOOEXC: print 'foo caught' -Barry

Barry A. Warsaw writes:
Except of course that it *will* work in Python version dating back to (I suspect) 1.0; that certainly was being done in 1.2, though I don't think it was ever recommended practice. That it worked before string interning was an accident of implementation: all the 'foo' in your example were in a single code object, and so were ensured by the compiler to be the same object (they shared an entry in the constants table). After string interning was added, it worked more broadly because interning caused a single 'foo' to be shared. I'd *love* to see a warning issued everywhere a string exception is raised or caught by a non-bare except clause! -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation

"Fred" == Fred L Drake, Jr <fdrake@acm.org> writes:
Fred> Except of course that it *will* work in Python version Fred> dating back to (I suspect) 1.0; that certainly was being Fred> done in 1.2, though I don't think it was ever recommended Fred> practice. Fred> That it worked before string interning was an accident of Fred> implementation: all the 'foo' in your example were in a Fred> single code object, and so were ensured by the compiler to Fred> be the same object (they shared an entry in the constants Fred> table). After string interning was added, it worked more Fred> broadly because interning caused a single 'foo' to be Fred> shared. Of course the first 'foo' and the second 'foo' need not have such a close lexical relationship. And can't interning (I think) be disabled? (Though I'm sure no one does this.) Also, isn't interning limited to just identifier-like strings:
So, yes the simple example I gave will work, but the more general concept, that string exceptions cannot guaranteed to be caught by value, still holds. -Barry

Barry A. Warsaw writes:
Yes, but in practice, the strings that were used for exceptions were simple in this way. I don't know whether there's a #define that controls the use of interning; I can't imaging that anyone would want to use it.
Agreed. But that's always been well-known, and probably even documented. ;-) -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation

[Fred L. Drake, Jr.]
Yes, but in practice, the strings that were used for exceptions were simple in this way.
When I first starting using Python, I believed the exception string had to be named 'error'. Timmy see, Timmy do. Guido scowl, Timmy start using nested tuple exceptions and break Guido's code. Heh heh.
I don't know whether there's a #define that controls the use of interning; I can't imaging that anyone would want to use it.
It's INTERN_STRINGS. I'd like to get rid of it. Ditto DONT_SHARE_SHORT_STRINGS. Ditto CACHE_HASH and COUNT_ALLOCS, for that matter. BTW, all four are used in PyString_FromStringAndSize -- and I'm sure we routinely test all 16 preprocessor variations <wink>. [Barry]
Agreed. But that's always been well-known, and probably even documented. ;-)
It's not that well-known, and because consts are "effectively" interned on a per-codeblock basis, it's easy to fool yourself into believing they're compared by value when writing simple test cases. For example, put this in a file and run it: try: raise "Woo hoo!" except "Woo hoo!": print "caught it" All instances of a given string within a single code block map to the same CO_CONSTS entry, so this *appears* to work fine, despite that it doesn't work at all <wink>.

"TP" == Tim Peters <tim.one@comcast.net> writes:
TP> It's INTERN_STRINGS. I'd like to get rid of it. Ditto TP> DONT_SHARE_SHORT_STRINGS. Ditto CACHE_HASH and COUNT_ALLOCS, TP> for that matter. BTW, all four are used in TP> PyString_FromStringAndSize -- and I'm sure we routinely test TP> all 16 preprocessor variations <wink>. I don't know what half of those do <0.5 wink>, but I'm all for getting rid of optional stuff that in practice no one ever avails themselves of. -Barry

INTERN_STRINGS and CACHE_HASH should always be on (as they are by default). DONT_SHARE_SHORT_STRINGS should always be off (as it is by default). COUNT_ALLOCS should be on iff Py_TRACE_REFS is on (though currently it's always off). I'd be happy to lose all 4 symbols. --Guido van Rossum (home page: http://www.python.org/~guido/)

SM> Taking a quick peek at my own code, the only place I see that SM> strings are raised is in code that works with ZServer SM> (e.g. "raise 'redirect'"). BAW> ---------------^^^^^^^^^^^^^^^ BAW> That's kind of scary Skip! That's what ZServer does or did require. Fortunately for me, this is in code that isn't actually used anymore. From Guido's response, it sounds like ZServer is getting away from that. Skip

Barry, he's doing what Zope tells him to do -- AFAIK Zope doesn't make identifiers available for these magic exceptions. It happens to work because string literals that look like identifiers are always intern()ed -- but the language doesn't guarantee this! --Guido van Rossum (home page: http://www.python.org/~guido/)

"MvL" == Martin v Loewis <martin@v.loewis.de> writes:
MvL> http://python.org/sf/518846 reports that new-style classes MvL> cannot be used as exceptions. I think it is desirable that this MvL> is fixed, but I also believe that it conflicts with string MvL> exceptions. So I would like to propose that string exceptions MvL> are deprecated for Python 2.3, in order to remove them in MvL> Python 2.4, simultaneously allowing arbitrary objects as MvL> exceptions. I didn't read most of this length thread the first time through, but I did run into the bug today in my own code and tried to fix it. I added a patch to 518846 that allows instances of new style classes, where the check is implemented by checking Py_TPFLAGS_HEAPTYPE, which is only defined for objects created by class statements (I think). This doesn't seem to cause any change in the behavior of string-based exceptions. I don't think it's necessary to have "except str:" catch string-based exceptions, because they're supported solely for backwards compatibility. There was also some discussion of making exceptions inherit from Exception, but I think that's a separate issue. Any reason not to commit the patch? Jeremy

In how many places have you posted about this issue? This is the third place where I see you trying to get people's attention. What's the urgency? :-) I don't think the patch is ready yet, see my comment on SF. If we decide that anything needs to be done in this area I want to look at it first, so please don't check anything in yet. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> In how many places have you posted about this issue? This is GvR> the third place where I see you trying to get people's GvR> attention. What's the urgency? :-) There's no urgency at all but a bug report isn't the right place for the discussin, nor is our group's private email. I didn't think that raising the question in the appropriate forum constituted emergency action :-). GvR> I don't think the patch is ready yet, see my comment on SF. If GvR> we decide that anything needs to be done in this area I want to GvR> look at it first, so please don't check anything in yet. Did I miss the consensus on inheriting from Exception? I tried to review the earlier thread, but the early stuff didn't have much on Exception and the later stuff seemed to be about documentation. So it must be buried in the middle if it's there :-). At any rate, I don't understand why it is helpful for classes to inherit from exception. I am also curious -- this is off-topic for exceptions -- what the right way to check for a new-style class is? And what other things define Py_TPFLAGS_HEAPTYPE? Jeremy

One of your messages sounded like you were impatiently waiting to commit your change, and I wondered why that was.
There are different views on this, but fact is that we've documented this as a recommendation since class exceptions were first introduced, and I've certainly considered starting to warn about exceptions raised or tested for that are *not* subclasses of Exception. There was some discussion that concluded that it was a useful feature (e.g. because the Exception class defines a standard signature and some standard attributes), and it was even suggested that in the future the traceback could be stored on the exception instance rather than in a separate variable. This would pave the way to deprecating sys.exc_info(). I kind of like that idea, so I am all for striving to enforce this in the future.
There is no way to distinguish a new-style class, because all type objects can be considered new-style classes. The only thing you could do is checking for "not classic-class". The HEAPTYPE flag is set only for new-style classes that are created dynamically; but eventually I expect that the built-in exceptions will be statically declared new-style classes. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> There was some discussion that concluded that it was a useful GvR> feature (e.g. because the Exception class defines a standard GvR> signature and some standard attributes) But most of the (early) built-in exception interfaces were chosen for backwards compatibility with the old string-based standard exceptions, so I'm not sure how useful they are as a specification. E.g. Exception.__init__() essentially takes a *args and assigns the tuple to exc.args, and that's about it. Maybe in a perfect world that's still a useful signature, I don't know. -Barry

Well, it could certainly grow more standard stuff (like a traceback pointer) and that would be more useful if there was a common base class to inherit it from. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Well, it could certainly grow more standard stuff (like a GvR> traceback pointer) and that would be more useful if there was GvR> a common base class to inherit it from. Agreed. Of course you can always play the old NeXTSTEP game of having one base class for backwards compatibility and another for the New Way, but that's probably more complexity than you really want. -Barry

"BAW" == Barry A Warsaw <barry@zope.com> writes:
"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Well, it could certainly grow more standard stuff (like a GvR> traceback pointer) and that would be more useful if there was a GvR> common base class to inherit it from. BAW> Agreed. Of course you can always play the old NeXTSTEP game of BAW> having one base class for backwards compatibility and another BAW> for the New Way, but that's probably more complexity than you BAW> really want. I'm not sure what the base class(es) actually buys us. We could just as well say by fiat that the interpreter will set the traceback attribute of an exception instance to the traceback. Why do we need a special base class to accomplish that? This is Python. You don't need to do isinstance(). You just need to see if it has the right attributes. BTW, what is the signature for Exception.__init__()? I've written many exception classes, often subclasses of some other exception, but I've hardly ever paid attention to the superclass __init__(). It usually suffices to set the right attributes. Jeremy

"JH" == Jeremy Hylton <jeremy@zope.com> writes:
JH> I'm not sure what the base class(es) actually buys us. We JH> could just as well say by fiat that the interpreter will set JH> the traceback attribute of an exception instance to the JH> traceback. Why do we need a special base class to accomplish JH> that? This is Python. You don't need to do isinstance(). JH> You just need to see if it has the right attributes. You might be right. It certainly hasn't hindered us up 'til now. JH> BTW, what is the signature for Exception.__init__()? I've JH> written many exception classes, often subclasses of some other JH> exception, but I've hardly ever paid attention to the JH> superclass __init__(). It usually suffices to set the right JH> attributes. When it was written in Python, I believe it was defined as class Exception: def __init__(self, *args): self.args = args and that's essentially what it is now that it's implemented in C. But many of the derived exception classes have their own funky __init__()s for backwards compatibility, e.g. EnvironmentError which looks at the number of arguments to decide which of the errno, strerror, and filename attributes to set. -Barry

Fair enough, though having a common base class makes it easier to augment the functionality -- every exception class would automatically inherit any functionality provided by the base class. But here's the real reason (which I brought up when we had this discussion a few weeks ago but didn't remember completely last night): once we reach the nirvana where all exceptions derive from Exception, we can declare that except: is equivament to except Exception: and then, when we also store the traceback on the exception object, we can (eventually) get rid of sys.exc_info().
It's been a documented recommended practice to inherit from Exception since the introduction of class exceptions. Why are you suddenly fighting this? --Guido van Rossum (home page: http://www.python.org/~guido/)

"Martin v. Loewis" wrote:
Should it be arbitrary objects or just subclasses of exception: "It is recommended that user-defined exceptions in new code be derived from Exception, although for backward compatibility reasons, this is not required. Eventually this rule will be tightened." * http://www.python.org/doc/essays/stdexceptions.html Paul Prescod

Can we safely make Exception (and hence all built-in exceptions) a new-style class? This could break user code (even when we don't enforce that exceptions are derived from Exception). --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Can we safely make Exception (and hence all built-in GvR> exceptions) a new-style class? This could break user code GvR> (even when we don't enforce that exceptions are derived from GvR> Exception). What's the advantage of making Exception a new-style class? Isn't that a separate issue from whether 1) we deprecate string exceptions, 2) whether we enforce exceptions to inherit from Exception? -Barry

Guido van Rossum <guido@python.org> writes:
I see no need to make such a change, with this change alone, I can't see risks for breaking code, either. If you would also make Exception.args a slot, there would be a rationale (efficiency), but you would also more likely break user code. Regards, Martin

Guido van Rossum <guido@python.org> writes:
For issues related to needing vs not-needing to dynamically create Java classes and corresponding security restrictions, it would be user-friendlier if Exception on Jython side would remain a classic-style class. We can give more input when we have sorted out the implementation of new-style classes subclassing (that's many month away :( ). Maybe the issues will become non-issues or not. regards.

[Samuele]
Good point. We'll be cautious. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Martin]
If that is the rule, the bug report can be closed as "not-a-bug".
I seem to have a particularly dense day. :-( What does "that" (in "If that is the rule") refer back to? --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
"user-defined exceptions be derived from Exception". It is only a recommendation in the sense that you can use arbitrary classic classes. If the rule is eventually tightened, it is ok if new-style classes are not allowed as exceptions right now. An action is only needed if you pronounce that it is desirable to allow new-style classes as exceptions - which would necessarily have a base class that is not derived from Exception. Regards, Martin

"Samuele Pedroni" <pedroni@inf.ethz.ch> writes:
The issue is more subtle: raising an instance of Z counts as raising a string, so you cannot catch with with "except Z", but you can catch it with the identical object. However, this is not the issue reported in bug #518846: Magnus Heino does not want to inherit from str, and his class does not inherit from Exception, either. Also, I believe that using your class Z as an exception class should not be supported: a "proper" exception should not just merely inherit from Exception - it should have Exception as its only root class (Z has both object and Exception as root classes). So yes, funny things can happen, but they are all accidental, and may stop happening without notice. Regards, Martin

I think that rule is too strong, and I don't see a reason for it. --Guido van Rossum (home page: http://www.python.org/~guido/)

"MvL" == Martin v Loewis <martin@v.loewis.de> writes:
MvL> Also, I believe that using your class Z as an exception class MvL> should not be supported: a "proper" exception should not just MvL> merely inherit from Exception - it should have Exception as MvL> its only root class (Z has both object and Exception as root MvL> classes). Can you explain why you think the rule should be so strict? I don't see a problem with using multiple inheritance to satisfy the "must derive" rule. -Barry

barry@zope.com (Barry A. Warsaw) writes:
The question is, whether, given class Base:pass class MyExc(Base, Exception):pass it would be valid to write try: foo() # raises MyExc except Base: pass If that ought to be allowed, I fail to see the rationale to require that exceptions be derived from Exception: The rationale could be "all exceptions are primarily instances of Exception" - yet in this case, Base is the primary class, and Exception is just a mix-in that plays no further role in this case of exception handling. If you want to allow Base in the except clause, but do allow Base as the base class of MyExc, I'd be curious what run-time semantics you'd associate with this example. Regards, Martin

The "except Base:" class would of course be illegal because Base doesn't derive from Exception. (Although the error might only be detected when MyExc is raised -- but PyChecker could do better.) But the statement "raise MyExc" would be perfectly legal, and could be caught either with "except MyExc" or "except Exception".
I have never heard of the concept "primarily an instance of". I also don't understand why that should be the rule.
the base class of MyExc, I'd be curious what run-time semantics you'd associate with this example.
See above. Before we waste more time on this, let me explain why I like the rule that all exception classes be derived from Exception. It's only a vague liking, and maybe it's not worth making it a rule. I like it because including Exception (or one of its well-known subclasses) in the base class is a clue to the reader that a particular class declaration is used as an exception. AFAIK this is the only reason why Java has a similar rule; C++ does not, and lets you throw any class. I can't see any implementation benefits from the requirement. It sounds like you can't either -- or else you would have pointed them out by now. So maybe we shouldn't bother with this rule, and then we should take the recommendation out of the documentation. But I still kind of like it, for the reason I explained in the previous paragraph. --Guido van Rossum (home page: http://www.python.org/~guido/)

[me]
One other, more practical reason to like the rule: "except Exception:" would become equivalent to "except:". The advantage is that you can then write "except Exception, e:" and catch the exception instance in a local variable without having to call sys.exc_info(). --Guido van Rossum (home page: http://www.python.org/~guido/)

On 28 Mar 2002 at 8:29, Guido van Rossum wrote:
Which, to my mind, is sufficient to justify the rule. Hmm. If the rule were (eventually) strictly enforced, could we get the C++-style "stack allocated object whose destructor releases the resource" trick working? (Which would allow killing off the recurrent "with" / "using" thread.) -- Gordon http://www.mcmillan-inc.com/

Which, to my mind, is sufficient to justify the rule.
And also to mine. (Barry, take note for the PEP. :-)
(a) I'm not sure I like to make that semantics official, since it's hard to implement e.g. in Jython. (b) I'm having another dense day. How would requiring exceptions to inherit from Exception make this easier?
(Which would allow killing off the recurrent "with" / "using" thread.)
In c.l.py? I'm not aware of it. --Guido van Rossum (home page: http://www.python.org/~guido/)

On 28 Mar 2002 at 9:43, Guido van Rossum wrote: [me, on requiring Exception as base class]
Don't blame me - I told JimH he was wasting his time <wink>!
Well, I implicitly hand-waved on a couple steps, like a total revamp of the sys.exc_* stuff. Bleh. No, I guess there's no way around the fact that that dangling reference is either a blessing or a curse, and which it is depends on circumstances external to the system.
We just had one here. Started out on hygenic macros, but ended up on hiding finally clauses. -- Gordon http://www.mcmillan-inc.com/

Guido> One other, more practical reason to like the rule: "except Guido> Exception:" would become equivalent to "except:". Just to make sure I'm not missing something (I probably am), I still think the recommended catch-all except construct should become "except StandardError:" with KeyboardInterrupt migrated to inherit from Exception instead of StandardError. Skip

I think I didn't pay attention when that was being discussed before. I definitely don't like to make "except:" mean anyting besides "catch *all* exceptions." There are too many different use cases to favor a specific non-obvious; for example, the runcode() method in class InteractiveInterpreter() in code.py needs to catch all exceptions including KeyboardInterrupt but excluding SystemExit. Also note that StopIteration and the warning categories don't derive from StandardError; but if any of these is accidentally raised, I'd want my "except:" clause to catch it! And, while sometimes it's confusing that SystemExit is caught by "except:", it's really hard to debug why your program exits without any warning or traceback when a rogue library function raises SystemExit. --Guido van Rossum (home page: http://www.python.org/~guido/)

"Guido" == Guido van Rossum <guido@python.org> writes:
>> Just to make sure I'm not missing something (I probably am), I still >> think the recommended catch-all except construct should become >> "except StandardError:" with KeyboardInterrupt migrated to inherit >> from Exception instead of StandardError. Guido> I think I didn't pay attention when that was being discussed Guido> before. I definitely don't like to make "except:" mean anyting Guido> besides "catch *all* exceptions." I agree with you. But much of the time, as http://python.org/sf/411881 demonstrates, "except:" is the wrong answer. If someone wants to catch "everything", they actually don't want to catch SystemExit or KeyboardInterrupt most of the time. That leads to code like try: fragile_code except (KeyboardInterrupt,SystemExit): raise except: handle_stuff_we_can or, with your suggestion: try: fragile_code except (KeyboardInterrupt,SystemExit): raise except Exception, e: handle_stuff_we_can How often (percentage-wise) do you see that as the catch-all construct? If KeyboardInterrupt inherited from Exception, the above could become: try: fragile_code except StandardError, e: handle_stuff_we_can which is much more likely for lazy programmers to write than the first two constructs. (Yes, the laziest people will still use "except:".) All I'm suggesting is that the recommended usage change slightly. (I guess I'd also vote that all exceptions inherit from Exception...) Guido> There are too many different use cases to favor a specific Guido> non-obvious; for example, the runcode() method in class Guido> InteractiveInterpreter() in code.py needs to catch all exceptions Guido> including KeyboardInterrupt but excluding SystemExit. Also note Guido> that StopIteration and the warning categories don't derive from Guido> StandardError; but if any of these is accidentally raised, I'd Guido> want my "except:" clause to catch it! And, while sometimes it's Guido> confusing that SystemExit is caught by "except:", it's really Guido> hard to debug why your program exits without any warning or Guido> traceback when a rogue library function raises SystemExit. A couple comments on this: * I'm not saying you can't use "except:". I'm not advocating a semantic change to the meaning of "except:". (I am suggesting that KeyboardInterrupt should not inherit from StandardError.) I'm saying that the recommended usage for application programmers should be to avoid it. * Special situations will always remain. The point I'm trying to make is that we should make it easier for application programmers to write good code. I don't think specialized standard library code should be held up as typical usage. I'd prefer to have to modify pick over the entire standard library (as I'm already doing) and have it be easier for Joe Programmer to write robust application code than for code.py to be easier to write and have JP naively write less robust code. * I would hope there are no "rogue" functions in the standard library. If so, we should fix them. As to other people's libraries, we can't do much. SystemExit is a well-defined way to exit the program. If the rogue programmer felt SystemExit was called for at that point, that's between him and the person using his code. Skip

[Skip]
You're looking at this all wrong. In the past, we've focused on saying "unqualified except is wrong". But IMO "except Exception" or "except StandardError" is just as wrong! You're still catching way more exceptions than is good for you. In the few use cases where you really *do* want to catch (almost) all exceptions, I think it's appropriate that you have to think about the exceptions (pun intended).
Sorry. I told you I hadn't read the thread the first time around.
We should fix the "except:" examples by catching a very specific error, like AttributeError, TypeError or KeyError. *Not* by catching Exception or StandardError.
* I would hope there are no "rogue" functions in the standard library.
No, but lots of users write them without thinking. E.g. this would seem a common idiom: def error(msg): print "ERROR:", msg sys.exit(1)
--Guido van Rossum (home page: http://www.python.org/~guido/)

Guido> You're looking at this all wrong. In the past, we've focused on Guido> saying "unqualified except is wrong". But IMO "except Exception" Guido> or "except StandardError" is just as wrong! You're still Guido> catching way more exceptions than is good for you. Point taken. >> * I'm not saying you can't use "except:". I'm not advocating a >> semantic change to the meaning of "except:". (I am suggesting that >> KeyboardInterrupt should not inherit from StandardError.) I'm >> saying that the recommended usage for application programmers >> should be to avoid it. Guido> Sorry. I told you I hadn't read the thread the first time around. So, do we agree on this point? Guido> We should fix the "except:" examples by catching a very specific Guido> error, like AttributeError, TypeError or KeyError. *Not* by Guido> catching Exception or StandardError. Correct. That's what the long-standing bug #411881 is about. It just deals with the standard library however, and doesn't delve into the stuff in Tools, Demos, etc. Skip

Guido> Sorry. I told you I hadn't read the thread the first time around.
So, do we agree on this point?
Yes, "except:" should catch all exceptions, and in the future (when we can enforce the rule) so should "except Exception:".
That's OK. But I don't understand why that bug would provide an argument for special-casing KeyboardInterrupt. --Guido van Rossum (home page: http://www.python.org/~guido/)

>> Correct. That's what the long-standing bug #411881 is about. It >> just deals with the standard library however, and doesn't delve into >> the stuff in Tools, Demos, etc. Guido> That's OK. But I don't understand why that bug would provide an Guido> argument for special-casing KeyboardInterrupt. It doesn't. It's just that KeyboardInterrupt is more like SystemExit than like a real error condition. Skip

"SM" == Skip Montanaro <skip@pobox.com> writes:
>> * I'm not saying you can't use "except:". I'm not advocating a >> semantic change to the meaning of "except:". (I am suggesting >> that KeyboardInterrupt should not inherit from StandardError.) >> I'm saying that the recommended usage for application >> programmers should be to avoid it. Guido> Sorry. I told you I hadn't read the thread the first time Guido> around. SM> So, do we agree on this point? There's definitely precedence for that, and I think you could argue that a KeyboardInterrupt isn't an error the same way SystemExit and StopIteration aren't errors. I worry about backwards compatibility, but I'll add this to the UPITS[1] Exception PEP (Does anybody else lament the lack of an inheritance diagram in the exceptions module documentation?) -Barry [1] Uber Py-In-The-Sky

(Does anybody else lament the lack of an inheritance diagram in the exceptions module documentation?)
I do lament it! It's a shame that the only useful diagram is hidden in a C source file. --Guido van Rossum (home page: http://www.python.org/~guido/)

----------
Now, in addition, I lament the fact that we've got two disjointly developed sets of documentation, fighting over who can be called authoritative: doc strings and the HTML docs on the web. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)

----------
Now, in addition, I lament the fact that we've got two disjointly developed sets of documentation, fighting over who can be called authoritative: doc strings and the HTML docs on the web. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)

>> >>> import exceptions >> >>> print exceptions.__doc__[1109:] Guido> Now, in addition, I lament the fact that we've got two disjointly Guido> developed sets of documentation, fighting over who can be called Guido> authoritative: doc strings and the HTML docs on the web. :-( Yeah, that's a bit of a bummer. I'm modifying libexcs.tex right now. I will add a comment to exceptions.c noting that the tex source has to be updated if the hierarchy changes. Some enterprising person could probably add a little magic to Doc/Makefile to automatically update the .tex file from the .c file, but I doubt it will change that often. I think the more correct way to do this would be to run help(exceptions) from Doc/Makefile and snatch the class hierarchy that Ping generates for use in the .tex file. I'd then advocate that the module doc string simply refer to the libref docs for the hierarchy. Skip

"Skip" == Skip Montanaro <skip@pobox.com> writes:
Skip> I'd then advocate that the module doc string simply refer to Skip> the libref docs for the hierarchy. Except that as I understand it, the libref docs are separate from the sources, and written in a different language. I know that Emacs and XEmacs manuals are continuously different from the docstrings, and the docstrings are usually more accurate for two reasons: (1) The docstrings are written by people who have just implemented the behavior described, in a form which does not require shifting mental gears. {C,Lisp} -> Texinfo is hard to get right. Requires validating-by-doc-build, so, ok, I can do that later<wink>. (2) Docstrings are a perfect forum for the "many eyes" to make small contributions, and we get a lot of them. It is counterproductive to say "this is no good without a corresponding Texinfo patch." NB. Unlike Emacs Lisp, whose definition is "emergent" from the development process, Python (as I understand it) has a more formal definition process, even for the libraries. So Skip has a good solid theoretical basis for his position IMHO. just-trying-to-confuse-you-with-facts-ly y'rs -- Institute of Policy and Planning Sciences http://turnbull.sk.tsukuba.ac.jp University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN Don't ask how you can "do" free software business; ask what your business can "do for" free software.

BAW> (Does anybody else lament the lack of an inheritance diagram in the BAW> exceptions module documentation?) Try import exceptions help(exceptions) Skip

"SM" == Skip Montanaro <skip@pobox.com> writes:
BAW> (Does anybody else lament the lack of an inheritance diagram BAW> in the exceptions module documentation?) SM> Try | import exceptions | help(exceptions) Ah, it would be nice to have this in the library reference manual. -Barry

SM> Try BAW> | import exceptions BAW> | help(exceptions) BAW> Ah, it would be nice to have this in the library reference manual. Should be checked in shortly... Skip

Skip Montanaro <skip@pobox.com> writes:
That is indeed a different issue. If you want to catch everything (including KeyboardInterrupt), you need an except: clause, in which case it is difficult to get at the exception object. Regards, Martin

Guido van Rossum wrote:
The traceback object could be part of the exception object, just like Java does it. When we have an exception that wraps another exception, both tracebacks would then be available. That's not exactly an implementation benefit, but an application benefit. -- Walter Dörwald · LivingLogic AG, Bayreuth/Germany · www.livinglogic.de

I think you can do this now, though not in a standard way: the wrapping exception would have to retrieve the traceback using sys.exc_info(), and then store it as an instance variable.
That's not exactly an implementation benefit, but an application benefit.
That's OK; I like application benefits better than implementation benefits to motivate feature! Maybe we should try to migrate to doing it this way in the future. With the traceback in the exception object, there's no need to call sys.exc_info() any more! It does mean that the exception object gets modified as it is passed along from frame to frame searching for an exception handler, accumulating traceback info. I think that's fine. If people like this idea enough, perhaps it could be PEPped? --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Maybe we should try to migrate to doing it this way in the GvR> future. With the traceback in the exception object, there's GvR> no need to call sys.exc_info() any more! GvR> If people like this idea enough, perhaps it could be PEPped? I like this idea too, and would be happy to add it to the eventual Exceptions Uber-PEP. Maybe it should be a separate PEP though? -Barry

No, just add sections to the one PEP. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum <guido@python.org> writes:
I can't see any implementation benefits from the requirement. It sounds like you can't either
If the requirement was extended to disallow multiple root classes, it would disambiguate the case of the class Z(str,Exception): It would be an error to raise an exception of class Z. Classes that only inherit from str would continue to operate as string exceptions, classes that inherit from Exception would be caught by their type - you couldn't have a class that is both. Regards, Martin

Yeah, but that's only a backwards compatibility hack. Eventually, string exceptions will be illegal, and then I don't see a good reason why exceptions couldn't derive from multiple classes. So I don't want to start with such a restriction. I'd rather continue to special-case string exceptions. There's no reason why in your example, the exception couldn't match both Exception and a string. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
There are several problems in the std library now: bdb.py:9 BdbQuit is a string exception macpath.py:173 norm_error is a string exception tabnanny.py:48 NannyNag does not derive from Exception xdrlib.py:12 ConversionError (Error) does not derive from Exception Shall I make all of these derive from Exception? Is there any potential problems with doing so? Neal

Please do. Note that the last two line numbers are off w.r.t. current CVS (the exception class is defined a few lines down) -- not sure if that's a lurking PyChecker bug or that you used an older version.
Is there any potential problems with doing so?
I don't think so. --Guido van Rossum (home page: http://www.python.org/~guido/)

Legal, but not particularly useful. Anyway, I think that "derives from Exception" overrules "derives from str" here, so this should be allowed. Note that currently it creates a new-style class and thus it doesn't work. --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (16)
-
barry@zope.com
-
Fred L. Drake, Jr.
-
Gordon McMillan
-
Guido van Rossum
-
Jeremy Hylton
-
jeremy@zope.com
-
Martin v. Loewis
-
martin@v.loewis.de
-
Neal Norwitz
-
Patrick K. O'Brien
-
Paul Prescod
-
Samuele Pedroni
-
Skip Montanaro
-
Stephen J. Turnbull
-
Tim Peters
-
Walter Dörwald