diff --git a/py/obj.h b/py/obj.h
index 48d332e20008847b46ae90d48039ed8d7572bbee..4982d5bc23c6824379c68bb5d38377dbdd203f45 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -215,8 +215,6 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
 #endif
 mp_obj_t mp_obj_new_exception(qstr id);
 mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg);
-mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1);
-mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2);
 mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
 mp_obj_t mp_obj_new_range(int start, int stop, int step);
 mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step);
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 952bce126bb37671f22f24eb7e8f45874166efc2..e3dce365f5f6f6948a6b8e10a4f735df37f84e1e 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -66,7 +66,7 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
         }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "complex takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "complex takes at most 2 arguments, %d given", n_args));
     }
 }
 
diff --git a/py/objexcept.c b/py/objexcept.c
index eedf05f21d4bb6d61dbc33f69a9c0f826d05a5c3..90e2cc73ac62865c1c9a438f1f973a6641c2aada 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -48,7 +48,7 @@ STATIC mp_obj_t exception_call(mp_obj_t self_in, uint n_args, uint n_kw, const m
     mp_obj_exception_t *base = self_in;
 
     if (n_kw != 0) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "%s does not take keyword arguments", qstr_str(base->id)));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "%s does not take keyword arguments", qstr_str(base->id)));
     }
 
     mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t, n_args);
@@ -75,14 +75,6 @@ mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg) {
     return mp_obj_new_exception_msg_varg(id, msg);
 }
 
-mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1) {
-    return mp_obj_new_exception_msg_varg(id, fmt, a1);
-}
-
-mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2) {
-    return mp_obj_new_exception_msg_varg(id, fmt, a1, a2);
-}
-
 mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...) {
     // make exception object
     mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t*, 0);
diff --git a/py/objfloat.c b/py/objfloat.c
index 309a92f9f15bec17f3b117f022b996c400416a1c..fdb82505688c6995177c29fc84c68a2d0cf30a2c 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -40,7 +40,7 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
             }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", n_args));
     }
 }
 
diff --git a/py/objfun.c b/py/objfun.c
index b28262b413fd6afc49b3ce742b94de24054659a7..72c23a9ec244a1fb75084eb1f9f84ba4ee97ade3 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -26,20 +26,19 @@ STATIC void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) {
 
     if (self->n_args_min == self->n_args_max) {
         if (n_args != self->n_args_min) {
-            nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError,
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
                                                      "function takes %d positional arguments but %d were given",
-                                                     (const char*)(machine_int_t)self->n_args_min,
-                                                     (const char*)(machine_int_t)n_args));
+                                                     self->n_args_min, n_args));
         }
     } else {
         if (n_args < self->n_args_min) {
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError,
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
                                                     "<fun name>() missing %d required positional arguments: <list of names of params>",
-                                                    (const char*)(machine_int_t)(self->n_args_min - n_args)));
+                                                    self->n_args_min - n_args));
         } else if (n_args > self->n_args_max) {
-            nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError,
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
                                                      "<fun name> expected at most %d arguments, got %d",
-                                                     (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args));
+                                                     self->n_args_max, n_args));
         }
     }
 }
@@ -144,7 +143,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
     mp_obj_fun_bc_t *self = self_in;
 
     if (n_args < self->n_args - self->n_def_args || n_args > self->n_args) {
-        nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
     }
     if (n_kw != 0) {
         nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
@@ -253,7 +252,7 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_
     mp_obj_fun_asm_t *self = self_in;
 
     if (n_args != self->n_args) {
-        nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
     }
     if (n_kw != 0) {
         nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
diff --git a/py/objgenerator.c b/py/objgenerator.c
index db61c0846cee19213aabe67b60a33907b558ff5a..dff4ade749ec6d338931195d8de4945f0b115063 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -28,7 +28,7 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp
     const byte *bc_code;
     mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code);
     if (n_args != bc_n_args) {
-        nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)bc_n_args, (const char*)(machine_int_t)n_args));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", bc_n_args, n_args));
     }
     if (n_kw != 0) {
         nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
diff --git a/py/objint.c b/py/objint.c
index 2aaf267dcf8481f866ad3f139dbba63948208a0b..51d3b7e1f13527a7c96ec4fc2efe7e36c5c065b9 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -39,7 +39,7 @@ STATIC mp_obj_t int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
         }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", n_args));
     }
 }
 
diff --git a/py/objlist.c b/py/objlist.c
index b565a88de993ef3a9e18fe1b94b87c195b4f67c8..5516a08f85c2267c9fee5ff7ee912bd975eb3558 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -62,7 +62,7 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
         }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", n_args));
     }
     return NULL;
 }
diff --git a/py/objset.c b/py/objset.c
index 08bcb70e11bc2b68dfcaa1ffc49171e354ae0abc..3cb19296f13558d4916a9e25288f8609ca3674e1 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -67,7 +67,7 @@ STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
         }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "set takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "set takes at most 1 argument, %d given", n_args));
     }
 }
 
