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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
a0e188d4
Commit
a0e188d4
authored
Jul 31, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Memoryview slice item assignment, better errors, pass all tests
parent
df5626e4
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
248 additions
and
267 deletions
+248
-267
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+31
-13
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+37
-23
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+11
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+34
-19
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+5
-2
tests/errors/memview_declarations.pyx
tests/errors/memview_declarations.pyx
+16
-18
tests/run/bufaccess.pyx
tests/run/bufaccess.pyx
+0
-16
tests/run/memslice.pyx
tests/run/memslice.pyx
+101
-169
tests/run/mockbuffers.pxi
tests/run/mockbuffers.pxi
+13
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
a0e188d4
...
@@ -594,8 +594,14 @@ class ExprNode(Node):
...
@@ -594,8 +594,14 @@ class ExprNode(Node):
"Cannot convert '%s' to memoryviewslice"
%
"Cannot convert '%s' to memoryviewslice"
%
(
src_type
,))
(
src_type
,))
elif
not
MemoryView
.
src_conforms_to_dst
(
src
.
type
,
dst_type
):
elif
not
MemoryView
.
src_conforms_to_dst
(
src
.
type
,
dst_type
):
error
(
self
.
pos
,
"Memoryview '%s' not conformable to memoryview '%s'."
%
if
src
.
type
.
dtype
.
same_as
(
dst_type
.
dtype
):
(
src
.
type
,
dst_type
))
msg
=
"Memoryview '%s' not conformable to memoryview '%s'."
tup
=
src
.
type
,
dst_type
else
:
msg
=
"Different base types for memoryviews (%s, %s)"
tup
=
src
.
type
.
dtype
,
dst_type
.
dtype
error
(
self
.
pos
,
msg
%
tup
)
elif
dst_type
.
is_pyobject
:
elif
dst_type
.
is_pyobject
:
if
not
src
.
type
.
is_pyobject
:
if
not
src
.
type
.
is_pyobject
:
...
@@ -2412,13 +2418,13 @@ class IndexNode(ExprNode):
...
@@ -2412,13 +2418,13 @@ class IndexNode(ExprNode):
self
.
is_temp
=
True
self
.
is_temp
=
True
if
setting
and
self
.
base
.
type
.
is_memoryviewslice
:
if
setting
and
self
.
base
.
type
.
is_memoryviewslice
:
self
.
type
.
writable_needed
=
True
self
.
base
.
type
.
writable_needed
=
True
elif
setting
:
elif
setting
:
if
not
self
.
base
.
entry
.
type
.
writable
:
if
not
self
.
base
.
entry
.
type
.
writable
:
error
(
self
.
pos
,
"Writing to readonly buffer"
)
error
(
self
.
pos
,
"Writing to readonly buffer"
)
else
:
else
:
self
.
writable_needed
=
True
self
.
writable_needed
=
True
if
self
.
type
.
is_buffer
:
if
self
.
base
.
type
.
is_buffer
:
self
.
base
.
entry
.
buffer_aux
.
writable_needed
=
True
self
.
base
.
entry
.
buffer_aux
.
writable_needed
=
True
elif
memoryviewslice_access
:
elif
memoryviewslice_access
:
...
@@ -2570,7 +2576,7 @@ class IndexNode(ExprNode):
...
@@ -2570,7 +2576,7 @@ class IndexNode(ExprNode):
if
self
.
is_buffer_access
:
if
self
.
is_buffer_access
:
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
self
.
put_nonecheck
(
code
)
self
.
put_nonecheck
(
code
)
self
.
buffer_ptr_code
=
self
.
buffer_lookup_code
(
code
)
buffer_entry
,
self
.
buffer_ptr_code
=
self
.
buffer_lookup_code
(
code
)
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
:
# is_temp is True, so must pull out value and incref it.
# is_temp is True, so must pull out value and incref it.
code
.
putln
(
"%s = *%s;"
%
(
self
.
result
(),
self
.
buffer_ptr_code
))
code
.
putln
(
"%s = *%s;"
%
(
self
.
result
(),
self
.
buffer_ptr_code
))
...
@@ -2657,11 +2663,14 @@ class IndexNode(ExprNode):
...
@@ -2657,11 +2663,14 @@ class IndexNode(ExprNode):
# Used from generate_assignment_code and InPlaceAssignmentNode
# Used from generate_assignment_code and InPlaceAssignmentNode
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
self
.
put_nonecheck
(
code
)
self
.
put_nonecheck
(
code
)
ptrexpr
=
self
.
buffer_lookup_code
(
code
)
buffer_entry
,
ptrexpr
=
self
.
buffer_lookup_code
(
code
)
if
self
.
buffer_type
.
dtype
.
is_pyobject
:
if
self
.
buffer_type
.
dtype
.
is_pyobject
:
# Must manage refcounts. Decref what is already there
# Must manage refcounts. Decref what is already there
# and incref what we put in.
# and incref what we put in.
ptr
=
code
.
funcstate
.
allocate_temp
(
self
.
buffer_type
.
buffer_ptr_type
,
manage_ref
=
False
)
ptr
=
code
.
funcstate
.
allocate_temp
(
buffer_entry
.
buf_ptr_type
,
manage_ref
=
False
)
rhs_code
=
rhs
.
result
()
rhs_code
=
rhs
.
result
()
code
.
putln
(
"%s = %s;"
%
(
ptr
,
ptrexpr
))
code
.
putln
(
"%s = %s;"
%
(
ptr
,
ptrexpr
))
code
.
put_gotref
(
"*%s"
%
ptr
)
code
.
put_gotref
(
"*%s"
%
ptr
)
...
@@ -2735,12 +2744,14 @@ class IndexNode(ExprNode):
...
@@ -2735,12 +2744,14 @@ class IndexNode(ExprNode):
buffer_entry
=
MemoryView
.
MemoryViewSliceBufferEntry
(
entry
)
buffer_entry
=
MemoryView
.
MemoryViewSliceBufferEntry
(
entry
)
negative_indices
=
Buffer
.
buffer_defaults
[
'negative_indices'
]
negative_indices
=
Buffer
.
buffer_defaults
[
'negative_indices'
]
return
Buffer
.
put_buffer_lookup_code
(
entry
=
buffer_entry
,
index_signeds
=
[
i
.
type
.
signed
for
i
in
self
.
indices
],
return
buffer_entry
,
Buffer
.
put_buffer_lookup_code
(
index_cnames
=
index_temps
,
entry
=
buffer_entry
,
directives
=
code
.
globalstate
.
directives
,
index_signeds
=
[
i
.
type
.
signed
for
i
in
self
.
indices
],
pos
=
self
.
pos
,
code
=
code
,
index_cnames
=
index_temps
,
negative_indices
=
negative_indices
)
directives
=
code
.
globalstate
.
directives
,
pos
=
self
.
pos
,
code
=
code
,
negative_indices
=
negative_indices
)
def
put_nonecheck
(
self
,
code
):
def
put_nonecheck
(
self
,
code
):
code
.
globalstate
.
use_utility_code
(
raise_noneindex_error_utility_code
)
code
.
globalstate
.
use_utility_code
(
raise_noneindex_error_utility_code
)
...
@@ -7681,6 +7692,13 @@ class CoerceToMemViewSliceNode(CoercionNode):
...
@@ -7681,6 +7692,13 @@ class CoerceToMemViewSliceNode(CoercionNode):
self
.
type
.
from_py_function
,
self
.
type
.
from_py_function
,
self
.
arg
.
py_result
()))
self
.
arg
.
py_result
()))
error_cond
=
self
.
type
.
error_condition
(
self
.
result
())
code
.
putln
(
code
.
error_goto_if
(
error_cond
,
self
.
pos
))
def
generate_disposal_code
(
self
,
code
):
code
.
put_xdecref_memoryviewslice
(
self
.
result
(),
have_gil
=
not
self
.
env
.
nogil
)
class
CastNode
(
CoercionNode
):
class
CastNode
(
CoercionNode
):
# Wrap a node in a C type cast.
# Wrap a node in a C type cast.
...
...
Cython/Compiler/MemoryView.py
View file @
a0e188d4
...
@@ -14,9 +14,8 @@ STOP_ERR = "Axis specification only allowed in the 'stop' slot."
...
@@ -14,9 +14,8 @@ STOP_ERR = "Axis specification only allowed in the 'stop' slot."
STEP_ERR
=
"Only the value 1 (one) or valid axis specification allowed in the step slot."
STEP_ERR
=
"Only the value 1 (one) or valid axis specification allowed in the step slot."
ONE_ERR
=
"The value 1 (one) may appear in the first or last axis specification only."
ONE_ERR
=
"The value 1 (one) may appear in the first or last axis specification only."
BOTH_CF_ERR
=
"Cannot specify an array that is both C and Fortran contiguous."
BOTH_CF_ERR
=
"Cannot specify an array that is both C and Fortran contiguous."
NOT_AMP_ERR
=
"Invalid operator, only an ampersand '&' is allowed."
INVALID_ERR
=
"Invalid axis specification."
INVALID_ERR
=
"Invalid axis specification."
EXPR_ERR
=
"no expressions allowed in axis spec, only names
(e.g. cython.view.contig)
."
EXPR_ERR
=
"no expressions allowed in axis spec, only names
and literals
."
CF_ERR
=
"Invalid axis specification for a C/Fortran contiguous array."
CF_ERR
=
"Invalid axis specification for a C/Fortran contiguous array."
def
concat_flags
(
*
flags
):
def
concat_flags
(
*
flags
):
...
@@ -24,9 +23,9 @@ def concat_flags(*flags):
...
@@ -24,9 +23,9 @@ def concat_flags(*flags):
format_flag
=
"PyBUF_FORMAT"
format_flag
=
"PyBUF_FORMAT"
memview_c_contiguous
=
concat_flags
(
format_flag
,
"PyBUF_C_CONTIGUOUS"
)
memview_c_contiguous
=
"(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)"
memview_f_contiguous
=
concat_flags
(
format_flag
,
"PyBUF_F_CONTIGUOUS"
)
memview_f_contiguous
=
"(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)"
memview_any_contiguous
=
concat_flags
(
format_flag
,
"PyBUF_ANY_CONTIGUOUS"
)
memview_any_contiguous
=
"(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)"
memview_full_access
=
"PyBUF_FULL"
memview_full_access
=
"PyBUF_FULL"
#memview_strided_access = "PyBUF_STRIDED"
#memview_strided_access = "PyBUF_STRIDED"
memview_strided_access
=
"PyBUF_RECORDS"
memview_strided_access
=
"PyBUF_RECORDS"
...
@@ -72,8 +71,8 @@ def mangle_dtype_name(dtype):
...
@@ -72,8 +71,8 @@ def mangle_dtype_name(dtype):
import
Buffer
import
Buffer
return
Buffer
.
mangle_dtype_name
(
dtype
)
return
Buffer
.
mangle_dtype_name
(
dtype
)
def
axes_to_str
(
axes
):
#
def axes_to_str(axes):
return
""
.
join
([
access
[
0
].
upper
()
+
packing
[
0
]
for
(
access
,
packing
)
in
axes
])
#
return "".join([access[0].upper()+packing[0] for (access, packing) in axes])
def
put_acquire_memoryviewslice
(
lhs_cname
,
lhs_type
,
lhs_pos
,
rhs
,
code
,
def
put_acquire_memoryviewslice
(
lhs_cname
,
lhs_type
,
lhs_pos
,
rhs
,
code
,
incref_rhs
=
True
,
have_gil
=
False
):
incref_rhs
=
True
,
have_gil
=
False
):
...
@@ -106,7 +105,7 @@ def put_assign_to_memviewslice(lhs_cname, rhs_cname, memviewslicetype, code,
...
@@ -106,7 +105,7 @@ def put_assign_to_memviewslice(lhs_cname, rhs_cname, memviewslicetype, code,
code
.
putln
(
"%s.strides[%d] = %s.strides[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
code
.
putln
(
"%s.strides[%d] = %s.strides[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
code
.
putln
(
"%s.suboffsets[%d] = %s.suboffsets[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
code
.
putln
(
"%s.suboffsets[%d] = %s.suboffsets[%d];"
%
(
lhs_cname
,
i
,
rhs_cname
,
i
))
def
get_buf_flag
(
specs
):
def
get_buf_flag
s
(
specs
):
is_c_contig
,
is_f_contig
=
is_cf_contig
(
specs
)
is_c_contig
,
is_f_contig
=
is_cf_contig
(
specs
)
if
is_c_contig
:
if
is_c_contig
:
...
@@ -196,50 +195,65 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
...
@@ -196,50 +195,65 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
suboffset
=
"%s.suboffsets[%d]"
%
(
self
.
cname
,
dim
)
suboffset
=
"%s.suboffsets[%d]"
%
(
self
.
cname
,
dim
)
index
=
index_cnames
[
dim
]
index
=
index_cnames
[
dim
]
if
access
==
'full'
and
packing
in
(
'strided'
,
'follow'
):
flag
=
get_memoryview_flag
(
access
,
packing
)
if
flag
==
"generic"
:
code
.
globalstate
.
use_utility_code
(
memviewslice_index_helpers
)
code
.
globalstate
.
use_utility_code
(
memviewslice_index_helpers
)
bufp
=
(
'__pyx_memviewslice_index_full(%s, %s, %s, %s)'
%
bufp
=
(
'__pyx_memviewslice_index_full(%s, %s, %s, %s)'
%
(
bufp
,
index
,
stride
,
suboffset
))
(
bufp
,
index
,
stride
,
suboffset
))
elif
access
==
'full'
and
packing
==
'contig'
:
elif
flag
==
"generic_contiguous"
:
# We can skip stride multiplication with the cast
# We can skip stride multiplication with the cast
code
.
globalstate
.
use_utility_code
(
memviewslice_index_helpers
)
code
.
globalstate
.
use_utility_code
(
memviewslice_index_helpers
)
bufp
=
'((char *) ((%s *) %s) + %s)'
%
(
type_decl
,
bufp
,
index
)
bufp
=
'((char *) ((%s *) %s) + %s)'
%
(
type_decl
,
bufp
,
index
)
bufp
=
(
'__pyx_memviewslice_index_full_contig(%s, %s)'
%
bufp
=
(
'__pyx_memviewslice_index_full_contig(%s, %s)'
%
(
bufp
,
suboffset
))
(
bufp
,
suboffset
))
elif
access
==
'ptr'
and
packing
in
(
'strided'
,
'follow'
)
:
elif
flag
==
"indirect"
:
bufp
=
(
"(*((char **) %s + %s * %s) + %s)"
%
bufp
=
(
"(*((char **) %s + %s * %s) + %s)"
%
(
bufp
,
index
,
stride
,
suboffset
))
(
bufp
,
index
,
stride
,
suboffset
))
elif
access
==
'ptr'
and
packing
==
'contig'
:
elif
flag
==
"indirect_contiguous"
:
bufp
=
"(*((char **) %s) + %s)"
%
(
bufp
,
suboffset
)
bufp
=
"(*((char **) %s) + %s)"
%
(
bufp
,
suboffset
)
elif
access
==
'direct'
and
packing
in
(
'strided'
,
'follow'
)
:
elif
flag
==
"strided"
:
bufp
=
"(%s + %s * %s)"
%
(
bufp
,
index
,
stride
)
bufp
=
"(%s + %s * %s)"
%
(
bufp
,
index
,
stride
)
else
:
else
:
assert
(
access
,
packing
)
==
(
'direct'
,
'contig'
),
(
access
,
packing
)
assert
flag
==
'contiguous'
,
flag
bufp
=
'((char *) (((%s *) %s) + %s))'
%
(
type_decl
,
bufp
,
index
)
bufp
=
'((char *) (((%s *) %s) + %s))'
%
(
type_decl
,
bufp
,
index
)
bufp
=
'( /* dim=%d */ %s )'
%
(
dim
,
bufp
)
bufp
=
'( /* dim=%d */ %s )'
%
(
dim
,
bufp
)
return
"((%s *) %s)"
%
(
type_decl
,
bufp
)
return
"((%s *) %s)"
%
(
type_decl
,
bufp
)
def
get_memoryview_flag
(
access
,
packing
):
if
access
==
'full'
and
packing
in
(
'strided'
,
'follow'
):
return
'generic'
elif
access
==
'full'
and
packing
==
'contig'
:
return
'generic_contiguous'
elif
access
==
'ptr'
and
packing
in
(
'strided'
,
'follow'
):
return
'indirect'
elif
access
==
'ptr'
and
packing
==
'contig'
:
return
'indirect_contiguous'
elif
access
==
'direct'
and
packing
in
(
'strided'
,
'follow'
):
return
'strided'
else
:
assert
(
access
,
packing
)
==
(
'direct'
,
'contig'
),
(
access
,
packing
)
return
'contiguous'
def
get_copy_func_name
(
to_memview
):
def
get_copy_func_name
(
to_memview
):
base
=
"__Pyx_BufferNew_%s_From_%s
_%s
"
base
=
"__Pyx_BufferNew_%s_From_%s"
if
to_memview
.
is_c_contig
:
if
to_memview
.
is_c_contig
:
return
base
%
(
'C'
,
axes_to_str
(
to_memview
.
axes
),
mangle_dtype_name
(
to_memview
.
dtype
))
return
base
%
(
'C'
,
to_memview
.
specialization_suffix
(
))
else
:
else
:
return
base
%
(
'F'
,
axes_to_str
(
to_memview
.
axes
),
mangle_dtype_name
(
to_memview
.
dtype
))
return
base
%
(
'F'
,
to_memview
.
specialization_suffix
(
))
def
get_copy_contents_name
(
from_mvs
,
to_mvs
):
def
get_copy_contents_name
(
from_mvs
,
to_mvs
):
dtype
=
from_mvs
.
dtype
assert
from_mvs
.
dtype
==
to_mvs
.
dtype
assert
dtype
==
to_mvs
.
dtype
return
'__Pyx_BufferCopyContents_%s_to_%s'
%
(
from_mvs
.
specialization_suffix
(),
return
(
'__Pyx_BufferCopyContents_%s_%s_%s'
%
to_mvs
.
specialization_suffix
())
(
axes_to_str
(
from_mvs
.
axes
),
axes_to_str
(
to_mvs
.
axes
),
mangle_dtype_name
(
dtype
)))
class
IsContigFuncUtilCode
(
object
):
class
IsContigFuncUtilCode
(
object
):
...
...
Cython/Compiler/Nodes.py
View file @
a0e188d4
...
@@ -1428,16 +1428,20 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1428,16 +1428,20 @@ class FuncDefNode(StatNode, BlockNode):
self
.
generate_argument_parsing_code
(
env
,
code
)
self
.
generate_argument_parsing_code
(
env
,
code
)
# If an argument is assigned to in the body, we must
# If an argument is assigned to in the body, we must
# incref it to properly keep track of refcounts.
# incref it to properly keep track of refcounts.
is_cdef
=
isinstance
(
self
,
CFuncDefNode
)
for
entry
in
lenv
.
arg_entries
:
for
entry
in
lenv
.
arg_entries
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
code
.
put_var_incref
(
entry
)
code
.
put_var_incref
(
entry
)
# Note: all memoryviewslices are already newly acquired references
# or increffed defaults!
# Note: defaults are always increffed. For def functions, we
#if entry.type.is_memoryviewslice:
# we aquire arguments from object converstion, so we have
# code.put_incref_memoryviewslice(entry.cname,
# new references. If we are a cdef function, we need to
# have_gil=not lenv.nogil)
# incref our arguments
#code.put_incref("%s.memview" % entry.cname, cython_memoryview_ptr_type)
if
is_cdef
and
entry
.
type
.
is_memoryviewslice
:
code
.
put_incref_memoryviewslice
(
entry
.
cname
,
have_gil
=
not
lenv
.
nogil
)
# ----- Initialise local buffer auxiliary variables
# ----- Initialise local buffer auxiliary variables
for
entry
in
lenv
.
var_entries
+
lenv
.
arg_entries
:
for
entry
in
lenv
.
var_entries
+
lenv
.
arg_entries
:
if
entry
.
type
.
is_buffer
and
entry
.
buffer_aux
.
buflocal_nd_var
.
used
:
if
entry
.
type
.
is_buffer
and
entry
.
buffer_aux
.
buflocal_nd_var
.
used
:
...
@@ -1567,7 +1571,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1567,7 +1571,7 @@ class FuncDefNode(StatNode, BlockNode):
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
code
.
put_var_decref
(
entry
)
code
.
put_var_decref
(
entry
)
if
entry
.
type
.
is_memoryviewslice
and
isinstance
(
self
,
DefNode
)
:
if
entry
.
type
.
is_memoryviewslice
:
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
)
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
)
#code.put_decref("%s.memview" % entry.cname, cython_memoryview_ptr_type)
#code.put_decref("%s.memview" % entry.cname, cython_memoryview_ptr_type)
if
self
.
needs_closure
:
if
self
.
needs_closure
:
...
...
Cython/Compiler/PyrexTypes.py
View file @
a0e188d4
...
@@ -338,9 +338,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -338,9 +338,7 @@ class MemoryViewSliceType(PyrexType):
to_py_function
=
None
to_py_function
=
None
exception_value
=
None
exception_value
=
None
exception_check
=
None
exception_check
=
True
utility_counter
=
0
def
__init__
(
self
,
base_dtype
,
axes
):
def
__init__
(
self
,
base_dtype
,
axes
):
'''
'''
...
@@ -381,7 +379,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -381,7 +379,7 @@ class MemoryViewSliceType(PyrexType):
self
.
dtype
=
base_dtype
self
.
dtype
=
base_dtype
self
.
axes
=
axes
self
.
axes
=
axes
self
.
ndim
=
len
(
axes
)
self
.
ndim
=
len
(
axes
)
self
.
flags
=
MemoryView
.
get_buf_flag
(
self
.
axes
)
self
.
flags
=
MemoryView
.
get_buf_flag
s
(
self
.
axes
)
self
.
is_c_contig
,
self
.
is_f_contig
=
MemoryView
.
is_cf_contig
(
self
.
axes
)
self
.
is_c_contig
,
self
.
is_f_contig
=
MemoryView
.
is_cf_contig
(
self
.
axes
)
assert
not
(
self
.
is_c_contig
and
self
.
is_f_contig
)
assert
not
(
self
.
is_c_contig
and
self
.
is_f_contig
)
...
@@ -416,7 +414,6 @@ class MemoryViewSliceType(PyrexType):
...
@@ -416,7 +414,6 @@ class MemoryViewSliceType(PyrexType):
if
self
.
scope
is
None
:
if
self
.
scope
is
None
:
import
Symtab
,
MemoryView
,
Options
import
Symtab
,
MemoryView
,
Options
from
MemoryView
import
axes_to_str
self
.
scope
=
scope
=
Symtab
.
CClassScope
(
self
.
scope
=
scope
=
Symtab
.
CClassScope
(
'mvs_class_'
+
self
.
specialization_suffix
(),
'mvs_class_'
+
self
.
specialization_suffix
(),
...
@@ -504,12 +501,12 @@ class MemoryViewSliceType(PyrexType):
...
@@ -504,12 +501,12 @@ class MemoryViewSliceType(PyrexType):
def
specialization_suffix
(
self
):
def
specialization_suffix
(
self
):
import
MemoryView
import
MemoryView
return
MemoryView
.
axes_to_str
(
self
.
axes
)
+
'_'
+
MemoryView
.
mangle_dtype_name
(
self
.
dtype
)
dtype_name
=
MemoryView
.
mangle_dtype_name
(
self
.
dtype
)
return
"%s_%s"
%
(
self
.
axes_to_name
(),
dtype_name
)
def
global_init_code
(
self
,
entry
,
code
):
#def global_init_code(self, entry, code):
code
.
putln
(
"%s.data = NULL;"
%
entry
.
cname
)
# code.putln("%s.data = NULL;" % entry.cname)
code
.
putln
(
"%s.memview = NULL;"
%
entry
.
cname
)
# code.putln("%s.memview = NULL;" % entry.cname)
#code.put_init_to_py_none("%s.memview" % entry.cname, cython_memoryview_ptr_type, nanny=False)
def
check_for_null_code
(
self
,
cname
):
def
check_for_null_code
(
self
,
cname
):
return
cname
+
'.memview'
return
cname
+
'.memview'
...
@@ -535,15 +532,14 @@ class MemoryViewSliceType(PyrexType):
...
@@ -535,15 +532,14 @@ class MemoryViewSliceType(PyrexType):
else
:
else
:
c_or_f_flag
=
"0"
c_or_f_flag
=
"0"
# specializing through UtilityCode.specialize is not so useful as
suffix
=
self
.
specialization_suffix
()
# specialize on too many things to include in the function name
funcname
=
"__Pyx_PyObject_to_MemoryviewSlice_"
+
suffix
funcname
=
"__Pyx_PyObject_to_MemoryviewSlice_%d"
%
self
.
utility_counter
context
=
dict
(
context
=
dict
(
MemoryView
.
context
,
MemoryView
.
context
,
buf_flag
=
self
.
flags
,
buf_flag
=
self
.
flags
,
ndim
=
self
.
ndim
,
ndim
=
self
.
ndim
,
axes_specs
=
', '
.
join
(
self
.
axes_
specs_
to_code
()),
axes_specs
=
', '
.
join
(
self
.
axes_to_code
()),
dtype_typedecl
=
self
.
dtype
.
declaration_code
(
""
),
dtype_typedecl
=
self
.
dtype
.
declaration_code
(
""
),
struct_nesting_depth
=
self
.
dtype
.
struct_nesting_depth
(),
struct_nesting_depth
=
self
.
dtype
.
struct_nesting_depth
(),
c_or_f_flag
=
c_or_f_flag
,
c_or_f_flag
=
c_or_f_flag
,
...
@@ -551,8 +547,6 @@ class MemoryViewSliceType(PyrexType):
...
@@ -551,8 +547,6 @@ class MemoryViewSliceType(PyrexType):
)
)
self
.
from_py_function
=
funcname
self
.
from_py_function
=
funcname
MemoryViewSliceType
.
utility_counter
+=
1
return
True
return
True
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
...
@@ -560,15 +554,15 @@ class MemoryViewSliceType(PyrexType):
...
@@ -560,15 +554,15 @@ class MemoryViewSliceType(PyrexType):
def
get_to_py_function
(
self
,
obj
):
def
get_to_py_function
(
self
,
obj
):
return
"__pyx_memoryview_fromslice(&%s, %s.memview->obj, %s, %s);"
%
(
return
"__pyx_memoryview_fromslice(&%s, %s.memview->obj, %s, %s);"
%
(
obj
.
result
(),
obj
.
result
(),
self
.
flags
,
self
.
ndim
)
obj
.
result
(),
obj
.
result
(),
self
.
flags
,
self
.
ndim
)
def
axes_
specs_
to_code
(
self
):
def
axes_to_code
(
self
):
"Return a list of code constants for each axis"
"Return a list of code constants for each axis"
import
MemoryView
import
MemoryView
d
=
MemoryView
.
_spec_to_const
d
=
MemoryView
.
_spec_to_const
return
[
"(%s | %s)"
%
(
d
[
a
],
d
[
p
])
for
a
,
p
in
self
.
axes
]
return
[
"(%s | %s)"
%
(
d
[
a
],
d
[
p
])
for
a
,
p
in
self
.
axes
]
def
axes_
specs_
to_name
(
self
):
def
axes_to_name
(
self
):
"Return an abbreviated name for our axes"
"Return an abbreviated name for our axes"
import
MemoryView
import
MemoryView
d
=
MemoryView
.
_spec_to_abbrev
d
=
MemoryView
.
_spec_to_abbrev
...
@@ -577,6 +571,24 @@ class MemoryViewSliceType(PyrexType):
...
@@ -577,6 +571,24 @@ class MemoryViewSliceType(PyrexType):
def
error_condition
(
self
,
result_code
):
def
error_condition
(
self
,
result_code
):
return
"!%s.memview"
%
result_code
return
"!%s.memview"
%
result_code
def
__str__
(
self
):
import
MemoryView
axes_code_list
=
[]
for
access
,
packing
in
self
.
axes
:
flag
=
MemoryView
.
get_memoryview_flag
(
access
,
packing
)
if
flag
==
"strided"
:
axes_code_list
.
append
(
":"
)
else
:
axes_code_list
.
append
(
"::"
+
flag
)
if
self
.
dtype
.
is_pyobject
:
dtype_name
=
self
.
dtype
.
name
else
:
dtype_name
=
self
.
dtype
return
"%s[%s]"
%
(
dtype_name
,
", "
.
join
(
axes_code_list
))
class
BufferType
(
BaseType
):
class
BufferType
(
BaseType
):
#
#
...
@@ -632,6 +644,9 @@ class PyObjectType(PyrexType):
...
@@ -632,6 +644,9 @@ class PyObjectType(PyrexType):
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"<PyObjectType>"
return
"<PyObjectType>"
def
__eq__
(
self
,
other
):
return
isinstance
(
other
,
PyObjectType
)
and
self
.
name
==
other
.
name
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
True
return
True
...
...
Cython/Utility/MemoryView.pyx
View file @
a0e188d4
...
@@ -258,6 +258,9 @@ cdef class memoryview(object):
...
@@ -258,6 +258,9 @@ cdef class memoryview(object):
bytesitem
=
itemp
[:
self
.
view
.
itemsize
]
bytesitem
=
itemp
[:
self
.
view
.
itemsize
]
return
struct
.
unpack
(
fmt
,
bytesitem
)
return
struct
.
unpack
(
fmt
,
bytesitem
)
def
__repr__
(
self
):
return
"<MemoryView of %s at 0x%x>"
%
(
self
.
obj
.
__class__
.
__name__
,
id
(
self
))
def
__str__
(
self
):
def
__str__
(
self
):
return
"<MemoryView of %r at 0x%x>"
%
(
self
.
obj
,
id
(
self
))
return
"<MemoryView of %r at 0x%x>"
%
(
self
.
obj
,
id
(
self
))
...
@@ -283,8 +286,8 @@ cdef memoryview_cwrapper(object o, int flags):
...
@@ -283,8 +286,8 @@ cdef memoryview_cwrapper(object o, int flags):
return
memoryview
(
o
,
flags
)
return
memoryview
(
o
,
flags
)
@
cname
(
'__pyx_memoryview_fromslice'
)
@
cname
(
'__pyx_memoryview_fromslice'
)
cdef
memoryview
memoryview_from_memview_cwrapper
(
cdef
memoryview
_from_memview_cwrapper
({{
memviewslice_name
}}
*
memviewslice
,
{{
memviewslice_name
}}
*
memviewslice
,
object
orig_obj
,
int
flags
,
int
new_ndim
):
object
orig_obj
,
int
flags
,
int
new_ndim
):
cdef
_memoryviewslice
result
=
_memoryviewslice
(
orig_obj
,
flags
)
cdef
_memoryviewslice
result
=
_memoryviewslice
(
orig_obj
,
flags
)
result
.
from_slice
=
memviewslice
[
0
]
result
.
from_slice
=
memviewslice
[
0
]
...
...
tests/errors/memview_declarations.pyx
View file @
a0e188d4
# mode: error
# mode: error
cimport
cython
cimport
cython
from
cython.view
cimport
contig
as
foo
,
full
as
bar
,
follow
from
cython
cimport
view
from
cython
cimport
view
biz
=
cython
.
view
.
contig
foz
=
cython
.
view
.
full
adict
=
{
'view'
:
cython
.
view
}
alist
=
[
adict
]
cdef
signed
short
[::
1
,
::
1
]
both
cdef
signed
short
[::
1
,
::
1
]
both
cdef
signed
short
[::
1
,
:,
:,
::
1
]
both2
cdef
signed
short
[::
1
,
:,
:,
::
1
]
both2
...
@@ -17,14 +17,15 @@ cdef long long[01::1, 0x01:, '0' :, False:] fort_contig0
...
@@ -17,14 +17,15 @@ cdef long long[01::1, 0x01:, '0' :, False:] fort_contig0
cdef
signed
char
[
1
::]
bad_start
cdef
signed
char
[
1
::]
bad_start
cdef
unsigned
long
[:,:
1
]
bad_stop
cdef
unsigned
long
[:,:
1
]
bad_stop
cdef
unsigned
long
[:,::
1
,:]
neither_c_or_f
cdef
unsigned
long
[:,::
1
,:]
neither_c_or_f
cdef
signed
char
[::
1
,
::
view
.
follow
&
view
.
direct
]
bad_f_contig
cdef
signed
char
[::
1
,
::
view
.
follow
]
bad_f_contig2
cdef
signed
char
[::
view
.
contig
|
view
.
direct
]
not_ampersand
cdef
signed
char
[::
view
.
ptr
&
view
.
direct
]
no_access_spec
cdef
signed
char
[::
1
-
1
+
1
]
expr_spec
cdef
signed
char
[::
1
-
1
+
1
]
expr_spec
cdef
signed
char
[::
blargh
]
bad_name
cdef
signed
char
[::
blargh
]
bad_name
cdef
double
[::
alist
[
0
][
'view'
].
full
]
expr_attribute
cdef
double
[::
alist
[
0
][
'view'
].
full
]
expr_attribute
cdef
double
[::
view
.
ptr
&
view
.
follow
]
no_single_follow
cdef
object
[::
1
,
:]
unconformable1
=
object
()
cdef
object
[:,
::
1
]
unconformable2
=
unconformable1
cdef
int
[::
1
,
:]
dtype_unconformable
=
object
()
unconformable1
=
dtype_unconformable
_ERRORS
=
u'''
_ERRORS
=
u'''
11:25: Cannot specify an array that is both C and Fortran contiguous.
11:25: Cannot specify an array that is both C and Fortran contiguous.
...
@@ -36,12 +37,9 @@ _ERRORS = u'''
...
@@ -36,12 +37,9 @@ _ERRORS = u'''
17:18: there must be nothing or the value 0 (zero) in the start slot.
17:18: there must be nothing or the value 0 (zero) in the start slot.
18:22: Axis specification only allowed in the 'stop' slot.
18:22: Axis specification only allowed in the 'stop' slot.
19:23: The value 1 (one) may appear in the first or last axis specification only.
19:23: The value 1 (one) may appear in the first or last axis specification only.
20:36: Invalid axis specification for a C/Fortran contiguous array.
20:22: Invalid axis specification.
21:28: Invalid axis specification for a C/Fortran contiguous array.
21:25: Invalid axis specification.
22:31: Invalid operator, only an ampersand '&' is allowed.
22:22: no expressions allowed in axis spec, only names and literals.
23:28: Invalid axis specification.
25:51: Memoryview 'object[::contiguous, :]' not conformable to memoryview 'object[:, ::contiguous]'.
24:22: Invalid axis specification.
28:36: Different base types for memoryviews (int, Python object)
25:25: Invalid axis specification.
26:22: no expressions allowed in axis spec, only names (e.g. cython.view.contig).
27:12: Invalid use of the follow specifier.
'''
'''
tests/run/bufaccess.pyx
View file @
a0e188d4
...
@@ -1062,22 +1062,6 @@ def nested_packed_struct(object[NestedPackedStruct] buf):
...
@@ -1062,22 +1062,6 @@ def nested_packed_struct(object[NestedPackedStruct] buf):
"""
"""
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
sub
.
a
,
buf
[
0
].
sub
.
b
,
buf
[
0
].
c
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
sub
.
a
,
buf
[
0
].
sub
.
b
,
buf
[
0
].
c
cdef
struct
LongComplex
:
long
double
real
long
double
imag
cdef
class
LongComplexMockBuffer
(
MockBuffer
):
cdef
int
write
(
self
,
char
*
buf
,
object
value
)
except
-
1
:
cdef
LongComplex
*
s
s
=
<
LongComplex
*>
buf
;
s
.
real
,
s
.
imag
=
value
return
0
cdef
get_itemsize
(
self
):
return
sizeof
(
LongComplex
)
cdef
get_default_format
(
self
):
return
b"Zg"
#cdef extern from "complex.h":
# pass
@
testcase
@
testcase
def
complex_dtype
(
object
[
long
double
complex
]
buf
):
def
complex_dtype
(
object
[
long
double
complex
]
buf
):
...
...
tests/run/memslice.pyx
View file @
a0e188d4
# Tests the buffer access syntax functionality by constructing
# Note: see also bufaccess.pyx
# mock buffer objects.
#
# Note that the buffers are mock objects created for testing
# the buffer access behaviour -- for instance there is no flag
# checking in the buffer objects (why test our test case?), rather
# what we want to test is what is passed into the flags argument.
#
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
...
@@ -417,25 +410,6 @@ def list_comprehension(int[:] buf, len):
...
@@ -417,25 +410,6 @@ def list_comprehension(int[:] buf, len):
cdef
int
i
cdef
int
i
print
u"|"
.
join
([
unicode
(
buf
[
i
])
for
i
in
range
(
len
)])
print
u"|"
.
join
([
unicode
(
buf
[
i
])
for
i
in
range
(
len
)])
#
# The negative_indices buffer option
#
@
testcase
def
no_negative_indices
(
object
[
int
,
negative_indices
=
False
]
buf
,
int
idx
):
"""
The most interesting thing here is to inspect the C source and
make sure optimal code is produced.
>>> A = IntMockBuffer(None, range(6))
>>> no_negative_indices(A, 3)
3
>>> no_negative_indices(A, -1)
Traceback (most recent call last):
...
IndexError: Out of bounds on buffer access (axis 0)
"""
return
buf
[
idx
]
@
testcase
@
testcase
@
cython
.
wraparound
(
False
)
@
cython
.
wraparound
(
False
)
def
wraparound_directive
(
int
[:]
buf
,
int
pos_idx
,
int
neg_idx
):
def
wraparound_directive
(
int
[:]
buf
,
int
pos_idx
,
int
neg_idx
):
...
@@ -459,19 +433,6 @@ def wraparound_directive(int[:] buf, int pos_idx, int neg_idx):
...
@@ -459,19 +433,6 @@ def wraparound_directive(int[:] buf, int pos_idx, int neg_idx):
#
#
# Test which flags are passed.
# Test which flags are passed.
#
#
# @testcase
# def readonly(obj):
# """
# >>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3))
# >>> readonly(R)
# acquired R
# 25
# released R
# >>> [str(x) for x in R.recieved_flags] # Works in both py2 and py3
# ['FORMAT', 'INDIRECT', 'ND', 'STRIDES']
# """
# cdef unsigned short int[:, :, :] buf = obj
# print buf[2, 2, 1]
@
testcase
@
testcase
def
writable
(
obj
):
def
writable
(
obj
):
...
@@ -510,7 +471,7 @@ def c_contig(int[::1] buf):
...
@@ -510,7 +471,7 @@ def c_contig(int[::1] buf):
>>> c_contig(A)
>>> c_contig(A)
2
2
>>> [str(x) for x in A.recieved_flags]
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS'
, 'WRITABLE'
]
"""
"""
return
buf
[
2
]
return
buf
[
2
]
...
@@ -523,7 +484,7 @@ def c_contig_2d(int[:, ::1] buf):
...
@@ -523,7 +484,7 @@ def c_contig_2d(int[:, ::1] buf):
>>> c_contig_2d(A)
>>> c_contig_2d(A)
7
7
>>> [str(x) for x in A.recieved_flags]
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS'
, 'WRITABLE'
]
"""
"""
return
buf
[
1
,
3
]
return
buf
[
1
,
3
]
...
@@ -534,12 +495,12 @@ def f_contig(int[::1, :] buf):
...
@@ -534,12 +495,12 @@ def f_contig(int[::1, :] buf):
>>> f_contig(A)
>>> f_contig(A)
2
2
>>> [str(x) for x in A.recieved_flags]
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS'
, 'WRITABLE'
]
"""
"""
return
buf
[
0
,
1
]
return
buf
[
0
,
1
]
@
testcase
@
testcase
def
f_contig_2d
(
object
[
int
,
ndim
=
2
,
mode
=
'fortran'
]
buf
):
def
f_contig_2d
(
int
[::
1
,
:
]
buf
):
"""
"""
Must set up strides manually to ensure Fortran ordering.
Must set up strides manually to ensure Fortran ordering.
...
@@ -547,7 +508,7 @@ def f_contig_2d(object[int, ndim=2, mode='fortran'] buf):
...
@@ -547,7 +508,7 @@ def f_contig_2d(object[int, ndim=2, mode='fortran'] buf):
>>> f_contig_2d(A)
>>> f_contig_2d(A)
7
7
>>> [str(x) for x in A.recieved_flags]
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS'
, 'WRITABLE'
]
"""
"""
return
buf
[
3
,
1
]
return
buf
[
3
,
1
]
...
@@ -600,18 +561,6 @@ def unsafe_get(int[:] buf, int idx):
...
@@ -600,18 +561,6 @@ def unsafe_get(int[:] buf, int idx):
"""
"""
return
buf
[
idx
]
return
buf
[
idx
]
# @testcase
# @cython.boundscheck(False)
# def unsafe_get_nonegative(object[int, negative_indices=False] buf, int idx):
# """
# Also inspect the C source to see that it is optimal...
#
# >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5)
# >>> unsafe_get_nonegative(A, -2)
# 3
# """
# return buf[idx]
@
testcase
@
testcase
def
mixed_get
(
int
[:]
buf
,
int
unsafe_idx
,
int
safe_idx
):
def
mixed_get
(
int
[:]
buf
,
int
unsafe_idx
,
int
safe_idx
):
"""
"""
...
@@ -629,25 +578,6 @@ def mixed_get(int[:] buf, int unsafe_idx, int safe_idx):
...
@@ -629,25 +578,6 @@ def mixed_get(int[:] buf, int unsafe_idx, int safe_idx):
two
=
buf
[
safe_idx
]
two
=
buf
[
safe_idx
]
return
(
one
,
two
)
return
(
one
,
two
)
#
# Coercions
#
## @testcase
## def coercions(object[unsigned char] uc):
## """
## TODO
## """
## print type(uc[0])
## uc[0] = -1
## print uc[0]
## uc[0] = <int>3.14
## print uc[0]
## cdef char* ch = b"asfd"
## cdef object[object] objbuf
## objbuf[3] = ch
#
#
# Testing that accessing data using various types of buffer access
# Testing that accessing data using various types of buffer access
# all works.
# all works.
...
@@ -759,7 +689,7 @@ def printbuf_td_cy_int(td_cy_int[:] buf, shape):
...
@@ -759,7 +689,7 @@ def printbuf_td_cy_int(td_cy_int[:] buf, shape):
print
'END'
print
'END'
@
testcase
@
testcase
def
printbuf_td_h_short
(
object
[
td_h_short
]
buf
,
shape
):
def
printbuf_td_h_short
(
td_h_short
[:
]
buf
,
shape
):
"""
"""
>>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,))
>>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,))
0 1 2 END
0 1 2 END
...
@@ -774,7 +704,7 @@ def printbuf_td_h_short(object[td_h_short] buf, shape):
...
@@ -774,7 +704,7 @@ def printbuf_td_h_short(object[td_h_short] buf, shape):
print
'END'
print
'END'
@
testcase
@
testcase
def
printbuf_td_h_cy_short
(
object
[
td_h_cy_short
]
buf
,
shape
):
def
printbuf_td_h_cy_short
(
td_h_cy_short
[:
]
buf
,
shape
):
"""
"""
>>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,))
>>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,))
0 1 2 END
0 1 2 END
...
@@ -789,7 +719,7 @@ def printbuf_td_h_cy_short(object[td_h_cy_short] buf, shape):
...
@@ -789,7 +719,7 @@ def printbuf_td_h_cy_short(object[td_h_cy_short] buf, shape):
print
'END'
print
'END'
@
testcase
@
testcase
def
printbuf_td_h_ushort
(
object
[
td_h_ushort
]
buf
,
shape
):
def
printbuf_td_h_ushort
(
td_h_ushort
[:
]
buf
,
shape
):
"""
"""
>>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,))
>>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,))
0 1 2 END
0 1 2 END
...
@@ -804,7 +734,7 @@ def printbuf_td_h_ushort(object[td_h_ushort] buf, shape):
...
@@ -804,7 +734,7 @@ def printbuf_td_h_ushort(object[td_h_ushort] buf, shape):
print
'END'
print
'END'
@
testcase
@
testcase
def
printbuf_td_h_double
(
object
[
td_h_double
]
buf
,
shape
):
def
printbuf_td_h_double
(
td_h_double
[:
]
buf
,
shape
):
"""
"""
>>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,))
>>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,))
0.25 1.0 3.125 END
0.25 1.0 3.125 END
...
@@ -831,7 +761,7 @@ def get_refcount(x):
...
@@ -831,7 +761,7 @@ def get_refcount(x):
return
(
<
PyObject
*>
x
).
ob_refcnt
return
(
<
PyObject
*>
x
).
ob_refcnt
@
testcase
@
testcase
def
printbuf_object
(
object
[
object
]
buf
,
shape
):
def
printbuf_object
(
object
[
:
]
buf
,
shape
):
"""
"""
Only play with unique objects, interned numbers etc. will have
Only play with unique objects, interned numbers etc. will have
unpredictable refcounts.
unpredictable refcounts.
...
@@ -854,7 +784,7 @@ def printbuf_object(object[object] buf, shape):
...
@@ -854,7 +784,7 @@ def printbuf_object(object[object] buf, shape):
print
repr
(
buf
[
i
]),
(
<
PyObject
*>
buf
[
i
]).
ob_refcnt
print
repr
(
buf
[
i
]),
(
<
PyObject
*>
buf
[
i
]).
ob_refcnt
@
testcase
@
testcase
def
assign_to_object
(
object
[
object
]
buf
,
int
idx
,
obj
):
def
assign_to_object
(
object
[
:
]
buf
,
int
idx
,
obj
):
"""
"""
See comments on printbuf_object above.
See comments on printbuf_object above.
...
@@ -873,7 +803,7 @@ def assign_to_object(object[object] buf, int idx, obj):
...
@@ -873,7 +803,7 @@ def assign_to_object(object[object] buf, int idx, obj):
buf
[
idx
]
=
obj
buf
[
idx
]
=
obj
@
testcase
@
testcase
def
assign_temporary_to_object
(
object
[
object
]
buf
):
def
assign_temporary_to_object
(
object
[
:
]
buf
):
"""
"""
See comments on printbuf_object above.
See comments on printbuf_object above.
...
@@ -899,69 +829,11 @@ def assign_temporary_to_object(object[object] buf):
...
@@ -899,69 +829,11 @@ def assign_temporary_to_object(object[object] buf):
"""
"""
buf
[
1
]
=
{
3
-
2
:
2
+
(
2
*
4
)
-
2
}
buf
[
1
]
=
{
3
-
2
:
2
+
(
2
*
4
)
-
2
}
#
# cast option
#
@
testcase
def
buffer_cast
(
object
[
unsigned
int
,
cast
=
True
]
buf
,
int
idx
):
"""
Round-trip a signed int through unsigned int buffer access.
>>> A = IntMockBuffer(None, [-100])
>>> buffer_cast(A, 0)
-100
"""
cdef
unsigned
int
data
=
buf
[
idx
]
return
<
int
>
data
@
testcase
def
buffer_cast_fails
(
object
[
char
,
cast
=
True
]
buf
):
"""
Cannot cast between datatype of different sizes.
>>> buffer_cast_fails(IntMockBuffer(None, [0]))
Traceback (most recent call last):
...
ValueError: Item size of buffer (4 bytes) does not match size of 'char' (1 byte)
"""
return
buf
[
0
]
#
# Typed buffers
#
@
testcase
def
typedbuffer1
(
obj
):
"""
>>> typedbuffer1(IntMockBuffer("A", range(10)))
acquired A
released A
>>> typedbuffer1(None)
>>> typedbuffer1(4)
Traceback (most recent call last):
...
TypeError: Cannot convert int to memslice.IntMockBuffer
"""
cdef
IntMockBuffer
[
int
,
ndim
=
1
]
buf
=
obj
@
testcase
def
typedbuffer2
(
IntMockBuffer
[
int
,
ndim
=
1
]
obj
):
"""
>>> typedbuffer2(IntMockBuffer("A", range(10)))
acquired A
released A
>>> typedbuffer2(None)
>>> typedbuffer2(4)
Traceback (most recent call last):
...
TypeError: Argument 'obj' has incorrect type (expected memslice.IntMockBuffer, got int)
"""
pass
#
#
# Test __cythonbufferdefaults__
# Test __cythonbufferdefaults__
#
#
@
testcase
@
testcase
def
bufdefaults1
(
IntStridedMockBuffer
[
int
,
ndim
=
1
]
buf
):
def
bufdefaults1
(
int
[:
]
buf
):
"""
"""
For IntStridedMockBuffer, mode should be
For IntStridedMockBuffer, mode should be
"strided" by defaults which should show
"strided" by defaults which should show
...
@@ -972,13 +844,13 @@ def bufdefaults1(IntStridedMockBuffer[int, ndim=1] buf):
...
@@ -972,13 +844,13 @@ def bufdefaults1(IntStridedMockBuffer[int, ndim=1] buf):
acquired A
acquired A
released A
released A
>>> [str(x) for x in A.recieved_flags]
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES']
['FORMAT', 'ND', 'STRIDES'
, 'WRITABLE'
]
"""
"""
pass
pass
@
testcase
@
testcase
def
basic_struct
(
object
[
MyStruct
]
buf
):
def
basic_struct
(
MyStruct
[:
]
buf
):
"""
"""
See also buffmt.pyx
See also buffmt.pyx
...
@@ -990,7 +862,7 @@ def basic_struct(object[MyStruct] buf):
...
@@ -990,7 +862,7 @@ def basic_struct(object[MyStruct] buf):
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
c
,
buf
[
0
].
d
,
buf
[
0
].
e
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
c
,
buf
[
0
].
d
,
buf
[
0
].
e
@
testcase
@
testcase
def
nested_struct
(
object
[
NestedStruct
]
buf
):
def
nested_struct
(
NestedStruct
[:
]
buf
):
"""
"""
See also buffmt.pyx
See also buffmt.pyx
...
@@ -1002,7 +874,7 @@ def nested_struct(object[NestedStruct] buf):
...
@@ -1002,7 +874,7 @@ def nested_struct(object[NestedStruct] buf):
print
buf
[
0
].
x
.
a
,
buf
[
0
].
x
.
b
,
buf
[
0
].
y
.
a
,
buf
[
0
].
y
.
b
,
buf
[
0
].
z
print
buf
[
0
].
x
.
a
,
buf
[
0
].
x
.
b
,
buf
[
0
].
y
.
a
,
buf
[
0
].
y
.
b
,
buf
[
0
].
z
@
testcase
@
testcase
def
packed_struct
(
object
[
PackedStruct
]
buf
):
def
packed_struct
(
PackedStruct
[:
]
buf
):
"""
"""
See also buffmt.pyx
See also buffmt.pyx
...
@@ -1017,7 +889,7 @@ def packed_struct(object[PackedStruct] buf):
...
@@ -1017,7 +889,7 @@ def packed_struct(object[PackedStruct] buf):
print
buf
[
0
].
a
,
buf
[
0
].
b
print
buf
[
0
].
a
,
buf
[
0
].
b
@
testcase
@
testcase
def
nested_packed_struct
(
object
[
NestedPackedStruct
]
buf
):
def
nested_packed_struct
(
NestedPackedStruct
[:
]
buf
):
"""
"""
See also buffmt.pyx
See also buffmt.pyx
...
@@ -1030,25 +902,9 @@ def nested_packed_struct(object[NestedPackedStruct] buf):
...
@@ -1030,25 +902,9 @@ def nested_packed_struct(object[NestedPackedStruct] buf):
"""
"""
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
sub
.
a
,
buf
[
0
].
sub
.
b
,
buf
[
0
].
c
print
buf
[
0
].
a
,
buf
[
0
].
b
,
buf
[
0
].
sub
.
a
,
buf
[
0
].
sub
.
b
,
buf
[
0
].
c
cdef
struct
LongComplex
:
long
double
real
long
double
imag
cdef
class
LongComplexMockBuffer
(
MockBuffer
):
cdef
int
write
(
self
,
char
*
buf
,
object
value
)
except
-
1
:
cdef
LongComplex
*
s
s
=
<
LongComplex
*>
buf
;
s
.
real
,
s
.
imag
=
value
return
0
cdef
get_itemsize
(
self
):
return
sizeof
(
LongComplex
)
cdef
get_default_format
(
self
):
return
b"Zg"
#cdef extern from "complex.h":
# pass
@
testcase
@
testcase
def
complex_dtype
(
object
[
long
double
complex
]
buf
):
def
complex_dtype
(
long
double
complex
[:
]
buf
):
"""
"""
>>> complex_dtype(LongComplexMockBuffer(None, [(0, -1)]))
>>> complex_dtype(LongComplexMockBuffer(None, [(0, -1)]))
-1j
-1j
...
@@ -1056,7 +912,7 @@ def complex_dtype(object[long double complex] buf):
...
@@ -1056,7 +912,7 @@ def complex_dtype(object[long double complex] buf):
print
buf
[
0
]
print
buf
[
0
]
@
testcase
@
testcase
def
complex_inplace
(
object
[
long
double
complex
]
buf
):
def
complex_inplace
(
long
double
complex
[:
]
buf
):
"""
"""
>>> complex_inplace(LongComplexMockBuffer(None, [(0, -1)]))
>>> complex_inplace(LongComplexMockBuffer(None, [(0, -1)]))
(1+1j)
(1+1j)
...
@@ -1065,7 +921,7 @@ def complex_inplace(object[long double complex] buf):
...
@@ -1065,7 +921,7 @@ def complex_inplace(object[long double complex] buf):
print
buf
[
0
]
print
buf
[
0
]
@
testcase
@
testcase
def
complex_struct_dtype
(
object
[
LongComplex
]
buf
):
def
complex_struct_dtype
(
LongComplex
[:
]
buf
):
"""
"""
Note that the format string is "Zg" rather than "2g", yet a struct
Note that the format string is "Zg" rather than "2g", yet a struct
is accessed.
is accessed.
...
@@ -1075,7 +931,7 @@ def complex_struct_dtype(object[LongComplex] buf):
...
@@ -1075,7 +931,7 @@ def complex_struct_dtype(object[LongComplex] buf):
print
buf
[
0
].
real
,
buf
[
0
].
imag
print
buf
[
0
].
real
,
buf
[
0
].
imag
@
testcase
@
testcase
def
complex_struct_inplace
(
object
[
LongComplex
]
buf
):
def
complex_struct_inplace
(
LongComplex
[:
]
buf
):
"""
"""
>>> complex_struct_inplace(LongComplexMockBuffer(None, [(0, -1)]))
>>> complex_struct_inplace(LongComplexMockBuffer(None, [(0, -1)]))
1.0 1.0
1.0 1.0
...
@@ -1092,9 +948,85 @@ def complex_struct_inplace(object[LongComplex] buf):
...
@@ -1092,9 +948,85 @@ def complex_struct_inplace(object[LongComplex] buf):
def
buffer_nogil
():
def
buffer_nogil
():
"""
"""
>>> buffer_nogil()
>>> buffer_nogil()
10
(10, 10)
"""
"""
cdef
int
[:]
buf
=
IntMockBuffer
(
None
,
[
1
,
2
,
3
])
cdef
int
[:]
buf
=
IntMockBuffer
(
None
,
[
1
,
2
,
3
])
cdef
int
[:]
buf2
=
IntMockBuffer
(
None
,
[
4
,
5
,
6
])
with
nogil
:
with
nogil
:
buf
[
1
]
=
10
buf
[
1
]
=
10
return
buf
[
1
]
buf2
=
buf
return
buf
[
1
],
buf2
[
1
]
#
### Test cdef functions
#
cdef
cdef
_function
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
ObjectMockBuffer
(
None
,
[[
"spam"
],[
"ham"
],[
"eggs"
]])):
print
'cdef called'
print
buf1
[
6
],
buf2
[
1
,
0
]
buf2
[
1
,
0
]
=
"eggs"
def
test_cdef_function
(
o1
,
o2
=
None
):
"""
>>> A = IntMockBuffer("A", range(10))
>>> test_cdef_function(A)
acquired A
cdef called
6 ham
released A
acquired A
cdef called
6 eggs
released A
>>> B = ObjectMockBuffer("B", range(25), shape=(5, 5))
>>> test_cdef_function(A, B)
acquired A
acquired B
cdef called
6 eggs
released A
released B
acquired A
acquired B
cdef called
6 eggs
released A
released B
"""
cdef
_function
(
o1
)
cdef
_function
(
o1
)
if
o2
:
cdef
_function
(
o1
,
o2
)
cdef
int
[:]
global_A
=
IntMockBuffer
(
"A"
,
range
(
10
))
cdef
object
[::
view
.
indirect
,
:]
global_B
=
ObjectMockBuffer
(
None
,
[[
"spam"
],[
"ham"
],[
"eggs"
]])
cdef
cdef
_function2
(
int
[:]
buf1
,
object
[::
view
.
indirect
,
:]
buf2
=
global_B
):
print
'cdef2 called'
print
buf1
[
6
],
buf2
[
1
,
0
]
buf2
[
1
,
0
]
=
"eggs"
def
test_cdef_function2
():
"""
>>> test_cdef_function2()
cdef2 called
6 ham
eggs
cdef2 called
6 eggs
"""
cdef
int
[:]
A
=
global_A
cdef
object
[::
view
.
indirect
,
:]
B
=
global_B
cdef
_function2
(
A
,
B
)
del
A
del
B
print
global_B
[
1
,
0
]
cdef
_function2
(
global_A
,
global_B
)
tests/run/mockbuffers.pxi
View file @
a0e188d4
...
@@ -311,3 +311,16 @@ cdef class NestedPackedStructMockBuffer(MockBuffer):
...
@@ -311,3 +311,16 @@ cdef class NestedPackedStructMockBuffer(MockBuffer):
cdef
get_itemsize
(
self
):
return
sizeof
(
NestedPackedStruct
)
cdef
get_itemsize
(
self
):
return
sizeof
(
NestedPackedStruct
)
cdef
get_default_format
(
self
):
return
b"ci^ci@i"
cdef
get_default_format
(
self
):
return
b"ci^ci@i"
cdef
struct
LongComplex
:
long
double
real
long
double
imag
cdef
class
LongComplexMockBuffer
(
MockBuffer
):
cdef
int
write
(
self
,
char
*
buf
,
object
value
)
except
-
1
:
cdef
LongComplex
*
s
s
=
<
LongComplex
*>
buf
;
s
.
real
,
s
.
imag
=
value
return
0
cdef
get_itemsize
(
self
):
return
sizeof
(
LongComplex
)
cdef
get_default_format
(
self
):
return
b"Zg"
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