pypy2.7-v7.3.9 encoded str use __mod__ method raise UnicodeDecodeError
env
pypy version: pypy2.7-v7.3.9
os: Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 (closed) SMP Mon Oct 19 16:18:59 UTC 2020
issue
my code:
>>>> fmt = "α:%s"
>>>> fmt % u"test"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
some questions
source code: pypy/objspace/std/formatting.py
why check_ascii_or_raise when got_unicode is true rather than check_utf8_or_raise?
def fmt_s(self, w_value):
space = self.space
got_unicode = space.isinstance_w(w_value, space.w_unicode)
if not do_unicode:
if got_unicode:
# Make sure the format string is ascii encodable
check_ascii_or_raise(space, self.fmt)
raise NeedUnicodeFormattingError
s = self.string_formatting(w_value)
else:
if not got_unicode:
w_value = space.call_function(space.w_unicode, w_value)
else:
from pypy.objspace.std.unicodeobject import unicode_from_object
w_value = unicode_from_object(space, w_value)
s = space.utf8_w(w_value)
self.std_wp(s, False)
why not assign do_unicode to true when w_format or w_values is instance of space.w_unicode. may be this is a fast path.
def mod_format(space, w_format, w_values, do_unicode=False):
if space.isinstance_w(w_values, space.w_tuple):
values_w = space.fixedview(w_values)
return format(space, w_format, values_w, None, do_unicode)
else:
# we check directly for dict to avoid obscure checking
# in simplest case
if space.isinstance_w(w_values, space.w_dict) or \
(space.lookup(w_values, '__getitem__') and
not space.isinstance_w(w_values, space.w_basestring)):
return format(space, w_format, [w_values], w_values, do_unicode)
else:
return format(space, w_format, [w_values], None, do_unicode)