Re: [Tutor] Subclassing Exceptions
On Friday 06 January 2012, Steven D'Aprano wrote: Chris Fuller wrote: class Foo(SyntaxError): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: None Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? What do you mean, doesn't work? It looks like it works to me. You get a Foo exception, exactly as expected. The error message isn't what you expect, because you're making unwarranted assumptions about SyntaxError and how it works. In general, when you override a method, you take full responsibility to perform everything that the superclass method was supposed to do. In this case, you fail to assign to msg as well as args. It is safer to overload a message rather than override it: class Spam(SyntaxError): ... def __init__(self, *args): ... if args: ... args = (I pity the fool who made a mistake,) + args[1:] ... super(Spam, self).__init__(*args) ... raise Spam('you made a mistake', 1, 2) Traceback (most recent call last): File stdin, line 1, in module __main__.Spam: I pity the fool who made a mistake Unfortunately, there's no real consistency in what arguments exceptions are expected to take. The best thing is to read the docs, if they have any, or use introspection and trial and error to work out what they do. try: ... raise SyntaxError(you made a mistake) ... except SyntaxError, err: ... pass ... err.msg 'you made a mistake' See dir(err) for more; you can use help(SyntaxError) but unfortunately it isn't very useful. You probably shouldn't inherit from SyntaxError, since it represents syntax errors in the Python code being interpreted or compiled. Any syntax error in your own data structures should be independent of SyntaxError. In Python: Essential Reference, David Beazley recommends that the parameters of the exception be assigned to the args attribute, so it is passed all the way through the traceback. You will observe that the last element in the traceback loses this information when subclassed from SyntaxError. This isn't a problem when the whole traceback is laid out before you, but can come into play with automated tools that catch/log/manipulate exceptions. This behavior of exceptions isn't apparently mentioned in the canonical documentation, however. I had the same thought about not wanting to mix syntax errors in the data with syntax errors in the code, but that applies to any exception, really. In fact, it's better to inherit from a more derived class, because when you catch an ancestor, you'll be grabbing less greedily at the possible coding errors. Which suggests that giving a damn about built-in ancestors of user-defined exceptions is a losing proposition, now that I think about it. Cheers ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Subclassing Exceptions
On 01/07/2012 03:56 PM, Steven D'Aprano wrote: Chris Fuller wrote: You probably shouldn't inherit from SyntaxError, since it represents syntax errors in the Python code being interpreted or compiled. Any syntax error in your own data structures should be independent of SyntaxError. I'd say a syntactical error in your own data structure is a kind of ValueError. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Subclassing Exceptions
I had an interesting experience today. Python 2.7.1 (r271:86832, Nov 28 2010, 19:31:37) [GCC 4.4.5] on linux2 Type help, copyright, credits or license for more information. class Foo(Exception): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: (1, 2, 3) class Foo(SyntaxError): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: None Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? By the way, inheriting from StandardError, the direct ancestor of SyntaxError, works as expected, and its parent is Exception. Cheers ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Subclassing Exceptions
Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? If somebody wanted to catch a ValueError, would they also mean to catch my error? (The same with SyntaxError and so on). Probably not. If they would, then I raise the relevant exception. It is very possible to accidentally catch the wrong thing if you put too much in a try block, and I don't like making that any easier. -- Devin On Fri, Jan 6, 2012 at 10:24 PM, Chris Fuller cfuller...@thinkingplanet.net wrote: I had an interesting experience today. Python 2.7.1 (r271:86832, Nov 28 2010, 19:31:37) [GCC 4.4.5] on linux2 Type help, copyright, credits or license for more information. class Foo(Exception): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: (1, 2, 3) class Foo(SyntaxError): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: None Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? By the way, inheriting from StandardError, the direct ancestor of SyntaxError, works as expected, and its parent is Exception. Cheers ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Subclassing Exceptions
Chris Fuller wrote: class Foo(SyntaxError): ... def __init__(self, a,b,c): ... self.args = (a,b,c) ... raise Foo(1,2,3) Traceback (most recent call last): File stdin, line 1, in module __main__.Foo: None Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? What do you mean, doesn't work? It looks like it works to me. You get a Foo exception, exactly as expected. The error message isn't what you expect, because you're making unwarranted assumptions about SyntaxError and how it works. In general, when you override a method, you take full responsibility to perform everything that the superclass method was supposed to do. In this case, you fail to assign to msg as well as args. It is safer to overload a message rather than override it: class Spam(SyntaxError): ... def __init__(self, *args): ... if args: ... args = (I pity the fool who made a mistake,) + args[1:] ... super(Spam, self).__init__(*args) ... raise Spam('you made a mistake', 1, 2) Traceback (most recent call last): File stdin, line 1, in module __main__.Spam: I pity the fool who made a mistake Unfortunately, there's no real consistency in what arguments exceptions are expected to take. The best thing is to read the docs, if they have any, or use introspection and trial and error to work out what they do. try: ... raise SyntaxError(you made a mistake) ... except SyntaxError, err: ... pass ... err.msg 'you made a mistake' See dir(err) for more; you can use help(SyntaxError) but unfortunately it isn't very useful. You probably shouldn't inherit from SyntaxError, since it represents syntax errors in the Python code being interpreted or compiled. Any syntax error in your own data structures should be independent of SyntaxError. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Subclassing Exceptions
Devin Jeanpierre wrote: Inheriting from SyntaxError doesn't work! When I create a new exception, I generally subclass from the built-in exception it most resembles, in case there was some reason to also catch it via an ancestor. But I'm not sure if that is really all that useful an idea in practice. How do you folk do it? If somebody wanted to catch a ValueError, would they also mean to catch my error? (The same with SyntaxError and so on). Probably not. If your error represents a value error, then yes they would. But in that case, why should I subclass ValueError instead of just using ValueError itself? Writing my own exceptions is only useful if I intend to give the caller the *choice* of either treating my exception the same or different from ValueError: that is, if my error is a more specific kind of ValueError. If it is not a specific kind of value error, then just use the generic built-in ValueError exception instead. try: x = some_function() except MyValueError: # treat my errors specially except ValueError: # any other kind of ValueError caught here vs. try: x = some_function() except ValueError: # any kind of ValueError caught here, including MyValueError The same goes for all exception types, although in practice I find that I generally only subclass ValueError. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor