Repository navigation
[Unicode] support startswith with args, start and end. #8557
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
Changes from 5 commits
5f2cc16
5e65597
7fa462e
4e5960d
76b58c2
9742576
33aaa1a
ac5ba28
ae74063
2216a7e
696dd8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -813,18 +813,6 @@ def impl(data, sep): | |
| return impl | ||
|
|
||
|
|
||
| @overload_method(types.UnicodeType, 'startswith') | ||
| def unicode_startswith(a, b): | ||
| if isinstance(b, types.UnicodeType): | ||
| def startswith_impl(a, b): | ||
| return _cmp_region(a, 0, b, 0, len(b)) == 0 | ||
| return startswith_impl | ||
| if isinstance(b, types.UnicodeCharSeq): | ||
| def startswith_impl(a, b): | ||
| return a.startswith(str(b)) | ||
| return startswith_impl | ||
|
|
||
|
|
||
| # https://github.com/python/cpython/blob/201c8f79450628241574fba940e08107178dc3a5/Objects/unicodeobject.c#L9342-L9354 # noqa: E501 | ||
| @register_jitable | ||
| def _adjust_indices(length, start, end): | ||
|
|
@@ -842,6 +830,56 @@ def _adjust_indices(length, start, end): | |
| return start, end | ||
|
|
||
|
|
||
| @overload_method(types.UnicodeType, 'startswith') | ||
| def unicode_startswith(s, prefix, start=None, end=None): | ||
| if not (start is None or isinstance(start, (types.Omitted, | ||
| types.Integer, | ||
| types.NoneType))): | ||
| raise TypingError('When specified, the arg "start" must be an Integer') | ||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
|
|
||
| if not (end is None or isinstance(end, (types.Omitted, | ||
| types.Integer, | ||
| types.NoneType))): | ||
| raise TypingError('When specified, the arg "end" must be an Integer') | ||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
|
|
||
| if isinstance(prefix, (types.Tuple, types.UniTuple)): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@njit
def foo():
print('abcde'.startswith(('a', 1)))
foo()it may be easier to just not accept
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer to accept a or another case: Both
BTW, I found an interesting thing in cpython (which I think we don't have to implement this short-cut strategy):
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revised, please review this issue again. @stuartarchibald
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By default, type inference will try using non-literal types first, and then if that fails, it will try again using literal types. Python source containing tuples of string literals will be inferred as from numba import njit
import numpy as np
@njit
def foo():
x = ('a', 'b')
foo()
foo.inspect_types()You can see the "try non-literal then literal" types behaviour by doing something like: from numba import njit, types
from numba.extending import overload
import numpy as np
def bar(tup):
pass
@overload(bar)
def ol_bar(tup):
print(f"bar:: tup type is {tup}")
@njit
def foo():
x = ('a', 'b')
bar(x)
foo()(ignore the compilation error, just look at what gets printed to stdout). RE: the |
||
| def startswith_tuple_impl(s, prefix, start=None, end=None): | ||
| for item in prefix: | ||
| if s.startswith(item, start, end): | ||
| return True | ||
| return False | ||
|
|
||
| return startswith_tuple_impl | ||
|
|
||
| if isinstance(prefix, types.UnicodeCharSeq): | ||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
| def startswith_char_seq_impl(s, prefix, start=None, end=None): | ||
| return s.startswith(str(prefix), start, end) | ||
|
|
||
| return startswith_char_seq_impl | ||
|
|
||
| if isinstance(prefix, types.UnicodeType): | ||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
| def startswith_unicode_impl(s, prefix, start=None, end=None): | ||
| length = len(s) | ||
| sub_length = len(prefix) | ||
| if start is None: | ||
| start = 0 | ||
| if end is None: | ||
| end = length | ||
|
|
||
| start, end = _adjust_indices(length, start, end) | ||
| if end - start < sub_length: | ||
| return False | ||
|
|
||
| if sub_length == 0: | ||
| return True | ||
|
|
||
| s = s[start:end] | ||
|
|
||
| return _cmp_region(s, 0, prefix, 0, sub_length) == 0 | ||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
|
|
||
| return startswith_unicode_impl | ||
|
|
||
|
dlee992 marked this conversation as resolved.
Resolved
|
||
|
|
||
| @overload_method(types.UnicodeType, 'endswith') | ||
| def unicode_endswith(s, substr, start=None, end=None): | ||
| if not (start is None or isinstance(start, (types.Omitted, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.