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
Gwenaël Samain
cython
Commits
1800cbda
Commit
1800cbda
authored
Sep 06, 2017
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial attempt at implementing read-only memoryviews. (Github issue #1605)
parent
1487db2f
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
215 additions
and
173 deletions
+215
-173
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+22
-15
Cython/Compiler/FusedNode.py
Cython/Compiler/FusedNode.py
+2
-2
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+6
-6
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+10
-19
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+6
-3
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+35
-26
Cython/Utility/MemoryView.pyx
Cython/Utility/MemoryView.pyx
+12
-2
Cython/Utility/MemoryView_C.c
Cython/Utility/MemoryView_C.c
+3
-3
tests/buffers/bufaccess.pyx
tests/buffers/bufaccess.pyx
+8
-8
tests/buffers/mockbuffers.pxi
tests/buffers/mockbuffers.pxi
+11
-6
tests/memoryview/memoryview.pyx
tests/memoryview/memoryview.pyx
+1
-1
tests/memoryview/memslice.pyx
tests/memoryview/memslice.pyx
+99
-82
No files found.
Cython/Compiler/ExprNodes.py
View file @
1800cbda
...
@@ -870,16 +870,19 @@ class ExprNode(Node):
...
@@ -870,16 +870,19 @@ class ExprNode(Node):
elif
not
src_type
.
is_error
:
elif
not
src_type
.
is_error
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Cannot convert '%s' to memoryviewslice"
%
(
src_type
,))
"Cannot convert '%s' to memoryviewslice"
%
(
src_type
,))
elif
not
src
.
type
.
conforms_to
(
dst_type
,
broadcast
=
self
.
is_memview_broadcast
,
else
:
copying
=
self
.
is_memview_copy_assignment
):
if
src
.
type
.
writable_needed
:
if
src
.
type
.
dtype
.
same_as
(
dst_type
.
dtype
):
dst_type
.
writable_needed
=
True
msg
=
"Memoryview '%s' not conformable to memoryview '%s'."
if
not
src
.
type
.
conforms_to
(
dst_type
,
broadcast
=
self
.
is_memview_broadcast
,
tup
=
src
.
type
,
dst_type
copying
=
self
.
is_memview_copy_assignment
):
else
:
if
src
.
type
.
dtype
.
same_as
(
dst_type
.
dtype
):
msg
=
"Different base types for memoryviews (%s, %s)"
msg
=
"Memoryview '%s' not conformable to memoryview '%s'."
tup
=
src
.
type
.
dtype
,
dst_type
.
dtype
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
)
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
:
...
@@ -4253,6 +4256,10 @@ class MemoryViewIndexNode(BufferIndexNode):
...
@@ -4253,6 +4256,10 @@ class MemoryViewIndexNode(BufferIndexNode):
indices
=
self
.
indices
indices
=
self
.
indices
have_slices
,
indices
,
newaxes
=
MemoryView
.
unellipsify
(
indices
,
self
.
base
.
type
.
ndim
)
have_slices
,
indices
,
newaxes
=
MemoryView
.
unellipsify
(
indices
,
self
.
base
.
type
.
ndim
)
if
not
getting
:
self
.
writable_needed
=
True
self
.
base
.
entry
.
type
.
writable_needed
=
True
self
.
memslice_index
=
(
not
newaxes
and
len
(
indices
)
==
self
.
base
.
type
.
ndim
)
self
.
memslice_index
=
(
not
newaxes
and
len
(
indices
)
==
self
.
base
.
type
.
ndim
)
axes
=
[]
axes
=
[]
...
@@ -12640,12 +12647,12 @@ class CoerceToMemViewSliceNode(CoercionNode):
...
@@ -12640,12 +12647,12 @@ class CoerceToMemViewSliceNode(CoercionNode):
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
self
.
type
.
create_from_py_utility_code
(
self
.
env
)
self
.
type
.
create_from_py_utility_code
(
self
.
env
)
code
.
putln
(
"%s = %s(%s);"
%
(
self
.
result
(),
code
.
putln
(
self
.
type
.
from_py_call_code
(
self
.
type
.
from_py_function
,
self
.
arg
.
py_result
()
,
self
.
arg
.
py_result
()))
self
.
result
(),
self
.
pos
,
error_cond
=
self
.
type
.
error_condition
(
self
.
result
())
code
code
.
putln
(
code
.
error_goto_if
(
error_cond
,
self
.
pos
))
))
class
CastNode
(
CoercionNode
):
class
CastNode
(
CoercionNode
):
...
...
Cython/Compiler/FusedNode.py
View file @
1800cbda
...
@@ -374,7 +374,7 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -374,7 +374,7 @@ class FusedCFuncDefNode(StatListNode):
coerce_from_py_func
=
memslice_type
.
from_py_function
,
coerce_from_py_func
=
memslice_type
.
from_py_function
,
dtype
=
dtype
)
dtype
=
dtype
)
decl_code
.
putln
(
decl_code
.
putln
(
"{{memviewslice_cname}} {{coerce_from_py_func}}(object)"
)
"{{memviewslice_cname}} {{coerce_from_py_func}}(object
, int
)"
)
pyx_code
.
context
.
update
(
pyx_code
.
context
.
update
(
specialized_type_name
=
specialized_type
.
specialization_string
,
specialized_type_name
=
specialized_type
.
specialization_string
,
...
@@ -384,7 +384,7 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -384,7 +384,7 @@ class FusedCFuncDefNode(StatListNode):
u"""
u"""
# try {{dtype}}
# try {{dtype}}
if itemsize == -1 or itemsize == {{sizeof_dtype}}:
if itemsize == -1 or itemsize == {{sizeof_dtype}}:
memslice = {{coerce_from_py_func}}(arg)
memslice = {{coerce_from_py_func}}(arg
, 0
)
if memslice.memview:
if memslice.memview:
__PYX_XDEC_MEMVIEW(&memslice, 1)
__PYX_XDEC_MEMVIEW(&memslice, 1)
# print 'found a match for the buffer through format parsing'
# print 'found a match for the buffer through format parsing'
...
...
Cython/Compiler/MemoryView.py
View file @
1800cbda
...
@@ -28,12 +28,12 @@ def concat_flags(*flags):
...
@@ -28,12 +28,12 @@ def concat_flags(*flags):
format_flag
=
"PyBUF_FORMAT"
format_flag
=
"PyBUF_FORMAT"
memview_c_contiguous
=
"(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT
| PyBUF_WRITABLE
)"
memview_c_contiguous
=
"(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT)"
memview_f_contiguous
=
"(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT
| PyBUF_WRITABLE
)"
memview_f_contiguous
=
"(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT)"
memview_any_contiguous
=
"(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT
| PyBUF_WRITABLE
)"
memview_any_contiguous
=
"(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT)"
memview_full_access
=
"PyBUF_FULL"
memview_full_access
=
"PyBUF_FULL
_RO
"
#memview_strided_access = "PyBUF_STRIDED"
#memview_strided_access = "PyBUF_STRIDED
_RO
"
memview_strided_access
=
"PyBUF_RECORDS"
memview_strided_access
=
"PyBUF_RECORDS
_RO
"
MEMVIEW_DIRECT
=
'__Pyx_MEMVIEW_DIRECT'
MEMVIEW_DIRECT
=
'__Pyx_MEMVIEW_DIRECT'
MEMVIEW_PTR
=
'__Pyx_MEMVIEW_PTR'
MEMVIEW_PTR
=
'__Pyx_MEMVIEW_PTR'
...
...
Cython/Compiler/Nodes.py
View file @
1800cbda
...
@@ -3698,18 +3698,12 @@ class DefNodeWrapper(FuncDefNode):
...
@@ -3698,18 +3698,12 @@ class DefNodeWrapper(FuncDefNode):
entry
=
arg
.
entry
entry
=
arg
.
entry
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
item
))
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
item
))
else
:
else
:
func
=
arg
.
type
.
from_py_function
if
arg
.
type
.
from_py_function
:
if
func
:
if
arg
.
default
:
if
arg
.
default
:
# C-typed default arguments must be handled here
# C-typed default arguments must be handled here
code
.
putln
(
'if (%s) {'
%
item
)
code
.
putln
(
'if (%s) {'
%
item
)
rhs
=
"%s(%s)"
%
(
func
,
item
)
code
.
putln
(
arg
.
type
.
from_py_call_code
(
if
arg
.
type
.
is_enum
:
item
,
arg
.
entry
.
cname
,
arg
.
pos
,
code
))
rhs
=
arg
.
type
.
cast_code
(
rhs
)
code
.
putln
(
"%s = %s; %s"
%
(
arg
.
entry
.
cname
,
rhs
,
code
.
error_goto_if
(
arg
.
type
.
error_condition
(
arg
.
entry
.
cname
),
arg
.
pos
)))
if
arg
.
default
:
if
arg
.
default
:
code
.
putln
(
'} else {'
)
code
.
putln
(
'} else {'
)
code
.
putln
(
"%s = %s;"
%
(
code
.
putln
(
"%s = %s;"
%
(
...
@@ -3950,17 +3944,14 @@ class DefNodeWrapper(FuncDefNode):
...
@@ -3950,17 +3944,14 @@ class DefNodeWrapper(FuncDefNode):
def
generate_arg_conversion_from_pyobject
(
self
,
arg
,
code
):
def
generate_arg_conversion_from_pyobject
(
self
,
arg
,
code
):
new_type
=
arg
.
type
new_type
=
arg
.
type
func
=
new_type
.
from_py_function
# copied from CoerceFromPyTypeNode
# copied from CoerceFromPyTypeNode
if
func
:
if
new_type
.
from_py_function
:
lhs
=
arg
.
entry
.
cname
code
.
putln
(
new_type
.
from_py_call_code
(
rhs
=
"%s(%s)"
%
(
func
,
arg
.
hdr_cname
)
arg
.
hdr_cname
,
if
new_type
.
is_enum
:
arg
.
entry
.
cname
,
rhs
=
PyrexTypes
.
typecast
(
new_type
,
PyrexTypes
.
c_long_type
,
rhs
)
arg
.
pos
,
code
.
putln
(
"%s = %s; %s"
%
(
code
,
lhs
,
))
rhs
,
code
.
error_goto_if
(
new_type
.
error_condition
(
arg
.
entry
.
cname
),
arg
.
pos
)))
else
:
else
:
error
(
arg
.
pos
,
"Cannot convert Python object argument to type '%s'"
%
new_type
)
error
(
arg
.
pos
,
"Cannot convert Python object argument to type '%s'"
%
new_type
)
...
...
Cython/Compiler/Parsing.py
View file @
1800cbda
...
@@ -2481,9 +2481,12 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
...
@@ -2481,9 +2481,12 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
if
s
.
systring
==
'const'
:
if
s
.
systring
==
'const'
:
s
.
next
()
s
.
next
()
base_type
=
p_c_base_type
(
s
,
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
if
isinstance
(
base_type
,
Nodes
.
MemoryViewSliceTypeNode
):
return
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
)
# reverse order to avoid having to write "(const int)[:]"
base_type
.
base_type_node
=
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
.
base_type_node
)
return
base_type
return
Nodes
.
CConstTypeNode
(
pos
,
base_type
=
base_type
)
if
looking_at_base_type
(
s
):
if
looking_at_base_type
(
s
):
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
#print "p_c_simple_base_type: looking_at_base_type at", s.position()
is_basic
=
1
is_basic
=
1
...
...
Cython/Compiler/PyrexTypes.py
View file @
1800cbda
...
@@ -314,6 +314,21 @@ class PyrexType(BaseType):
...
@@ -314,6 +314,21 @@ class PyrexType(BaseType):
def
needs_nonecheck
(
self
):
def
needs_nonecheck
(
self
):
return
0
return
0
def
_assign_from_py_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
,
extra_args
=
None
):
args
=
', '
+
', '
.
join
(
'%s'
%
arg
for
arg
in
extra_args
)
if
extra_args
else
''
convert_call
=
"%s(%s%s)"
%
(
from_py_function
or
self
.
from_py_function
,
source_code
,
args
,
)
if
self
.
is_enum
:
convert_call
=
typecast
(
self
,
c_long_type
,
convert_call
)
return
'%s = %s; %s'
%
(
result_code
,
convert_call
,
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
def
public_decl
(
base_code
,
dll_linkage
):
def
public_decl
(
base_code
,
dll_linkage
):
if
dll_linkage
:
if
dll_linkage
:
...
@@ -491,12 +506,11 @@ class CTypedefType(BaseType):
...
@@ -491,12 +506,11 @@ class CTypedefType(BaseType):
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
):
from_py_function
=
None
,
error_condition
=
None
):
if
from_py_function
is
None
:
from_py_function
=
self
.
from_py_function
if
error_condition
is
None
:
error_condition
=
self
.
error_condition
(
result_code
)
return
self
.
typedef_base_type
.
from_py_call_code
(
return
self
.
typedef_base_type
.
from_py_call_code
(
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
,
error_condition
)
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
or
self
.
from_py_function
,
error_condition
or
self
.
error_condition
(
result_code
)
)
def
overflow_check_binop
(
self
,
binop
,
env
,
const_rhs
=
False
):
def
overflow_check_binop
(
self
,
binop
,
env
,
const_rhs
=
False
):
env
.
use_utility_code
(
UtilityCode
.
load
(
"Common"
,
"Overflow.c"
))
env
.
use_utility_code
(
UtilityCode
.
load
(
"Common"
,
"Overflow.c"
))
...
@@ -619,6 +633,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -619,6 +633,7 @@ class MemoryViewSliceType(PyrexType):
def
same_as_resolved_type
(
self
,
other_type
):
def
same_as_resolved_type
(
self
,
other_type
):
return
((
other_type
.
is_memoryviewslice
and
return
((
other_type
.
is_memoryviewslice
and
self
.
writable_needed
==
other_type
.
writable_needed
and
self
.
dtype
.
same_as
(
other_type
.
dtype
)
and
self
.
dtype
.
same_as
(
other_type
.
dtype
)
and
self
.
axes
==
other_type
.
axes
)
or
self
.
axes
==
other_type
.
axes
)
or
other_type
is
error_type
)
other_type
is
error_type
)
...
@@ -767,7 +782,14 @@ class MemoryViewSliceType(PyrexType):
...
@@ -767,7 +782,14 @@ class MemoryViewSliceType(PyrexType):
src
=
self
src
=
self
if
src
.
dtype
!=
dst
.
dtype
:
if
self
.
writable_needed
and
not
dst
.
writable_needed
:
return
False
src_dtype
,
dst_dtype
=
src
.
dtype
,
dst
.
dtype
if
dst_dtype
.
is_const
and
not
src_dtype
.
is_const
:
dst_dtype
=
dst_dtype
.
const_base_type
if
src_dtype
!=
dst_dtype
:
return
False
return
False
if
src
.
ndim
!=
dst
.
ndim
:
if
src
.
ndim
!=
dst
.
ndim
:
...
@@ -885,11 +907,9 @@ class MemoryViewSliceType(PyrexType):
...
@@ -885,11 +907,9 @@ class MemoryViewSliceType(PyrexType):
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
):
from_py_function
=
None
,
error_condition
=
None
):
return
'%s = %s(%s); %s'
%
(
return
self
.
_assign_from_py_code
(
result_code
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
,
error_condition
,
from_py_function
or
self
.
from_py_function
,
extra_args
=
[
'PyBUF_WRITABLE'
if
self
.
writable_needed
else
'0'
])
source_code
,
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
def
create_to_py_utility_code
(
self
,
env
):
def
create_to_py_utility_code
(
self
,
env
):
self
.
_dtype_to_py_func
,
self
.
_dtype_from_py_func
=
self
.
dtype_object_conversion_funcs
(
env
)
self
.
_dtype_to_py_func
,
self
.
_dtype_from_py_func
=
self
.
dtype_object_conversion_funcs
(
env
)
...
@@ -1467,11 +1487,9 @@ class CType(PyrexType):
...
@@ -1467,11 +1487,9 @@ class CType(PyrexType):
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
):
from_py_function
=
None
,
error_condition
=
None
):
return
'%s = %s(%s); %s'
%
(
return
self
.
_assign_from_py_code
(
result_code
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
,
error_condition
)
from_py_function
or
self
.
from_py_function
,
source_code
,
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
class
PythranExpr
(
CType
):
class
PythranExpr
(
CType
):
# Pythran object of a given type
# Pythran object of a given type
...
@@ -2403,6 +2421,7 @@ class CArrayType(CPointerBaseType):
...
@@ -2403,6 +2421,7 @@ class CArrayType(CPointerBaseType):
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
):
from_py_function
=
None
,
error_condition
=
None
):
assert
not
error_condition
call_code
=
"%s(%s, %s, %s)"
%
(
call_code
=
"%s(%s, %s, %s)"
%
(
from_py_function
or
self
.
from_py_function
,
from_py_function
or
self
.
from_py_function
,
source_code
,
result_code
,
self
.
size
)
source_code
,
result_code
,
self
.
size
)
...
@@ -3826,16 +3845,6 @@ class CEnumType(CType):
...
@@ -3826,16 +3845,6 @@ class CEnumType(CType):
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
return
True
return
True
def
from_py_call_code
(
self
,
source_code
,
result_code
,
error_pos
,
code
,
from_py_function
=
None
,
error_condition
=
None
):
rhs
=
"%s(%s)"
%
(
from_py_function
or
self
.
from_py_function
,
source_code
)
return
'%s = %s;%s'
%
(
result_code
,
typecast
(
self
,
c_long_type
,
rhs
),
' %s'
%
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
def
create_type_wrapper
(
self
,
env
):
def
create_type_wrapper
(
self
,
env
):
from
.UtilityCode
import
CythonUtilityCode
from
.UtilityCode
import
CythonUtilityCode
env
.
use_utility_code
(
CythonUtilityCode
.
load
(
env
.
use_utility_code
(
CythonUtilityCode
.
load
(
...
...
Cython/Utility/MemoryView.pyx
View file @
1800cbda
...
@@ -65,6 +65,7 @@ cdef extern from *:
...
@@ -65,6 +65,7 @@ cdef extern from *:
PyBUF_STRIDES
PyBUF_STRIDES
PyBUF_INDIRECT
PyBUF_INDIRECT
PyBUF_RECORDS
PyBUF_RECORDS
PyBUF_RECORDS_RO
ctypedef
struct
__Pyx_TypeInfo
:
ctypedef
struct
__Pyx_TypeInfo
:
pass
pass
...
@@ -408,6 +409,9 @@ cdef class memoryview(object):
...
@@ -408,6 +409,9 @@ cdef class memoryview(object):
return
self
.
convert_item_to_object
(
itemp
)
return
self
.
convert_item_to_object
(
itemp
)
def
__setitem__
(
memoryview
self
,
object
index
,
object
value
):
def
__setitem__
(
memoryview
self
,
object
index
,
object
value
):
if
self
.
view
.
readonly
:
raise
TypeError
(
"Cannot assign to read-only memoryview"
)
have_slices
,
index
=
_unellipsify
(
index
,
self
.
view
.
ndim
)
have_slices
,
index
=
_unellipsify
(
index
,
self
.
view
.
ndim
)
if
have_slices
:
if
have_slices
:
...
@@ -507,6 +511,9 @@ cdef class memoryview(object):
...
@@ -507,6 +511,9 @@ cdef class memoryview(object):
@
cname
(
'getbuffer'
)
@
cname
(
'getbuffer'
)
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
def
__getbuffer__
(
self
,
Py_buffer
*
info
,
int
flags
):
if
flags
&
PyBUF_WRITABLE
and
self
.
view
.
readonly
:
raise
ValueError
(
"Cannot create writable memory view from read-only memoryview"
)
if
flags
&
PyBUF_STRIDES
:
if
flags
&
PyBUF_STRIDES
:
info
.
shape
=
self
.
view
.
shape
info
.
shape
=
self
.
view
.
shape
else
:
else
:
...
@@ -531,7 +538,7 @@ cdef class memoryview(object):
...
@@ -531,7 +538,7 @@ cdef class memoryview(object):
info
.
ndim
=
self
.
view
.
ndim
info
.
ndim
=
self
.
view
.
ndim
info
.
itemsize
=
self
.
view
.
itemsize
info
.
itemsize
=
self
.
view
.
itemsize
info
.
len
=
self
.
view
.
len
info
.
len
=
self
.
view
.
len
info
.
readonly
=
0
info
.
readonly
=
self
.
view
.
readonly
info
.
obj
=
self
info
.
obj
=
self
__pyx_getbuffer
=
capsule
(
<
void
*>
&
__pyx_memoryview_getbuffer
,
"getbuffer(obj, view, flags)"
)
__pyx_getbuffer
=
capsule
(
<
void
*>
&
__pyx_memoryview_getbuffer
,
"getbuffer(obj, view, flags)"
)
...
@@ -1012,7 +1019,10 @@ cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
...
@@ -1012,7 +1019,10 @@ cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
(
<
__pyx_buffer
*>
&
result
.
view
).
obj
=
Py_None
(
<
__pyx_buffer
*>
&
result
.
view
).
obj
=
Py_None
Py_INCREF
(
Py_None
)
Py_INCREF
(
Py_None
)
result
.
flags
=
PyBUF_RECORDS
if
(
<
memoryview
>
memviewslice
.
memview
).
flags
&
PyBUF_WRITABLE
:
result
.
flags
=
PyBUF_RECORDS
else
:
result
.
flags
=
PyBUF_RECORDS_RO
result
.
view
.
shape
=
<
Py_ssize_t
*>
result
.
from_slice
.
shape
result
.
view
.
shape
=
<
Py_ssize_t
*>
result
.
from_slice
.
shape
result
.
view
.
strides
=
<
Py_ssize_t
*>
result
.
from_slice
.
strides
result
.
view
.
strides
=
<
Py_ssize_t
*>
result
.
from_slice
.
strides
...
...
Cython/Utility/MemoryView_C.c
View file @
1800cbda
...
@@ -82,7 +82,7 @@ typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
...
@@ -82,7 +82,7 @@ typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
/////////////// ObjectToMemviewSlice.proto ///////////////
/////////////// ObjectToMemviewSlice.proto ///////////////
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
);
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
,
int
writable_flag
);
////////// MemviewSliceInit.proto //////////
////////// MemviewSliceInit.proto //////////
...
@@ -127,7 +127,7 @@ static CYTHON_INLINE char *__pyx_memviewslice_index_full(
...
@@ -127,7 +127,7 @@ static CYTHON_INLINE char *__pyx_memviewslice_index_full(
/////////////// ObjectToMemviewSlice ///////////////
/////////////// ObjectToMemviewSlice ///////////////
//@requires: MemviewSliceValidateAndInit
//@requires: MemviewSliceValidateAndInit
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
obj
)
{
static
CYTHON_INLINE
{{
memviewslice_name
}}
{{
funcname
}}(
PyObject
*
obj
,
int
writable_flag
)
{
{{
memviewslice_name
}}
result
=
{{
memslice_init
}};
{{
memviewslice_name
}}
result
=
{{
memslice_init
}};
__Pyx_BufFmt_StackElem
stack
[{{
struct_nesting_depth
}}];
__Pyx_BufFmt_StackElem
stack
[{{
struct_nesting_depth
}}];
int
axes_specs
[]
=
{
{{
axes_specs
}}
};
int
axes_specs
[]
=
{
{{
axes_specs
}}
};
...
@@ -140,7 +140,7 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) {
...
@@ -140,7 +140,7 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) {
}
}
retcode
=
__Pyx_ValidateAndInit_memviewslice
(
axes_specs
,
{{
c_or_f_flag
}},
retcode
=
__Pyx_ValidateAndInit_memviewslice
(
axes_specs
,
{{
c_or_f_flag
}},
{{
buf_flag
}},
{{
ndim
}},
{{
buf_flag
}}
|
writable_flag
,
{{
ndim
}},
&
{{
dtype_typeinfo
}},
stack
,
&
{{
dtype_typeinfo
}},
stack
,
&
result
,
obj
);
&
result
,
obj
);
...
...
tests/buffers/bufaccess.pyx
View file @
1800cbda
...
@@ -599,7 +599,7 @@ def readonly(obj):
...
@@ -599,7 +599,7 @@ def readonly(obj):
acquired R
acquired R
25
25
released R
released R
>>> [str(x) for x in R.rec
ie
ved_flags] # Works in both py2 and py3
>>> [str(x) for x in R.rec
ei
ved_flags] # Works in both py2 and py3
['FORMAT', 'INDIRECT', 'ND', 'STRIDES']
['FORMAT', 'INDIRECT', 'ND', 'STRIDES']
"""
"""
cdef
object
[
unsigned
short
int
,
ndim
=
3
]
buf
=
obj
cdef
object
[
unsigned
short
int
,
ndim
=
3
]
buf
=
obj
...
@@ -612,7 +612,7 @@ def writable(obj):
...
@@ -612,7 +612,7 @@ def writable(obj):
>>> writable(R)
>>> writable(R)
acquired R
acquired R
released R
released R
>>> [str(x) for x in R.rec
ie
ved_flags] # Py2/3
>>> [str(x) for x in R.rec
ei
ved_flags] # Py2/3
['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE']
['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE']
"""
"""
cdef
object
[
unsigned
short
int
,
ndim
=
3
]
buf
=
obj
cdef
object
[
unsigned
short
int
,
ndim
=
3
]
buf
=
obj
...
@@ -626,7 +626,7 @@ def strided(object[int, ndim=1, mode='strided'] buf):
...
@@ -626,7 +626,7 @@ def strided(object[int, ndim=1, mode='strided'] buf):
acquired A
acquired A
released A
released A
2
2
>>> [str(x) for x in A.rec
ie
ved_flags] # Py2/3
>>> [str(x) for x in A.rec
ei
ved_flags] # Py2/3
['FORMAT', 'ND', 'STRIDES']
['FORMAT', 'ND', 'STRIDES']
Check that the suboffsets were patched back prior to release.
Check that the suboffsets were patched back prior to release.
...
@@ -641,7 +641,7 @@ def c_contig(object[int, ndim=1, mode='c'] buf):
...
@@ -641,7 +641,7 @@ def c_contig(object[int, ndim=1, mode='c'] buf):
>>> A = IntMockBuffer(None, range(4))
>>> A = IntMockBuffer(None, range(4))
>>> c_contig(A)
>>> c_contig(A)
2
2
>>> [str(x) for x in A.rec
ie
ved_flags]
>>> [str(x) for x in A.rec
ei
ved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
"""
"""
return
buf
[
2
]
return
buf
[
2
]
...
@@ -654,7 +654,7 @@ def c_contig_2d(object[int, ndim=2, mode='c'] buf):
...
@@ -654,7 +654,7 @@ def c_contig_2d(object[int, ndim=2, mode='c'] buf):
>>> A = IntMockBuffer(None, range(12), shape=(3,4))
>>> A = IntMockBuffer(None, range(12), shape=(3,4))
>>> c_contig_2d(A)
>>> c_contig_2d(A)
7
7
>>> [str(x) for x in A.rec
ie
ved_flags]
>>> [str(x) for x in A.rec
ei
ved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
"""
"""
return
buf
[
1
,
3
]
return
buf
[
1
,
3
]
...
@@ -665,7 +665,7 @@ def f_contig(object[int, ndim=1, mode='fortran'] buf):
...
@@ -665,7 +665,7 @@ def f_contig(object[int, ndim=1, mode='fortran'] buf):
>>> A = IntMockBuffer(None, range(4))
>>> A = IntMockBuffer(None, range(4))
>>> f_contig(A)
>>> f_contig(A)
2
2
>>> [str(x) for x in A.rec
ie
ved_flags]
>>> [str(x) for x in A.rec
ei
ved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
"""
"""
return
buf
[
2
]
return
buf
[
2
]
...
@@ -678,7 +678,7 @@ def f_contig_2d(object[int, ndim=2, mode='fortran'] buf):
...
@@ -678,7 +678,7 @@ def f_contig_2d(object[int, ndim=2, mode='fortran'] buf):
>>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4))
>>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4))
>>> f_contig_2d(A)
>>> f_contig_2d(A)
7
7
>>> [str(x) for x in A.rec
ie
ved_flags]
>>> [str(x) for x in A.rec
ei
ved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
"""
"""
return
buf
[
3
,
1
]
return
buf
[
3
,
1
]
...
@@ -1103,7 +1103,7 @@ def bufdefaults1(IntStridedMockBuffer[int, ndim=1] buf):
...
@@ -1103,7 +1103,7 @@ def bufdefaults1(IntStridedMockBuffer[int, ndim=1] buf):
>>> bufdefaults1(A)
>>> bufdefaults1(A)
acquired A
acquired A
released A
released A
>>> [str(x) for x in A.rec
ie
ved_flags]
>>> [str(x) for x in A.rec
ei
ved_flags]
['FORMAT', 'ND', 'STRIDES']
['FORMAT', 'ND', 'STRIDES']
"""
"""
pass
pass
...
...
tests/buffers/mockbuffers.pxi
View file @
1800cbda
...
@@ -18,16 +18,17 @@ cdef class MockBuffer:
...
@@ -18,16 +18,17 @@ cdef class MockBuffer:
cdef
object
format
,
offset
cdef
object
format
,
offset
cdef
void
*
buffer
cdef
void
*
buffer
cdef
Py_ssize_t
len
,
itemsize
cdef
Py_ssize_t
len
,
itemsize
cdef
int
ndim
cdef
Py_ssize_t
*
strides
cdef
Py_ssize_t
*
strides
cdef
Py_ssize_t
*
shape
cdef
Py_ssize_t
*
shape
cdef
Py_ssize_t
*
suboffsets
cdef
Py_ssize_t
*
suboffsets
cdef
object
label
,
log
cdef
object
label
,
log
cdef
int
ndim
cdef
bint
writable
cdef
readonly
object
rec
ie
ved_flags
,
release_ok
cdef
readonly
object
rec
ei
ved_flags
,
release_ok
cdef
public
object
fail
cdef
public
object
fail
def
__init__
(
self
,
label
,
data
,
shape
=
None
,
strides
=
None
,
format
=
None
,
offset
=
0
):
def
__init__
(
self
,
label
,
data
,
shape
=
None
,
strides
=
None
,
format
=
None
,
writable
=
True
,
offset
=
0
):
# It is important not to store references to data after the constructor
# It is important not to store references to data after the constructor
# as refcounting is checked on object buffers.
# as refcounting is checked on object buffers.
self
.
label
=
label
self
.
label
=
label
...
@@ -35,6 +36,7 @@ cdef class MockBuffer:
...
@@ -35,6 +36,7 @@ cdef class MockBuffer:
self
.
log
=
""
self
.
log
=
""
self
.
offset
=
offset
self
.
offset
=
offset
self
.
itemsize
=
self
.
get_itemsize
()
self
.
itemsize
=
self
.
get_itemsize
()
self
.
writable
=
writable
if
format
is
None
:
format
=
self
.
get_default_format
()
if
format
is
None
:
format
=
self
.
get_default_format
()
if
shape
is
None
:
shape
=
(
len
(
data
),)
if
shape
is
None
:
shape
=
(
len
(
data
),)
if
strides
is
None
:
if
strides
is
None
:
...
@@ -127,16 +129,19 @@ cdef class MockBuffer:
...
@@ -127,16 +129,19 @@ cdef class MockBuffer:
if
self
.
fail
:
if
self
.
fail
:
raise
ValueError
(
"Failing on purpose"
)
raise
ValueError
(
"Failing on purpose"
)
self
.
rec
ie
ved_flags
=
[]
self
.
rec
ei
ved_flags
=
[]
cdef
int
value
cdef
int
value
for
name
,
value
in
available_flags
:
for
name
,
value
in
available_flags
:
if
(
value
&
flags
)
==
value
:
if
(
value
&
flags
)
==
value
:
self
.
recieved_flags
.
append
(
name
)
self
.
received_flags
.
append
(
name
)
if
flags
&
cpython
.
buffer
.
PyBUF_WRITABLE
and
not
self
.
writable
:
raise
BufferError
(
"Writable buffer requested from read-only mock: %s"
%
' | '
.
join
(
self
.
received_flags
))
buffer
.
buf
=
<
void
*>
(
<
char
*>
self
.
buffer
+
(
<
int
>
self
.
offset
*
self
.
itemsize
))
buffer
.
buf
=
<
void
*>
(
<
char
*>
self
.
buffer
+
(
<
int
>
self
.
offset
*
self
.
itemsize
))
buffer
.
obj
=
self
buffer
.
obj
=
self
buffer
.
len
=
self
.
len
buffer
.
len
=
self
.
len
buffer
.
readonly
=
0
buffer
.
readonly
=
not
self
.
writable
buffer
.
format
=
<
char
*>
self
.
format
buffer
.
format
=
<
char
*>
self
.
format
buffer
.
ndim
=
self
.
ndim
buffer
.
ndim
=
self
.
ndim
buffer
.
shape
=
self
.
shape
buffer
.
shape
=
self
.
shape
...
...
tests/memoryview/memoryview.pyx
View file @
1800cbda
...
@@ -420,7 +420,7 @@ def writable(unsigned short int[:, :, :] mslice):
...
@@ -420,7 +420,7 @@ def writable(unsigned short int[:, :, :] mslice):
>>> writable(R)
>>> writable(R)
acquired R
acquired R
released R
released R
>>> [str(x) for x in R.rec
ie
ved_flags] # Py2/3
>>> [str(x) for x in R.rec
ei
ved_flags] # Py2/3
['FORMAT', 'ND', 'STRIDES', 'WRITABLE']
['FORMAT', 'ND', 'STRIDES', 'WRITABLE']
"""
"""
buf
=
mslice
buf
=
mslice
...
...
tests/memoryview/memslice.pyx
View file @
1800cbda
This diff is collapsed.
Click to expand it.
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