utility_code=UtilityCode.load("StringJoin", "StringTools.c")),
]),
("bytearray", "PyByteArray_Type", [
- BuiltinMethod("append", "Tz", "r", "__Pyx_PyByteArray_Append",
- utility_code=UtilityCode.load("ByteArrayAppend", "StringTools.c")),
]),
("bytes", "PyBytes_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"),
BuiltinMethod("join", "TO", "O", "__Pyx_PyBytes_Join",
utility_code=load_c_utility('append')
)
+ PyByteArray_Append_func_type = PyrexTypes.CFuncType(
+ PyrexTypes.c_returncode_type, [
+ PyrexTypes.CFuncTypeArg("bytearray", PyrexTypes.py_object_type, None),
+ PyrexTypes.CFuncTypeArg("value", PyrexTypes.c_int_type, None),
+ ],
+ exception_value="-1")
+
+ PyByteArray_AppendObject_func_type = PyrexTypes.CFuncType(
+ PyrexTypes.c_returncode_type, [
+ PyrexTypes.CFuncTypeArg("bytearray", PyrexTypes.py_object_type, None),
+ PyrexTypes.CFuncTypeArg("value", PyrexTypes.py_object_type, None),
+ ],
+ exception_value="-1")
+
+ def _handle_simple_method_bytearray_append(self, node, function, args, is_unbound_method):
+ if len(args) != 2:
+ return node
+ func_name = "__Pyx_PyByteArray_Append"
+ func_type = self.PyByteArray_Append_func_type
+
+ value = unwrap_coerced_node(args[1])
+ if value.type.is_int:
+ value = value.coerce_to(PyrexTypes.c_int_type, self.current_env())
+ utility_code = UtilityCode.load_cached("ByteArrayAppend", "StringTools.c")
+ elif value.is_string_literal:
+ if not value.can_coerce_to_char_literal():
+ return node
+ value = value.coerce_to(PyrexTypes.c_char_type, self.current_env())
+ utility_code = UtilityCode.load_cached("ByteArrayAppend", "StringTools.c")
+ elif value.type.is_pyobject:
+ func_name = "__Pyx_PyByteArray_AppendObject"
+ func_type = self.PyByteArray_AppendObject_func_type
+ utility_code = UtilityCode.load_cached("ByteArrayAppendObject", "StringTools.c")
+ else:
+ return node
+
+ new_node = ExprNodes.PythonCapiCallNode(
+ node.pos, func_name, func_type,
+ args=[args[0], value],
+ may_return_none=False,
+ is_temp=node.is_temp,
+ utility_code=utility_code,
+ )
+ if node.result_is_used:
+ new_node = new_node.coerce_to(node.type, self.current_env())
+ return new_node
+
PyObject_Pop_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None),
#endif
+//////////////////// ByteArrayAppendObject.proto ////////////////////
+
+static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value);
+
+//////////////////// ByteArrayAppendObject ////////////////////
+//@requires: ByteArrayAppend
+
+static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value) {
+ Py_ssize_t ival;
+#if PY_MAJOR_VERSION < 3
+ if (unlikely(PyString_Check(value))) {
+ if (unlikely(PyString_GET_SIZE(value) != 1)) {
+ PyErr_SetString(PyExc_ValueError, "string must be of size 1");
+ return -1;
+ }
+ ival = PyString_AS_STRING(value)[0];
+ } else
+#endif
+ {
+ ival = __Pyx_PyIndex_AsSsize_t(value);
+ if (unlikely(ival == -1 && PyErr_Occurred()))
+ return -1;
+ }
+ return __Pyx_PyByteArray_Append(bytearray, ival);
+}
+
//////////////////// ByteArrayAppend.proto ////////////////////
-static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, Py_ssize_t value);
+static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value);
//////////////////// ByteArrayAppend ////////////////////
//@requires: ObjectHandling.c::PyObjectCallMethod
// signature uses Py_ssize_t to make coercions use PyNumber_Index(), as CPython does
-static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, Py_ssize_t value) {
+static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value) {
PyObject *pyval, *retval;
#if CYTHON_COMPILING_IN_CPYTHON
- Py_ssize_t n = Py_SIZE(bytearray);
if (likely((value >= 0) & (value <= 255))) {
- if (likely(n < PY_SSIZE_T_MAX)) {
+ Py_ssize_t n = Py_SIZE(bytearray);
+ if (likely(n != PY_SSIZE_T_MAX)) {
if (unlikely(PyByteArray_Resize(bytearray, n + 1) < 0))
return -1;
PyByteArray_AS_STRING(bytearray)[n] = value;
return 0;
}
+ } else {
+ PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ return -1;
}
#endif
pyval = PyInt_FromLong(value);
+
+import sys
+IS_PY3 = sys.version_info[0] >= 3
+
cimport cython
b_a = bytearray(b'a')
def bytearray_append(bytearray b, char c, int i, object o):
"""
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), ord('y'), ord('z'))
>>> print(b.decode('ascii'))
abcXxyz
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
+ >>> b = bytearray_append(b, ord('x'), ord('y'), ord('z') if IS_PY3 else b'z')
+ >>> print(b.decode('ascii'))
+ abcXxyz
+
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, -1, ord('y'), ord('z')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: ...
>>> print(b.decode('ascii'))
abcX
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), -1, ord('z')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: ...
>>> print(b.decode('ascii'))
abcXx
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), 256, ord('z')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: ...
>>> print(b.decode('ascii'))
abcXx
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), ord('y'), -1) # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: ...
>>> print(b.decode('ascii'))
abcXxy
- >>> b = bytearray('abc'.encode('ascii'))
+ >>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), ord('y'), 256) # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: ...
>>> print(b.decode('ascii'))
abcXxy
"""
- b.append('X')
+ assert b.append('X') is None
b.append(c)
b.append(i)
b.append(o)