-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] feat: new primitive for int.to_bytes
#19674
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
base: master
Are you sure you want to change the base?
Changes from 23 commits
2058f81
f62bfd2
813c510
4be77d6
cb93329
6ff1c9b
166b6f4
be2d2de
9ff3a7c
8399619
db7b483
ed05c00
a0c147b
5bab265
b346bbf
8d523a0
85652a2
8e97165
3660a01
6a8a83c
ec95008
95fa8b0
78f4ca1
326484b
245a122
d2994e1
1138448
0715ca2
7cce1e7
c3aaefa
0d7cb57
db09bc0
a7151dd
bdd320e
4518aea
97873da
d7b0023
26cd5c6
30c4a30
84acab3
b5a6c06
ef5b1d7
9b629a5
9b69d58
6a5de07
251986e
f5f9d30
9a27e5d
6c82357
c4d9673
3ad1e50
77535d3
d291fb1
66bb191
420b8e2
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 |
---|---|---|
|
@@ -581,3 +581,59 @@ double CPyTagged_TrueDivide(CPyTagged x, CPyTagged y) { | |
} | ||
return 1.0; | ||
} | ||
|
||
// int.to_bytes(length, byteorder, signed=False) | ||
PyObject *CPyTagged_ToBytes(CPyTagged self, Py_ssize_t length, PyObject *byteorder, int signed_flag) { | ||
PyObject *pyint = CPyTagged_StealAsObject(self); | ||
if (!PyLong_Check(pyint)) { | ||
|
||
Py_DECREF(pyint); | ||
BobTheBuidler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
PyErr_SetString(PyExc_TypeError, "self must be int"); | ||
return NULL; | ||
} | ||
if (!PyUnicode_Check(byteorder)) { | ||
Py_DECREF(pyint); | ||
PyErr_SetString(PyExc_TypeError, "byteorder must be str"); | ||
return NULL; | ||
} | ||
const char *order = PyUnicode_AsUTF8(byteorder); | ||
if (!order) { | ||
Py_DECREF(pyint); | ||
return NULL; | ||
} | ||
PyObject *result = CPyLong_ToBytes(pyint, length, order, signed_flag); | ||
Py_DECREF(pyint); | ||
return result; | ||
} | ||
|
||
|
||
// Helper for CPyLong_ToBytes (Python 3.2+) | ||
PyObject *CPyLong_ToBytes(PyObject *v, Py_ssize_t length, const char *byteorder, int signed_flag) { | ||
BobTheBuidler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
// This is a wrapper for PyLong_AsByteArray and PyBytes_FromStringAndSize | ||
unsigned char *bytes = (unsigned char *)PyMem_Malloc(length); | ||
BobTheBuidler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
if (!bytes) { | ||
PyErr_NoMemory(); | ||
return NULL; | ||
} | ||
int little_endian; | ||
if (strcmp(byteorder, "big") == 0) { | ||
little_endian = 0; | ||
} else if (strcmp(byteorder, "little") == 0) { | ||
little_endian = 1; | ||
} else { | ||
PyMem_Free(bytes); | ||
PyErr_SetString(PyExc_ValueError, "byteorder must be either 'little' or 'big'"); | ||
return NULL; | ||
} | ||
#if PY_VERSION_HEX >= 0x030D0000 // 3.13.0 | ||
int res = _PyLong_AsByteArray((PyLongObject *)v, bytes, length, little_endian, signed_flag, 1); | ||
#else | ||
int res = _PyLong_AsByteArray((PyLongObject *)v, bytes, length, little_endian, signed_flag); | ||
#endif | ||
if (res < 0) { | ||
PyMem_Free(bytes); | ||
return NULL; | ||
} | ||
PyObject *result = PyBytes_FromStringAndSize((const char *)bytes, length); | ||
PyMem_Free(bytes); | ||
return result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -572,3 +572,12 @@ class subc(int): | |
[file userdefinedint.py] | ||
class int: | ||
pass | ||
|
||
[case testIntToBytes] | ||
def to_bytes(n: int, length: int, byteorder: str, signed: bool = False) -> bytes: | ||
return n.to_bytes(length, byteorder, signed=signed) | ||
def test_to_bytes() -> None: | ||
assert to_bytes(255, 2, "big") == b'\x00\xff' | ||
assert to_bytes(255, 2, "little") == b'\xff\x00' | ||
assert to_bytes(-1, 2, "big", True) == b'\xff\xff' | ||
BobTheBuidler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
assert to_bytes(0, 1, "big") == b'\x00' | ||
|
Uh oh!
There was an error while loading. Please reload this page.