Skip to content

[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

Merged
merged 4 commits into from
Aug 4, 2021

Conversation

97littleleaf11
Copy link
Collaborator

@97littleleaf11 97littleleaf11 commented Aug 1, 2021

Description

  • Use PyBytes_FromObject for bytes(o)
  • Use PyByteArray_FromObject for bytearray(o)

Current approach doesn't support empty initialization.

mypyc/mypyc#880

Test Plan

Added some new irbuild tests.

Copy link
Collaborator

@JukkaL JukkaL left a 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(
Copy link
Collaborator

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).

b4 = bytes(b'aaa')
assert b4 == b'aaa'
# b5 = bytes(5)
# assert b5 == b'\x00\x00\x00\x00\x00'
Copy link
Collaborator Author

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

Copy link
Collaborator

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:

  1. Don't add the primitive
  2. Add an argument type restriction to the use of the primitive (e.g. only support bytes or list -- whatever works).
  3. 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).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bytearray(5) works well

return_type=bytes_rprimitive,
c_function_name='CPyBytes_FromInt',
error_kind=ERR_MAGIC,
priority=2)
Copy link
Collaborator

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.

Copy link
Collaborator Author

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"
Copy link
Collaborator Author

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.

Copy link
Collaborator

@JukkaL JukkaL left a 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.

@JukkaL JukkaL merged commit d991d19 into python:master Aug 4, 2021
@97littleleaf11 97littleleaf11 deleted the add-new-bytes-op branch August 4, 2021 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants