diff --git a/py/objstr.c b/py/objstr.c
index b0d5cba6f17162a8fd866fd6739e1997d9b0f958..b5504da1b54c9c425eff24958bd29d2c1900b46a 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -493,7 +493,9 @@ STATIC mp_obj_t str_startswith(mp_obj_t self_in, mp_obj_t arg) {
     return MP_BOOL(memcmp(str, prefix, prefix_len) == 0);
 }
 
-STATIC mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
+enum { LSTRIP, RSTRIP, STRIP };
+
+STATIC mp_obj_t str_uni_strip(int type, uint n_args, const mp_obj_t *args) {
     assert(1 <= n_args && n_args <= 2);
     assert(MP_OBJ_IS_STR(args[0]));
 
@@ -516,13 +518,18 @@ STATIC mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
     machine_uint_t first_good_char_pos = 0;
     bool first_good_char_pos_set = false;
     machine_uint_t last_good_char_pos = 0;
+    // TODO: For RSPLIT, scan from end
     for (machine_uint_t i = 0; i < orig_str_len; i++) {
         if (find_subbytes(chars_to_del, chars_to_del_len, &orig_str[i], 1, 1) == NULL) {
-            last_good_char_pos = i;
             if (!first_good_char_pos_set) {
                 first_good_char_pos = i;
+                if (type == LSTRIP) {
+                    last_good_char_pos = orig_str_len - 1;
+                    break;
+                }
                 first_good_char_pos_set = true;
             }
+            last_good_char_pos = i;
         }
     }
 
@@ -532,11 +539,26 @@ STATIC mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
     }
 
     assert(last_good_char_pos >= first_good_char_pos);
+    if (type == RSTRIP) {
+        first_good_char_pos = 0;
+    }
     //+1 to accomodate the last character
     machine_uint_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
     return mp_obj_new_str(orig_str + first_good_char_pos, stripped_len, false);
 }
 
+STATIC mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
+    return str_uni_strip(STRIP, n_args, args);
+}
+
+STATIC mp_obj_t str_lstrip(uint n_args, const mp_obj_t *args) {
+    return str_uni_strip(LSTRIP, n_args, args);
+}
+
+STATIC mp_obj_t str_rstrip(uint n_args, const mp_obj_t *args) {
+    return str_uni_strip(RSTRIP, n_args, args);
+}
+
 // Takes an int arg, but only parses unsigned numbers, and only changes
 // *num if at least one digit was parsed.
 static int str_to_int(const char *str, int *num) {
@@ -1354,6 +1376,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, str_split);
 STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_startswith_obj, str_startswith);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_lstrip_obj, 1, 2, str_lstrip);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rstrip_obj, 1, 2, str_rstrip);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, mp_obj_str_format);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count);
@@ -1373,6 +1397,8 @@ STATIC const mp_map_elem_t str_locals_dict_table[] = {
     { MP_OBJ_NEW_QSTR(MP_QSTR_split), (mp_obj_t)&str_split_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_startswith), (mp_obj_t)&str_startswith_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_strip), (mp_obj_t)&str_strip_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_lstrip), (mp_obj_t)&str_lstrip_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_rstrip), (mp_obj_t)&str_rstrip_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_format), (mp_obj_t)&str_format_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_replace), (mp_obj_t)&str_replace_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_count), (mp_obj_t)&str_count_obj },
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 784bf59d2382df2f0339b5814a46c426434c2b83..bcbbcf98e9a5242ca9b431635e1dad3a6b099834 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -180,6 +180,8 @@ Q(pop)
 Q(sort)
 Q(join)
 Q(strip)
+Q(lstrip)
+Q(rstrip)
 Q(format)
 Q(key)
 Q(reverse)
diff --git a/tests/basics/string_strip.py b/tests/basics/string_strip.py
index 518dfd66ec08f00dc11db6ca2c41b813e1e16729..8e03eff93af221e0ab6e305016ee41562b19d6b4 100644
--- a/tests/basics/string_strip.py
+++ b/tests/basics/string_strip.py
@@ -4,3 +4,9 @@ print(" T E S T".strip())
 print("abcabc".strip("ce"))
 print("aaa".strip("b"))
 print("abc  efg ".strip("g a"))
+
+print('   spacious   '.lstrip())
+print('www.example.com'.lstrip('cmowz.'))
+
+print('   spacious   '.rstrip())
+print('mississippi'.rstrip('ipz'))