[pypy-commit] pypy py3.5: Fix %r, %a formatting

arigo pypy.commits at gmail.com
Sat Oct 15 05:18:19 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r87801:9d5476bc80e9
Date: 2016-10-15 11:17 +0200
http://bitbucket.org/pypy/pypy/changeset/9d5476bc80e9/

Log:	Fix %r, %a formatting

diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -439,19 +439,25 @@
             self.std_wp(s)
 
         def fmt_r(self, w_value):
-            self.fmt_a(w_value)
+            if not do_unicode:
+                # on bytes, %r is equivalent to %a
+                self.fmt_a(w_value)
+            else:
+                # on unicodes, %r calls repr(), which typically returns
+                # arbitrary unicode chars if w_value is an arbitrary unicode
+                # string
+                w_value = self.space.repr(w_value)
+                self.std_wp(self.space.unicode_w(w_value))
 
         def fmt_a(self, w_value):
-            if not do_unicode:
-                # - on the bytes StringFormatter, %r or %a must not call
-                #   std_wp(unicode)
-                raise NotImplementedError("FIX ME")
-                # - another problem with fmt_r = fmt_a is that on
-                #   UnicodeFormatter, repr() != ascii() sometimes
-
             from pypy.objspace.std.unicodeobject import ascii_from_object
             w_value = ascii_from_object(self.space, w_value)
-            self.std_wp(self.space.unicode_w(w_value))
+            # %a calls ascii(), which should return an ascii unicode string
+            if do_unicode:
+                value = self.space.unicode_w(w_value)
+            else:
+                value = self.space.str_w(w_value)
+            self.std_wp(value)
 
         def fmt_c(self, w_value):
             self.prec = -1     # just because
diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py
--- a/pypy/objspace/std/test/test_stringformat.py
+++ b/pypy/objspace/std/test/test_stringformat.py
@@ -329,5 +329,13 @@
     def test_ascii(self):
         assert "<%a>" % "test" == "<'test'>"
         assert "<%a>" % "\t\x80" == "<'\\t\\x80'>"
+        assert repr("\xe9") == "'\xe9'"
         assert "<%r>" % "\xe9" == "<'\xe9'>"
         assert "<%a>" % "\xe9" == "<'\\xe9'>"
+
+    def test_ascii_bytes(self):
+        assert b"<%a>" % b"test" == b"<b'test'>"
+        assert b"<%a>" % b"\t\x80" == b"<b'\\t\\x80'>"
+        assert repr(b"\xe9") == "b'\\xe9'"
+        assert b"<%r>" % b"\xe9" == b"<b'\\xe9'>"
+        assert b"<%a>" % b"\xe9" == b"<b'\\xe9'>"


More information about the pypy-commit mailing list