Re: string interpolation mystery in Python 2.6

2009-09-16 Thread Scott David Daniels

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

2009-09-12 Thread Alan G Isaac

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-09-12 Thread Vlastimil Brom
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

2009-09-11 Thread Steven D'Aprano
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

2009-09-11 Thread Chris Rebert
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

2009-09-11 Thread Alan G Isaac

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

2009-09-11 Thread Alan G Isaac

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