Re: string interpolation mystery in Python 2.6
Alan G Isaac wrote: George Brandl explained it to me this way: It's probably best explained with a bit of code: >>> class C(object): ... def __str__(self): return '[str]' ... def __unicode__(self): return '[unicode]' ... >>> "%s %s" % ('foo', C()) 'foo [str]' >>> "%s %s" % (u'foo', C()) u'foo [unicode]' I.e., as soon as a Unicode element is interpolated into a string, further interpolations automatically request Unicode via __unicode__, if it exists. Even more fun (until you know what is going on): >>> c = C() >>> "%s %s %s" % (c, u'c', c) u'[str] c [unicode]' --Scott David Daniels Scott David dani...@acm.org -- http://mail.python.org/mailman/listinfo/python-list
Re: string interpolation mystery in Python 2.6
On 9/11/2009 9:42 PM, Steven D'Aprano wrote: However, I must admit I'm perplexed why the original example is calling __unicode__() in the first place! Given the line: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, error)) it looks to me like it should be calling error.__str__() not error.__unicode(). Making the suggested edit: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, str(error))) should have no effect. But it (apparently) does. This brings us back to Alan's original question: "MYSTERY: how can "%s"%error be different from "%s"%str(error) in Python 2.6?" George Brandl explained it to me this way: It's probably best explained with a bit of code: >>> >>> class C(object): ... def __str__(self): return '[str]' ... def __unicode__(self): return '[unicode]' ... >>> "%s %s" % ('foo', C()) 'foo [str]' >>> "%s %s" % (u'foo', C()) u'foo [unicode]' I.e., as soon as a Unicode element is interpolated into a string, further interpolations automatically request Unicode via __unicode__, if it exists. Pretty subtle ... Cheers, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
Re: string interpolation mystery in Python 2.6
2009/9/12 Steven D'Aprano : > On Fri, 11 Sep 2009 15:19:05 -0700, Chris Rebert wrote: > >> Sounds like IOError or one of its ancestors defines both __str__() and >> __unicode__ () special methods but has them produce different output. > > > That's what it looks like to me too, which I wouldn't call either a bug > or a feature. I don't think Python makes any promises regarding exception > messages. > > There are some report about the apparently same issue in the bug tracker. http://bugs.python.org/issue5274 http://bugs.python.org/issue6108 vbr -- http://mail.python.org/mailman/listinfo/python-list
Re: string interpolation mystery in Python 2.6
On Fri, 11 Sep 2009 15:19:05 -0700, Chris Rebert wrote: > On Fri, Sep 11, 2009 at 3:12 PM, Alan G Isaac > wrote: >> Michael Foord came up with a much simpler illustration. With Python >> 2.6:: [snip] > Sounds like IOError or one of its ancestors defines both __str__() and > __unicode__ () special methods but has them produce different output. That's what it looks like to me too, which I wouldn't call either a bug or a feature. I don't think Python makes any promises regarding exception messages. However, I must admit I'm perplexed why the original example is calling __unicode__() in the first place! Given the line: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, error)) it looks to me like it should be calling error.__str__() not error.__unicode(). Making the suggested edit: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, str(error))) should have no effect. But it (apparently) does. This brings us back to Alan's original question: "MYSTERY: how can "%s"%error be different from "%s"%str(error) in Python 2.6?" -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: string interpolation mystery in Python 2.6
On Fri, Sep 11, 2009 at 3:12 PM, Alan G Isaac wrote: > Michael Foord came up with a much simpler > illustration. With Python 2.6:: > > >>> try: > ... open('flooble') > ... except Exception as e: > ... pass > ... > >>> e > IOError(2, 'No such file or directory') > >>> unicode(e) > u"(2, 'No such file or directory')" > >>> str(e) > "[Errno 2] No such file or directory: 'flooble'" > >>> u'%s' % e > u"(2, 'No such file or directory')" > >>> '%s' % e > "[Errno 2] No such file or directory: 'flooble'" Sounds like IOError or one of its ancestors defines both __str__() and __unicode__ () special methods but has them produce different output. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: string interpolation mystery in Python 2.6
Michael Foord came up with a much simpler illustration. With Python 2.6:: >>> try: ... open('flooble') ... except Exception as e: ... pass ... >>> e IOError(2, 'No such file or directory') >>> unicode(e) u"(2, 'No such file or directory')" >>> str(e) "[Errno 2] No such file or directory: 'flooble'" >>> u'%s' % e u"(2, 'No such file or directory')" >>> '%s' % e "[Errno 2] No such file or directory: 'flooble'" Cheers, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
string interpolation mystery in Python 2.6
MYSTERY: how can "%s"%error be different from "%s"%str(error) in Python 2.6? APOLOGY: I tried to strip this down, but could not find a simple way to reproduce the problem. This way works, however. (There is a discussion on the docutils-develop list.) Although there are several steps, we are talking about less than 5 minutes to document the puzzle. Please use the specific revision (or earlier) in the directions, as later revisions implement a work around. 1. Check out revision 6121 from docutils http://docutils.sourceforge.net/docs/dev/repository.html 2. Install docutils under Python 2.6 3. Process the file below [1]_ using the rst2html.py script (found in Python26/Scripts on Windows platforms) 4. Note the IOError:: temp.rst:: (SEVERE/4) Problems with "include" directive path: IOError: (2, 'No such file or directory'). Exiting due to level-4 (SEVERE) system message. 5. Make the following change and *no other* changes: In docutils/parsers/rst/directives/misc.py (line 66-67) change :: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, error)) to :: raise self.severe('Problems with "%s" directive path:\n%s: %s.' % (self.name, error.__class__.__name__, str(error))) 6. Process the same file the same way. Note the change in the IOError:: temp.rst:: (SEVERE/4) Problems with "include" directive path: IOError: [Errno 2] No such file or directory: 'doesnotexist.rst'. Exiting due to level-4 (SEVERE) system message. 7. Try this again in Python 2.5. The correct (filename reported) error report is produced both times. So this is a Python 2.6 change. Clues? Bug or feature? I'm going to hazard a guess that there was an undocumented (in What's New) change to the __unicode__ method of BaseException. Thanks, Alan Isaac .. [1] Following is the rst file to process: Test This is just a test. .. include:: doesnotexist.rst -- http://mail.python.org/mailman/listinfo/python-list