Thanks Steve, I appreciate your patience. On Jan 31, 1:39 am, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > If the built-in isn't Unicode aware, subclassing it won't magically make > it so :-) Oh, I agree. If I have a string mesg that is unicode-not-ascii and I say try: raise Exception mesg except Exception, err: print "Trouble"+mesg then I have problems. I however am under the impression, perhaps mistaken, that the built-in exceptions in the library will return as error strings only ascii. (I take as evidence of my understanding that the built-in exceptions have a __str__() method but do not have an explicit __unicode__() and so rely on a unicode(err) call being passed on to __str__(). But as I've said above, I've been wrong so many times before. ;-)
My main point about the built-ins is that I want to catch them along with my own exceptions. That's what I meant by the next paragraph. My class myException is a subclass of Exception so I can catch my stuff and the standard stuff with an all-in-one panic button. > > > For instance, I write a lot of CGI and I want to wrap everything in a > > try .. except. > > try: > > main() > > except Exception, err: > > print "Terrible blunder: ",str(err) > > so that the err can be one of my exceptions, or can be one that came > > with Python. > > (And, that I can see, err.args can be either the relevant > > string or a tuple containing the relevant string and the documentation > > is silent on whether in the built-in exceptions if err.args is a tuple > > then the string is guaranteed to be first in the tuple.) > > Does it matter? Just print the tuple. In truth, it does matter. In that example, for instance, some error message is passed on to the user and I don't want it to be too bad. "Database cannot be opened" is better than a "(u'Database cannot be opened,1)"-type thing. Besides which, Python is a nice language, and I'm certain there is a nice way to do this; it is just that I'm having trouble making it out. > >> (2) convert the file name to ASCII before you store it; or > > > I need the non-ascii information, though, which is why I included it > > in the error message. > > If you have the exception captured in "err", then you can grab it with > err.where_i_put_the_unicode. I want a method of grabbing it that is the same as the method used by the built-ins, for the uniformity reasons that I gave above. That I could make out, the documentation was silent on what is the approved way to grab the string. > >> (3) add a __str__ method to your exception that is Unicode aware. > > > I have two difficulties with this: (1) as above I often raise Python's > > built-in exceptions and for those __str__() is what it is, and > > Then don't use the built-in exception. If it won't do what you want it do > do, use something else. I use my exceptions for errors in my logic, etc. But not being perfect, sometimes I raise exceptions that I had not anticipated; these are built-ins. > > (2) this > > goes against the meaning of __str__() that I find in the documentation > > in ref/customization.html which says that the return value must be a > > string object. > > I didn't mean return a unicode object :) > > You're absolutely correct. Your __str__ would need to return a string > object, which means encoding the Unicode correctly to get a string object > without raising an exception. > > e.g. something like this maybe (untested, not thought-through, probably > won't work correctly, blah blah blah): > > def __str__(self): > s = self.args.encode('ascii', 'replace') > return "Unicode error converted to plain ASCII:\n" + s > > or whatever encoding scheme works for your application. I did discuss this suggestion from another person above. That would mean either (a) throwing away the unicode-not-ascii parts of the error message (but I want those parts, which is why I put them in there) or (b) hard-coding the output encoding for error strings in hundreds of error cases (yes, I have hundreds) or (c) passing as a parameter the errorEncoding to each function that I write. That last case doesn't seem to be to be a likely best practice for such a nice language as Python; I want a way to get the unicode object and go forward in the program with that. > It can take whatever you want it to take: > > class MyStupidException(Exception): > def __init__(self, dayofweek, breakfast="spam and baked beans", > *everythingelse): > self.day = dayofweek > self.breakfast = breakfast > self.args = everythingelse > def __str__(self): > s = "On %s I ate %s and then an error '%s' occurred." % \ > (self.day.title(), self.breakfast, self.args) > return s > > >>> raise MyStupidException('monday', 'cheese', 'bad things', 'happened', 2) > > Traceback (most recent call last): > File "<stdin>", line 1, in ? > __main__.MyStupidException: On Monday I ate cheese and then an error > '('bad things', 'happened', 2)' occurred. Thank you for the example; I learned something from it. But as I mentioned above, I need to guard against the system raising built-ins also and so I am still a bit puzzled by how to get at the error strings in built-ins. In case anyone is still reading this :-) someone else suggested the err.message attribute. I had missed that in the documentation somehow, but on rereading it, I thought he had solved my problem. However, sadly, I cannot get Python to like a call to err.message: .......................................................... $ python Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02) [GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> try: ... raise Exception, 'this is the error message' ... except Exception, err: ... print "result: ",err.message ... result: Traceback (most recent call last): File "<stdin>", line 4, in ? AttributeError: Exception instance has no attribute 'message' >>> ...................................................................................... So, in case it helps anyone, I am going with this: ..................................................................................... def errorValue(err): """Return the string error message from an exception message string. err exception instance Note: I cannot get err.message to work. I sent a note to clp on Jan 29 2007 with a related query and this is the best that I figured out. """ return err[0] class jhError(StandardError): """Subclass this to get exceptions that behave correctly when you do this. try: raise subclassOfJhError, 'some error message with unicode chars' except subclassOfJhError, err mesg='the message is '+unicode(err) """ def __unicode__(self): return errorValue(self) class myException(jhError): pass .................................................................................... No doubt I'll discover what is wrong with it today. :-) Jim -- http://mail.python.org/mailman/listinfo/python-list