From 76d982ef343dcadd35355aed9c568984c850fb7b Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Mon, 13 Jan 2014 19:19:16 +0200
Subject: [PATCH] type->print(): Distinguish str() and repr() variety by
 passing extra param.

---
 py/builtin.c                     | 10 ++--------
 py/obj.c                         |  8 ++++----
 py/obj.h                         | 10 +++++++---
 py/objbool.c                     |  2 +-
 py/objcomplex.c                  |  2 +-
 py/objdict.c                     | 10 +++++-----
 py/objexcept.c                   | 18 +++++++++++++++---
 py/objfloat.c                    |  2 +-
 py/objgenerator.c                |  2 +-
 py/objint.c                      |  2 +-
 py/objint.h                      |  2 +-
 py/objlist.c                     |  4 ++--
 py/objmodule.c                   |  2 +-
 py/objnone.c                     |  2 +-
 py/objset.c                      |  4 ++--
 py/objslice.c                    |  4 ++--
 py/objstr.c                      | 13 +++++++++----
 py/objtuple.c                    |  4 ++--
 py/objtuple.h                    |  2 +-
 py/objtype.c                     |  4 ++--
 stm/main.c                       | 10 +++++-----
 stm/timer.c                      |  2 +-
 tests/basics/tests/exception1.py | 12 +++++++++---
 unix/file.c                      |  2 +-
 unix/main.c                      |  4 ++--
 25 files changed, 79 insertions(+), 58 deletions(-)

diff --git a/py/builtin.c b/py/builtin.c
index 8f93e843b..a45b1463d 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -64,7 +64,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj, 2, mp_builtin___buil
 
 static mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
     if (o != mp_const_none) {
-        mp_obj_print(o);
+        mp_obj_print(o, PRINT_REPR);
         printf("\n");
     }
     return mp_const_none;
@@ -285,13 +285,7 @@ static mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args) {
         if (i > 0) {
             printf(" ");
         }
-        if (MP_OBJ_IS_TYPE(args[i], &str_type)) {
-            // special case, print string raw
-            printf("%s", qstr_str(mp_obj_str_get(args[i])));
-        } else {
-            // print the object Python style
-            mp_obj_print(args[i]);
-        }
+        mp_obj_print(args[i], PRINT_STR);
     }
     printf("\n");
     return mp_const_none;
diff --git a/py/obj.c b/py/obj.c
index 206bf7a24..9ca3d5d16 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -41,21 +41,21 @@ void printf_wrapper(void *env, const char *fmt, ...) {
     va_end(args);
 }
 
-void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     if (MP_OBJ_IS_SMALL_INT(o_in)) {
         print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(o_in));
     } else {
         mp_obj_base_t *o = o_in;
         if (o->type->print != NULL) {
-            o->type->print(print, env, o_in);
+            o->type->print(print, env, o_in, kind);
         } else {
             print(env, "<%s>", o->type->name);
         }
     }
 }
 
-void mp_obj_print(mp_obj_t o_in) {
-    mp_obj_print_helper(printf_wrapper, NULL, o_in);
+void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
+    mp_obj_print_helper(printf_wrapper, NULL, o_in, kind);
 }
 
 bool mp_obj_is_callable(mp_obj_t o_in) {
diff --git a/py/obj.h b/py/obj.h
index 6dcc6827e..7c740182a 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -85,7 +85,11 @@ typedef mp_obj_t (*mp_fun_t)(void);
 typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *);
 typedef mp_obj_t (*mp_fun_kw_t)(mp_obj_t, struct _mp_map_t*);
 
-typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o);
+typedef enum {
+    PRINT_STR, PRINT_REPR
+} mp_print_kind_t;
+
+typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o, mp_print_kind_t kind);
 typedef mp_obj_t (*mp_make_new_fun_t)(mp_obj_t type_in, int n_args, const mp_obj_t *args); // args are in reverse order in the array
 typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array
 typedef mp_obj_t (*mp_call_n_kw_fun_t)(mp_obj_t fun, int n_args, int n_kw, const mp_obj_t *args); // args are in reverse order in the array
