diff --git a/py/objstr.c b/py/objstr.c
index 714a170d0ae39874db28274abfd3b305c38d102c..6ddba18a3b837696a86861cfa6ab2eb5cda75f4a 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -344,11 +344,14 @@ uncomparable:
     return MP_OBJ_NULL; // op not supported
 }
 
+#if !MICROPY_PY_BUILTINS_STR_UNICODE
+// objstrunicode defines own version
 const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, uint self_len,
                              mp_obj_t index, bool is_slice) {
     machine_uint_t index_val = mp_get_index(type, self_len, index, is_slice);
     return self_data + index_val;
 }
+#endif
 
 STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
     mp_obj_type_t *type = mp_obj_get_type(self_in);
diff --git a/py/objstr.h b/py/objstr.h
index 75de50d29b5c0b9f7826591a701f80cb3a87a444..da2c9cd5138605cad0b6074b3a75cbf4c8e317fe 100644
--- a/py/objstr.h
+++ b/py/objstr.h
@@ -57,6 +57,9 @@ mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte* data, uin
 mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
 machine_int_t str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, int flags);
 
+const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, uint self_len,
+                             mp_obj_t index, bool is_slice);
+
 MP_DECLARE_CONST_FUN_OBJ(str_encode_obj);
 MP_DECLARE_CONST_FUN_OBJ(str_find_obj);
 MP_DECLARE_CONST_FUN_OBJ(str_rfind_obj);
diff --git a/py/objstrunicode.c b/py/objstrunicode.c
index 334d9895e852f8d75812474fa07398e9de9ffa2d..052028eee062ba09f1f302bec185be5a3d381b0e 100644
--- a/py/objstrunicode.c
+++ b/py/objstrunicode.c
@@ -154,7 +154,8 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
 
 // Convert an index into a pointer to its lead byte. Out of bounds indexing will raise IndexError or
 // be capped to the first/last character of the string, depending on is_slice.
-STATIC const char *str_index_to_ptr(const char *self_data, uint self_len, mp_obj_t index, bool is_slice) {
+const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, uint self_len,
+                             mp_obj_t index, bool is_slice) {
     machine_int_t i;
     // Copied from mp_get_index; I don't want bounds checking, just give me
     // the integer as-is. (I can't bounds-check without scanning the whole
@@ -164,7 +165,7 @@ STATIC const char *str_index_to_ptr(const char *self_data, uint self_len, mp_obj
     } else if (!mp_obj_get_int_maybe(index, &i)) {
         nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "string indices must be integers, not %s", mp_obj_get_type_str(index)));
     }
-    const char *s, *top = self_data + self_len;
+    const byte *s, *top = self_data + self_len;
     if (i < 0)
     {
         // Negative indexing is performed by counting from the end of the string.
@@ -235,18 +236,18 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
                 }
                 return mp_obj_new_str_of_type(type, self_data + start, stop - start);
             }
-            const char *pstart, *pstop;
+            const byte *pstart, *pstop;
             if (ostart != mp_const_none) {
-                pstart = str_index_to_ptr((const char *)self_data, self_len, ostart, true);
+                pstart = str_index_to_ptr(type, self_data, self_len, ostart, true);
             } else {
-                pstart = (const char *)self_data;
+                pstart = self_data;
             }
             if (ostop != mp_const_none) {
                 // pstop will point just after the stop character. This depends on
                 // the \0 at the end of the string.
-                pstop = str_index_to_ptr((const char *)self_data, self_len, ostop, true);
+                pstop = str_index_to_ptr(type, self_data, self_len, ostop, true);
             } else {
-                pstop = (const char *)self_data + self_len;
+                pstop = self_data + self_len;
             }
             if (pstop < pstart) {
                 return MP_OBJ_NEW_QSTR(MP_QSTR_);
@@ -258,7 +259,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
             uint index_val = mp_get_index(type, self_len, index, false);
             return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self_data[index_val]);
         }
-        const char *s = str_index_to_ptr((const char *)self_data, self_len, index, false);
+        const byte *s = str_index_to_ptr(type, self_data, self_len, index, false);
         int len = 1;
         if (UTF8_IS_NONASCII(*s)) {
             // Count the number of 1 bits (after the first)
@@ -266,7 +267,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
                 ++len;
             }
         }
-        return mp_obj_new_str(s, len, true); // This will create a one-character string
+        return mp_obj_new_str((const char*)s, len, true); // This will create a one-character string
     } else {
         return MP_OBJ_NULL; // op not supported
     }