Skip to content

Commit 038fd52

Browse files
committed
Merge branch 'str-index' of github.com:xbe/micropython into xbe-str-index
2 parents 5589db8 + 3d9a39e commit 038fd52

4 files changed

Lines changed: 178 additions & 5 deletions

File tree

py/objstr.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
438438
return res;
439439
}
440440

441-
STATIC mp_obj_t str_finder(uint n_args, const mp_obj_t *args, machine_int_t direction) {
441+
STATIC mp_obj_t str_finder(uint n_args, const mp_obj_t *args, machine_int_t direction, bool is_index) {
442442
assert(2 <= n_args && n_args <= 4);
443443
assert(MP_OBJ_IS_STR(args[0]));
444444
assert(MP_OBJ_IS_STR(args[1]));
@@ -458,19 +458,31 @@ STATIC mp_obj_t str_finder(uint n_args, const mp_obj_t *args, machine_int_t dire
458458
const byte *p = find_subbytes(haystack + start, end - start, needle, needle_len, direction);
459459
if (p == NULL) {
460460
// not found
461-
return MP_OBJ_NEW_SMALL_INT(-1);
461+
if (is_index) {
462+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "substring not found"));
463+
} else {
464+
return MP_OBJ_NEW_SMALL_INT(-1);
465+
}
462466
} else {
463467
// found
464468
return MP_OBJ_NEW_SMALL_INT(p - haystack);
465469
}
466470
}
467471

468472
STATIC mp_obj_t str_find(uint n_args, const mp_obj_t *args) {
469-
return str_finder(n_args, args, 1);
473+
return str_finder(n_args, args, 1, false);
470474
}
471475

472476
STATIC mp_obj_t str_rfind(uint n_args, const mp_obj_t *args) {
473-
return str_finder(n_args, args, -1);
477+
return str_finder(n_args, args, -1, false);
478+
}
479+
480+
STATIC mp_obj_t str_index(uint n_args, const mp_obj_t *args) {
481+
return str_finder(n_args, args, 1, true);
482+
}
483+
484+
STATIC mp_obj_t str_rindex(uint n_args, const mp_obj_t *args) {
485+
return str_finder(n_args, args, -1, true);
474486
}
475487

476488
// TODO: (Much) more variety in args
@@ -1125,7 +1137,7 @@ STATIC mp_obj_t str_replace(uint n_args, const mp_obj_t *args) {
11251137
}
11261138
}
11271139

1128-
// if max_rep is still 0 by this point we will need to do all possible replacements
1140+
// if max_rep is still -1 by this point we will need to do all possible replacements
11291141

11301142
// check argument types
11311143

@@ -1304,6 +1316,8 @@ STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, in
13041316