@@ -230,8 +234,8 @@ mp_obj_t mp_obj_new_module(qstr module_name);
 mp_obj_t mp_obj_get_type(mp_obj_t o_in);
 const char *mp_obj_get_type_str(mp_obj_t o_in);
 
-void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in);
-void mp_obj_print(mp_obj_t o);
+void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
+void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
 
 bool mp_obj_is_callable(mp_obj_t o_in);
 machine_int_t mp_obj_hash(mp_obj_t o_in);
diff --git a/py/objbool.c b/py/objbool.c
index da9a67806..66f9e902a 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -13,7 +13,7 @@ typedef struct _mp_obj_bool_t {
     bool value;
 } mp_obj_bool_t;
 
-static void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_bool_t *self = self_in;
     if (self->value) {
         print(env, "True");
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 1036bae42..bd103bbfa 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -21,7 +21,7 @@ typedef struct _mp_obj_complex_t {
 
 mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
 
-void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_complex_t *o = o_in;
     if (o->real == 0) {
         print(env, "%.8gj", o->imag);
diff --git a/py/objdict.c b/py/objdict.c
index e164ed74c..da1b5b9f5 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -20,7 +20,7 @@ typedef struct _mp_obj_dict_t {
 static mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur);
 static mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in);
 
-static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_dict_t *self = self_in;
     bool first = true;
     print(env, "{");
@@ -31,9 +31,9 @@ static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
             print(env, ", ");
         }
         first = false;
-        mp_obj_print_helper(print, env, next->key);
+        mp_obj_print_helper(print, env, next->key, PRINT_REPR);
         print(env, ": ");
-        mp_obj_print_helper(print, env, next->value);
+        mp_obj_print_helper(print, env, next->value, PRINT_REPR);
     }
     print(env, "}");
 }
@@ -350,7 +350,7 @@ static mp_obj_t dict_view_getiter(mp_obj_t view_in) {
     return o;
 }
 
-static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     assert(MP_OBJ_IS_TYPE(self_in, &dict_view_type));
     mp_obj_dict_view_t *self = self_in;
     bool first = true;
@@ -363,7 +363,7 @@ static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void
             print(env, ", ");
         }
         first = false;
-        mp_obj_print_helper(print, env, next);
+        mp_obj_print_helper(print, env, next, PRINT_REPR);
     }
     print(env, "])");
 }
diff --git a/py/objexcept.c b/py/objexcept.c
index f083e61e5..67e6d6315 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -21,13 +21,25 @@ typedef struct mp_obj_exception_t {
     mp_obj_tuple_t args;
 } mp_obj_exception_t;
 
-void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_exception_t *o = o_in;
     if (o->msg != 0) {
         print(env, "%s: %s", qstr_str(o->id), qstr_str(o->msg));
     } else {
-        print(env, "%s", qstr_str(o->id));
-        tuple_print(print, env, &o->args);
+        // Yes, that's how CPython has it
+        if (kind == PRINT_REPR) {
+            print(env, "%s", qstr_str(o->id));
+        }
+        if (kind == PRINT_STR) {
+            if (o->args.len == 0) {
+                print(env, "");
+                return;
+            } else if (o->args.len == 1) {
+                mp_obj_print_helper(print, env, o->args.items[0], PRINT_STR);
+                return;
+            }
+        }
+        tuple_print(print, env, &o->args, kind);
     }
 }
 
diff --git a/py/objfloat.c b/py/objfloat.c
index bb44ac954..1ac8754e4 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -19,7 +19,7 @@ typedef struct _mp_obj_float_t {
 
 mp_obj_t mp_obj_new_float(mp_float_t value);
 
-static void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+static void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_float_t *o = o_in;
     print(env, "%.8g", o->value);
 }
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 7eeb4ef80..40f202df3 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -61,7 +61,7 @@ typedef struct _mp_obj_gen_instance_t {
     mp_obj_t state[];
 } mp_obj_gen_instance_t;
 
-void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     print(env, "<generator object 'fun-name' at %p>", self_in);
 }
 
diff --git a/py/objint.c b/py/objint.c
index c0bf756f1..efec60030 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -39,7 +39,7 @@ const mp_obj_type_t int_type = {
 
 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
 // This is called only for non-SMALL_INT
-void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
 }
 
 // This is called only for non-SMALL_INT
