Commit 1461e514 authored by Stefan Behnel's avatar Stefan Behnel

Clean up the NumPy integration test by moving the doctests into the functions that they test.

parent 68bb7164
# mode: run
# tag: numpy # tag: numpy
cimport numpy as np cimport numpy as np
cimport cython cimport cython
import numpy as np
import re import re
...@@ -16,6 +19,7 @@ def testcase(f): ...@@ -16,6 +19,7 @@ def testcase(f):
# but is a useful indicator of what functions are designed as tests # but is a useful indicator of what functions are designed as tests
return f return f
if little_endian(): if little_endian():
my_endian = '<' my_endian = '<'
other_endian = '>' other_endian = '>'
...@@ -23,17 +27,55 @@ else: ...@@ -23,17 +27,55 @@ else:
my_endian = '>' my_endian = '>'
other_endian = '<' other_endian = '<'
try:
import numpy as np
__doc__ = u"""
def assert_dtype_sizes():
"""
>>> assert_dtype_sizes() >>> assert_dtype_sizes()
"""
assert sizeof(np.int8_t) == 1
assert sizeof(np.int16_t) == 2
assert sizeof(np.int32_t) == 4
assert sizeof(np.int64_t) == 8
assert sizeof(np.uint8_t) == 1
assert sizeof(np.uint16_t) == 2
assert sizeof(np.uint32_t) == 4
assert sizeof(np.uint64_t) == 8
assert sizeof(np.float32_t) == 4
assert sizeof(np.float64_t) == 8
assert sizeof(np.complex64_t) == 8
assert sizeof(np.complex128_t) == 16
@testcase
def test_enums():
"""
>>> test_enums()
"""
cdef np.NPY_CASTING nc = np.NPY_NO_CASTING
assert nc != np.NPY_SAFE_CASTING
def ndarray_str(arr):
u"""
Work around display differences in NumPy 1.14.
"""
return re.sub(ur'\[ +', '[', unicode(arr))
def basic():
"""
>>> basic() >>> basic()
[[0 1 2 3 4] [[0 1 2 3 4]
[5 6 7 8 9]] [5 6 7 8 9]]
2 0 9 5 2 0 9 5
"""
cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5))
print buf
print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0]
def three_dim():
"""
>>> three_dim() # doctest: +NORMALIZE_WHITESPACE >>> three_dim() # doctest: +NORMALIZE_WHITESPACE
[[[0. 1. 2. 3.] [[[0. 1. 2. 3.]
[4. 5. 6. 7.]] [4. 5. 6. 7.]]
...@@ -44,11 +86,25 @@ try: ...@@ -44,11 +86,25 @@ try:
[[16. 17. 18. 19.] [[16. 17. 18. 19.]
[20. 21. 22. 23.]]] [20. 21. 22. 23.]]]
6.0 0.0 13.0 8.0 6.0 0.0 13.0 8.0
"""
cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4))
print ndarray_str(buf)
print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0]
def obj_array():
"""
>>> obj_array() >>> obj_array()
[a 1 {}] [a 1 {}]
a 1 {} a 1 {}
"""
cdef object[object, ndim=1] buf = np.array(["a", 1, {}])
print str(buf).replace('"', '').replace("'", '')
print buf[0], buf[1], buf[2]
def print_long_2d(np.ndarray[long, ndim=2] arr):
"""
Test various forms of slicing, picking etc. Test various forms of slicing, picking etc.
>>> a = np.arange(10, dtype='l').reshape(2, 5) >>> a = np.arange(10, dtype='l').reshape(2, 5)
>>> print_long_2d(a) >>> print_long_2d(a)
...@@ -78,9 +134,16 @@ try: ...@@ -78,9 +134,16 @@ try:
2 7 2 7
3 8 3 8
4 9 4 9
"""
cdef int i, j
for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
def put_range_long_1d(np.ndarray[long] arr):
"""
Write to slices Write to slices
>>> b = a.copy() >>> b = np.arange(10, dtype='l').reshape(2, 5)
>>> put_range_long_1d(b[:, 3]) >>> put_range_long_1d(b[:, 3])
>>> print (b) >>> print (b)
[[0 1 2 0 4] [[0 1 2 0 4]
...@@ -101,7 +164,16 @@ try: ...@@ -101,7 +164,16 @@ try:
>>> print (a) >>> print (a)
[[0 0 0 0 0] [[0 0 0 0 0]
[0 0 0 0 0]] [0 0 0 0 0]]
"""
# Writes 0,1,2,... to array and returns array
cdef int value = 0, i
for i in range(arr.shape[0]):
arr[i] = value
value += 1
def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr):
"""
Test contiguous access modes: Test contiguous access modes:
>>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C') >>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C')
>>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F') >>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F')
...@@ -109,200 +181,39 @@ try: ...@@ -109,200 +181,39 @@ try:
0 1 2 3 0 1 2 3
4 5 6 7 4 5 6 7
8 9 10 11 8 9 10 11
>>> test_f_contig(f_arr)
0 1 2 3
4 5 6 7
8 9 10 11
>>> test_c_contig(f_arr) #doctest: +ELLIPSIS >>> test_c_contig(f_arr) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: ndarray is not C...contiguous ValueError: ndarray is not C...contiguous
>>> test_f_contig(c_arr) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ndarray is not Fortran contiguous
>>> test_c_contig(c_arr[::2,::2]) #doctest: +ELLIPSIS >>> test_c_contig(c_arr[::2,::2]) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: ndarray is not C...contiguous ValueError: ndarray is not C...contiguous
>>> test_dtype('?', inc1_bool)
>>> test_dtype('b', inc1_byte)
>>> test_dtype('B', inc1_ubyte)
>>> test_dtype('h', inc1_short)
>>> test_dtype('H', inc1_ushort)
>>> test_dtype('i', inc1_int)
>>> test_dtype('I', inc1_uint)
>>> test_dtype('l', inc1_long)
>>> test_dtype('L', inc1_ulong)
>>> test_dtype('f', inc1_float)
>>> test_dtype('d', inc1_double)
>>> test_dtype('g', inc1_longdouble)
>>> test_dtype('O', inc1_object)
>>> test_dtype('F', inc1_cfloat) # numpy format codes differ from buffer ones here
>>> test_dtype('D', inc1_cdouble)
>>> test_dtype('G', inc1_clongdouble)
>>> test_dtype('F', inc1_cfloat_struct)
>>> test_dtype('D', inc1_cdouble_struct)
>>> test_dtype('G', inc1_clongdouble_struct)
>>> test_dtype(np.int, inc1_int_t)
>>> test_dtype(np.longlong, inc1_longlong_t)
>>> test_dtype(np.float, inc1_float_t)
>>> test_dtype(np.double, inc1_double_t)
>>> test_dtype(np.intp, inc1_intp_t)
>>> test_dtype(np.uintp, inc1_uintp_t)
>>> test_dtype(np.longdouble, inc1_longdouble_t)
>>> test_dtype(np.int32, inc1_int32_t)
>>> test_dtype(np.float64, inc1_float64_t)
Endian tests:
>>> test_dtype('%si' % my_endian, inc1_int)
>>> test_dtype('%si' % other_endian, inc1_int) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
>>> test_recordarray()
>>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
('a', np.dtype('i,i')),\
('b', np.dtype('i,i'))\
])))) # doctest: +NORMALIZE_WHITESPACE
array([((0, 0), (0, 0)), ((1, 2), (1, 4)), ((1, 2), (1, 4))],
dtype=[('a', [('f0', '!i4'), ('f1', '!i4')]), ('b', [('f0', '!i4'), ('f1', '!i4')])])
>>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
('a', np.dtype('i,f')),\
('b', np.dtype('i,i'))\
]))))
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'int' but got 'float' in 'DoubleInt.y'
>>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=False))))
[(22, 23)]
The output changed in Python 3:
>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
array([(22, 23)],
dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')])
->
array([(22, 23)],
dtype={'names':['f0','f1'], 'formats':['i1','!i4'], 'offsets':[0,4], 'itemsize':8, 'aligned':True})
>>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
[(22, 23)]
>>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
>>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
>>> test_good_cast()
True
>>> test_bad_cast()
Traceback (most recent call last):
...
ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes)
>>> test_complextypes()
1,1
1,1
8,16
>>> test_point_record() # doctest: +NORMALIZE_WHITESPACE
array([(0., 0.), (1., -1.), (2., -2.)],
dtype=[('x', '!f8'), ('y', '!f8')])
"""
except:
__doc__ = u""
def assert_dtype_sizes():
assert sizeof(np.int8_t) == 1
assert sizeof(np.int16_t) == 2
assert sizeof(np.int32_t) == 4
assert sizeof(np.int64_t) == 8
assert sizeof(np.uint8_t) == 1
assert sizeof(np.uint16_t) == 2
assert sizeof(np.uint32_t) == 4
assert sizeof(np.uint64_t) == 8
assert sizeof(np.float32_t) == 4
assert sizeof(np.float64_t) == 8
assert sizeof(np.complex64_t) == 8
assert sizeof(np.complex128_t) == 16
@testcase
def test_enums():
"""
>>> test_enums()
""" """
cdef np.NPY_CASTING nc = np.NPY_NO_CASTING
assert nc != np.NPY_SAFE_CASTING
def ndarray_str(arr):
u"""
Work around display differences in NumPy 1.14.
"""
return re.sub(ur'\[ +', '[', unicode(arr))
def basic():
cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5))
print buf
print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0]
def three_dim():
cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4))
print ndarray_str(buf)
print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0]
def obj_array():
cdef object[object, ndim=1] buf = np.array(["a", 1, {}])
print str(buf).replace('"', '').replace("'", '')
print buf[0], buf[1], buf[2]
def print_long_2d(np.ndarray[long, ndim=2] arr):
cdef int i, j cdef int i, j
for i in range(arr.shape[0]): for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
def put_range_long_1d(np.ndarray[long] arr):
u"""Writes 0,1,2,... to array and returns array"""
cdef int value = 0, i
for i in range(arr.shape[0]):
arr[i] = value
value += 1
def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr):
cdef int i, j
for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr): def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr):
"""
Test contiguous access modes:
>>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C')
>>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F')
>>> test_f_contig(f_arr)
0 1 2 3
4 5 6 7
8 9 10 11
>>> test_f_contig(c_arr) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ndarray is not Fortran contiguous
"""
cdef int i, j cdef int i, j
for i in range(arr.shape[0]): for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
# Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes # Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes
def inc1_bool(np.ndarray[unsigned char] arr): arr[1] += 1 def inc1_bool(np.ndarray[unsigned char] arr): arr[1] += 1
def inc1_byte(np.ndarray[char] arr): arr[1] += 1 def inc1_byte(np.ndarray[char] arr): arr[1] += 1
...@@ -343,7 +254,6 @@ def inc1_object(np.ndarray[object] arr): ...@@ -343,7 +254,6 @@ def inc1_object(np.ndarray[object] arr):
o += 1 o += 1
arr[1] = o # unfortunately, += segfaults for objects arr[1] = o # unfortunately, += segfaults for objects
def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1 def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1
def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1 def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1
def inc1_longlong_t(np.ndarray[np.longlong_t] arr): arr[1] += 1 def inc1_longlong_t(np.ndarray[np.longlong_t] arr): arr[1] += 1
...@@ -359,6 +269,47 @@ def inc1_float64_t(np.ndarray[np.float64_t] arr): arr[1] += 1 ...@@ -359,6 +269,47 @@ def inc1_float64_t(np.ndarray[np.float64_t] arr): arr[1] += 1
def test_dtype(dtype, inc1): def test_dtype(dtype, inc1):
"""
>>> test_dtype('?', inc1_bool)
>>> test_dtype('b', inc1_byte)
>>> test_dtype('B', inc1_ubyte)
>>> test_dtype('h', inc1_short)
>>> test_dtype('H', inc1_ushort)
>>> test_dtype('i', inc1_int)
>>> test_dtype('I', inc1_uint)
>>> test_dtype('l', inc1_long)
>>> test_dtype('L', inc1_ulong)
>>> test_dtype('f', inc1_float)
>>> test_dtype('d', inc1_double)
>>> test_dtype('g', inc1_longdouble)
>>> test_dtype('O', inc1_object)
>>> test_dtype('F', inc1_cfloat) # numpy format codes differ from buffer ones here
>>> test_dtype('D', inc1_cdouble)
>>> test_dtype('G', inc1_clongdouble)
>>> test_dtype('F', inc1_cfloat_struct)
>>> test_dtype('D', inc1_cdouble_struct)
>>> test_dtype('G', inc1_clongdouble_struct)
>>> test_dtype(np.int, inc1_int_t)
>>> test_dtype(np.longlong, inc1_longlong_t)
>>> test_dtype(np.float, inc1_float_t)
>>> test_dtype(np.double, inc1_double_t)
>>> test_dtype(np.intp, inc1_intp_t)
>>> test_dtype(np.uintp, inc1_uintp_t)
>>> test_dtype(np.longdouble, inc1_longdouble_t)
>>> test_dtype(np.int32, inc1_int32_t)
>>> test_dtype(np.float64, inc1_float64_t)
Endian tests:
>>> test_dtype('%si' % my_endian, inc1_int)
>>> test_dtype('%si' % other_endian, inc1_int) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
"""
if dtype in ("g", np.longdouble, if dtype in ("g", np.longdouble,
"G", np.clongdouble): "G", np.clongdouble):
if sizeof(double) == sizeof(long double): # MSVC if sizeof(double) == sizeof(long double): # MSVC
...@@ -379,10 +330,14 @@ def test_dtype(dtype, inc1): ...@@ -379,10 +330,14 @@ def test_dtype(dtype, inc1):
inc1(a) inc1(a)
if a[1] != 11: print u"failed!" if a[1] != 11: print u"failed!"
cdef struct DoubleInt: cdef struct DoubleInt:
int x, y int x, y
def test_recordarray(): def test_recordarray():
"""
>>> test_recordarray()
"""
cdef object[DoubleInt] arr cdef object[DoubleInt] arr
arr = np.array([(5,5), (4, 6)], dtype=np.dtype('i,i')) arr = np.array([(5,5), (4, 6)], dtype=np.dtype('i,i'))
cdef DoubleInt rec cdef DoubleInt rec
...@@ -398,6 +353,7 @@ def test_recordarray(): ...@@ -398,6 +353,7 @@ def test_recordarray():
if arr[1].x != 5: print u"failed" if arr[1].x != 5: print u"failed"
if arr[1].y != 10: print u"failed" if arr[1].y != 10: print u"failed"
cdef struct NestedStruct: cdef struct NestedStruct:
DoubleInt a DoubleInt a
DoubleInt b DoubleInt b
...@@ -411,6 +367,22 @@ cdef struct BadNestedStruct: ...@@ -411,6 +367,22 @@ cdef struct BadNestedStruct:
BadDoubleInt b BadDoubleInt b
def test_nested_dtypes(obj): def test_nested_dtypes(obj):
"""
>>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
('a', np.dtype('i,i')),\
('b', np.dtype('i,i'))\
])))) # doctest: +NORMALIZE_WHITESPACE
array([((0, 0), (0, 0)), ((1, 2), (1, 4)), ((1, 2), (1, 4))],
dtype=[('a', [('f0', '!i4'), ('f1', '!i4')]), ('b', [('f0', '!i4'), ('f1', '!i4')])])
>>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
('a', np.dtype('i,f')),\
('b', np.dtype('i,i'))\
]))))
Traceback (most recent call last):
...
ValueError: Buffer dtype mismatch, expected 'int' but got 'float' in 'DoubleInt.y'
"""
cdef object[NestedStruct] arr = obj cdef object[NestedStruct] arr = obj
arr[1].a.x = 1 arr[1].a.x = 1
arr[1].a.y = 2 arr[1].a.y = 2
...@@ -419,19 +391,36 @@ def test_nested_dtypes(obj): ...@@ -419,19 +391,36 @@ def test_nested_dtypes(obj):
arr[2] = arr[1] arr[2] = arr[1]
return repr(arr).replace('<', '!').replace('>', '!') return repr(arr).replace('<', '!').replace('>', '!')
def test_bad_nested_dtypes(): def test_bad_nested_dtypes():
"""
>>> test_bad_nested_dtypes()
"""
cdef object[BadNestedStruct] arr cdef object[BadNestedStruct] arr
def test_good_cast(): def test_good_cast():
"""
>>> test_good_cast()
True
"""
# Check that a signed int can round-trip through casted unsigned int access # Check that a signed int can round-trip through casted unsigned int access
cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i') cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i')
cdef unsigned int data = arr[0] cdef unsigned int data = arr[0]
return -100 == <int>data return -100 == <int>data
def test_bad_cast(): def test_bad_cast():
"""
>>> test_bad_cast()
Traceback (most recent call last):
...
ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes)
"""
# This should raise an exception # This should raise an exception
cdef np.ndarray[int, cast=True] arr = np.array([1], dtype='b') cdef np.ndarray[int, cast=True] arr = np.array([1], dtype='b')
cdef packed struct PackedStruct: cdef packed struct PackedStruct:
char a char a
int b int b
...@@ -453,16 +442,45 @@ cdef packed struct PartiallyPackedStruct2: ...@@ -453,16 +442,45 @@ cdef packed struct PartiallyPackedStruct2:
UnpackedStruct sub UnpackedStruct sub
def test_packed_align(np.ndarray[PackedStruct] arr): def test_packed_align(np.ndarray[PackedStruct] arr):
"""
>>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=False))))
[(22, 23)]
>>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
"""
arr[0].a = 22 arr[0].a = 22
arr[0].b = 23 arr[0].b = 23
return list(arr) return list(arr)
def test_unpacked_align(np.ndarray[UnpackedStruct] arr): def test_unpacked_align(np.ndarray[UnpackedStruct] arr):
"""
The output changed in Python 3:
>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
array([(22, 23)],
dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')])
->
array([(22, 23)],
dtype={'names':['f0','f1'], 'formats':['i1','!i4'], 'offsets':[0,4], 'itemsize':8, 'aligned':True})
>>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
[(22, 23)]
>>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
"""
arr[0].a = 22 arr[0].a = 22
arr[0].b = 23 arr[0].b = 23
# return repr(arr).replace('<', '!').replace('>', '!') # return repr(arr).replace('<', '!').replace('>', '!')
return list(arr) return list(arr)
def test_partially_packed_align(np.ndarray[PartiallyPackedStruct] arr): def test_partially_packed_align(np.ndarray[PartiallyPackedStruct] arr):
arr[0].a = 22 arr[0].a = 22
arr[0].b = 23 arr[0].b = 23
...@@ -471,6 +489,7 @@ def test_partially_packed_align(np.ndarray[PartiallyPackedStruct] arr): ...@@ -471,6 +489,7 @@ def test_partially_packed_align(np.ndarray[PartiallyPackedStruct] arr):
arr[0].c = 26 arr[0].c = 26
return repr(arr).replace('<', '!').replace('>', '!') return repr(arr).replace('<', '!').replace('>', '!')
def test_partially_packed_align_2(np.ndarray[PartiallyPackedStruct2] arr): def test_partially_packed_align_2(np.ndarray[PartiallyPackedStruct2] arr):
arr[0].a = 22 arr[0].a = 22
arr[0].b = 23 arr[0].b = 23
...@@ -479,7 +498,14 @@ def test_partially_packed_align_2(np.ndarray[PartiallyPackedStruct2] arr): ...@@ -479,7 +498,14 @@ def test_partially_packed_align_2(np.ndarray[PartiallyPackedStruct2] arr):
arr[0].sub.b = 28 arr[0].sub.b = 28
return repr(arr).replace('<', '!').replace('>', '!') return repr(arr).replace('<', '!').replace('>', '!')
def test_complextypes(): def test_complextypes():
"""
>>> test_complextypes()
1,1
1,1
8,16
"""
cdef np.complex64_t x64 = 1, y64 = 1j cdef np.complex64_t x64 = 1, y64 = 1j
cdef np.complex128_t x128 = 1, y128 = 1j cdef np.complex128_t x128 = 1, y128 = 1j
x64 = x64 + y64 x64 = x64 + y64
...@@ -493,6 +519,11 @@ cdef struct Point: ...@@ -493,6 +519,11 @@ cdef struct Point:
np.float64_t x, y np.float64_t x, y
def test_point_record(): def test_point_record():
"""
>>> test_point_record() # doctest: +NORMALIZE_WHITESPACE
array([(0., 0.), (1., -1.), (2., -2.)],
dtype=[('x', '!f8'), ('y', '!f8')])
"""
cdef np.ndarray[Point] test cdef np.ndarray[Point] test
Point_dtype = np.dtype([('x', np.float64), ('y', np.float64)]) Point_dtype = np.dtype([('x', np.float64), ('y', np.float64)])
test = np.zeros(3, Point_dtype) test = np.zeros(3, Point_dtype)
...@@ -504,6 +535,7 @@ def test_point_record(): ...@@ -504,6 +535,7 @@ def test_point_record():
r'\.0+\b', '.', repr(test).replace('<', '!').replace('>', '!') r'\.0+\b', '.', repr(test).replace('<', '!').replace('>', '!')
.replace('( ', '(').replace(', ', ', ')) .replace('( ', '(').replace(', ', ', '))
# Test fused np.ndarray dtypes and runtime dispatch # Test fused np.ndarray dtypes and runtime dispatch
@testcase @testcase
def test_fused_ndarray_floating_dtype(np.ndarray[cython.floating, ndim=1] a): def test_fused_ndarray_floating_dtype(np.ndarray[cython.floating, ndim=1] a):
...@@ -536,6 +568,7 @@ cdef fused fused_external: ...@@ -536,6 +568,7 @@ cdef fused fused_external:
np.float32_t np.float32_t
np.float64_t np.float64_t
@testcase @testcase
def test_fused_external(np.ndarray[fused_external, ndim=1] a): def test_fused_external(np.ndarray[fused_external, ndim=1] a):
""" """
...@@ -554,6 +587,7 @@ def test_fused_external(np.ndarray[fused_external, ndim=1] a): ...@@ -554,6 +587,7 @@ def test_fused_external(np.ndarray[fused_external, ndim=1] a):
""" """
print a.dtype print a.dtype
cdef fused fused_buffers: cdef fused fused_buffers:
np.ndarray[np.int32_t, ndim=1] np.ndarray[np.int32_t, ndim=1]
np.int64_t[::1] np.int64_t[::1]
...@@ -565,6 +599,7 @@ def test_fused_buffers(fused_buffers arg): ...@@ -565,6 +599,7 @@ def test_fused_buffers(fused_buffers arg):
['int64_t[::1]', 'ndarray[int32_t,ndim=1]'] ['int64_t[::1]', 'ndarray[int32_t,ndim=1]']
""" """
cpdef _fused_cpdef_buffers(np.ndarray[fused_external] a): cpdef _fused_cpdef_buffers(np.ndarray[fused_external] a):
print a.dtype print a.dtype
...@@ -580,6 +615,7 @@ def test_fused_cpdef_buffers(): ...@@ -580,6 +615,7 @@ def test_fused_cpdef_buffers():
cdef np.ndarray[np.int32_t] typed_array = int32_array cdef np.ndarray[np.int32_t] typed_array = int32_array
_fused_cpdef_buffers(typed_array) _fused_cpdef_buffers(typed_array)
@testcase @testcase
def test_fused_ndarray_integral_dtype(np.ndarray[cython.integral, ndim=1] a): def test_fused_ndarray_integral_dtype(np.ndarray[cython.integral, ndim=1] a):
""" """
...@@ -602,6 +638,7 @@ def test_fused_ndarray_integral_dtype(np.ndarray[cython.integral, ndim=1] a): ...@@ -602,6 +638,7 @@ def test_fused_ndarray_integral_dtype(np.ndarray[cython.integral, ndim=1] a):
# select different integer types with equal sizeof() # select different integer types with equal sizeof()
print a[5], b[6] print a[5], b[6]
cdef fused fused_dtype: cdef fused fused_dtype:
float complex float complex
double complex double complex
...@@ -668,6 +705,7 @@ def test_fused_ndarray(fused_ndarray a): ...@@ -668,6 +705,7 @@ def test_fused_ndarray(fused_ndarray a):
else: else:
print b[5] print b[5]
cpdef test_fused_cpdef_ndarray(fused_ndarray a): cpdef test_fused_cpdef_ndarray(fused_ndarray a):
""" """
>>> import cython >>> import cython
...@@ -692,6 +730,7 @@ cpdef test_fused_cpdef_ndarray(fused_ndarray a): ...@@ -692,6 +730,7 @@ cpdef test_fused_cpdef_ndarray(fused_ndarray a):
else: else:
print b[5] print b[5]
def test_fused_cpdef_ndarray_cdef_call(): def test_fused_cpdef_ndarray_cdef_call():
""" """
>>> test_fused_cpdef_ndarray_cdef_call() >>> test_fused_cpdef_ndarray_cdef_call()
...@@ -701,6 +740,7 @@ def test_fused_cpdef_ndarray_cdef_call(): ...@@ -701,6 +740,7 @@ def test_fused_cpdef_ndarray_cdef_call():
cdef np.ndarray[Foo, ndim=1] foo_array = get_Foo_array() cdef np.ndarray[Foo, ndim=1] foo_array = get_Foo_array()
test_fused_cpdef_ndarray(foo_array) test_fused_cpdef_ndarray(foo_array)
cdef fused int_type: cdef fused int_type:
np.int32_t np.int32_t
np.int64_t np.int64_t
...@@ -729,6 +769,7 @@ def test_dispatch_non_clashing_declarations_repeating_types(np.ndarray[cython.fl ...@@ -729,6 +769,7 @@ def test_dispatch_non_clashing_declarations_repeating_types(np.ndarray[cython.fl
""" """
print a1[1], a2[2], a3[3], a4[4] print a1[1], a2[2], a3[3], a4[4]
ctypedef np.int32_t typedeffed_type ctypedef np.int32_t typedeffed_type
cdef fused typedeffed_fused_type: cdef fused typedeffed_fused_type:
...@@ -763,6 +804,7 @@ def test_dispatch_external_typedef(np.ndarray[confusing_fused_typedef] a): ...@@ -763,6 +804,7 @@ def test_dispatch_external_typedef(np.ndarray[confusing_fused_typedef] a):
""" """
print a[3] print a[3]
# test fused memoryview slices # test fused memoryview slices
cdef fused memslice_fused_dtype: cdef fused memslice_fused_dtype:
float float
...@@ -793,6 +835,7 @@ def test_fused_memslice_other_dtypes(memslice_fused_dtype[:] a): ...@@ -793,6 +835,7 @@ def test_fused_memslice_other_dtypes(memslice_fused_dtype[:] a):
cdef memslice_fused_dtype[:] b = a cdef memslice_fused_dtype[:] b = a
print cython.typeof(a), cython.typeof(b), a[5], b[6] print cython.typeof(a), cython.typeof(b), a[5], b[6]
cdef fused memslice_fused: cdef fused memslice_fused:
float[:] float[:]
double[:] double[:]
...@@ -822,6 +865,7 @@ def test_fused_memslice(memslice_fused a): ...@@ -822,6 +865,7 @@ def test_fused_memslice(memslice_fused a):
cdef memslice_fused b = a cdef memslice_fused b = a
print cython.typeof(a), cython.typeof(b), a[5], b[6] print cython.typeof(a), cython.typeof(b), a[5], b[6]
@testcase @testcase
def test_dispatch_memoryview_object(): def test_dispatch_memoryview_object():
""" """
...@@ -833,6 +877,7 @@ def test_dispatch_memoryview_object(): ...@@ -833,6 +877,7 @@ def test_dispatch_memoryview_object():
cdef int[:] m3 = <object> m cdef int[:] m3 = <object> m
test_fused_memslice(m3) test_fused_memslice(m3)
cdef fused ndim_t: cdef fused ndim_t:
double[:] double[:]
double[:, :] double[:, :]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment