def put_assert(cond, msg):
defcode.putln("if (!(%s)) {" % cond)
- msg += ", got '%s'"
- defcode.putln('PyErr_Format(PyExc_ValueError, "%s", ts);' % msg)
+ defcode.putln('PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (%s)", __Pyx_DescribeTokenInFormatString(ts));' % msg)
defcode.putln("return NULL;")
defcode.putln("}")
(char, ctype, against, ctype))
defcode.putln("default: ok = 0;")
defcode.putln("}")
- defcode.putln("if (!ok) {")
- if dtype.typestring is not None:
- errmsg = "Buffer datatype mismatch (expected '%s', got '%%s')" % dtype.typestring
- else:
- errmsg = "Buffer datatype mismatch (rejecting on '%s')"
- defcode.putln('PyErr_Format(PyExc_ValueError, "%s", ts);' % errmsg)
- defcode.putln("return NULL;");
- defcode.putln("}")
+ put_assert("ok", "expected %s, got %%s" % dtype)
defcode.putln("++ts;")
elif complex_possible:
# Could be a struct representing a complex number, so allow
real_t.declaration_code(""),
imag_t.declaration_code("")))
defcode.putln('PyErr_SetString(PyExc_ValueError, "Cannot store complex number in \'%s\' as \'%s\' differs from \'%s\' in size.");' % (
- dtype.declaration_code("", for_display=True),
- real_t.declaration_code("", for_display=True),
- imag_t.declaration_code("", for_display=True)))
+ dtype, real_t, imag_t))
defcode.putln("return NULL;")
defcode.putln("}")
check_real, check_imag = [x[2] for x in field_blocks]
defcode.putln("int n, count;")
defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;")
- for n, type, checker in field_blocks:
+ next_types = [x[1] for x in field_blocks[1:]] + ["end"]
+ for (n, type, checker), next_type in zip(field_blocks, next_types):
if n == 1:
defcode.putln("if (*ts == '1') ++ts;")
else:
defcode.putln("n = %d;" % n);
defcode.putln("do {")
defcode.putln("ts = __Pyx_ParseTypestringRepeat(ts, &count); n -= count;")
+ put_assert("n >= 0", "expected %s, got %%s" % next_type)
simple = type.is_simple_buffer_dtype()
if not simple:
- put_assert("*ts == 'T' && *(ts+1) == '{'", "Expected start of %s" % type.declaration_code("", for_display=True))
+ put_assert("*ts == 'T' && *(ts+1) == '{'", "expected %s, got %%s" % type)
defcode.putln("ts += 2;")
defcode.putln("ts = %s(ts); if (!ts) return NULL;" % checker)
if not simple:
- put_assert("*ts == '}'", "Expected end of '%s'" % type.declaration_code("", for_display=True))
+ put_assert("*ts == '}'", "expected end of %s struct, got %%s" % type)
defcode.putln("++ts;")
if n > 1:
if (!ts) goto fail;
if (*ts != 0) {
PyErr_Format(PyExc_ValueError,
- "Buffer format string specifies more data than '%(dtype_name)s' can hold (expected end, got '%%s')", ts);
+ "Buffer dtype mismatch (expected end, got %%s)",
+ __Pyx_DescribeTokenInFormatString(ts));
goto fail;
}
} else {
static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/
static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/
static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/
+static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/
""", """
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
if (info->buf == NULL) return;
expected_ndim, buffer->ndim);
}
+static const char* __Pyx_DescribeTokenInFormatString(const char* ts) {
+ switch (*ts) {
+ case 'b': return "char";
+ case 'B': return "unsigned char";
+ case 'h': return "short";
+ case 'H': return "unsigned short";
+ case 'i': return "int";
+ case 'I': return "unsigned int";
+ case 'l': return "long";
+ case 'L': return "unsigned long";
+ case 'q': return "long long";
+ case 'Q': return "unsigned long long";
+ case 'f': return "float";
+ case 'd': return "double";
+ case 'g': return "long double";
+ case 'Z': switch (*(ts+1)) {
+ case 'f': return "complex float";
+ case 'd': return "complex double";
+ case 'g': return "complex long double";
+ default: return "unparseable format string";
+ }
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ default: return "unparseable format string";
+ }
+}
+
"""]
@testcase
def wrong_string(object[int] buf):
"""
- >>> wrong_string(IntMockBuffer(None, [1,2], format="iasdf"))
+ >>> wrong_string(IntMockBuffer(None, [1,2], format="if"))
Traceback (most recent call last):
...
- ValueError: Buffer format string specifies more data than 'int' can hold (expected end, got 'asdf')
+ ValueError: Buffer dtype mismatch (expected end, got float)
>>> wrong_string(IntMockBuffer(None, [1,2], format="$$"))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (expected 'i', got '$$')
+ ValueError: Buffer dtype mismatch (expected int, got unparseable format string)
"""
print buf[1]
>>> fmtst1(IntMockBuffer("A", range(3)))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (expected 'f', got 'i')
+ ValueError: Buffer dtype mismatch (expected float, got int)
"""
cdef object[float] a = buf
>>> fmtst2(FloatMockBuffer("A", range(3)))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (expected 'i', got 'f')
+ ValueError: Buffer dtype mismatch (expected int, got float)
"""
@testcase
>>> printbuf_td_cy_int(ShortMockBuffer(None, range(3)), (3,))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (rejecting on 'h')
+ ValueError: Buffer dtype mismatch (expected bufaccess.td_cy_int, got short)
"""
cdef int i
>>> printbuf_td_h_short(IntMockBuffer(None, range(3)), (3,))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (rejecting on 'i')
+ ValueError: Buffer dtype mismatch (expected bufaccess.td_h_short, got int)
"""
cdef int i
for i in range(shape[0]):
>>> printbuf_td_h_cy_short(IntMockBuffer(None, range(3)), (3,))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (rejecting on 'i')
+ ValueError: Buffer dtype mismatch (expected bufaccess.td_h_cy_short, got int)
"""
cdef int i
for i in range(shape[0]):
>>> printbuf_td_h_ushort(ShortMockBuffer(None, range(3)), (3,))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (rejecting on 'h')
+ ValueError: Buffer dtype mismatch (expected bufaccess.td_h_ushort, got short)
"""
cdef int i
for i in range(shape[0]):
>>> printbuf_td_h_double(FloatMockBuffer(None, [0.25, 1, 3.125]), (3,))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (rejecting on 'f')
+ ValueError: Buffer dtype mismatch (expected bufaccess.td_h_double, got float)
"""
cdef int i
for i in range(shape[0]):
1 2 3 4 5
>>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="bbqii"))
1 2 3 4 5
+ >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="23bqii"))
+ Traceback (most recent call last):
+ ...
+ ValueError: Buffer dtype mismatch (expected long long, got char)
>>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="i"))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (expected 'b', got 'i')
+ ValueError: Buffer dtype mismatch (expected char, got int)
"""
print buf[0].a, buf[0].b, buf[0].c, buf[0].d, buf[0].e
>>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="iiiii"))
Traceback (most recent call last):
...
- ValueError: Expected start of SmallStruct, got 'iiiii'
+ ValueError: Buffer dtype mismatch (expected SmallStruct, got int)
+ >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="T{iii}T{ii}i"))
+ Traceback (most recent call last):
+ ...
+ ValueError: Buffer dtype mismatch (expected end of SmallStruct struct, got int)
"""
print buf[0].x.a, buf[0].x.b, buf[0].y.a, buf[0].y.b, buf[0].z
])))
Traceback (most recent call last):
...
- ValueError: Buffer datatype mismatch (expected 'i', got 'f}T{ii}')
+ ValueError: Buffer dtype mismatch (expected int, got float)
>>> test_good_cast()
True