13051317
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
13061318
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj, 2, 4, str_rfind);
1319+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj, 2, 4, str_index);
1320+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex);
13071321
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
13081322
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, str_split);
13091323
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_startswith_obj, str_startswith);
@@ -1317,6 +1331,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition);
13171331
STATIC const mp_map_elem_t str_locals_dict_table[] = {
13181332
{ MP_OBJ_NEW_QSTR(MP_QSTR_find), (mp_obj_t)&str_find_obj },
13191333
{ MP_OBJ_NEW_QSTR(MP_QSTR_rfind), (mp_obj_t)&str_rfind_obj },
1334+
{ MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&str_index_obj },
1335+
{ MP_OBJ_NEW_QSTR(MP_QSTR_rindex), (mp_obj_t)&str_rindex_obj },
13201336
{ MP_OBJ_NEW_QSTR(MP_QSTR_join), (mp_obj_t)&str_join_obj },
13211337
{ MP_OBJ_NEW_QSTR(MP_QSTR_split), (mp_obj_t)&str_split_obj },
13221338
{ MP_OBJ_NEW_QSTR(MP_QSTR_startswith), (mp_obj_t)&str_startswith_obj },

py/qstrdefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ Q(union)
183183
Q(update)
184184
Q(find)
185185
Q(rfind)
186+
Q(rindex)
186187
Q(split)
187188
Q(startswith)
188189
Q(replace)

tests/basics/string_index.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
print("hello world".index("ll"))
2+
print("hello world".index("ll", None))
3+
print("hello world".index("ll", 1))
4+
print("hello world".index("ll", 1, None))
5+
print("hello world".index("ll", None, None))
6+
print("hello world".index("ll", 1, -1))
7+
8+
try:
9+
print("hello world".index("ll", 1, 1))
10+
except ValueError:
11+
print("Raised ValueError")
12+
else:
13+
print("Did not raise ValueError")
14+
15+
try:
16+
print("hello world".index("ll", 1, 2))
17+
except ValueError:
18+
print("Raised ValueError")
19+
else:
20+
print("Did not raise ValueError")
21+
22+
try:
23+
print("hello world".index("ll", 1, 3))
24+
except ValueError:
25+
print("Raised ValueError")
26+
else:
27+
print("Did not raise ValueError")
28+
29+
print("hello world".index("ll", 1, 4))
30+
print("hello world".index("ll", 1, 5))
31+
print("hello world".index("ll", -100))
32+
print("0000".index('0'))
33+
print("0000".index('0', 0))
34+
print("0000".index('0', 1))
35+
print("0000".index('0', 2))
36+
print("0000".index('0', 3))
37+
38+
try:
39+
print("0000".index('0', 4))
40+
except ValueError:
41+
print("Raised ValueError")
42+
else:
43+
print("Did not raise ValueError")
44+
45+
try:
46+
print("0000".index('0', 5))
47+
except ValueError:
48+
print("Raised ValueError")
49+
else:
50+
print("Did not raise ValueError")
51+
52+
try:
53+
print("0000".index('-1', 3))
54+
except ValueError:
55+
print("Raised ValueError")
56+
else:
57+
print("Did not raise ValueError")
58+
59+
try:
60+
print("0000".index('1', 3))
61+
except ValueError:
62+
print("Raised ValueError")
63+
else:
64+
print("Did not raise ValueError")
65+
66+
try:
67+
print("0000".index('1', 4))
68+
except ValueError:
69+
print("Raised ValueError")
70+
else:
71+
print("Did not raise ValueError")
72+
73+
try:
74+
print("0000".index('1', 5))
75+
except ValueError:
76+
print("Raised ValueError")
77+
else:
78+
print("Did not raise ValueError")

tests/basics/string_rindex.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
print("hello world".rindex("ll"))
2+
print("hello world".rindex("ll", None))
3+
print("hello world".rindex("ll", 1))
4+
print("hello world".rindex("ll", 1, None))
5+
print("hello world".rindex("ll", None, None))
6+
print("hello world".rindex("ll", 1, -1))
7+
8+
try:
9+
print("hello world".rindex("ll", 1, 1))
10+
except ValueError:
11+
print("Raised ValueError")
12+
else:
13+
print("Did not raise ValueError")
14+
15+
try:
16+
print("hello world".rindex("ll", 1, 2))
17+
except ValueError:
18+
print("Raised ValueError")
19+
else:
20+
print("Did not raise ValueError")
21+
22+
try:
23+
print("hello world".rindex("ll", 1, 3))
24+
except ValueError:
25+
print("Raised ValueError")
26+
else:
27+
print("Did not raise ValueError")
28+
29+
print("hello world".rindex("ll", 1, 4))
30+
print("hello world".rindex("ll", 1, 5))
31+
print("hello world".rindex("ll", -100))
32+
print("0000".rindex('0'))
33+
print("0000".rindex('0', 0))
34+
print("0000".rindex('0', 1))
35+
print("0000".rindex('0', 2))
36+
print("0000".rindex('0', 3))
37+
38+
try:
39+
print("0000".rindex('0', 4))
40+
except ValueError:
41+
print("Raised ValueError")
42+
else:
43+
print("Did not raise ValueError")
44+
45+
try:
46+
print("0000".rindex('0', 5))
47+
except ValueError:
48+
print("Raised ValueError")
49+
else:
50+
print("Did not raise ValueError")
51+
52+
try:
53+
print("0000".rindex('-1', 3))
54+
except ValueError:
55+
print("Raised ValueError")
56+
else:
57+
print("Did not raise ValueError")
58+
59+
try:
60+
print("0000".rindex('1', 3))
61+
except ValueError:
62+
print("Raised ValueError")
63+
else:
64+
print("Did not raise ValueError")
65+
66+
try:
67+
print("0000".rindex('1', 4))
68+
except ValueError:
69+
print("Raised ValueError")
70+
else:
71+
print("Did not raise ValueError")
72+
73+
try:
74+
print("0000".rindex('1', 5))
75+
except ValueError:
76+
print("Raised ValueError")
77+
else:
78+
print("Did not raise ValueError")

0 commit comments

Comments
 (0)