Skip to content

[mypyc] Improve str.startswith and str.endswith with tuple argument #18703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mypyc/lib-rt/str_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ int CPyStr_Startswith(PyObject *self, PyObject *subobj) {
"tuple for startswith must only contain str, "
"not %.100s",
Py_TYPE(substring)->tp_name);
return -1;
return 2;
}
int result = PyUnicode_Tailmatch(self, substring, start, end, -1);
if (result) {
Expand All @@ -197,7 +197,7 @@ int CPyStr_Endswith(PyObject *self, PyObject *subobj) {
"tuple for endswith must only contain str, "
"not %.100s",
Py_TYPE(substring)->tp_name);
return -1;
return 2;
}
int result = PyUnicode_Tailmatch(self, substring, start, end, 1);
if (result) {
Expand Down
14 changes: 6 additions & 8 deletions mypyc/primitives/str_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,13 @@
error_kind=ERR_NEVER,
)

# str.startswith(tuple) (return -1/0/1)
# str.startswith(tuple)
method_op(
name="startswith",
arg_types=[str_rprimitive, tuple_rprimitive],
return_type=c_int_rprimitive,
return_type=bool_rprimitive,
c_function_name="CPyStr_Startswith",
truncated_type=bool_rprimitive,
error_kind=ERR_NEG_INT,
error_kind=ERR_MAGIC,
)

# str.endswith(str)
Expand All @@ -131,14 +130,13 @@
error_kind=ERR_NEVER,
)

# str.endswith(tuple) (return -1/0/1)
# str.endswith(tuple)
method_op(
name="endswith",
arg_types=[str_rprimitive, tuple_rprimitive],
return_type=c_int_rprimitive,
return_type=bool_rprimitive,
c_function_name="CPyStr_Endswith",
truncated_type=bool_rprimitive,
error_kind=ERR_NEG_INT,
error_kind=ERR_MAGIC,
)

# str.removeprefix(str)
Expand Down
48 changes: 16 additions & 32 deletions mypyc/test-data/irbuild-str.test
Original file line number Diff line number Diff line change
Expand Up @@ -153,55 +153,39 @@ def do_tuple_literal_args(s1: str) -> None:
def do_startswith(s1, s2):
s1 :: str
s2 :: tuple
r0 :: i32
r1 :: bit
r2 :: bool
r0 :: bool
L0:
r0 = CPyStr_Startswith(s1, s2)
r1 = r0 >= 0 :: signed
r2 = truncate r0: i32 to builtins.bool
return r2
return r0
def do_endswith(s1, s2):
s1 :: str
s2 :: tuple
r0 :: i32
r1 :: bit
r2 :: bool
r0 :: bool
L0:
r0 = CPyStr_Endswith(s1, s2)
r1 = r0 >= 0 :: signed
r2 = truncate r0: i32 to builtins.bool
return r2
return r0
def do_tuple_literal_args(s1):
s1, r0, r1 :: str
r2 :: tuple[str, str]
r3 :: object
r4 :: i32
r5 :: bit
r6, x :: bool
r7, r8 :: str
r9 :: tuple[str, str]
r10 :: object
r11 :: i32
r12 :: bit
r13, y :: bool
r4, x :: bool
r5, r6 :: str
r7 :: tuple[str, str]
r8 :: object
r9, y :: bool
L0:
r0 = 'a'
r1 = 'b'
r2 = (r0, r1)
r3 = box(tuple[str, str], r2)
r4 = CPyStr_Startswith(s1, r3)
r5 = r4 >= 0 :: signed
r6 = truncate r4: i32 to builtins.bool
x = r6
r7 = 'a'
r8 = 'b'
r9 = (r7, r8)
r10 = box(tuple[str, str], r9)
r11 = CPyStr_Endswith(s1, r10)
r12 = r11 >= 0 :: signed
r13 = truncate r11: i32 to builtins.bool
y = r13
x = r4
r5 = 'a'
r6 = 'b'
r7 = (r5, r6)
r8 = box(tuple[str, str], r7)
r9 = CPyStr_Endswith(s1, r8)
y = r9
return 1

[case testStrToBool]
Expand Down