diff --git a/py/objint.h b/py/objint.h
index 14cf977be..7d43971ec 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -5,5 +5,5 @@ typedef struct _mp_obj_int_t {
 #endif
 } mp_obj_int_t;
 
-void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in);
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
 mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
diff --git a/py/objlist.c b/py/objlist.c
index 100a02f3c..829677b43 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -26,14 +26,14 @@ static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
 /******************************************************************************/
 /* list                                                                       */
 
-static void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+static void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_list_t *o = o_in;
     print(env, "[");
     for (int i = 0; i < o->len; i++) {
         if (i > 0) {
             print(env, ", ");
         }
-        mp_obj_print_helper(print, env, o->items[i]);
+        mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
     }
     print(env, "]");
 }
diff --git a/py/objmodule.c b/py/objmodule.c
index ade936917..50d2bb35e 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -17,7 +17,7 @@ typedef struct _mp_obj_module_t {
     mp_map_t *globals;
 } mp_obj_module_t;
 
-static void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_module_t *self = self_in;
     print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name));
 }
diff --git a/py/objnone.c b/py/objnone.c
index c0efe6c0f..84d0ba164 100644
--- a/py/objnone.c
+++ b/py/objnone.c
@@ -10,7 +10,7 @@ typedef struct _mp_obj_none_t {
     mp_obj_base_t base;
 } mp_obj_none_t;
 
-void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     print(env, "None");
 }
 
diff --git a/py/objset.c b/py/objset.c
index ba083ada8..6ea6d62d8 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -25,7 +25,7 @@ typedef struct _mp_obj_set_it_t {
 
 static mp_obj_t set_it_iternext(mp_obj_t self_in);
 
-void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_set_t *self = self_in;
     if (self->set.used == 0) {
         print(env, "set()");
@@ -39,7 +39,7 @@ void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
                 print(env, ", ");
             }
             first = false;
-            mp_obj_print_helper(print, env, self->set.table[i]);
+            mp_obj_print_helper(print, env, self->set.table[i], PRINT_REPR);
         }
     }
     print(env, "}");
diff --git a/py/objslice.c b/py/objslice.c
index d95ccef06..8abcea08d 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -16,7 +16,7 @@ typedef struct _mp_obj_ellipsis_t {
     mp_obj_base_t base;
 } mp_obj_ellipsis_t;
 
-void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     print(env, "Ellipsis");
 }
 
@@ -42,7 +42,7 @@ typedef struct _mp_obj_slice_t {
     machine_int_t stop;
 } mp_obj_slice_t;
 
-void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_slice_t *o = o_in;
     print(env, "slice(" INT_FMT ", " INT_FMT ")", o->start, o->stop);
 }
diff --git a/py/objstr.c b/py/objstr.c
index 8b7ab9692..81fd95291 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -22,10 +22,14 @@ static mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur);
 /******************************************************************************/
 /* str                                                                        */
 
-void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_str_t *self = self_in;
-    // TODO need to escape chars etc
-    print(env, "'%s'", qstr_str(self->qstr));
+    if (kind == PRINT_STR) {
+        print(env, "%s", qstr_str(self->qstr));
+    } else {
+        // TODO need to escape chars etc
+        print(env, "'%s'", qstr_str(self->qstr));
+    }
 }
 
 mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
@@ -277,7 +281,8 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
                 if (arg_i >= n_args) {
                     nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "tuple index out of range"));
                 }
-                mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]);
+                // TODO: may be PRINT_REPR depending on formatting code
+                mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i], PRINT_STR);
                 arg_i++;
             }
         } else {
diff --git a/py/objtuple.c b/py/objtuple.c
index 15e74636f..a64b1fa16 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -16,14 +16,14 @@ static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur);
 /******************************************************************************/
 /* tuple                                                                      */
 
