Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xavier Thompson
cython
Commits
3c13f13d
Commit
3c13f13d
authored
Oct 01, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support packed struct cython.array cast + better dtype error checking
parent
d2797186
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
315 additions
and
62 deletions
+315
-62
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+7
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+10
-3
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+21
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+1
-3
Cython/Utility/Buffer.c
Cython/Utility/Buffer.c
+7
-5
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+86
-29
tests/run/cythonarray.pyx
tests/run/cythonarray.pyx
+1
-1
tests/run/cythonarrayutil.pxi
tests/run/cythonarrayutil.pxi
+1
-1
tests/run/numpy_memoryview.pyx
tests/run/numpy_memoryview.pyx
+181
-19
No files found.
Cython/Compiler/Buffer.py
View file @
3c13f13d
...
@@ -713,6 +713,9 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -713,6 +713,9 @@ def get_type_information_cname(code, dtype, maxdepth=None):
assert
False
assert
False
rep
=
str
(
dtype
)
rep
=
str
(
dtype
)
flags
=
"0"
if
dtype
.
is_int
:
if
dtype
.
is_int
:
if
dtype
.
signed
==
0
:
if
dtype
.
signed
==
0
:
typegroup
=
'U'
typegroup
=
'U'
...
@@ -724,6 +727,8 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -724,6 +727,8 @@ def get_type_information_cname(code, dtype, maxdepth=None):
typegroup
=
'R'
typegroup
=
'R'
elif
dtype
.
is_struct
:
elif
dtype
.
is_struct
:
typegroup
=
'S'
typegroup
=
'S'
if
dtype
.
packed
:
flags
=
"__PYX_BUF_FLAGS_PACKED_STRUCT"
elif
dtype
.
is_pyobject
:
elif
dtype
.
is_pyobject
:
typegroup
=
'O'
typegroup
=
'O'
else
:
else
:
...
@@ -735,13 +740,14 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -735,13 +740,14 @@ def get_type_information_cname(code, dtype, maxdepth=None):
else
:
else
:
is_unsigned
=
"0"
is_unsigned
=
"0"
typecode
.
putln
((
'static __Pyx_TypeInfo %s = { "%s", %s, sizeof(%s),
\
'
%s
\
'
, %s };'
typecode
.
putln
((
'static __Pyx_TypeInfo %s = { "%s", %s, sizeof(%s),
\
'
%s
\
'
, %s
, %s
};'
)
%
(
name
,
)
%
(
name
,
rep
,
rep
,
structinfo_name
,
structinfo_name
,
declcode
,
declcode
,
typegroup
,
typegroup
,
is_unsigned
,
is_unsigned
,
flags
,
),
safe
=
True
)
),
safe
=
True
)
return
name
return
name
...
...
Cython/Compiler/ExprNodes.py
View file @
3c13f13d
...
@@ -6242,7 +6242,7 @@ class CythonArrayNode(ExprNode):
...
@@ -6242,7 +6242,7 @@ class CythonArrayNode(ExprNode):
Used when a pointer of base_type is cast to a memoryviewslice with that
Used when a pointer of base_type is cast to a memoryviewslice with that
base type. i.e.
base type. i.e.
<int[:
:1, :
]> p
<int[:
M:1, :N
]> p
creates a fortran-contiguous cython.array.
creates a fortran-contiguous cython.array.
...
@@ -6302,13 +6302,14 @@ class CythonArrayNode(ExprNode):
...
@@ -6302,13 +6302,14 @@ class CythonArrayNode(ExprNode):
self
.
operand
.
analyse_types
(
env
)
self
.
operand
.
analyse_types
(
env
)
array_dtype
=
self
.
base_type_node
.
base_type_node
.
analyse
(
env
)
array_dtype
=
self
.
base_type_node
.
base_type_node
.
analyse
(
env
)
MemoryView
.
validate_memslice_dtype
(
self
.
pos
,
array_dtype
)
if
not
self
.
operand
.
type
.
is_ptr
:
if
not
self
.
operand
.
type
.
is_ptr
:
return
error
(
self
.
operand
.
pos
,
ERR_NOT_POINTER
)
return
error
(
self
.
operand
.
pos
,
ERR_NOT_POINTER
)
elif
not
self
.
operand
.
type
.
base_type
.
same_as
(
array_dtype
):
elif
not
self
.
operand
.
type
.
base_type
.
same_as
(
array_dtype
):
return
error
(
self
.
operand
.
pos
,
ERR_BASE_TYPE
)
return
error
(
self
.
operand
.
pos
,
ERR_BASE_TYPE
)
#self.operand = self.operand.coerce_to(PyrexTypes.c_char_ptr_type, env)
if
not
self
.
operand
.
is_name
:
if
not
self
.
operand
.
is_name
:
self
.
operand
=
self
.
operand
.
coerce_to_temp
(
env
)
self
.
operand
=
self
.
operand
.
coerce_to_temp
(
env
)
...
@@ -6320,7 +6321,7 @@ class CythonArrayNode(ExprNode):
...
@@ -6320,7 +6321,7 @@ class CythonArrayNode(ExprNode):
self
.
coercion_type
=
PyrexTypes
.
MemoryViewSliceType
(
array_dtype
,
axes
)
self
.
coercion_type
=
PyrexTypes
.
MemoryViewSliceType
(
array_dtype
,
axes
)
#self.type = py_object_type
#self.type = py_object_type
self
.
type
=
env
.
global_scope
().
context
.
cython_scope
.
lookup
(
"array"
).
type
self
.
type
=
self
.
get_cython_array_type
(
env
)
assert
self
.
type
assert
self
.
type
env
.
use_utility_code
(
MemoryView
.
cython_array_utility_code
)
env
.
use_utility_code
(
MemoryView
.
cython_array_utility_code
)
...
@@ -6332,6 +6333,12 @@ class CythonArrayNode(ExprNode):
...
@@ -6332,6 +6333,12 @@ class CythonArrayNode(ExprNode):
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
self
.
type
,
True
)
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
self
.
type
,
True
)
def
infer_type
(
self
,
env
):
return
self
.
get_cython_array_type
(
env
)
def
get_cython_array_type
(
self
,
env
):
return
env
.
global_scope
().
context
.
cython_scope
.
lookup
(
"array"
).
type
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
import
Buffer
import
Buffer
...
...
Cython/Compiler/MemoryView.py
View file @
3c13f13d
...
@@ -161,6 +161,27 @@ def src_conforms_to_dst(src, dst):
...
@@ -161,6 +161,27 @@ def src_conforms_to_dst(src, dst):
return
True
return
True
def
valid_memslice_dtype
(
dtype
):
"""
Return whether type dtype can be used as the base type of a
memoryview slice
"""
if
dtype
.
is_complex
and
dtype
.
real_type
.
is_int
:
return
False
return
(
dtype
.
is_error
or
dtype
.
is_ptr
or
dtype
.
is_numeric
or
dtype
.
is_struct
or
dtype
.
is_pyobject
or
(
dtype
.
is_typedef
and
valid_memslice_dtype
(
dtype
.
typedef_base_type
))
)
def
validate_memslice_dtype
(
pos
,
dtype
):
if
not
valid_memslice_dtype
(
dtype
):
error
(
pos
,
"Invalid base type for memoryview slice"
)
class
MemoryViewSliceBufferEntry
(
Buffer
.
BufferEntry
):
class
MemoryViewSliceBufferEntry
(
Buffer
.
BufferEntry
):
def
__init__
(
self
,
entry
):
def
__init__
(
self
,
entry
):
...
...
Cython/Compiler/Nodes.py
View file @
3c13f13d
...
@@ -828,10 +828,8 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
...
@@ -828,10 +828,8 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
self
.
type
=
PyrexTypes
.
ErrorType
()
self
.
type
=
PyrexTypes
.
ErrorType
()
return
self
.
type
return
self
.
type
MemoryView
.
validate_memslice_dtype
(
self
.
pos
,
base_type
)
self
.
type
=
PyrexTypes
.
MemoryViewSliceType
(
base_type
,
axes_specs
)
self
.
type
=
PyrexTypes
.
MemoryViewSliceType
(
base_type
,
axes_specs
)
if
self
.
type
.
dtype
.
is_memoryviewslice
:
error
(
self
.
pos
,
"Memoryview slices may not be used as the "
"base type for memoryview slices"
)
self
.
use_memview_utilities
(
env
)
self
.
use_memview_utilities
(
env
)
return
self
.
type
return
self
.
type
...
...
Cython/Utility/Buffer.c
View file @
3c13f13d
...
@@ -42,12 +42,15 @@ static void __Pyx_RaiseBufferFallbackError(void) {
...
@@ -42,12 +42,15 @@ static void __Pyx_RaiseBufferFallbackError(void) {
/* Run-time type information about structs used with buffers */
/* Run-time type information about structs used with buffers */
struct
__Pyx_StructField_
;
struct
__Pyx_StructField_
;
#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
typedef
struct
{
typedef
struct
{
const
char
*
name
;
/* for error messages only */
const
char
*
name
;
/* for error messages only */
struct
__Pyx_StructField_
*
fields
;
struct
__Pyx_StructField_
*
fields
;
size_t
size
;
/* sizeof(type) */
size_t
size
;
/* sizeof(type) */
char
typegroup
;
/* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
char
typegroup
;
/* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
char
is_unsigned
;
char
is_unsigned
;
int
flags
;
}
__Pyx_TypeInfo
;
}
__Pyx_TypeInfo
;
typedef
struct
__Pyx_StructField_
{
typedef
struct
__Pyx_StructField_
{
...
@@ -544,7 +547,7 @@ static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type)
...
@@ -544,7 +547,7 @@ static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type)
case
'I'
:
case
'I'
:
case
'U'
:
case
'U'
:
if
(
size
==
1
)
if
(
size
==
1
)
*
buf
=
'
c
'
;
*
buf
=
'
b
'
;
else
if
(
size
==
2
)
else
if
(
size
==
2
)
*
buf
=
'h'
;
*
buf
=
'h'
;
else
if
(
size
==
4
)
else
if
(
size
==
4
)
...
@@ -559,16 +562,15 @@ static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type)
...
@@ -559,16 +562,15 @@ static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type)
*
buf
=
'P'
;
*
buf
=
'P'
;
break
;
break
;
case
'C'
:
case
'C'
:
{
{
__Pyx_TypeInfo
complex_type
=
*
type
;
__Pyx_TypeInfo
complex_type
=
*
type
;
complex_type
.
typegroup
=
'R'
;
complex_type
.
typegroup
=
'R'
;
complex_type
.
size
/=
2
;
complex_type
.
size
/=
2
;
*
buf
++
=
'Z'
;
*
buf
++
=
'Z'
;
/* Note: What about short/int/long complex? Probably not used? */
*
buf
=
__Pyx_TypeInfoToFormat
(
&
complex_type
).
string
[
0
];
*
buf
=
__Pyx_TypeInfoToFormat
(
&
complex_type
).
string
[
0
];
break
;
break
;
}
}
case
'R'
:
case
'R'
:
if
(
size
==
4
)
if
(
size
==
4
)
*
buf
=
'f'
;
*
buf
=
'f'
;
...
...
Cython/Utility/MemoryView.pyx
View file @
3c13f13d
...
@@ -28,13 +28,13 @@ cdef class array:
...
@@ -28,13 +28,13 @@ cdef class array:
Py_ssize_t
len
Py_ssize_t
len
char
*
format
char
*
format
int
ndim
int
ndim
Py_ssize_t
*
shape
Py_ssize_t
*
_
shape
Py_ssize_t
*
strides
Py_ssize_t
*
_
strides
Py_ssize_t
itemsize
Py_ssize_t
itemsize
unicode
mode
unicode
mode
bytes
_format
bytes
_format
void
(
*
callback_free_data
)(
char
*
data
)
void
(
*
callback_free_data
)(
char
*
data
)
cdef
object
_memview
#
cdef object _memview
def
__cinit__
(
array
self
,
tuple
shape
,
Py_ssize_t
itemsize
,
format
,
def
__cinit__
(
array
self
,
tuple
shape
,
Py_ssize_t
itemsize
,
format
,
mode
=
u"c"
,
bint
allocate_buffer
=
True
):
mode
=
u"c"
,
bint
allocate_buffer
=
True
):
...
@@ -54,12 +54,12 @@ cdef class array:
...
@@ -54,12 +54,12 @@ cdef class array:
self
.
_format
=
format
self
.
_format
=
format
self
.
format
=
self
.
_format
self
.
format
=
self
.
_format
self
.
shape
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
self
.
_
shape
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
self
.
strides
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
self
.
_
strides
=
<
Py_ssize_t
*>
malloc
(
sizeof
(
Py_ssize_t
)
*
self
.
ndim
)
if
not
self
.
shape
or
not
self
.
strides
:
if
not
self
.
_shape
or
not
self
.
_
strides
:
free
(
self
.
shape
)
free
(
self
.
_
shape
)
free
(
self
.
strides
)
free
(
self
.
_
strides
)
raise
MemoryError
(
"unable to allocate shape or strides."
)
raise
MemoryError
(
"unable to allocate shape or strides."
)
cdef
int
idx
cdef
int
idx
...
@@ -69,20 +69,20 @@ cdef class array:
...
@@ -69,20 +69,20 @@ cdef class array:
if
dim
<=
0
:
if
dim
<=
0
:
raise
ValueError
(
"Invalid shape."
)
raise
ValueError
(
"Invalid shape."
)
self
.
shape
[
idx
]
=
dim
self
.
_
shape
[
idx
]
=
dim
idx
+=
1
idx
+=
1
stride
=
itemsize
stride
=
itemsize
if
mode
==
"fortran"
:
if
mode
==
"fortran"
:
idx
=
0
idx
=
0
for
dim
in
shape
:
for
dim
in
shape
:
self
.
strides
[
idx
]
=
stride
self
.
_
strides
[
idx
]
=
stride
stride
=
stride
*
dim
stride
=
stride
*
dim
idx
+=
1
idx
+=
1
elif
mode
==
"c"
:
elif
mode
==
"c"
:
idx
=
self
.
ndim
-
1
idx
=
self
.
ndim
-
1
for
dim
in
shape
[::
-
1
]:
for
dim
in
shape
[::
-
1
]:
self
.
strides
[
idx
]
=
stride
self
.
_
strides
[
idx
]
=
stride
stride
=
stride
*
dim
stride
=
stride
*
dim
idx
-=
1
idx
-=
1
else
:
else
:
...
@@ -111,8 +111,8 @@ cdef class array:
...
@@ -111,8 +111,8 @@ cdef class array:
info
.
buf
=
self
.
data
info
.
buf
=
self
.
data
info
.
len
=
self
.
len
info
.
len
=
self
.
len
info
.
ndim
=
self
.
ndim
info
.
ndim
=
self
.
ndim
info
.
shape
=
self
.
shape
info
.
shape
=
self
.
_
shape
info
.
strides
=
self
.
strides
info
.
strides
=
self
.
_
strides
info
.
suboffsets
=
NULL
info
.
suboffsets
=
NULL
info
.
itemsize
=
self
.
itemsize
info
.
itemsize
=
self
.
itemsize
info
.
readonly
=
0
info
.
readonly
=
0
...
@@ -122,6 +122,8 @@ cdef class array:
...
@@ -122,6 +122,8 @@ cdef class array:
else
:
else
:
info
.
format
=
NULL
info
.
format
=
NULL
info
.
obj
=
self
def
__dealloc__
(
array
self
):
def
__dealloc__
(
array
self
):
if
self
.
callback_free_data
!=
NULL
:
if
self
.
callback_free_data
!=
NULL
:
self
.
callback_free_data
(
self
.
data
)
self
.
callback_free_data
(
self
.
data
)
...
@@ -130,13 +132,13 @@ cdef class array:
...
@@ -130,13 +132,13 @@ cdef class array:
self
.
data
=
NULL
self
.
data
=
NULL
if
self
.
strides
:
if
self
.
_
strides
:
free
(
self
.
strides
)
free
(
self
.
_
strides
)
self
.
strides
=
NULL
self
.
_
strides
=
NULL
if
self
.
shape
:
if
self
.
_
shape
:
free
(
self
.
shape
)
free
(
self
.
_
shape
)
self
.
shape
=
NULL
self
.
_
shape
=
NULL
self
.
format
=
NULL
self
.
format
=
NULL
self
.
itemsize
=
0
self
.
itemsize
=
0
...
@@ -145,11 +147,14 @@ cdef class array:
...
@@ -145,11 +147,14 @@ cdef class array:
@
cname
(
'__pyx_cython_array_get_memview'
)
@
cname
(
'__pyx_cython_array_get_memview'
)
def
__get__
(
self
):
def
__get__
(
self
):
# Make this a property as 'data' may be set after instantiation
# Make this a property as 'data' may be set after instantiation
if
self
.
_memview
is
None
:
#if self._memview is None:
flags
=
PyBUF_ANY_CONTIGUOUS
|
PyBUF_FORMAT
|
PyBUF_WRITABLE
# flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
self
.
_memview
=
__pyx_memoryview_new
(
self
,
flags
)
# self._memview = __pyx_memoryview_new(self, flags)
#return self._memview
flags
=
PyBUF_ANY_CONTIGUOUS
|
PyBUF_FORMAT
|
PyBUF_WRITABLE
return
__pyx_memoryview_new
(
self
,
flags
)
return
self
.
_memview
def
__getattr__
(
self
,
attr
):
def
__getattr__
(
self
,
attr
):
return
getattr
(
self
.
memview
,
attr
)
return
getattr
(
self
.
memview
,
attr
)
...
@@ -221,6 +226,15 @@ cdef extern from *:
...
@@ -221,6 +226,15 @@ cdef extern from *:
PyObject
*
Py_None
PyObject
*
Py_None
cdef
enum
:
PyBUF_C_CONTIGUOUS
,
PyBUF_F_CONTIGUOUS
,
PyBUF_ANY_CONTIGUOUS
PyBUF_FORMAT
PyBUF_WRITABLE
PyBUF_STRIDES
PyBUF_INDIRECT
@
cname
(
'__pyx_MemviewEnum'
)
@
cname
(
'__pyx_MemviewEnum'
)
cdef
class
Enum
(
object
):
cdef
class
Enum
(
object
):
cdef
object
name
cdef
object
name
...
@@ -348,11 +362,34 @@ cdef class memoryview(object):
...
@@ -348,11 +362,34 @@ cdef class memoryview(object):
itemp
[
i
]
=
c
itemp
[
i
]
=
c
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
# Note: self.view.obj must not be NULL
if
flags
&
PyBUF_STRIDES
:
Py_INCREF
(
self
.
view
.
obj
)
info
.
shape
=
self
.
view
.
shape
info
[
0
]
=
self
.
view
else
:
info
.
shape
=
NULL
if
flags
&
PyBUF_STRIDES
:
info
.
strides
=
self
.
view
.
strides
else
:
info
.
strides
=
NULL
if
flags
&
PyBUF_INDIRECT
:
info
.
suboffsets
=
self
.
view
.
suboffsets
else
:
info
.
suboffsets
=
NULL
if
flags
&
PyBUF_FORMAT
:
info
.
format
=
self
.
view
.
format
else
:
info
.
format
=
NULL
info
.
buf
=
self
.
view
.
buf
info
.
ndim
=
self
.
view
.
ndim
info
.
itemsize
=
self
.
view
.
itemsize
info
.
len
=
self
.
view
.
len
info
.
readonly
=
0
info
.
obj
=
self
info
.
obj
=
self
# Some properties that have the same sematics as in NumPy
# Some properties that have the same sematics as in NumPy
property
T
:
property
T
:
@
cname
(
'__pyx_memoryview_transpose'
)
@
cname
(
'__pyx_memoryview_transpose'
)
...
@@ -374,11 +411,18 @@ cdef class memoryview(object):
...
@@ -374,11 +411,18 @@ cdef class memoryview(object):
property
strides
:
property
strides
:
@
cname
(
'__pyx_memoryview_get_strides'
)
@
cname
(
'__pyx_memoryview_get_strides'
)
def
__get__
(
self
):
def
__get__
(
self
):
if
self
.
view
.
strides
==
NULL
:
# Note: we always ask for strides, so if this is not set it's a bug
raise
ValueError
(
"Buffer view does not expose strides"
)
return
tuple
([
self
.
view
.
strides
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
return
tuple
([
self
.
view
.
strides
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
property
suboffsets
:
property
suboffsets
:
@
cname
(
'__pyx_memoryview_get_suboffsets'
)
@
cname
(
'__pyx_memoryview_get_suboffsets'
)
def
__get__
(
self
):
def
__get__
(
self
):
if
self
.
view
.
suboffsets
==
NULL
:
return
[
-
1
]
*
self
.
view
.
ndim
return
tuple
([
self
.
view
.
suboffsets
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
return
tuple
([
self
.
view
.
suboffsets
[
i
]
for
i
in
xrange
(
self
.
view
.
ndim
)])
property
ndim
:
property
ndim
:
...
@@ -409,6 +453,9 @@ cdef class memoryview(object):
...
@@ -409,6 +453,9 @@ cdef class memoryview(object):
return
self
.
_size
return
self
.
_size
# The __array_interface__ is broken as it does not properly convert PEP 3118 format
# strings into NumPy typestrs. NumPy 1.5 support the new buffer interface though.
'''
property __array_interface__:
property __array_interface__:
@cname('__pyx_numpy_array_interface')
@cname('__pyx_numpy_array_interface')
def __get__(self):
def __get__(self):
...
@@ -424,10 +471,11 @@ cdef class memoryview(object):
...
@@ -424,10 +471,11 @@ cdef class memoryview(object):
data = (PyLong_FromVoidPtr(self.view.buf), False),
data = (PyLong_FromVoidPtr(self.view.buf), False),
shape = self.shape,
shape = self.shape,
strides = self.strides,
strides = self.strides,
typestr
=
"%s%d"
%
(
self
.
format
,
self
.
view
.
itemsize
),
typestr = "%s%d" % (self.
view.
format, self.view.itemsize),
version = 3)
version = 3)
return self._array_interface
return self._array_interface
'''
def
__len__
(
self
):
def
__len__
(
self
):
if
self
.
view
.
ndim
>=
1
:
if
self
.
view
.
ndim
>=
1
:
...
@@ -848,12 +896,17 @@ cdef memoryview_copy(memoryview memview):
...
@@ -848,12 +896,17 @@ cdef memoryview_copy(memoryview memview):
cdef
extern
from
*
:
cdef
extern
from
*
:
ctypedef
struct
__Pyx_StructField
ctypedef
struct
__Pyx_StructField
cdef
enum
:
__PYX_BUF_FLAGS_PACKED_STRUCT
__PYX_BUF_FLAGS_INTEGER_COMPLEX
ctypedef
struct
__Pyx_TypeInfo
:
ctypedef
struct
__Pyx_TypeInfo
:
char
*
name
char
*
name
__Pyx_StructField
*
fields
__Pyx_StructField
*
fields
size_t
size
size_t
size
char
typegroup
char
typegroup
char
is_unsigned
char
is_unsigned
int
flags
ctypedef
struct
__Pyx_StructField
:
ctypedef
struct
__Pyx_StructField
:
__Pyx_TypeInfo
*
type
__Pyx_TypeInfo
*
type
...
@@ -882,6 +935,11 @@ cdef format_from_typeinfo(__Pyx_TypeInfo *type):
...
@@ -882,6 +935,11 @@ cdef format_from_typeinfo(__Pyx_TypeInfo *type):
if
type
.
typegroup
==
'S'
:
if
type
.
typegroup
==
'S'
:
assert
type
.
fields
!=
NULL
and
type
.
fields
.
type
!=
NULL
assert
type
.
fields
!=
NULL
and
type
.
fields
.
type
!=
NULL
if
type
.
flags
&
__PYX_BUF_FLAGS_PACKED_STRUCT
:
alignment
=
'^'
else
:
alignment
=
''
parts
=
[
"T{"
]
parts
=
[
"T{"
]
field
=
type
.
fields
field
=
type
.
fields
...
@@ -889,8 +947,7 @@ cdef format_from_typeinfo(__Pyx_TypeInfo *type):
...
@@ -889,8 +947,7 @@ cdef format_from_typeinfo(__Pyx_TypeInfo *type):
parts
.
append
(
format_from_typeinfo
(
field
.
type
))
parts
.
append
(
format_from_typeinfo
(
field
.
type
))
field
+=
1
field
+=
1
parts
.
append
(
"}"
)
result
=
alignment
.
join
(
parts
)
+
'}'
result
=
""
.
join
(
parts
)
else
:
else
:
fmt
=
__Pyx_TypeInfoToFormat
(
type
)
fmt
=
__Pyx_TypeInfoToFormat
(
type
)
result
=
fmt
.
string
result
=
fmt
.
string
...
...
tests/run/cythonarray.pyx
View file @
3c13f13d
...
@@ -60,7 +60,7 @@ def full_or_strided():
...
@@ -60,7 +60,7 @@ def full_or_strided():
def
dont_allocate_buffer
():
def
dont_allocate_buffer
():
"""
"""
>>> dont_allocate_buffer()
>>> dont_allocate_buffer()
callback called
1
callback called
"""
"""
cdef
cy
.
array
result
=
cy
.
array
((
10
,
10
),
itemsize
=
sizeof
(
int
),
format
=
'i'
,
allocate_buffer
=
False
)
cdef
cy
.
array
result
=
cy
.
array
((
10
,
10
),
itemsize
=
sizeof
(
int
),
format
=
'i'
,
allocate_buffer
=
False
)
assert
result
.
data
==
NULL
assert
result
.
data
==
NULL
...
...
tests/run/cythonarrayutil.pxi
View file @
3c13f13d
...
@@ -2,7 +2,7 @@ from libc.stdlib cimport malloc, free
...
@@ -2,7 +2,7 @@ from libc.stdlib cimport malloc, free
cimport
cython
cimport
cython
cdef
void
callback
(
char
*
data
):
cdef
void
callback
(
char
*
data
):
print
"callback called
%d"
%
<
long
>
data
print
"callback called
"
def
create_array
(
shape
,
mode
,
use_callback
=
False
):
def
create_array
(
shape
,
mode
,
use_callback
=
False
):
cdef
cython
.
array
result
=
cython
.
array
(
shape
,
itemsize
=
sizeof
(
int
),
cdef
cython
.
array
result
=
cython
.
array
(
shape
,
itemsize
=
sizeof
(
int
),
...
...
tests/run/numpy_memoryview.pyx
View file @
3c13f13d
...
@@ -9,6 +9,7 @@ cimport numpy as np
...
@@ -9,6 +9,7 @@ cimport numpy as np
import
numpy
as
np
import
numpy
as
np
include
"cythonarrayutil.pxi"
include
"cythonarrayutil.pxi"
include
"mockbuffers.pxi"
ctypedef
np
.
int32_t
dtype_t
ctypedef
np
.
int32_t
dtype_t
...
@@ -27,10 +28,23 @@ def ae(*args):
...
@@ -27,10 +28,23 @@ def ae(*args):
if
x
!=
args
[
0
]:
if
x
!=
args
[
0
]:
raise
AssertionError
(
args
)
raise
AssertionError
(
args
)
__test__
=
{}
def
testcase
(
f
):
__test__
[
f
.
__name__
]
=
f
.
__doc__
return
f
def
testcase_numpy_1_5
(
f
):
major
,
minor
,
*
rest
=
np
.
__version__
.
split
(
'.'
)
if
(
int
(
major
),
int
(
minor
))
>=
(
1
,
5
):
__test__
[
f
.
__name__
]
=
f
.
__doc__
return
f
#
#
### Test slicing memoryview slices
### Test slicing memoryview slices
#
#
@
testcase
def
test_partial_slicing
(
array
):
def
test_partial_slicing
(
array
):
"""
"""
>>> test_partial_slicing(a)
>>> test_partial_slicing(a)
...
@@ -46,6 +60,7 @@ def test_partial_slicing(array):
...
@@ -46,6 +60,7 @@ def test_partial_slicing(array):
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
@
testcase
def
test_ellipsis
(
array
):
def
test_ellipsis
(
array
):
"""
"""
>>> test_ellipsis(a)
>>> test_ellipsis(a)
...
@@ -87,7 +102,7 @@ def test_ellipsis(array):
...
@@ -87,7 +102,7 @@ def test_ellipsis(array):
#
#
### Test slicing memoryview objects
### Test slicing memoryview objects
#
#
@
testcase
def
test_partial_slicing_memoryview
(
array
):
def
test_partial_slicing_memoryview
(
array
):
"""
"""
>>> test_partial_slicing_memoryview(a)
>>> test_partial_slicing_memoryview(a)
...
@@ -104,6 +119,7 @@ def test_partial_slicing_memoryview(array):
...
@@ -104,6 +119,7 @@ def test_partial_slicing_memoryview(array):
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
0
],
c
.
strides
[
0
],
obj
.
strides
[
0
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
ae
(
b
.
strides
[
1
],
c
.
strides
[
1
],
obj
.
strides
[
1
])
@
testcase
def
test_ellipsis_memoryview
(
array
):
def
test_ellipsis_memoryview
(
array
):
"""
"""
>>> test_ellipsis_memoryview(a)
>>> test_ellipsis_memoryview(a)
...
@@ -143,6 +159,7 @@ def test_ellipsis_memoryview(array):
...
@@ -143,6 +159,7 @@ def test_ellipsis_memoryview(array):
ae
(
e
.
shape
[
0
],
e_obj
.
shape
[
0
])
ae
(
e
.
shape
[
0
],
e_obj
.
shape
[
0
])
ae
(
e
.
strides
[
0
],
e_obj
.
strides
[
0
])
ae
(
e
.
strides
[
0
],
e_obj
.
strides
[
0
])
@
testcase
def
test_transpose
():
def
test_transpose
():
"""
"""
>>> test_transpose()
>>> test_transpose()
...
@@ -172,26 +189,10 @@ def test_transpose():
...
@@ -172,26 +189,10 @@ def test_transpose():
print
a
[
3
,
2
],
a
.
T
[
2
,
3
],
a_obj
[
3
,
2
],
a_obj
.
T
[
2
,
3
],
numpy_obj
[
3
,
2
],
numpy_obj
.
T
[
2
,
3
]
print
a
[
3
,
2
],
a
.
T
[
2
,
3
],
a_obj
[
3
,
2
],
a_obj
.
T
[
2
,
3
],
numpy_obj
[
3
,
2
],
numpy_obj
.
T
[
2
,
3
]
def
test_coerce_to_numpy
():
@
testcase
"""
>>> test_coerce_to_numpy()
34
34
2
"""
cyarray
=
create_array
(
shape
=
(
8
,
5
),
mode
=
"c"
,
use_callback
=
True
)
numarray
=
np
.
asarray
(
cyarray
)
print
cyarray
[
6
,
4
]
del
cyarray
print
numarray
[
6
,
4
]
numarray
[
6
,
4
]
=
2
print
numarray
[
6
,
4
]
def
test_numpy_like_attributes
(
cyarray
):
def
test_numpy_like_attributes
(
cyarray
):
"""
"""
>>> cyarray = create_array(shape=(8, 5), mode="c"
, use_callback=True
)
>>> cyarray = create_array(shape=(8, 5), mode="c")
>>> test_numpy_like_attributes(cyarray)
>>> test_numpy_like_attributes(cyarray)
>>> test_numpy_like_attributes(cyarray.memview)
>>> test_numpy_like_attributes(cyarray.memview)
"""
"""
...
@@ -205,3 +206,164 @@ def test_numpy_like_attributes(cyarray):
...
@@ -205,3 +206,164 @@ def test_numpy_like_attributes(cyarray):
cdef
int
[:,
:]
mslice
=
numarray
cdef
int
[:,
:]
mslice
=
numarray
assert
(
<
object
>
mslice
).
base
is
numarray
assert
(
<
object
>
mslice
).
base
is
numarray
ctypedef
int
td_cy_int
cdef
extern
from
"bufaccess.h"
:
ctypedef
td_cy_int
td_h_short
# Defined as short, but Cython doesn't know this!
ctypedef
float
td_h_double
# Defined as double
ctypedef
unsigned
int
td_h_ushort
# Defined as unsigned short
ctypedef
td_h_short
td_h_cy_short
cdef
void
dealloc_callback
(
char
*
data
):
print
"deallocating..."
def
index
(
cython
.
array
array
):
array
.
callback_free_data
=
dealloc_callback
print
np
.
asarray
(
array
)[
3
,
2
]
@
testcase_numpy_1_5
def
test_coerce_to_numpy
():
"""
Test coercion to NumPy arrays, especially with automatically
generated format strings.
>>> test_coerce_to_numpy()
(97, 98, 600L, 700, 800)
deallocating...
(600, 700)
deallocating...
((100, 200), (300, 400), 500)
deallocating...
(97, 900)
deallocating...
99
deallocating...
111
deallocating...
222
deallocating...
333
deallocating...
11.1
deallocating...
12.2
deallocating...
13.3
deallocating...
(14.4+15.5j)
deallocating...
(16.6+17.7j)
deallocating...
(18.8+19.9j)
deallocating...
22
deallocating...
33.33
deallocating...
44
deallocating...
"""
#
### First set up some C arrays that will be used to hold data
#
cdef
MyStruct
mystructs
[
20
]
cdef
SmallStruct
smallstructs
[
20
]
cdef
NestedStruct
nestedstructs
[
20
]
cdef
PackedStruct
packedstructs
[
20
]
cdef
char
chars
[
20
]
cdef
short
shorts
[
20
]
cdef
int
ints
[
20
]
cdef
long
long
longlongs
[
20
]
cdef
td_h_short
externs
[
20
]
cdef
float
floats
[
20
]
cdef
double
doubles
[
20
]
cdef
long
double
longdoubles
[
20
]
cdef
float
complex
floatcomplex
[
20
]
cdef
double
complex
doublecomplex
[
20
]
cdef
long
double
complex
longdoublecomplex
[
20
]
cdef
td_h_short
h_shorts
[
20
]
cdef
td_h_double
h_doubles
[
20
]
cdef
td_h_ushort
h_ushorts
[
20
]
cdef
Py_ssize_t
idx
=
17
#
### Initialize one element in each array
#
mystructs
[
idx
]
=
{
'a'
:
'a'
,
'b'
:
'b'
,
'c'
:
600
,
'd'
:
700
,
'e'
:
800
,
}
smallstructs
[
idx
]
=
{
'a'
:
600
,
'b'
:
700
}
nestedstructs
[
idx
]
=
{
'x'
:
{
'a'
:
100
,
'b'
:
200
},
'y'
:
{
'a'
:
300
,
'b'
:
400
},
'z'
:
500
,
}
packedstructs
[
idx
]
=
{
'a'
:
'a'
,
'b'
:
900
}
chars
[
idx
]
=
99
shorts
[
idx
]
=
111
ints
[
idx
]
=
222
longlongs
[
idx
]
=
333
externs
[
idx
]
=
444
floats
[
idx
]
=
11.1
doubles
[
idx
]
=
12.2
longdoubles
[
idx
]
=
13.3
floatcomplex
[
idx
]
=
14.4
+
15.5j
doublecomplex
[
idx
]
=
16.6
+
17.7j
longdoublecomplex
[
idx
]
=
18.8
+
19.9j
h_shorts
[
idx
]
=
22
h_doubles
[
idx
]
=
33.33
h_ushorts
[
idx
]
=
44
#
### Create a NumPy array and see if our element can be correctly retrieved
#
index
(
<
MyStruct
[:
4
,
:
5
]
>
<
MyStruct
*>
mystructs
)
index
(
<
SmallStruct
[:
4
,
:
5
]
>
<
SmallStruct
*>
smallstructs
)
index
(
<
NestedStruct
[:
4
,
:
5
]
>
<
NestedStruct
*>
nestedstructs
)
index
(
<
PackedStruct
[:
4
,
:
5
]
>
<
PackedStruct
*>
packedstructs
)
index
(
<
char
[:
4
,
:
5
]
>
<
char
*>
chars
)
index
(
<
short
[:
4
,
:
5
]
>
<
short
*>
shorts
)
index
(
<
int
[:
4
,
:
5
]
>
<
int
*>
ints
)
index
(
<
long
long
[:
4
,
:
5
]
>
<
long
long
*>
longlongs
)
index
(
<
float
[:
4
,
:
5
]
>
<
float
*>
floats
)
index
(
<
double
[:
4
,
:
5
]
>
<
double
*>
doubles
)
index
(
<
long
double
[:
4
,
:
5
]
>
<
long
double
*>
longdoubles
)
index
(
<
float
complex
[:
4
,
:
5
]
>
<
float
complex
*>
floatcomplex
)
index
(
<
double
complex
[:
4
,
:
5
]
>
<
double
complex
*>
doublecomplex
)
index
(
<
long
double
complex
[:
4
,
:
5
]
>
<
long
double
complex
*>
longdoublecomplex
)
index
(
<
td_h_short
[:
4
,
:
5
]
>
<
td_h_short
*>
h_shorts
)
index
(
<
td_h_double
[:
4
,
:
5
]
>
<
td_h_double
*>
h_doubles
)
index
(
<
td_h_ushort
[:
4
,
:
5
]
>
<
td_h_ushort
*>
h_ushorts
)
@
testcase_numpy_1_5
def
test_memslice_getbuffer
():
"""
>>> test_memslice_getbuffer()
[[ 0 2 4]
[10 12 14]]
callback called
"""
cdef
int
[:,
:]
array
=
create_array
((
4
,
5
),
mode
=
"c"
,
use_callback
=
True
)
print
np
.
asarray
(
array
)[::
2
,
::
2
]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment