From 000730ecaa24f39ff0459573a293e62d6928d3de Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Sun, 30 Aug 2015 12:43:21 +0100
Subject: [PATCH] py/objstr: Simplify error handling for bad conversion
 specifier.

---
 py/objstr.c                   | 22 ++++++++++++----------
 tests/basics/string_format.py |  8 ++++++++
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/py/objstr.c b/py/objstr.c
index f91e1731c..814dd9e13 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -894,9 +894,17 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa
             } else {
                 if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
                     terse_str_format_value_error();
-                } else {
+                } else if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL) {
                     nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
-                        "end of format while looking for conversion specifier"));
+                        "bad conversion specifier"));
+                } else {
+                    if (str >= top) {
+                        nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
+                            "end of format while looking for conversion specifier"));
+                    } else {
+                        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+                            "unknown conversion specifier %c", *str));
+                    }
                 }
             }
         }
@@ -989,15 +997,9 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwa
             mp_print_kind_t print_kind;
             if (conversion == 's') {
                 print_kind = PRINT_STR;
-            } else if (conversion == 'r') {
-                print_kind = PRINT_REPR;
             } else {
-                if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
-                    terse_str_format_value_error();
-                } else {
-                    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
-                        "unknown conversion specifier %c", conversion));
-                }
+                assert(conversion == 'r');
+                print_kind = PRINT_REPR;
             }
             vstr_t arg_vstr;
             mp_print_t arg_print;
diff --git a/tests/basics/string_format.py b/tests/basics/string_format.py
index 55d843e1e..b0e49f530 100644
--- a/tests/basics/string_format.py
+++ b/tests/basics/string_format.py
@@ -140,6 +140,13 @@ try:
 except ValueError:
     print('ValueError')
 
+# end of format parsing conversion specifier
+try:
+    '{!'.format('a')
+except ValueError:
+    print('ValueError')
+
+# unknown conversion specifier
 try:
     'abc{!d}'.format('1')
 except ValueError:
@@ -150,6 +157,7 @@ try:
 except ValueError:
     print('ValueError')
 
+# expected ':' after specifier
 try:
     '{!s :}'.format(2)
 except ValueError:
-- 
GitLab