-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] Add bytes and bytearray initialization ops #10900
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
Conversation
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! It would be good to have some more tests, otherwise looks good.
error_kind=ERR_MAGIC) | ||
|
||
# bytearray(obj) | ||
function_op( |
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 also run tests to make sure the C API functions do what they should. For example, test bytes([5])
, bytes(bytearray(b'foo'))
and bytes('x')
(the last one should raise an exception).
mypyc/test-data/run-bytes.test
Outdated
b4 = bytes(b'aaa') | ||
assert b4 == b'aaa' | ||
# b5 = bytes(5) | ||
# assert b5 == b'\x00\x00\x00\x00\x00' |
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.
This line causes a runtime error
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.
Unfortunately this means that C API function is not a 1:1 replacement for bytes(x)
and can't be used as such. We now have these options:
- Don't add the primitive
- Add an argument type restriction to the use of the primitive (e.g. only support
bytes
orlist
-- whatever works). - Implement a C helper that implements the missing functionality and falls back to the C API function for the supported functionality.
What do you think? Also test bytearray(5)
.
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.
bytearray(5)
works well
mypyc/primitives/bytes_ops.py
Outdated
return_type=bytes_rprimitive, | ||
c_function_name='CPyBytes_FromInt', | ||
error_kind=ERR_MAGIC, | ||
priority=2) |
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.
Using a priority to pick an alternative implementation isn't enough here, since the integer argument could have a static type Any
, and this alternative implementation wouldn't be picked up. The integer case would need to be handled in the main primitive that accepts any object
. Also, since bytes(n)
is an extremely rare thing to do, maybe you shouldn't bother with it and only optimize the more common cases.
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.
I prefer using RUnion now
// These are registered in mypyc.primitives.bytes_ops. | ||
|
||
#include <Python.h> | ||
#include "CPy.h" |
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.
I'll add some helper functions in later prs. I think it's fine to keep this.
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.
Looks good! There's one more thing (in a separate PR): test calling bytearray(...)
with different operand types, including integer and list.
Description
PyBytes_FromObject
forbytes(o)
PyByteArray_FromObject
forbytearray(o)
Current approach doesn't support empty initialization.
mypyc/mypyc#880
Test Plan
Added some new irbuild tests.