Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

311 lines (255 sloc) 7.648 kb
from __future__ import unicode_literals
# Tests buffer format string parsing.
__test__ = {}
def testcase(func):
__test__[func.__name__] = func.__doc__
return func
cimport stdlib
def little_endian():
cdef unsigned int n = 1
return (<unsigned char*>&n)[0] != 0
if little_endian():
current_endian = '<'
other_endian = '>'
else:
current_endian = '>'
other_endian = '<'
cdef struct align_of_float_helper:
char ch
float d
cdef struct align_of_int_helper:
char ch
int i
float_align = sizeof(align_of_float_helper) - sizeof(float)
int_align = sizeof(align_of_int_helper) - sizeof(int)
if float_align != 4 or sizeof(float) != 4:
raise RuntimeError("Alignment or size of float is %d on this system, please report to cython-dev for a testcase fix" % float_align)
if int_align != 4 or sizeof(int) != 4:
raise RuntimeError("Alignment or size of int is %d on this system, please report to cython-dev for a testcase fix" % int_align)
cdef class MockBuffer:
cdef Py_ssize_t zero
cdef Py_ssize_t minusone
cdef object format
cdef object itemsize
def __init__(self, format, itemsize):
self.format = unicode(format).encode(u"ASCII")
self.itemsize = itemsize
self.zero = 0
self.minusone = -1
def __getbuffer__(self, Py_buffer* info, int flags):
info.buf = NULL
info.strides = &self.zero
info.suboffsets = &self.minusone
info.shape = &self.zero
info.ndim = 1
info.format = self.format
info.itemsize = self.itemsize
@testcase
def _int(fmt):
"""
>>> _int("i")
>>> _int("b")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'int' but got 'char'
>>> _int("if")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected end but got 'float'
>>> _int("$$")
Traceback (most recent call last):
...
ValueError: Does not understand character buffer dtype format string ('$')
"""
cdef object[int] buf = MockBuffer(fmt, sizeof(int))
@testcase
def _ulong(fmt):
"""
>>> _ulong("L")
"""
cdef object[unsigned long] buf = MockBuffer(fmt, sizeof(unsigned long))
@testcase
def wrongsize():
"""
>>> wrongsize()
Traceback (most recent call last):
...
ValueError: Item size of buffer (1 byte) does not match size of 'float' (4 bytes)
"""
cdef object[float] buf = MockBuffer("f", 1)
@testcase
def _obj(fmt):
"""
>>> _obj("O")
>>> _obj("i")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'Python object' but got 'int'
"""
cdef object[object] buf = MockBuffer(fmt, sizeof(void*))
cdef struct ComplexFloat:
float real
float imag
ctypedef struct Char3Int:
char a
int b
int c
int d
cdef struct CharIntCFloat:
char a
int b
ComplexFloat c
float d
cdef struct UnpackedStruct1:
char a
int b
ComplexFloat c
float c2
Char3Int d
ctypedef struct UnpackedStruct2:
CharIntCFloat a
Char3Int b
ctypedef struct UnpackedStruct3:
CharIntCFloat a
char b
int c, d, e
cdef struct UnpackedStruct4:
char a
int b
ComplexFloat c
float c2
char d
int e, f, g
@testcase
def char3int(fmt):
"""
>>> char3int("ciii")
>>> char3int("c1i1i1i")
>>> char3int("c3i")
>>> char3int("ci2i")
#TODO > char3int("c@i@2i")
Extra pad bytes (assuming int size is 4 or more)
>>> char3int("cxiii")
>>> char3int("c3xiii")
>>> char3int("cxxxiii")
Standard alignment (assming int size is 4)
>>> char3int("=c3xiii")
>>> char3int("=ciii")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected
#TODO char3int("=cxxx@iii")
Error:
>>> char3int("cii")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'int' but got end in 'Char3Int.d'
"""
obj = MockBuffer(fmt, sizeof(Char3Int))
cdef object[Char3Int, ndim=1] buf = obj
@testcase
def unpacked_struct(fmt):
"""
Native formats:
>>> unpacked_struct("biZffbiii")
>>> unpacked_struct("@bi3fb3i")
>>> unpacked_struct("@biZffbi2i")
>>> unpacked_struct("biZffT{biii}")
>>> unpacked_struct("bT{ifffb2i}i")
>>> unpacked_struct("biZffb3T{i}")
>>> unpacked_struct("T{b}T{T{iZffT{bi}}}2T{T{i}}")
"""
assert (sizeof(UnpackedStruct1) == sizeof(UnpackedStruct2)
== sizeof(UnpackedStruct3) == sizeof(UnpackedStruct4))
obj = MockBuffer(fmt, sizeof(UnpackedStruct1))
cdef object[UnpackedStruct1, ndim=1] buf1 = obj
cdef object[UnpackedStruct2, ndim=1] buf2 = obj
cdef object[UnpackedStruct3, ndim=1] buf3 = obj
cdef object[UnpackedStruct4, ndim=1] buf4 = obj
cdef struct ComplexTest:
ComplexFloat a, b, c
@testcase
def complex_test(fmt):
"""
>>> complex_test("ZfZfZf")
>>> complex_test("3Zf")
>>> complex_test("6f")
>>> complex_test("3T{Zf}")
>>> complex_test("fZfZff")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'float' but got 'complex float' in 'ComplexFloat.imag'
"""
obj = MockBuffer(fmt, sizeof(ComplexTest))
cdef object[ComplexTest] buf1 = obj
@testcase
def alignment_string(fmt, exc=None):
"""
>>> alignment_string("@i")
>>> alignment_string("%si" % current_endian)
>>> alignment_string("%si" % other_endian, "X-endian buffer not supported on X-endian compiler")
>>> alignment_string("=i")
"""
cdef object[int] buf
try:
buf = MockBuffer(fmt, sizeof(int))
except ValueError, e:
msg = unicode(e).replace("Big", "X").replace("Little", "X").replace("big", "X").replace("little", "X")
if msg != exc:
print msg
print " is not equal to"
print exc
return
if exc:
print "fail"
@testcase
def int_and_long_are_same():
"""
>>> int_and_long_are_same()
"""
cdef object[int] intarr
cdef object[long] longarr
if sizeof(int) == sizeof(long):
intarr = MockBuffer("l", sizeof(int))
longarr = MockBuffer("i", sizeof(int))
cdef struct MixedComplex:
double real
float imag
@testcase
def mixed_complex_struct():
"""
Triggering a specific execution path for this case.
>>> mixed_complex_struct()
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'double' but got 'complex double' in 'MixedComplex.real'
"""
cdef object[MixedComplex] buf = MockBuffer("Zd",
sizeof(MixedComplex))
cdef packed struct PackedSubStruct:
char x
int y
cdef packed struct PackedStruct:
char a
int b
PackedSubStruct sub
@testcase
def packed_struct(fmt):
"""
Assuming int is four bytes:
>>> packed_struct("^cici")
>>> packed_struct("=cibi")
>>> packed_struct("^c@i^ci")
Traceback (most recent call last):
...
ValueError: Buffer packing mode currently only allowed at beginning of format string (this is a defect)
However aligned access won't work:
>>> packed_struct("@cici")
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch; next field is at offset 4 but 1 expected
"""
cdef object[PackedStruct] buf = MockBuffer(fmt, sizeof(PackedStruct))
# TODO: empty struct
# TODO: Incomplete structs
# TODO: mixed structs
Jump to Line
Something went wrong with that request. Please try again.