diff --git a/py/objtuple.c b/py/objtuple.c
index 9ca777e3407bf66dc0b80dec77fafd5f053f9769..f30b9a13c7941d74aea871dde00ce5fd8ef7d2f0 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -70,7 +70,7 @@ STATIC mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
         }
 
         default:
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "tuple takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "tuple takes at most 1 argument, %d given", n_args));
     }
 }
 
diff --git a/py/objtype.c b/py/objtype.c
index 162dfd22153ed3ff0f5a47e9ac2b0b733b70414e..5b364e61693d56f2a830760761348c7aa92028f9 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -103,13 +103,13 @@ STATIC mp_obj_t class_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const m
             m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw);
         }
         if (init_ret != mp_const_none) {
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
         }
 
     } else {
         // TODO
         if (n_args != 0) {
-            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "function takes 0 positional arguments but %d were given", (void*)(machine_int_t)n_args));
+            nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes 0 positional arguments but %d were given", n_args));
         }
     }
 
@@ -284,7 +284,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj
     mp_obj_type_t *self = self_in;
 
     if (self->make_new == NULL) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "cannot create '%s' instances", self->name));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "cannot create '%s' instances", self->name));
     }
 
     // make new instance
@@ -511,7 +511,7 @@ STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint
     assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod);
 
     if (n_args != 1 || n_kw != 0) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "function takes 1 positional argument but %d were given", (void*)(machine_int_t)n_args));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes 1 positional argument but %d were given", n_args));
     }
 
     mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
diff --git a/py/strtonum.c b/py/strtonum.c
index d8bb05ac8d955e38c1063634ba0556b3035281fd..74fa3d6759fed9ea61b0122dba4a7afca73278e9 100644
--- a/py/strtonum.c
+++ b/py/strtonum.c
@@ -84,7 +84,7 @@ done:
     return (found ^ neg) - neg;
 
 value_error:
-    nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_ValueError, "invalid literal for int() with base %d: '%s'", (void*)(machine_uint_t)base, s));
+    nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "invalid literal for int() with base %d: '%s'", base, s));
 }
 
 #else /* defined(UNIX) */
diff --git a/stm/adc.c b/stm/adc.c
index a5cdc0e3e8997dc5c2c1b08bc06f88076f11e922..51d3e9f91be4d3db3e28820f18caa2558b467c8e 100644
--- a/stm/adc.c
+++ b/stm/adc.c
@@ -427,7 +427,7 @@ mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
     }
 
     if (i == ADC_NUM_CHANNELS) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name));
+        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name));
     }
 
     // init ADC just for this channel
@@ -438,7 +438,7 @@ mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
     return o;
 
 pin_error:
-    nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
+    nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
 }
 
 MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_obj, pyb_ADC);
diff --git a/stm/main.c b/stm/main.c
index be8697b652ab6d734d93dfb562146bb8d261bd40..3425435942f528714e3203f9d84309a07d98a59c 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -535,7 +535,7 @@ mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
     }
 
 pin_error:
-    nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
+    nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
 }
 
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
diff --git a/stm/pybwlan.c b/stm/pybwlan.c
index e403a645eec0f77f357b8426f9ab0be37a6fb881..36a27c525538f2e46e91c016cb7ab019ce178fe0 100644
--- a/stm/pybwlan.c
+++ b/stm/pybwlan.c
@@ -129,7 +129,7 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
     }
     int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (sd < 0) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", (void*)sd));
+        nlr_jump(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", sd));
     }
     //printf("socket seemed to work\n");
     //sys_tick_delay_ms(200);
@@ -140,7 +140,7 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
     remote.sin_addr.s_addr = htonl(last_ip);
     int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr));
     if (ret != 0) {
-        nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "connect failed: %d", (void*)ret));
+        nlr_jump(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "connect failed: %d", ret));
     }
     //printf("connect seemed to work\n");
     //sys_tick_delay_ms(200);
@@ -198,7 +198,7 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
             // read data
             ret = recv(sd, buf, 64, 0);
             if (ret < 0) {
-                nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "recv failed %d", (void*)ret));
+                nlr_jump(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "recv failed %d", ret));
             }
             vstr_add_strn(vstr, buf, ret);
         }
@@ -218,7 +218,7 @@ mp_obj_t pyb_wlan_serve(void) {
     sys_tick_delay_ms(500);
     if (sd < 0) {
         printf("socket fail\n");
-        nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", (void*)sd));
+        nlr_jump(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", sd));
     }
 
     /*
@@ -239,7 +239,7 @@ mp_obj_t pyb_wlan_serve(void) {
     sys_tick_delay_ms(100);
     if (ret != 0) {
         printf("bind fail\n");
-        nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "bind failed: %d", (void*)ret));
+        nlr_jump(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "bind failed: %d", ret));
     }
     printf("bind seemed to work\n");
 
diff --git a/teensy/main.c b/teensy/main.c
index bbfa7590fa4854ac1a5a8f6ff59caba7dbea3e2b..70067927fe77d5cd7ba15207d10da1611d87fe9d 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -190,7 +190,7 @@ mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) {
     return mp_const_none;
 
 pin_error:
-    nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %d does not exist", (void *)(machine_uint_t)pin));
+    nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %d does not exist", pin));
 }
 
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);