diff --git a/py/obj.h b/py/obj.h
index ea4534bb25f4e6b3e72a382e32fffa0d463f68b7..5a3b4a852fb28adbac09c885b52352894c2225af 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -169,9 +169,10 @@ typedef mp_obj_t (*mp_fun_var_t)(uint n, const mp_obj_t *);
 typedef mp_obj_t (*mp_fun_kw_t)(uint n, const mp_obj_t *, mp_map_t *);
 
 typedef enum {
-    PRINT_STR,
-    PRINT_REPR,
-    PRINT_EXC, // Special format for printing exception in unhandled exception message
+    PRINT_STR = 0,
+    PRINT_REPR = 1,
+    PRINT_EXC = 2, // Special format for printing exception in unhandled exception message
+    PRINT_EXC_SUBCLASS = 4, // Internal flag for printing exception subclasses
 } 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);
@@ -424,6 +425,7 @@ mp_float_t mp_obj_int_as_float(mp_obj_t self_in);
 machine_int_t mp_obj_int_get_checked(mp_obj_t self_in);
 
 // exception
+#define mp_obj_is_native_exception_instance(o) (mp_obj_get_type(o)->make_new == mp_obj_exception_make_new)
 bool mp_obj_is_exception_type(mp_obj_t self_in);
 bool mp_obj_is_exception_instance(mp_obj_t self_in);
 bool mp_obj_exception_match(mp_obj_t exc, const mp_obj_type_t *exc_type);
@@ -431,6 +433,7 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in);
 void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block);
 void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values);
 mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in);
+mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args);
 
 // str
 mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data);
diff --git a/py/objexcept.c b/py/objexcept.c
index 160cf09fd42e8f13596d6188802332460658deab..60e15b6dba7013459ee91610161a57987a6e7c9c 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -30,12 +30,17 @@ const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit},
 
 STATIC void mp_obj_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 (kind == PRINT_REPR) {
+    mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS;
+    bool is_subclass = kind & PRINT_EXC_SUBCLASS;
+    if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) {
         print(env, "%s", qstr_str(o->base.type->name));
-    } else if (kind == PRINT_EXC) {
-        print(env, "%s: ", qstr_str(o->base.type->name));
     }
-    if (kind == PRINT_STR || kind == PRINT_EXC) {
+
+    if (k == PRINT_EXC) {
+        print(env, ": ");
+    }
+
+    if (k == PRINT_STR || k == PRINT_EXC) {
         if (o->args == NULL || o->args->len == 0) {
             print(env, "");
             return;
@@ -47,7 +52,7 @@ STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...
     tuple_print(print, env, o->args, kind);
 }
 
-STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
     mp_obj_type_t *type = type_in;
 
     if (n_kw != 0) {
diff --git a/py/objtype.c b/py/objtype.c
index 56a5dd937d37e09d03b5750bfe73ce86150dd276..83a6755b45fff4098853af27938f607c7abddc7e 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -148,7 +148,15 @@ STATIC void class_print(void (*print)(void *env, const char *fmt, ...), void *en
     }
 
     if (member[0] == MP_OBJ_SENTINEL) {
-        mp_obj_print_helper(print, env, self->subobj[0], kind);
+        // Handle Exception subclasses specially
+        if (mp_obj_is_native_exception_instance(self->subobj[0])) {
+            if (kind != PRINT_STR) {
+                print(env, "%s", qstr_str(self->base.type->name));
+            }
+            mp_obj_print_helper(print, env, self->subobj[0], kind | PRINT_EXC_SUBCLASS);
+        } else {
+            mp_obj_print_helper(print, env, self->subobj[0], kind);
+        }
         return;
     }
 
diff --git a/tests/basics/subclass-native3.py b/tests/basics/subclass-native3.py
index 5d443cf5cd92dd078357a1f167b8dae5e78f3665..dd6a94a614f0192a0f916173b0a01ca7b2f1cf80 100644
--- a/tests/basics/subclass-native3.py
+++ b/tests/basics/subclass-native3.py
@@ -3,6 +3,5 @@ class MyExc(Exception):
 
 e = MyExc(100, "Some error")
 print(e)
-# TODO: Prints native base class name
-#print(repr(e))
+print(repr(e))
 print(e.args)