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
Kirill Smelkov
cython
Commits
71433dd7
Commit
71433dd7
authored
Aug 06, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Buffers: Added __cythonbufferdefaults__ and refactor in buffer option parsing.
dtype is not supported yet (needs change in parser).
parent
eedd37bc
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
236 additions
and
105 deletions
+236
-105
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+67
-0
Cython/Compiler/Interpreter.py
Cython/Compiler/Interpreter.py
+55
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+30
-16
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+56
-75
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+3
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+3
-1
Cython/Compiler/Tests/TestBuffer.py
Cython/Compiler/Tests/TestBuffer.py
+9
-6
tests/errors/e_bufaccess.pyx
tests/errors/e_bufaccess.pyx
+8
-6
tests/run/bufaccess.pyx
tests/run/bufaccess.pyx
+5
-1
No files found.
Cython/Compiler/Buffer.py
View file @
71433dd7
...
@@ -5,6 +5,7 @@ from Cython.Compiler.ExprNodes import *
...
@@ -5,6 +5,7 @@ from Cython.Compiler.ExprNodes import *
from
Cython.Compiler.TreeFragment
import
TreeFragment
from
Cython.Compiler.TreeFragment
import
TreeFragment
from
Cython.Utils
import
EncodedString
from
Cython.Utils
import
EncodedString
from
Cython.Compiler.Errors
import
CompileError
from
Cython.Compiler.Errors
import
CompileError
import
Interpreter
import
PyrexTypes
import
PyrexTypes
from
sets
import
Set
as
set
from
sets
import
Set
as
set
import
textwrap
import
textwrap
...
@@ -104,7 +105,73 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
...
@@ -104,7 +105,73 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
return
node
return
node
#
# Analysis
#
buffer_options
=
(
"dtype"
,
"ndim"
,
"mode"
)
# ordered!
buffer_defaults
=
{
"ndim"
:
1
,
"mode"
:
"full"
}
ERR_BUF_OPTION_UNKNOWN
=
'"%s" is not a buffer option'
ERR_BUF_TOO_MANY
=
'Too many buffer options'
ERR_BUF_DUP
=
'"%s" buffer option already supplied'
ERR_BUF_MISSING
=
'"%s" missing'
ERR_BUF_MODE
=
'Only allowed buffer modes are "full" or "strided" (as a compile-time string)'
ERR_BUF_NDIM
=
'ndim must be a non-negative integer'
def
analyse_buffer_options
(
globalpos
,
env
,
posargs
,
dictargs
,
defaults
=
None
,
need_complete
=
True
):
"""
Must be called during type analysis, as analyse is called
on the dtype argument.
posargs and dictargs should consist of a list and a dict
of tuples (value, pos). Defaults should be a dict of values.
Returns a dict containing all the options a buffer can have and
its value (with the positions stripped).
"""
if
defaults
is
None
:
defaults
=
buffer_defaults
posargs
,
dictargs
=
Interpreter
.
interpret_compiletime_options
(
posargs
,
dictargs
,
type_env
=
env
)
if
len
(
posargs
)
>
len
(
buffer_options
):
raise
CompileError
(
posargs
[
-
1
][
1
],
ERR_BUF_TOO_MANY
)
options
=
{}
for
name
,
(
value
,
pos
)
in
dictargs
.
iteritems
():
if
not
name
in
buffer_options
:
raise
CompileError
(
pos
,
ERR_BUF_OPTION_UNKNOWN
%
name
)
options
[
name
]
=
value
for
name
,
(
value
,
pos
)
in
zip
(
buffer_options
,
posargs
):
if
not
name
in
buffer_options
:
raise
CompileError
(
pos
,
ERR_BUF_OPTION_UNKNOWN
%
name
)
if
name
in
options
:
raise
CompileError
(
pos
,
ERR_BUF_DUP
%
name
)
options
[
name
]
=
value
# Check that they are all there and copy defaults
for
name
in
buffer_options
:
if
not
name
in
options
:
try
:
options
[
name
]
=
defaults
[
name
]
except
KeyError
:
if
need_complete
:
raise
CompileError
(
globalpos
,
ERR_BUF_MISSING
%
name
)
ndim
=
options
[
"ndim"
]
if
not
isinstance
(
ndim
,
int
)
or
ndim
<
0
:
raise
CompileError
(
globalpos
,
ERR_BUF_NDIM
)
if
not
options
[
"mode"
]
in
(
'full'
,
'strided'
):
raise
CompileError
(
globalpos
,
ERR_BUF_MODE
)
return
options
#
# Code generation
#
def
get_flags
(
buffer_aux
,
buffer_type
):
def
get_flags
(
buffer_aux
,
buffer_type
):
...
...
Cython/Compiler/Interpreter.py
0 → 100644
View file @
71433dd7
"""
This module deals with interpreting the parse tree as Python
would have done, in the compiler.
For now this only covers parse tree to value conversion of
compile-time values.
"""
from
Nodes
import
*
from
ExprNodes
import
*
from
Visitor
import
BasicVisitor
from
Errors
import
CompileError
class
EmptyScope
:
def
lookup
(
self
,
name
):
return
None
empty_scope
=
EmptyScope
()
def
interpret_compiletime_options
(
optlist
,
optdict
,
type_env
=
None
):
"""
Tries to interpret a list of compile time option nodes.
The result will be a tuple (optlist, optdict) but where
all expression nodes have been interpreted. The result is
in the form of tuples (value, pos).
optlist is a list of nodes, while optdict is a DictNode (the
result optdict is a dict)
If type_env is set, all type nodes will be analysed and the resulting
type set. Otherwise only interpretateable ExprNodes
are allowed, other nodes raises errors.
A CompileError will be raised if there are problems.
"""
def
interpret
(
node
):
if
isinstance
(
node
,
CBaseTypeNode
):
if
type_env
:
return
(
node
.
analyse
(
type_env
),
node
.
pos
)
else
:
raise
CompileError
(
node
.
pos
,
"Type not allowed here."
)
else
:
return
(
node
.
compile_time_value
(
empty_scope
),
node
.
pos
)
if
optlist
:
optlist
=
[
interpret
(
x
)
for
x
in
optlist
]
if
optdict
:
assert
isinstance
(
optdict
,
DictNode
)
new_optdict
=
{}
for
item
in
optdict
.
key_value_pairs
:
new_optdict
[
item
.
key
.
value
]
=
interpret
(
item
.
value
)
optdict
=
new_optdict
return
(
optlist
,
new_optdict
)
Cython/Compiler/Nodes.py
View file @
71433dd7
...
@@ -573,29 +573,33 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
...
@@ -573,29 +573,33 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
else
:
else
:
return
PyrexTypes
.
error_type
return
PyrexTypes
.
error_type
class
CBufferAccessTypeNode
(
Node
):
class
CBufferAccessTypeNode
(
CBaseType
Node
):
# After parsing:
# After parsing:
# positional_args [ExprNode] List of positional arguments
# positional_args [ExprNode] List of positional arguments
# keyword_args DictNode Keyword arguments
# keyword_args DictNode Keyword arguments
# base_type_node CBaseTypeNode
# base_type_node CBaseTypeNode
# After PostParse:
# dtype_node CBaseTypeNode
# ndim int
# After analysis:
# After analysis:
# type PyrexType.PyrexType
# type PyrexType.BufferType ...containing the right options
child_attrs
=
[
"base_type_node"
,
"positional_args"
,
"keyword_args"
,
child_attrs
=
[
"base_type_node"
,
"positional_args"
,
"dtype_node"
]
"
keyword_args"
,
"
dtype_node"
]
dtype_node
=
None
dtype_node
=
None
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
):
base_type
=
self
.
base_type_node
.
analyse
(
env
)
base_type
=
self
.
base_type_node
.
analyse
(
env
)
dtype
=
self
.
dtype_node
.
analyse
(
env
)
import
Buffer
self
.
type
=
PyrexTypes
.
BufferType
(
base_type
,
dtype
=
dtype
,
ndim
=
self
.
ndim
,
mode
=
self
.
mode
)
options
=
Buffer
.
analyse_buffer_options
(
self
.
pos
,
env
,
self
.
positional_args
,
self
.
keyword_args
,
base_type
.
buffer_defaults
)
self
.
type
=
PyrexTypes
.
BufferType
(
base_type
,
**
options
)
return
self
.
type
return
self
.
type
class
CComplexBaseTypeNode
(
CBaseTypeNode
):
class
CComplexBaseTypeNode
(
CBaseTypeNode
):
...
@@ -628,7 +632,6 @@ class CVarDefNode(StatNode):
...
@@ -628,7 +632,6 @@ class CVarDefNode(StatNode):
dest_scope
=
env
dest_scope
=
env
self
.
dest_scope
=
dest_scope
self
.
dest_scope
=
dest_scope
base_type
=
self
.
base_type
.
analyse
(
env
)
base_type
=
self
.
base_type
.
analyse
(
env
)
if
(
dest_scope
.
is_c_class_scope
if
(
dest_scope
.
is_c_class_scope
and
self
.
visibility
==
'public'
and
self
.
visibility
==
'public'
and
base_type
.
is_pyobject
and
base_type
.
is_pyobject
...
@@ -2051,16 +2054,26 @@ class CClassDefNode(ClassDefNode):
...
@@ -2051,16 +2054,26 @@ class CClassDefNode(ClassDefNode):
# body StatNode or None
# body StatNode or None
# entry Symtab.Entry
# entry Symtab.Entry
# base_type PyExtensionType or None
# base_type PyExtensionType or None
# bufferdefaults dict or None Declares defaults for a buffer
# buffer_defaults_node DictNode or None Declares defaults for a buffer
# buffer_defaults_pos
child_attrs
=
[
"body"
]
child_attrs
=
[
"body"
]
bufferdefaults
=
None
buffer_defaults_node
=
None
buffer_defaults_pos
=
None
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
#print "CClassDefNode.analyse_declarations:", self.class_name
#print "CClassDefNode.analyse_declarations:", self.class_name
#print "...visibility =", self.visibility
#print "...visibility =", self.visibility
#print "...module_name =", self.module_name
#print "...module_name =", self.module_name
import
Buffer
if
self
.
buffer_defaults_node
:
buffer_defaults
=
Buffer
.
analyse_buffer_options
(
self
.
buffer_defaults_pos
,
env
,
[],
self
.
buffer_defaults_node
,
need_complete
=
False
)
else
:
buffer_defaults
=
None
if
env
.
in_cinclude
and
not
self
.
objstruct_name
:
if
env
.
in_cinclude
and
not
self
.
objstruct_name
:
error
(
self
.
pos
,
"Object struct name specification required for "
error
(
self
.
pos
,
"Object struct name specification required for "
"C class defined in 'extern from' block"
)
"C class defined in 'extern from' block"
)
...
@@ -2112,7 +2125,8 @@ class CClassDefNode(ClassDefNode):
...
@@ -2112,7 +2125,8 @@ class CClassDefNode(ClassDefNode):
typeobj_cname
=
self
.
typeobj_name
,
typeobj_cname
=
self
.
typeobj_name
,
visibility
=
self
.
visibility
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
)
api
=
self
.
api
,
buffer_defaults
=
buffer_defaults
)
if
home_scope
is
not
env
and
self
.
visibility
==
'extern'
:
if
home_scope
is
not
env
and
self
.
visibility
==
'extern'
:
env
.
add_imported_entry
(
self
.
class_name
,
self
.
entry
,
pos
)
env
.
add_imported_entry
(
self
.
class_name
,
self
.
entry
,
pos
)
scope
=
self
.
entry
.
type
.
scope
scope
=
self
.
entry
.
type
.
scope
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
71433dd7
...
@@ -77,15 +77,10 @@ class NormalizeTree(CythonTransform):
...
@@ -77,15 +77,10 @@ class NormalizeTree(CythonTransform):
class
PostParseError
(
CompileError
):
pass
class
PostParseError
(
CompileError
):
pass
# error strings checked by unit tests, so define them
# error strings checked by unit tests, so define them
ERR_BUF_OPTION_UNKNOWN
=
'"%s" is not a buffer option'
ERR_BUF_TOO_MANY
=
'Too many buffer options'
ERR_BUF_DUP
=
'"%s" buffer option already supplied'
ERR_BUF_MISSING
=
'"%s" missing'
ERR_BUF_INT
=
'"%s" must be an integer'
ERR_BUF_NONNEG
=
'"%s" must be non-negative'
ERR_CDEF_INCLASS
=
'Cannot assign default value to cdef class attributes'
ERR_CDEF_INCLASS
=
'Cannot assign default value to cdef class attributes'
ERR_BUF_LOCALONLY
=
'Buffer types only allowed as function local variables'
ERR_BUF_LOCALONLY
=
'Buffer types only allowed as function local variables'
ERR_BUF_MODEHELP
=
'Only allowed buffer modes are "full" or "strided" (as a compile-time string)'
ERR_BUF_DEFAULTS
=
'Invalid buffer defaults specification (see docs)'
ERR_INVALID_SPECIALATTR_TYPE
=
'Special attributes must not have a type declared'
class
PostParse
(
CythonTransform
):
class
PostParse
(
CythonTransform
):
"""
"""
Basic interpretation of the parse tree, as well as validity
Basic interpretation of the parse tree, as well as validity
...
@@ -97,10 +92,24 @@ class PostParse(CythonTransform):
...
@@ -97,10 +92,24 @@ class PostParse(CythonTransform):
- Default values to cdef assignments are turned into single
- Default values to cdef assignments are turned into single
assignments following the declaration (everywhere but in class
assignments following the declaration (everywhere but in class
bodies, where they raise a compile error)
bodies, where they raise a compile error)
- CBufferAccessTypeNode has its options interpreted:
- Interpret some node structures into Python runtime values.
Some nodes take compile-time arguments (currently:
CBufferAccessTypeNode[args] and __cythonbufferdefaults__ = {args}),
which should be interpreted. This happens in a general way
and other steps should be taken to ensure validity.
Type arguments cannot be interpreted in this way.
- For __cythonbufferdefaults__ the arguments are checked for
validity.
CBufferAccessTypeNode has its options interpreted:
Any first positional argument goes into the "dtype" attribute,
Any first positional argument goes into the "dtype" attribute,
any "ndim" keyword argument goes into the "ndim" attribute and
any "ndim" keyword argument goes into the "ndim" attribute and
so on. Also it is checked that the option combination is valid.
so on. Also it is checked that the option combination is valid.
- __cythonbufferdefaults__ attributes are parsed and put into the
type information.
Note: Currently Parsing.py does a lot of interpretation and
Note: Currently Parsing.py does a lot of interpretation and
reorganization that can be refactored into this transform
reorganization that can be refactored into this transform
...
@@ -110,6 +119,12 @@ class PostParse(CythonTransform):
...
@@ -110,6 +119,12 @@ class PostParse(CythonTransform):
# Track our context.
# Track our context.
scope_type
=
None
# can be either of 'module', 'function', 'class'
scope_type
=
None
# can be either of 'module', 'function', 'class'
def
__init__
(
self
,
context
):
super
(
PostParse
,
self
).
__init__
(
context
)
self
.
specialattribute_handlers
=
{
'__cythonbufferdefaults__'
:
self
.
handle_bufferdefaults
}
def
visit_ModuleNode
(
self
,
node
):
def
visit_ModuleNode
(
self
,
node
):
self
.
scope_type
=
'module'
self
.
scope_type
=
'module'
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
...
@@ -118,8 +133,10 @@ class PostParse(CythonTransform):
...
@@ -118,8 +133,10 @@ class PostParse(CythonTransform):
def
visit_ClassDefNode
(
self
,
node
):
def
visit_ClassDefNode
(
self
,
node
):
prev
=
self
.
scope_type
prev
=
self
.
scope_type
self
.
scope_type
=
'class'
self
.
scope_type
=
'class'
self
.
classnode
=
node
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
self
.
scope_type
=
prev
self
.
scope_type
=
prev
del
self
.
classnode
return
node
return
node
def
visit_FuncDefNode
(
self
,
node
):
def
visit_FuncDefNode
(
self
,
node
):
...
@@ -130,6 +147,12 @@ class PostParse(CythonTransform):
...
@@ -130,6 +147,12 @@ class PostParse(CythonTransform):
return
node
return
node
# cdef variables
# cdef variables
def
handle_bufferdefaults
(
self
,
decl
):
if
not
isinstance
(
decl
.
default
,
DictNode
):
raise
PostParseError
(
decl
.
pos
,
ERR_BUF_DEFAULTS
)
self
.
classnode
.
buffer_defaults_node
=
decl
.
default
self
.
classnode
.
buffer_defaults_pos
=
decl
.
pos
def
visit_CVarDefNode
(
self
,
node
):
def
visit_CVarDefNode
(
self
,
node
):
# This assumes only plain names and pointers are assignable on
# This assumes only plain names and pointers are assignable on
# declaration. Also, it makes use of the fact that a cdef decl
# declaration. Also, it makes use of the fact that a cdef decl
...
@@ -137,81 +160,39 @@ class PostParse(CythonTransform):
...
@@ -137,81 +160,39 @@ class PostParse(CythonTransform):
# "i = 3; cdef int i = i" and can simply move the nodes around.
# "i = 3; cdef int i = i" and can simply move the nodes around.
try
:
try
:
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
stats
=
[
node
]
newdecls
=
[]
for
decl
in
node
.
declarators
:
declbase
=
decl
while
isinstance
(
declbase
,
CPtrDeclaratorNode
):
declbase
=
declbase
.
base
if
isinstance
(
declbase
,
CNameDeclaratorNode
):
if
declbase
.
default
is
not
None
:
if
self
.
scope_type
==
'class'
:
if
isinstance
(
self
.
classnode
,
CClassDefNode
):
handler
=
self
.
specialattribute_handlers
.
get
(
decl
.
name
)
if
handler
:
if
decl
is
not
declbase
:
raise
PostParseError
(
decl
.
pos
,
ERR_INVALID_SPECIALATTR_TYPE
)
handler
(
decl
)
continue
# Remove declaration
raise
PostParseError
(
decl
.
pos
,
ERR_CDEF_INCLASS
)
stats
.
append
(
SingleAssignmentNode
(
node
.
pos
,
lhs
=
NameNode
(
node
.
pos
,
name
=
declbase
.
name
),
rhs
=
declbase
.
default
,
first
=
True
))
declbase
.
default
=
None
newdecls
.
append
(
decl
)
node
.
declarators
=
newdecls
return
stats
except
PostParseError
,
e
:
except
PostParseError
,
e
:
# An error in a cdef clause is ok, simply remove the declaration
# An error in a cdef clause is ok, simply remove the declaration
# and try to move on to report more errors
# and try to move on to report more errors
self
.
context
.
nonfatal_error
(
e
)
self
.
context
.
nonfatal_error
(
e
)
return
None
return
None
stats
=
[
node
]
for
decl
in
node
.
declarators
:
while
isinstance
(
decl
,
CPtrDeclaratorNode
):
decl
=
decl
.
base
if
isinstance
(
decl
,
CNameDeclaratorNode
):
if
decl
.
default
is
not
None
:
if
self
.
scope_type
==
'class'
:
raise
PostParseError
(
decl
.
pos
,
ERR_CDEF_INCLASS
)
stats
.
append
(
SingleAssignmentNode
(
node
.
pos
,
lhs
=
NameNode
(
node
.
pos
,
name
=
decl
.
name
),
rhs
=
decl
.
default
,
first
=
True
))
decl
.
default
=
None
return
stats
# buffer access
buffer_options
=
(
"dtype"
,
"ndim"
,
"mode"
)
# ordered!
def
visit_CBufferAccessTypeNode
(
self
,
node
):
def
visit_CBufferAccessTypeNode
(
self
,
node
):
if
not
self
.
scope_type
==
'function'
:
if
not
self
.
scope_type
==
'function'
:
raise
PostParseError
(
node
.
pos
,
ERR_BUF_LOCALONLY
)
raise
PostParseError
(
node
.
pos
,
ERR_BUF_LOCALONLY
)
options
=
{}
# Fetch positional arguments
if
len
(
node
.
positional_args
)
>
len
(
self
.
buffer_options
):
raise
PostParseError
(
node
.
pos
,
ERR_BUF_TOO_MANY
)
for
arg
,
unicode_name
in
zip
(
node
.
positional_args
,
self
.
buffer_options
):
name
=
str
(
unicode_name
)
options
[
name
]
=
arg
# Fetch named arguments
for
item
in
node
.
keyword_args
.
key_value_pairs
:
name
=
str
(
item
.
key
.
value
)
if
not
name
in
self
.
buffer_options
:
raise
PostParseError
(
item
.
key
.
pos
,
ERR_BUF_OPTION_UNKNOWN
%
name
)
if
name
in
options
.
keys
():
raise
PostParseError
(
item
.
key
.
pos
,
ERR_BUF_DUP
%
key
)
options
[
name
]
=
item
.
value
# get dtype
dtype
=
options
.
get
(
"dtype"
)
if
dtype
is
None
:
raise
PostParseError
(
node
.
pos
,
ERR_BUF_MISSING
%
'dtype'
)
node
.
dtype_node
=
dtype
# get ndim
if
"ndim"
in
options
:
ndimnode
=
options
[
"ndim"
]
if
not
isinstance
(
ndimnode
,
IntNode
):
# Compile-time values (DEF) are currently resolved by the parser,
# so nothing more to do here
raise
PostParseError
(
ndimnode
.
pos
,
ERR_BUF_INT
%
'ndim'
)
ndim_value
=
int
(
ndimnode
.
value
)
if
ndim_value
<
0
:
raise
PostParseError
(
ndimnode
.
pos
,
ERR_BUF_NONNEG
%
'ndim'
)
node
.
ndim
=
int
(
ndimnode
.
value
)
else
:
node
.
ndim
=
1
if
"mode"
in
options
:
modenode
=
options
[
"mode"
]
if
not
isinstance
(
modenode
,
StringNode
):
raise
PostParseError
(
modenode
.
pos
,
ERR_BUF_MODEHELP
)
mode
=
modenode
.
value
if
not
mode
in
(
'full'
,
'strided'
):
raise
PostParseError
(
modenode
.
pos
,
ERR_BUF_MODEHELP
)
node
.
mode
=
mode
else
:
node
.
mode
=
'full'
# We're done with the parse tree args
node
.
positional_args
=
None
node
.
keyword_args
=
None
return
node
return
node
class
PxdPostParse
(
CythonTransform
):
class
PxdPostParse
(
CythonTransform
):
...
...
Cython/Compiler/PyrexTypes.py
View file @
71433dd7
...
@@ -224,11 +224,13 @@ class PyObjectType(PyrexType):
...
@@ -224,11 +224,13 @@ class PyObjectType(PyrexType):
#
#
# Base class for all Python object types (reference-counted).
# Base class for all Python object types (reference-counted).
#
#
# buffer_defaults dict or None Default options for bu
is_pyobject
=
1
is_pyobject
=
1
default_value
=
"0"
default_value
=
"0"
parsetuple_format
=
"O"
parsetuple_format
=
"O"
pymemberdef_typecode
=
"T_OBJECT"
pymemberdef_typecode
=
"T_OBJECT"
buffer_defaults
=
None
def
__str__
(
self
):
def
__str__
(
self
):
return
"Python object"
return
"Python object"
...
@@ -271,6 +273,7 @@ class BuiltinObjectType(PyObjectType):
...
@@ -271,6 +273,7 @@ class BuiltinObjectType(PyObjectType):
return
"<%s>"
%
self
.
cname
return
"<%s>"
%
self
.
cname
def
assignable_from
(
self
,
src_type
):
def
assignable_from
(
self
,
src_type
):
if
isinstance
(
src_type
,
BuiltinObjectType
):
if
isinstance
(
src_type
,
BuiltinObjectType
):
return
src_type
.
name
==
self
.
name
return
src_type
.
name
==
self
.
name
else
:
else
:
...
...
Cython/Compiler/Symtab.py
View file @
71433dd7
...
@@ -946,7 +946,8 @@ class ModuleScope(Scope):
...
@@ -946,7 +946,8 @@ class ModuleScope(Scope):
def declare_c_class(self, name, pos, defining = 0, implementing = 0,
def declare_c_class(self, name, pos, defining = 0, implementing = 0,
module_name = None, base_type = None, objstruct_cname = None,
module_name = None, base_type = None, objstruct_cname = None,
typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0):
typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
buffer_defaults = None):
#
#
# Look for previous declaration as a type
# Look for previous declaration as a type
#
#
...
@@ -970,6 +971,7 @@ class ModuleScope(Scope):
...
@@ -970,6 +971,7 @@ class ModuleScope(Scope):
if not entry:
if not entry:
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type.pos = pos
type.pos = pos
type.buffer_defaults = buffer_defaults
if visibility == 'extern':
if visibility == 'extern':
type.module_name = module_name
type.module_name = module_name
else:
else:
...
...
Cython/Compiler/Tests/TestBuffer.py
View file @
71433dd7
...
@@ -2,6 +2,7 @@ from Cython.TestUtils import CythonTest
...
@@ -2,6 +2,7 @@ from Cython.TestUtils import CythonTest
import
Cython.Compiler.Errors
as
Errors
import
Cython.Compiler.Errors
as
Errors
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.ParseTreeTransforms
import
*
from
Cython.Compiler.ParseTreeTransforms
import
*
from
Cython.Compiler.Buffer
import
*
class
TestBufferParsing
(
CythonTest
):
class
TestBufferParsing
(
CythonTest
):
...
@@ -49,6 +50,8 @@ class TestBufferParsing(CythonTest):
...
@@ -49,6 +50,8 @@ class TestBufferParsing(CythonTest):
# See also tests/error/e_bufaccess.pyx and tets/run/bufaccess.pyx
# See also tests/error/e_bufaccess.pyx and tets/run/bufaccess.pyx
# THESE TESTS ARE NOW DISABLED, the code they test was pretty much
# refactored away
class
TestBufferOptions
(
CythonTest
):
class
TestBufferOptions
(
CythonTest
):
# Tests the full parsing of the options within the brackets
# Tests the full parsing of the options within the brackets
...
@@ -78,24 +81,24 @@ class TestBufferOptions(CythonTest):
...
@@ -78,24 +81,24 @@ class TestBufferOptions(CythonTest):
# e = self.should_fail(lambda: self.parse_opts(opts))
# e = self.should_fail(lambda: self.parse_opts(opts))
self
.
assertEqual
(
expected_err
,
self
.
error
.
message_only
)
self
.
assertEqual
(
expected_err
,
self
.
error
.
message_only
)
def
test_basic
(
self
):
def
__
test_basic
(
self
):
buf
=
self
.
parse_opts
(
u"unsigned short int, 3"
)
buf
=
self
.
parse_opts
(
u"unsigned short int, 3"
)
self
.
assert_
(
isinstance
(
buf
.
dtype_node
,
CSimpleBaseTypeNode
))
self
.
assert_
(
isinstance
(
buf
.
dtype_node
,
CSimpleBaseTypeNode
))
self
.
assert_
(
buf
.
dtype_node
.
signed
==
0
and
buf
.
dtype_node
.
longness
==
-
1
)
self
.
assert_
(
buf
.
dtype_node
.
signed
==
0
and
buf
.
dtype_node
.
longness
==
-
1
)
self
.
assertEqual
(
3
,
buf
.
ndim
)
self
.
assertEqual
(
3
,
buf
.
ndim
)
def
test_dict
(
self
):
def
__
test_dict
(
self
):
buf
=
self
.
parse_opts
(
u"ndim=3, dtype=unsigned short int"
)
buf
=
self
.
parse_opts
(
u"ndim=3, dtype=unsigned short int"
)
self
.
assert_
(
isinstance
(
buf
.
dtype_node
,
CSimpleBaseTypeNode
))
self
.
assert_
(
isinstance
(
buf
.
dtype_node
,
CSimpleBaseTypeNode
))
self
.
assert_
(
buf
.
dtype_node
.
signed
==
0
and
buf
.
dtype_node
.
longness
==
-
1
)
self
.
assert_
(
buf
.
dtype_node
.
signed
==
0
and
buf
.
dtype_node
.
longness
==
-
1
)
self
.
assertEqual
(
3
,
buf
.
ndim
)
self
.
assertEqual
(
3
,
buf
.
ndim
)
def
test_ndim
(
self
):
def
__
test_ndim
(
self
):
self
.
parse_opts
(
u"int, 2"
)
self
.
parse_opts
(
u"int, 2"
)
self
.
non_parse
(
ERR_BUF_
INT
%
'ndim'
,
u"int, 'a'"
)
self
.
non_parse
(
ERR_BUF_
NDIM
,
u"int, 'a'"
)
self
.
non_parse
(
ERR_BUF_N
ONNEG
%
'ndim'
,
u"int, -34"
)
self
.
non_parse
(
ERR_BUF_N
DIM
,
u"int, -34"
)
def
test_use_DEF
(
self
):
def
__
test_use_DEF
(
self
):
t
=
self
.
fragment
(
u"""
t
=
self
.
fragment
(
u"""
DEF ndim = 3
DEF ndim = 3
def f():
def f():
...
...
tests/errors/e_bufaccess.pyx
View file @
71433dd7
...
@@ -15,11 +15,13 @@ _ERRORS = u"""
...
@@ -15,11 +15,13 @@ _ERRORS = u"""
1:11: Buffer types only allowed as function local variables
1:11: Buffer types only allowed as function local variables
3:15: Buffer types only allowed as function local variables
3:15: Buffer types only allowed as function local variables
6:27: "fakeoption" is not a buffer option
6:27: "fakeoption" is not a buffer option
7:22: "ndim" must be non-negative
8:15: "dtype" missing
9:21: "ndim" must be an integer
10:15: Too many buffer options
11:24: Only allowed buffer modes are "full" or "strided" (as a compile-time string)
12:28: Only allowed buffer modes are "full" or "strided" (as a compile-time string)
"""
"""
#TODO:
#7:22: "ndim" must be non-negative
#8:15: "dtype" missing
#9:21: "ndim" must be an integer
#10:15: Too many buffer options
#11:24: Only allowed buffer modes are "full" or "strided" (as a compile-time string)
#12:28: Only allowed buffer modes are "full" or "strided" (as a compile-time string)
#"""
tests/run/bufaccess.pyx
View file @
71433dd7
...
@@ -894,7 +894,7 @@ cdef class UnsignedShortMockBuffer(MockBuffer):
...
@@ -894,7 +894,7 @@ cdef class UnsignedShortMockBuffer(MockBuffer):
cdef
get_itemsize
(
self
):
return
sizeof
(
unsigned
short
)
cdef
get_itemsize
(
self
):
return
sizeof
(
unsigned
short
)
cdef
get_default_format
(
self
):
return
"=H"
cdef
get_default_format
(
self
):
return
"=H"
cdef
class
IntStridedMockBuffer
(
MockBuffer
):
cdef
class
IntStridedMockBuffer
(
Int
MockBuffer
):
cdef
__cythonbufferdefaults__
=
{
"mode"
:
"strided"
}
cdef
__cythonbufferdefaults__
=
{
"mode"
:
"strided"
}
cdef
class
ErrorBuffer
:
cdef
class
ErrorBuffer
:
...
@@ -946,6 +946,10 @@ def typedbuffer2(IntMockBuffer[int, 1] obj):
...
@@ -946,6 +946,10 @@ def typedbuffer2(IntMockBuffer[int, 1] obj):
@
testcase
@
testcase
def
bufdefaults1
(
IntStridedMockBuffer
[
int
,
1
]
buf
):
def
bufdefaults1
(
IntStridedMockBuffer
[
int
,
1
]
buf
):
"""
"""
For IntStridedMockBuffer, mode should be
"strided" by defaults which should show
up in the flags.
>>> A = IntStridedMockBuffer("A", range(10))
>>> A = IntStridedMockBuffer("A", range(10))
>>> bufdefaults1(A)
>>> bufdefaults1(A)
acquired A
acquired A
...
...
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