-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[mypyc] feat: new primitives for bytes.rjust and bytes.ljust
#19672
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 all commits
ab75317
02d76a5
6453373
0c33019
2baf425
350db60
ee1a76e
e5d6e43
b936c3c
c5ed8a4
3db102b
4fd876f
b82c603
a106445
a44e9b5
10e5093
600b276
eaee990
3e66f36
0edcb0d
1be3982
c1caaa2
b28b6d1
b63c06d
5aee840
51fe159
b780cb8
1e50094
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 |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
|
|
||
| #include <Python.h> | ||
| #include "CPy.h" | ||
| #include <string.h> | ||
|
|
||
| // Returns -1 on error, 0 on inequality, 1 on equality. | ||
| // | ||
|
|
@@ -162,3 +163,97 @@ CPyTagged CPyBytes_Ord(PyObject *obj) { | |
| PyErr_SetString(PyExc_TypeError, "ord() expects a character"); | ||
| return CPY_INT_TAG; | ||
| } | ||
|
|
||
|
|
||
| PyObject *CPyBytes_RjustDefaultFill(PyObject *self, CPyTagged width) { | ||
| if (!PyBytes_Check(self)) { | ||
| PyErr_SetString(PyExc_TypeError, "self must be bytes"); | ||
| return NULL; | ||
| } | ||
| Py_ssize_t width_size_t = CPyTagged_AsSsize_t(width); | ||
| Py_ssize_t len = PyBytes_Size(self); | ||
| if (width_size_t <= len) { | ||
| Py_INCREF(self); | ||
| return self; | ||
| } | ||
| Py_ssize_t pad = width_size_t - len; | ||
| PyObject *result = PyBytes_FromStringAndSize(NULL, width_size_t); | ||
| if (!result) return NULL; | ||
| char *res_buf = PyBytes_AsString(result); | ||
| memset(res_buf, ' ', pad); | ||
| memcpy(res_buf + pad, PyBytes_AsString(self), len); | ||
| return result; | ||
| } | ||
|
|
||
|
|
||
| PyObject *CPyBytes_RjustCustomFill(PyObject *self, CPyTagged width, PyObject *fillbyte) { | ||
| if (!PyBytes_Check(self)) { | ||
|
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. Can we get rid of these type checks?
Collaborator
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. A variable annotated with |
||
| PyErr_SetString(PyExc_TypeError, "self must be bytes"); | ||
| return NULL; | ||
| } | ||
| if (!PyBytes_Check(fillbyte) || PyBytes_Size(fillbyte) != 1) { | ||
|
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. Can we get rid of these type checks?
Collaborator
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. See above -- we need type checks, and they must use an exact bytes check, and there must also be a fallback implementation. |
||
| PyErr_SetString(PyExc_TypeError, "fillbyte must be a single byte"); | ||
| return NULL; | ||
| } | ||
| Py_ssize_t width_size_t = CPyTagged_AsSsize_t(width); | ||
| Py_ssize_t len = PyBytes_Size(self); | ||
| if (width_size_t <= len) { | ||
| Py_INCREF(self); | ||
| return self; | ||
| } | ||
| char fill = PyBytes_AsString(fillbyte)[0]; | ||
| Py_ssize_t pad = width_size_t - len; | ||
| PyObject *result = PyBytes_FromStringAndSize(NULL, width_size_t); | ||
| if (!result) return NULL; | ||
| char *res_buf = PyBytes_AsString(result); | ||
| memset(res_buf, fill, pad); | ||
| memcpy(res_buf + pad, PyBytes_AsString(self), len); | ||
| return result; | ||
| } | ||
|
|
||
|
|
||
| PyObject *CPyBytes_LjustDefaultFill(PyObject *self, CPyTagged width) { | ||
| if (!PyBytes_Check(self)) { | ||
| PyErr_SetString(PyExc_TypeError, "self must be bytes"); | ||
| return NULL; | ||
| } | ||
| Py_ssize_t width_size_t = CPyTagged_AsSsize_t(width); | ||
| Py_ssize_t len = PyBytes_Size(self); | ||
| if (width_size_t <= len) { | ||
| Py_INCREF(self); | ||
| return self; | ||
| } | ||
| Py_ssize_t pad = width_size_t - len; | ||
| PyObject *result = PyBytes_FromStringAndSize(NULL, width_size_t); | ||
| if (!result) return NULL; | ||
| char *res_buf = PyBytes_AsString(result); | ||
| memcpy(res_buf, PyBytes_AsString(self), len); | ||
| memset(res_buf + len, ' ', pad); | ||
| return result; | ||
| } | ||
|
|
||
|
|
||
| PyObject *CPyBytes_LjustCustomFill(PyObject *self, CPyTagged width, PyObject *fillbyte) { | ||
| if (!PyBytes_Check(self)) { | ||
| PyErr_SetString(PyExc_TypeError, "self must be bytes"); | ||
| return NULL; | ||
| } | ||
| if (!PyBytes_Check(fillbyte) || PyBytes_Size(fillbyte) != 1) { | ||
| PyErr_SetString(PyExc_TypeError, "fillbyte must be a single byte"); | ||
| return NULL; | ||
| } | ||
| Py_ssize_t width_size_t = CPyTagged_AsSsize_t(width); | ||
| Py_ssize_t len = PyBytes_Size(self); | ||
| if (width_size_t <= len) { | ||
| Py_INCREF(self); | ||
| return self; | ||
| } | ||
| char fill = PyBytes_AsString(fillbyte)[0]; | ||
| Py_ssize_t pad = width_size_t - len; | ||
| PyObject *result = PyBytes_FromStringAndSize(NULL, width_size_t); | ||
| if (!result) return NULL; | ||
| char *res_buf = PyBytes_AsString(result); | ||
| memcpy(res_buf, PyBytes_AsString(self), len); | ||
| memset(res_buf + len, fill, pad); | ||
| return result; | ||
| } | ||
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.
Please share most of the implementations using a helper function, since the functions are very similar (across all four functions), and these methods probably aren't super performance critical to make the code duplication worth it (the likely gains would be very small, since most of the CPU is spent in the common shared code). E.g. add a function that takes the bytes value, width, a bool flag for ljust/rjust and the fill character (
char) as arguments.