From ef1ff8f3137e773c9960bb0ebaee879fc0583017 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 14 Feb 2025 13:33:45 +0100 Subject: [PATCH 1/2] [mypyc] Optimize str.__contains__ --- mypyc/doc/str_operations.rst | 1 + mypyc/primitives/str_ops.py | 11 +++++++++++ mypyc/test-data/run-strings.test | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/mypyc/doc/str_operations.rst b/mypyc/doc/str_operations.rst index b2e632a8bbb6..a7e9ccc58cd1 100644 --- a/mypyc/doc/str_operations.rst +++ b/mypyc/doc/str_operations.rst @@ -21,6 +21,7 @@ Operators * Slicing (``s[n:m]``, ``s[n:]``, ``s[:m]``) * Comparisons (``==``, ``!=``) * Augmented assignment (``s1 += s2``) +* Containment (``s1 in s2``) .. _str-methods: diff --git a/mypyc/primitives/str_ops.py b/mypyc/primitives/str_ops.py index 255728187604..a1c778aa781f 100644 --- a/mypyc/primitives/str_ops.py +++ b/mypyc/primitives/str_ops.py @@ -84,6 +84,17 @@ error_kind=ERR_MAGIC, ) +# item in str +set_in_op = binary_op( + name="in", + arg_types=[str_rprimitive, str_rprimitive], + return_type=c_int_rprimitive, + c_function_name="PyUnicode_Contains", + error_kind=ERR_NEG_INT, + truncated_type=bool_rprimitive, + ordering=[1, 0], +) + # str.join(obj) method_op( name="join", diff --git a/mypyc/test-data/run-strings.test b/mypyc/test-data/run-strings.test index 94fcf84f085b..5927b5fc91a1 100644 --- a/mypyc/test-data/run-strings.test +++ b/mypyc/test-data/run-strings.test @@ -140,11 +140,21 @@ def test_partition() -> None: with assertRaises(ValueError, "empty separator"): rpartition(s_partition, "") +def contains(s: str, o: str) -> bool: + return o in s + def getitem(s: str, index: int) -> str: return s[index] s = "abc" +def test_contains() -> None: + assert contains(s, "a") is True + assert contains(s, "abc") is True + assert contains(s, "Hello") is False + assert contains(s, "") is True + assert contains(s, " ") is False + def test_getitem() -> None: assert getitem(s, 0) == "a" assert getitem(s, 1) == "b" From f4c922845e7ed42541795ed703a7f21e955de9e8 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:01:33 +0100 Subject: [PATCH 2/2] Review --- mypyc/primitives/str_ops.py | 2 +- mypyc/test-data/run-strings.test | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mypyc/primitives/str_ops.py b/mypyc/primitives/str_ops.py index a1c778aa781f..aef3575d8eb4 100644 --- a/mypyc/primitives/str_ops.py +++ b/mypyc/primitives/str_ops.py @@ -85,7 +85,7 @@ ) # item in str -set_in_op = binary_op( +binary_op( name="in", arg_types=[str_rprimitive, str_rprimitive], return_type=c_int_rprimitive, diff --git a/mypyc/test-data/run-strings.test b/mypyc/test-data/run-strings.test index 5927b5fc91a1..7eadaeee0707 100644 --- a/mypyc/test-data/run-strings.test +++ b/mypyc/test-data/run-strings.test @@ -152,6 +152,9 @@ def test_contains() -> None: assert contains(s, "a") is True assert contains(s, "abc") is True assert contains(s, "Hello") is False + assert contains(s, "bc") is True + assert contains(s, "abcd") is False + assert contains(s, "bb") is False assert contains(s, "") is True assert contains(s, " ") is False