-void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
     mp_obj_tuple_t *o = o_in;
     print(env, "(");
     for (int i = 0; i < o->len; i++) {
         if (i > 0) {
             print(env, ", ");
         }
-        mp_obj_print_helper(print, env, o->items[i]);
+        mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
     }
     if (o->len == 1) {
         print(env, ",");
diff --git a/py/objtuple.h b/py/objtuple.h
index 9c672fe3f..6ff38c10e 100644
--- a/py/objtuple.h
+++ b/py/objtuple.h
@@ -4,4 +4,4 @@ typedef struct _mp_obj_tuple_t {
     mp_obj_t items[];
 } mp_obj_tuple_t;
 
-void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in);
+void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
diff --git a/py/objtype.c b/py/objtype.c
index 011ee4355..5a2f96d6b 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -66,7 +66,7 @@ static mp_map_elem_t *mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr,
     }
 }
 
-static void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     print(env, "<%s object at %p>", mp_obj_get_type_str(self_in), self_in);
 }
 
@@ -148,7 +148,7 @@ static bool class_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
 //  - there is a constant mp_obj_type_t (called mp_const_type) for the 'type' object
 //  - creating a new class (a new type) creates a new mp_obj_type_t
 
-static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_type_t *self = self_in;
     print(env, "<class '%s'>", self->name);
 }
diff --git a/stm/main.c b/stm/main.c
index ab8cced6a..a27c4e52f 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -436,7 +436,7 @@ void do_repl(void) {
                     }
                 } else {
                     // uncaught exception
-                    mp_obj_print((mp_obj_t)nlr.ret_val);
+                    mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
                     printf("\n");
                 }
             }
@@ -474,7 +474,7 @@ bool do_file(const char *filename) {
         return true;
     } else {
         // uncaught exception
-        mp_obj_print((mp_obj_t)nlr.ret_val);
+        mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
         printf("\n");
         return false;
     }
@@ -656,7 +656,7 @@ typedef struct _pyb_file_obj_t {
     FIL fp;
 } pyb_file_obj_t;
 
-void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     printf("<file %p>", self_in);
 }
 
@@ -1097,13 +1097,13 @@ soft_reset:
                 if (nlr_push(&nlr) == 0) {
                     mp_obj_t ret = rt_call_function_0(module_fun);
                     printf("done! got: ");
-                    mp_obj_print(ret);
+                    mp_obj_print(ret, PRINT_REPR);
                     printf("\n");
                     nlr_pop();
                 } else {
                     // uncaught exception
                     printf("exception: ");
-                    mp_obj_print((mp_obj_t)nlr.ret_val);
+                    mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
                     printf("\n");
                 }
 
diff --git a/stm/timer.c b/stm/timer.c
index c665a461d..062f8c689 100644
--- a/stm/timer.c
+++ b/stm/timer.c
@@ -89,7 +89,7 @@ void timer_interrupt(void) {
         } else {
             // uncaught exception
             printf("exception in timer interrupt\n");
-            mp_obj_print((mp_obj_t)nlr.ret_val);
+            mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
             printf("\n");
         }
     }
diff --git a/tests/basics/tests/exception1.py b/tests/basics/tests/exception1.py
index 95d933de7..93d2cbfb9 100644
--- a/tests/basics/tests/exception1.py
+++ b/tests/basics/tests/exception1.py
@@ -1,3 +1,9 @@
-# TODO: requires repr()
-#a = IndexError(1, "test", [100, 200])
-#print(repr(a))
+print(repr(IndexError()))
+print(str(IndexError()))
+
+print(repr(IndexError("foo")))
+print(str(IndexError("foo")))
+
+a = IndexError(1, "test", [100, 200])
+print(str(a))
+print(repr(a))
diff --git a/unix/file.c b/unix/file.c
index 204dc1b7e..eef3378d8 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -15,7 +15,7 @@ typedef struct _mp_obj_fdfile_t {
     int fd;
 } mp_obj_fdfile_t;
 
-static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     mp_obj_fdfile_t *self = self_in;
     print(env, "<io.FileIO %d>", self->fd);
 }
diff --git a/unix/main.c b/unix/main.c
index 15a4000ab..e96ee2846 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -63,7 +63,7 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
         nlr_pop();
     } else {
         // uncaught exception
-        mp_obj_print((mp_obj_t)nlr.ret_val);
+        mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
         printf("\n");
     }
 }
@@ -159,7 +159,7 @@ typedef struct _test_obj_t {
     int value;
 } test_obj_t;
 
-static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     test_obj_t *self = self_in;
     print(env, "<test %d>", self->value);
 }
-- 
GitLab