-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
[mypyc] Support str.replace #10088
[mypyc] Support str.replace #10088
Conversation
Thanks for contributing! Looks pretty close, the error is caused by missing fixture. You can try to update |
I got several compiler warnings, which would lead to pytest failure.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! @JukkaL Please take a look if you have time
mypyc/primitives/str_ops.py
Outdated
# str.replace(old, new) | ||
method_op( | ||
name='replace', | ||
arg_types=[str_rprimitive, str_rprimitive], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the signature here https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_Replace, I think each these arg_types
might need one additional str_primitive
to account for the "self" argument.
I noticed after compiling:
message = 'hello world'.replace('world', 'mars')
print(message)
in build/opts.txt
we get:
...
L3:
r5 = 'hello world'
r6 = 'world'
r7 = 'mars'
r8 = 'replace'
r9 = CPyObject_CallMethodObjArgs(r5, r8, r6, r7, 0)
...
(I think because the arg types don't quite align in the mypyc/irbuild/ll_builder.py::matching_call_c
check and mypyc/irbuild/ll_builder.py::translate_special_method_call
will return None
instead of the op for PyUnicode_Replace
). With an additional str_primitive
arg, I think we will get the desired:
...
L3:
r5 = 'hello world'
r6 = 'world'
r7 = 'mars'
r8 = PyUnicode_Replace(r5, r6, r7, -1)
...
Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thomasjohns Thanks for pointing it out! Yeah you are right, I've just suggested the changes and @97littleleaf11 please also include an IR test for this primitive. You can find examples of IR test in mypyc/test-data/irbuild-str.test
mypyc/primitives/str_ops.py
Outdated
# str.replace(old, new) | ||
method_op( | ||
name='replace', | ||
arg_types=[str_rprimitive, str_rprimitive], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arg_types=[str_rprimitive, str_rprimitive], | |
arg_types=[str_rprimitive, str_rprimitive, str_rprimitive], |
@thomasjohns @TH3CHARLie Thanks for reviewing!
I checked the IR and found the issue:
We cannot directly feed the
It can pass the pytest now. |
I see. It's caused by mypyc's tagged integer which uses its lowest bit to represent tag and remaining bits to store the immediate value or the object pointer: https://github.com/python/mypy/blob/master/mypyc/doc/dev-intro.md#value-representation So yes, you need a wrapper function and you find the correct way to do so. Please send a new commit to include your changes(both the IR test and the wrapper function) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates! LGTM! Only a small nit to patch and I believe it's good to go.
mypyc/test-data/irbuild-str.test
Outdated
r6 = PyUnicode_Replace(s, old_substr, new_substr, -1) | ||
return r6 | ||
L5: | ||
unreachable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a newline at the end of IR test
[mypyc] Support str.replace (python#10088)
Description
str.replace
primitiveTest Plan