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
0527db06
Commit
0527db06
authored
Nov 03, 2014
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ctuple'
parents
28a78cb2
2c104e67
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
698 additions
and
94 deletions
+698
-94
CHANGES.rst
CHANGES.rst
+2
-0
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+4
-4
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+1
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+105
-30
Cython/Compiler/FusedNode.py
Cython/Compiler/FusedNode.py
+2
-2
Cython/Compiler/MemoryView.py
Cython/Compiler/MemoryView.py
+6
-6
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+12
-8
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+160
-9
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+1
-1
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+13
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+161
-27
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+17
-2
Cython/Utility/TypeConversion.c
Cython/Utility/TypeConversion.c
+49
-0
tests/run/arrayassign.pyx
tests/run/arrayassign.pyx
+18
-0
tests/run/ctuple.pyx
tests/run/ctuple.pyx
+142
-0
tests/run/type_inference.pyx
tests/run/type_inference.pyx
+5
-3
No files found.
CHANGES.rst
View file @
0527db06
...
@@ -47,6 +47,8 @@ Features added
...
@@ -47,6 +47,8 @@ Features added
* ``PySlice_*()`` C-API functions are available from the ``cpython.slice``
* ``PySlice_*()`` C-API functions are available from the ``cpython.slice``
module.
module.
* Anonymous C tuple types can be declared as (ctype1, ctype2, ...).
* Allow arrays of C++ classes.
* Allow arrays of C++ classes.
Bugs fixed
Bugs fixed
...
...
Cython/Compiler/Buffer.py
View file @
0527db06
...
@@ -256,7 +256,7 @@ class BufferEntry(object):
...
@@ -256,7 +256,7 @@ class BufferEntry(object):
defcode
=
code
.
globalstate
[
'utility_code_def'
]
defcode
=
code
.
globalstate
[
'utility_code_def'
]
funcgen
(
protocode
,
defcode
,
name
=
funcname
,
nd
=
nd
)
funcgen
(
protocode
,
defcode
,
name
=
funcname
,
nd
=
nd
)
buf_ptr_type_code
=
self
.
buf_ptr_type
.
declaration_code
(
""
)
buf_ptr_type_code
=
self
.
buf_ptr_type
.
empty_declaration_code
(
)
ptrcode
=
"%s(%s, %s, %s)"
%
(
funcname
,
buf_ptr_type_code
,
self
.
buf_ptr
,
ptrcode
=
"%s(%s, %s, %s)"
%
(
funcname
,
buf_ptr_type_code
,
self
.
buf_ptr
,
", "
.
join
(
params
))
", "
.
join
(
params
))
return
ptrcode
return
ptrcode
...
@@ -627,7 +627,7 @@ def mangle_dtype_name(dtype):
...
@@ -627,7 +627,7 @@ def mangle_dtype_name(dtype):
prefix
=
"nn_"
prefix
=
"nn_"
else
:
else
:
prefix
=
""
prefix
=
""
type_decl
=
dtype
.
declaration_code
(
""
)
type_decl
=
dtype
.
empty_declaration_code
(
)
type_decl
=
type_decl
.
replace
(
" "
,
"_"
)
type_decl
=
type_decl
.
replace
(
" "
,
"_"
)
return
prefix
+
type_decl
.
replace
(
"["
,
"_"
).
replace
(
"]"
,
"_"
)
return
prefix
+
type_decl
.
replace
(
"["
,
"_"
).
replace
(
"]"
,
"_"
)
...
@@ -665,7 +665,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -665,7 +665,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
complex_possible
=
dtype
.
is_struct_or_union
and
dtype
.
can_be_complex
()
complex_possible
=
dtype
.
is_struct_or_union
and
dtype
.
can_be_complex
()
declcode
=
dtype
.
declaration_code
(
""
)
declcode
=
dtype
.
empty_declaration_code
(
)
if
dtype
.
is_simple_buffer_dtype
():
if
dtype
.
is_simple_buffer_dtype
():
structinfo_name
=
"NULL"
structinfo_name
=
"NULL"
elif
dtype
.
is_struct
:
elif
dtype
.
is_struct
:
...
@@ -678,7 +678,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
...
@@ -678,7 +678,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
typecode
.
putln
(
"static __Pyx_StructField %s[] = {"
%
structinfo_name
,
safe
=
True
)
typecode
.
putln
(
"static __Pyx_StructField %s[] = {"
%
structinfo_name
,
safe
=
True
)
for
f
,
typeinfo
in
zip
(
fields
,
types
):
for
f
,
typeinfo
in
zip
(
fields
,
types
):
typecode
.
putln
(
' {&%s, "%s", offsetof(%s, %s)},'
%
typecode
.
putln
(
' {&%s, "%s", offsetof(%s, %s)},'
%
(
typeinfo
,
f
.
name
,
dtype
.
declaration_code
(
""
),
f
.
cname
),
safe
=
True
)
(
typeinfo
,
f
.
name
,
dtype
.
empty_declaration_code
(
),
f
.
cname
),
safe
=
True
)
typecode
.
putln
(
' {NULL, NULL, 0}'
,
safe
=
True
)
typecode
.
putln
(
' {NULL, NULL, 0}'
,
safe
=
True
)
typecode
.
putln
(
"};"
,
safe
=
True
)
typecode
.
putln
(
"};"
,
safe
=
True
)
else
:
else
:
...
...
Cython/Compiler/Code.py
View file @
0527db06
...
@@ -369,7 +369,7 @@ class UtilityCode(UtilityCodeBase):
...
@@ -369,7 +369,7 @@ class UtilityCode(UtilityCodeBase):
def specialize(self, pyrex_type=None, **data):
def specialize(self, pyrex_type=None, **data):
# Dicts aren't hashable...
# Dicts aren't hashable...
if pyrex_type is not None:
if pyrex_type is not None:
data['type'] = pyrex_type.
declaration_code(''
)
data['type'] = pyrex_type.
empty_declaration_code(
)
data['type_name'] = pyrex_type.specialization_name()
data['type_name'] = pyrex_type.specialization_name()
key = tuple(sorted(data.items()))
key = tuple(sorted(data.items()))
try:
try:
...
...
Cython/Compiler/ExprNodes.py
View file @
0527db06
...
@@ -819,6 +819,10 @@ class ExprNode(Node):
...
@@ -819,6 +819,10 @@ class ExprNode(Node):
return
self
return
self
elif
type
.
is_pyobject
or
type
.
is_int
or
type
.
is_ptr
or
type
.
is_float
:
elif
type
.
is_pyobject
or
type
.
is_int
or
type
.
is_ptr
or
type
.
is_float
:
return
CoerceToBooleanNode
(
self
,
env
)
return
CoerceToBooleanNode
(
self
,
env
)
elif
type
.
is_ctuple
:
bool_value
=
len
(
type
.
components
)
==
0
return
BoolNode
(
self
.
pos
,
value
=
bool_value
,
constant_result
=
bool_value
)
else
:
else
:
error
(
self
.
pos
,
"Type '%s' not acceptable as a boolean"
%
type
)
error
(
self
.
pos
,
"Type '%s' not acceptable as a boolean"
%
type
)
return
self
return
self
...
@@ -1556,7 +1560,7 @@ class NewExprNode(AtomicExprNode):
...
@@ -1556,7 +1560,7 @@ class NewExprNode(AtomicExprNode):
pass
pass
def
calculate_result_code
(
self
):
def
calculate_result_code
(
self
):
return
"new "
+
self
.
class_type
.
declaration_code
(
""
)
return
"new "
+
self
.
class_type
.
empty_declaration_code
(
)
class
NameNode
(
AtomicExprNode
):
class
NameNode
(
AtomicExprNode
):
...
@@ -2919,6 +2923,12 @@ class IndexNode(ExprNode):
...
@@ -2919,6 +2923,12 @@ class IndexNode(ExprNode):
return
item_type
return
item_type
elif
base_type
.
is_ptr
or
base_type
.
is_array
:
elif
base_type
.
is_ptr
or
base_type
.
is_array
:
return
base_type
.
base_type
return
base_type
.
base_type
elif
base_type
.
is_ctuple
and
isinstance
(
self
.
index
,
IntNode
):
index
=
self
.
index
.
constant_result
if
index
<
0
:
index
+=
base_type
.
size
if
0
<=
index
<
base_type
.
size
:
return
base_type
.
components
[
index
]
if
base_type
.
is_cpp_class
:
if
base_type
.
is_cpp_class
:
class
FakeOperand
:
class
FakeOperand
:
...
@@ -3254,6 +3264,21 @@ class IndexNode(ExprNode):
...
@@ -3254,6 +3264,21 @@ class IndexNode(ExprNode):
error
(
self
.
pos
,
"Wrong number of template arguments: expected %s, got %s"
%
(
error
(
self
.
pos
,
"Wrong number of template arguments: expected %s, got %s"
%
(
(
len
(
base_type
.
templates
),
len
(
self
.
type_indices
))))
(
len
(
base_type
.
templates
),
len
(
self
.
type_indices
))))
self
.
type
=
base_type
.
specialize
(
dict
(
zip
(
base_type
.
templates
,
self
.
type_indices
)))
self
.
type
=
base_type
.
specialize
(
dict
(
zip
(
base_type
.
templates
,
self
.
type_indices
)))
elif
base_type
.
is_ctuple
:
if
isinstance
(
self
.
index
,
IntNode
):
index
=
self
.
index
.
constant_result
if
-
base_type
.
size
<=
index
<
base_type
.
size
:
if
index
<
0
:
index
+=
base_type
.
size
self
.
type
=
base_type
.
components
[
index
]
else
:
error
(
self
.
pos
,
"Index %s out of bounds for '%s'"
%
(
index
,
base_type
))
self
.
type
=
PyrexTypes
.
error_type
else
:
self
.
base
=
self
.
base
.
coerce_to_pyobject
(
env
)
return
self
.
analyse_base_and_index_types
(
env
,
getting
=
getting
,
setting
=
setting
,
analyse_base
=
False
)
else
:
else
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Attempting to index non-array type '%s'"
%
"Attempting to index non-array type '%s'"
%
...
@@ -3435,7 +3460,12 @@ class IndexNode(ExprNode):
...
@@ -3435,7 +3460,12 @@ class IndexNode(ExprNode):
elif
self
.
base
.
type
.
is_cfunction
:
elif
self
.
base
.
type
.
is_cfunction
:
return
"%s<%s>"
%
(
return
"%s<%s>"
%
(
self
.
base
.
result
(),
self
.
base
.
result
(),
","
.
join
([
param
.
declaration_code
(
""
)
for
param
in
self
.
type_indices
]))
","
.
join
([
param
.
empty_declaration_code
()
for
param
in
self
.
type_indices
]))
elif
self
.
base
.
type
.
is_ctuple
:
index
=
self
.
index
.
constant_result
if
index
<
0
:
index
+=
self
.
base
.
type
.
size
return
"%s.f%s"
%
(
self
.
base
.
result
(),
index
)
else
:
else
:
if
(
self
.
type
.
is_ptr
or
self
.
type
.
is_array
)
and
self
.
type
==
self
.
base
.
type
:
if
(
self
.
type
.
is_ptr
or
self
.
type
.
is_array
)
and
self
.
type
==
self
.
base
.
type
:
error
(
self
.
pos
,
"Invalid use of pointer slice"
)
error
(
self
.
pos
,
"Invalid use of pointer slice"
)
...
@@ -3453,7 +3483,7 @@ class IndexNode(ExprNode):
...
@@ -3453,7 +3483,7 @@ class IndexNode(ExprNode):
and
self
.
index
.
constant_result
>=
0
))
and
self
.
index
.
constant_result
>=
0
))
boundscheck
=
bool
(
code
.
globalstate
.
directives
[
'boundscheck'
])
boundscheck
=
bool
(
code
.
globalstate
.
directives
[
'boundscheck'
])
return
", %s, %d, %s, %d, %d, %d"
%
(
return
", %s, %d, %s, %d, %d, %d"
%
(
self
.
original_index_type
.
declaration_code
(
""
),
self
.
original_index_type
.
empty_declaration_code
(
),
self
.
original_index_type
.
signed
and
1
or
0
,
self
.
original_index_type
.
signed
and
1
or
0
,
self
.
original_index_type
.
to_py_function
,
self
.
original_index_type
.
to_py_function
,
is_list
,
wraparound
,
boundscheck
)
is_list
,
wraparound
,
boundscheck
)
...
@@ -4365,7 +4395,7 @@ class CallNode(ExprNode):
...
@@ -4365,7 +4395,7 @@ class CallNode(ExprNode):
constructor
=
type
.
scope
.
lookup
(
"<init>"
)
constructor
=
type
.
scope
.
lookup
(
"<init>"
)
self
.
function
=
RawCNameExprNode
(
self
.
function
.
pos
,
constructor
.
type
)
self
.
function
=
RawCNameExprNode
(
self
.
function
.
pos
,
constructor
.
type
)
self
.
function
.
entry
=
constructor
self
.
function
.
entry
=
constructor
self
.
function
.
set_cname
(
type
.
declaration_code
(
""
))
self
.
function
.
set_cname
(
type
.
empty_declaration_code
(
))
self
.
analyse_c_function_call
(
env
)
self
.
analyse_c_function_call
(
env
)
self
.
type
=
type
self
.
type
=
type
return
True
return
True
...
@@ -4447,7 +4477,7 @@ class SimpleCallNode(CallNode):
...
@@ -4447,7 +4477,7 @@ class SimpleCallNode(CallNode):
func_type
=
self
.
function_type
()
func_type
=
self
.
function_type
()
if
func_type
.
is_pyobject
:
if
func_type
.
is_pyobject
:
self
.
arg_tuple
=
TupleNode
(
self
.
pos
,
args
=
self
.
args
)
self
.
arg_tuple
=
TupleNode
(
self
.
pos
,
args
=
self
.
args
)
self
.
arg_tuple
=
self
.
arg_tuple
.
analyse_types
(
env
)
self
.
arg_tuple
=
self
.
arg_tuple
.
analyse_types
(
env
)
.
coerce_to_pyobject
(
env
)
self
.
args
=
None
self
.
args
=
None
if
func_type
is
Builtin
.
type_type
and
function
.
is_name
and
\
if
func_type
is
Builtin
.
type_type
and
function
.
is_name
and
\
function
.
entry
and
\
function
.
entry
and
\
...
@@ -6070,6 +6100,10 @@ class SequenceNode(ExprNode):
...
@@ -6070,6 +6100,10 @@ class SequenceNode(ExprNode):
', '
.
join
([
arg
.
py_result
()
for
arg
in
self
.
args
]),
', '
.
join
([
arg
.
py_result
()
for
arg
in
self
.
args
]),
code
.
error_goto_if_null
(
target
,
self
.
pos
)))
code
.
error_goto_if_null
(
target
,
self
.
pos
)))
code
.
put_gotref
(
target
)
code
.
put_gotref
(
target
)
elif
self
.
type
.
is_ctuple
:
for
i
,
arg
in
enumerate
(
self
.
args
):
code
.
putln
(
"%s.f%s = %s;"
%
(
target
,
i
,
arg
.
result
()))
else
:
else
:
# build the tuple/list step by step, potentially multiplying it as we go
# build the tuple/list step by step, potentially multiplying it as we go
if
self
.
type
is
Builtin
.
list_type
:
if
self
.
type
is
Builtin
.
list_type
:
...
@@ -6443,27 +6477,61 @@ class TupleNode(SequenceNode):
...
@@ -6443,27 +6477,61 @@ class TupleNode(SequenceNode):
gil_message
=
"Constructing Python tuple"
gil_message
=
"Constructing Python tuple"
def
infer_type
(
self
,
env
):
if
self
.
mult_factor
or
not
self
.
args
:
return
tuple_type
arg_types
=
[
arg
.
infer_type
(
env
)
for
arg
in
self
.
args
]
if
any
(
type
.
is_pyobject
or
type
.
is_unspecified
or
type
.
is_fused
for
type
in
arg_types
):
return
tuple_type
else
:
type
=
PyrexTypes
.
c_tuple_type
(
arg_types
)
env
.
declare_tuple_type
(
self
.
pos
,
type
)
return
type
def
analyse_types
(
self
,
env
,
skip_children
=
False
):
def
analyse_types
(
self
,
env
,
skip_children
=
False
):
if
len
(
self
.
args
)
==
0
:
if
len
(
self
.
args
)
==
0
:
node
=
self
self
.
is_temp
=
False
node
.
is_temp
=
Fals
e
self
.
is_literal
=
Tru
e
node
.
is_literal
=
True
return
self
else
:
else
:
node
=
SequenceNode
.
analyse_types
(
self
,
env
,
skip_children
)
if
not
skip_children
:
for
child
in
node
.
args
:
self
.
args
=
[
arg
.
analyse_types
(
env
)
for
arg
in
self
.
args
]
if
not
child
.
is_literal
:
if
not
self
.
mult_factor
and
not
any
(
arg
.
type
.
is_pyobject
or
arg
.
type
.
is_fused
for
arg
in
self
.
args
):
break
self
.
type
=
PyrexTypes
.
c_tuple_type
(
arg
.
type
for
arg
in
self
.
args
)
env
.
declare_tuple_type
(
self
.
pos
,
self
.
type
)
self
.
is_temp
=
1
return
self
else
:
else
:
if
not
node
.
mult_factor
or
node
.
mult_factor
.
is_literal
and
\
node
=
SequenceNode
.
analyse_types
(
self
,
env
,
skip_children
=
True
)
isinstance
(
node
.
mult_factor
.
constant_result
,
(
int
,
long
))
:
for
child
in
node
.
args
:
node
.
is_temp
=
False
if
not
child
.
is_literal
:
node
.
is_literal
=
True
break
else
:
else
:
if
not
node
.
mult_factor
.
type
.
is_pyobject
:
if
not
node
.
mult_factor
or
node
.
mult_factor
.
is_literal
and
\
node
.
mult_factor
=
node
.
mult_factor
.
coerce_to_pyobject
(
env
)
isinstance
(
node
.
mult_factor
.
constant_result
,
(
int
,
long
)):
node
.
is_temp
=
True
node
.
is_temp
=
False
node
.
is_partly_literal
=
True
node
.
is_literal
=
True
return
node
else
:
if
not
node
.
mult_factor
.
type
.
is_pyobject
:
node
.
mult_factor
=
node
.
mult_factor
.
coerce_to_pyobject
(
env
)
node
.
is_temp
=
True
node
.
is_partly_literal
=
True
return
node
def
coerce_to
(
self
,
dst_type
,
env
):
if
self
.
type
.
is_ctuple
:
if
dst_type
.
is_ctuple
and
self
.
type
.
size
==
dst_type
.
size
:
if
self
.
type
==
dst_type
:
return
self
coerced_args
=
[
arg
.
coerce_to
(
type
,
env
)
for
arg
,
type
in
zip
(
self
.
args
,
dst_type
.
components
)]
return
TupleNode
(
self
.
pos
,
args
=
coerced_args
,
type
=
dst_type
,
is_temp
=
1
)
elif
dst_type
is
tuple_type
or
dst_type
is
py_object_type
:
coerced_args
=
[
arg
.
coerce_to_pyobject
(
env
)
for
arg
in
self
.
args
]
return
TupleNode
(
self
.
pos
,
args
=
coerced_args
,
type
=
tuple_type
,
is_temp
=
1
).
analyse_types
(
env
,
skip_children
=
True
)
else
:
return
self
.
coerce_to_pyobject
(
env
).
coerce_to
(
dst_type
,
env
)
else
:
return
SequenceNode
.
coerce_to
(
self
,
dst_type
,
env
)
def
is_simple
(
self
):
def
is_simple
(
self
):
# either temp or constant => always simple
# either temp or constant => always simple
...
@@ -6515,6 +6583,7 @@ class TupleNode(SequenceNode):
...
@@ -6515,6 +6583,7 @@ class TupleNode(SequenceNode):
self
.
generate_sequence_packing_code
(
code
)
self
.
generate_sequence_packing_code
(
code
)
code
.
put_giveref
(
self
.
py_result
())
code
.
put_giveref
(
self
.
py_result
())
else
:
else
:
self
.
type
.
entry
.
used
=
True
self
.
generate_sequence_packing_code
(
code
)
self
.
generate_sequence_packing_code
(
code
)
...
@@ -8029,6 +8098,9 @@ class DefaultsTupleNode(TupleNode):
...
@@ -8029,6 +8098,9 @@ class DefaultsTupleNode(TupleNode):
args
.
append
(
arg
)
args
.
append
(
arg
)
super
(
DefaultsTupleNode
,
self
).
__init__
(
pos
,
args
=
args
)
super
(
DefaultsTupleNode
,
self
).
__init__
(
pos
,
args
=
args
)
def
analyse_types
(
self
,
env
,
skip_children
=
False
):
return
super
(
DefaultsTupleNode
,
self
).
analyse_types
(
env
,
skip_children
).
coerce_to_pyobject
(
env
)
class
DefaultsKwDictNode
(
DictNode
):
class
DefaultsKwDictNode
(
DictNode
):
# CyFunction's __kwdefaults__ dict
# CyFunction's __kwdefaults__ dict
...
@@ -8382,7 +8454,7 @@ class UnopNode(ExprNode):
...
@@ -8382,7 +8454,7 @@ class UnopNode(ExprNode):
return
self
.
operand
.
check_const
()
return
self
.
operand
.
check_const
()
def
is_py_operation
(
self
):
def
is_py_operation
(
self
):
return
self
.
operand
.
type
.
is_pyobject
return
self
.
operand
.
type
.
is_pyobject
or
self
.
operand
.
type
.
is_ctuple
def
nogil_check
(
self
,
env
):
def
nogil_check
(
self
,
env
):
if
self
.
is_py_operation
():
if
self
.
is_py_operation
():
...
@@ -8949,7 +9021,7 @@ class CythonArrayNode(ExprNode):
...
@@ -8949,7 +9021,7 @@ class CythonArrayNode(ExprNode):
shapes_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
shapes_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
format_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
format_temp
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
True
)
itemsize
=
"sizeof(%s)"
%
dtype
.
declaration_code
(
""
)
itemsize
=
"sizeof(%s)"
%
dtype
.
empty_declaration_code
(
)
type_info
=
Buffer
.
get_type_information_cname
(
code
,
dtype
)
type_info
=
Buffer
.
get_type_information_cname
(
code
,
dtype
)
if
self
.
operand
.
type
.
is_ptr
:
if
self
.
operand
.
type
.
is_ptr
:
...
@@ -9069,7 +9141,7 @@ class SizeofTypeNode(SizeofNode):
...
@@ -9069,7 +9141,7 @@ class SizeofTypeNode(SizeofNode):
# we want the size of the actual struct
# we want the size of the actual struct
arg_code
=
self
.
arg_type
.
declaration_code
(
""
,
deref
=
1
)
arg_code
=
self
.
arg_type
.
declaration_code
(
""
,
deref
=
1
)
else
:
else
:
arg_code
=
self
.
arg_type
.
declaration_code
(
""
)
arg_code
=
self
.
arg_type
.
empty_declaration_code
(
)
return
"(sizeof(%s))"
%
arg_code
return
"(sizeof(%s))"
%
arg_code
...
@@ -9236,7 +9308,7 @@ class BinopNode(ExprNode):
...
@@ -9236,7 +9308,7 @@ class BinopNode(ExprNode):
return
self
.
is_py_operation_types
(
self
.
operand1
.
type
,
self
.
operand2
.
type
)
return
self
.
is_py_operation_types
(
self
.
operand1
.
type
,
self
.
operand2
.
type
)
def
is_py_operation_types
(
self
,
type1
,
type2
):
def
is_py_operation_types
(
self
,
type1
,
type2
):
return
type1
.
is_pyobject
or
type2
.
is_pyobject
return
type1
.
is_pyobject
or
type2
.
is_pyobject
or
type1
.
is_ctuple
or
type2
.
is_ctuple
def
is_cpp_operation
(
self
):
def
is_cpp_operation
(
self
):
return
(
self
.
operand1
.
type
.
is_cpp_class
return
(
self
.
operand1
.
type
.
is_cpp_class
...
@@ -9697,12 +9769,12 @@ class DivNode(NumBinopNode):
...
@@ -9697,12 +9769,12 @@ class DivNode(NumBinopNode):
# explicitly signed, no runtime check needed
# explicitly signed, no runtime check needed
minus1_check
=
'unlikely(%s == -1)'
%
self
.
operand2
.
result
()
minus1_check
=
'unlikely(%s == -1)'
%
self
.
operand2
.
result
()
else
:
else
:
type_of_op2
=
self
.
operand2
.
type
.
declaration_code
(
''
)
type_of_op2
=
self
.
operand2
.
type
.
empty_declaration_code
(
)
minus1_check
=
'(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)'
%
(
minus1_check
=
'(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)'
%
(
type_of_op2
,
self
.
operand2
.
result
(),
type_of_op2
)
type_of_op2
,
self
.
operand2
.
result
(),
type_of_op2
)
code
.
putln
(
"else if (sizeof(%s) == sizeof(long) && %s "
code
.
putln
(
"else if (sizeof(%s) == sizeof(long) && %s "
" && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {"
%
(
" && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {"
%
(
self
.
type
.
declaration_code
(
''
),
self
.
type
.
empty_declaration_code
(
),
minus1_check
,
minus1_check
,
self
.
operand1
.
result
()))
self
.
operand1
.
result
()))
code
.
put_ensure_gil
()
code
.
put_ensure_gil
()
...
@@ -9850,11 +9922,11 @@ class PowNode(NumBinopNode):
...
@@ -9850,11 +9922,11 @@ class PowNode(NumBinopNode):
elif
self
.
type
.
is_float
:
elif
self
.
type
.
is_float
:
self
.
pow_func
=
"pow"
+
self
.
type
.
math_h_modifier
self
.
pow_func
=
"pow"
+
self
.
type
.
math_h_modifier
elif
self
.
type
.
is_int
:
elif
self
.
type
.
is_int
:
self
.
pow_func
=
"__Pyx_pow_%s"
%
self
.
type
.
declaration_code
(
''
).
replace
(
' '
,
'_'
)
self
.
pow_func
=
"__Pyx_pow_%s"
%
self
.
type
.
empty_declaration_code
(
).
replace
(
' '
,
'_'
)
env
.
use_utility_code
(
env
.
use_utility_code
(
int_pow_utility_code
.
specialize
(
int_pow_utility_code
.
specialize
(
func_name
=
self
.
pow_func
,
func_name
=
self
.
pow_func
,
type
=
self
.
type
.
declaration_code
(
''
),
type
=
self
.
type
.
empty_declaration_code
(
),
signed
=
self
.
type
.
signed
and
1
or
0
))
signed
=
self
.
type
.
signed
and
1
or
0
))
elif
not
self
.
type
.
is_error
:
elif
not
self
.
type
.
is_error
:
error
(
self
.
pos
,
"got unexpected types for C power operator: %s, %s"
%
error
(
self
.
pos
,
"got unexpected types for C power operator: %s, %s"
%
...
@@ -10355,7 +10427,10 @@ class CmpNode(object):
...
@@ -10355,7 +10427,10 @@ class CmpNode(object):
if
new_common_type
is
None
:
if
new_common_type
is
None
:
# fall back to generic type compatibility tests
# fall back to generic type compatibility tests
if
type1
==
type2
:
if
type1
==
type2
:
new_common_type
=
type1
if
type1
.
is_ctuple
:
new_common_type
=
py_object_type
else
:
new_common_type
=
type1
elif
type1
.
is_pyobject
or
type2
.
is_pyobject
:
elif
type1
.
is_pyobject
or
type2
.
is_pyobject
:
if
type2
.
is_numeric
or
type2
.
is_string
:
if
type2
.
is_numeric
or
type2
.
is_string
:
if
operand2
.
check_for_coercion_error
(
type1
,
env
):
if
operand2
.
check_for_coercion_error
(
type1
,
env
):
...
...
Cython/Compiler/FusedNode.py
View file @
0527db06
...
@@ -481,7 +481,7 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -481,7 +481,7 @@ class FusedCFuncDefNode(StatListNode):
# self._dtype_name(dtype)))
# self._dtype_name(dtype)))
decl_code
.
putln
(
'ctypedef %s %s "%s"'
%
(
dtype
.
resolve
(),
decl_code
.
putln
(
'ctypedef %s %s "%s"'
%
(
dtype
.
resolve
(),
self
.
_dtype_name
(
dtype
),
self
.
_dtype_name
(
dtype
),
dtype
.
declaration_code
(
""
)))
dtype
.
empty_declaration_code
(
)))
if
buffer_type
.
dtype
.
is_int
:
if
buffer_type
.
dtype
.
is_int
:
if
str
(
dtype
)
not
in
seen_int_dtypes
:
if
str
(
dtype
)
not
in
seen_int_dtypes
:
...
@@ -729,7 +729,7 @@ class FusedCFuncDefNode(StatListNode):
...
@@ -729,7 +729,7 @@ class FusedCFuncDefNode(StatListNode):
if
self
.
py_func
:
if
self
.
py_func
:
args
=
[
CloneNode
(
default
)
for
default
in
defaults
if
default
]
args
=
[
CloneNode
(
default
)
for
default
in
defaults
if
default
]
self
.
defaults_tuple
=
TupleNode
(
self
.
pos
,
args
=
args
)
self
.
defaults_tuple
=
TupleNode
(
self
.
pos
,
args
=
args
)
self
.
defaults_tuple
=
self
.
defaults_tuple
.
analyse_types
(
env
,
skip_children
=
True
)
self
.
defaults_tuple
=
self
.
defaults_tuple
.
analyse_types
(
env
,
skip_children
=
True
)
.
coerce_to_pyobject
(
env
)
self
.
defaults_tuple
=
ProxyNode
(
self
.
defaults_tuple
)
self
.
defaults_tuple
=
ProxyNode
(
self
.
defaults_tuple
)
self
.
code_object
=
ProxyNode
(
self
.
specialized_pycfuncs
[
0
].
code_object
)
self
.
code_object
=
ProxyNode
(
self
.
specialized_pycfuncs
[
0
].
code_object
)
...
...
Cython/Compiler/MemoryView.py
View file @
0527db06
...
@@ -237,7 +237,7 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
...
@@ -237,7 +237,7 @@ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
def
_generate_buffer_lookup_code
(
self
,
code
,
axes
,
cast_result
=
True
):
def
_generate_buffer_lookup_code
(
self
,
code
,
axes
,
cast_result
=
True
):
bufp
=
self
.
buf_ptr
bufp
=
self
.
buf_ptr
type_decl
=
self
.
type
.
dtype
.
declaration_code
(
""
)
type_decl
=
self
.
type
.
dtype
.
empty_declaration_code
(
)
for
dim
,
index
,
access
,
packing
in
axes
:
for
dim
,
index
,
access
,
packing
in
axes
:
shape
=
"%s.shape[%d]"
%
(
self
.
cname
,
dim
)
shape
=
"%s.shape[%d]"
%
(
self
.
cname
,
dim
)
...
@@ -467,7 +467,7 @@ def copy_broadcast_memview_src_to_dst(src, dst, code):
...
@@ -467,7 +467,7 @@ def copy_broadcast_memview_src_to_dst(src, dst, code):
def
get_1d_fill_scalar_func
(
type
,
code
):
def
get_1d_fill_scalar_func
(
type
,
code
):
dtype
=
type
.
dtype
dtype
=
type
.
dtype
type_decl
=
dtype
.
declaration_code
(
""
)
type_decl
=
dtype
.
empty_declaration_code
(
)
dtype_name
=
mangle_dtype_name
(
dtype
)
dtype_name
=
mangle_dtype_name
(
dtype
)
context
=
dict
(
dtype_name
=
dtype_name
,
type_decl
=
type_decl
)
context
=
dict
(
dtype_name
=
dtype_name
,
type_decl
=
type_decl
)
...
@@ -482,8 +482,8 @@ def assign_scalar(dst, scalar, code):
...
@@ -482,8 +482,8 @@ def assign_scalar(dst, scalar, code):
"""
"""
verify_direct_dimensions
(
dst
)
verify_direct_dimensions
(
dst
)
dtype
=
dst
.
type
.
dtype
dtype
=
dst
.
type
.
dtype
type_decl
=
dtype
.
declaration_code
(
""
)
type_decl
=
dtype
.
empty_declaration_code
(
)
slice_decl
=
dst
.
type
.
declaration_code
(
""
)
slice_decl
=
dst
.
type
.
empty_declaration_code
(
)
code
.
begin_block
()
code
.
begin_block
()
code
.
putln
(
"%s __pyx_temp_scalar = %s;"
%
(
type_decl
,
scalar
.
result
()))
code
.
putln
(
"%s __pyx_temp_scalar = %s;"
%
(
type_decl
,
scalar
.
result
()))
...
@@ -527,7 +527,7 @@ class ContigSliceIter(SliceIter):
...
@@ -527,7 +527,7 @@ class ContigSliceIter(SliceIter):
code
=
self
.
code
code
=
self
.
code
code
.
begin_block
()
code
.
begin_block
()
type_decl
=
self
.
slice_type
.
dtype
.
declaration_code
(
""
)
type_decl
=
self
.
slice_type
.
dtype
.
empty_declaration_code
(
)
total_size
=
' * '
.
join
(
"%s.shape[%d]"
%
(
self
.
slice_temp
,
i
)
total_size
=
' * '
.
join
(
"%s.shape[%d]"
%
(
self
.
slice_temp
,
i
)
for
i
in
range
(
self
.
ndim
))
for
i
in
range
(
self
.
ndim
))
...
@@ -613,7 +613,7 @@ def get_copy_new_utility(pos, from_memview, to_memview):
...
@@ -613,7 +613,7 @@ def get_copy_new_utility(pos, from_memview, to_memview):
context
=
dict
(
context
=
dict
(
context
,
context
,
mode
=
mode
,
mode
=
mode
,
dtype_decl
=
to_memview
.
dtype
.
declaration_code
(
''
),
dtype_decl
=
to_memview
.
dtype
.
empty_declaration_code
(
),
contig_flag
=
contig_flag
,
contig_flag
=
contig_flag
,
ndim
=
to_memview
.
ndim
,
ndim
=
to_memview
.
ndim
,
func_cname
=
copy_c_or_fortran_cname
(
to_memview
),
func_cname
=
copy_c_or_fortran_cname
(
to_memview
),
...
...
Cython/Compiler/ModuleNode.py
View file @
0527db06
...
@@ -251,7 +251,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -251,7 +251,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
%
(
entry
.
name
,
cname
,
sig
))
%
(
entry
.
name
,
cname
,
sig
))
for
entry
in
api_vars
:
for
entry
in
api_vars
:
cname
=
env
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
cname
=
env
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
sig
=
entry
.
type
.
declaration_code
(
""
)
sig
=
entry
.
type
.
empty_declaration_code
(
)
h_code
.
putln
(
h_code
.
putln
(
'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
cname
,
sig
))
%
(
entry
.
name
,
cname
,
sig
))
...
@@ -721,6 +721,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -721,6 +721,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
pass
pass
elif
type
.
is_struct_or_union
or
type
.
is_cpp_class
:
elif
type
.
is_struct_or_union
or
type
.
is_cpp_class
:
self
.
generate_struct_union_predeclaration
(
entry
,
code
)
self
.
generate_struct_union_predeclaration
(
entry
,
code
)
elif
type
.
is_ctuple
and
entry
.
used
:
self
.
generate_struct_union_predeclaration
(
entry
.
type
.
struct_entry
,
code
)
elif
type
.
is_extension_type
:
elif
type
.
is_extension_type
:
self
.
generate_objstruct_predeclaration
(
type
,
code
)
self
.
generate_objstruct_predeclaration
(
type
,
code
)
# Actual declarations
# Actual declarations
...
@@ -734,6 +736,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -734,6 +736,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_enum_definition
(
entry
,
code
)
self
.
generate_enum_definition
(
entry
,
code
)
elif
type
.
is_struct_or_union
:
elif
type
.
is_struct_or_union
:
self
.
generate_struct_union_definition
(
entry
,
code
)
self
.
generate_struct_union_definition
(
entry
,
code
)
elif
type
.
is_ctuple
and
entry
.
used
:
self
.
generate_struct_union_definition
(
entry
.
type
.
struct_entry
,
code
)
elif
type
.
is_cpp_class
:
elif
type
.
is_cpp_class
:
self
.
generate_cpp_class_definition
(
entry
,
code
)
self
.
generate_cpp_class_definition
(
entry
,
code
)
elif
type
.
is_extension_type
:
elif
type
.
is_extension_type
:
...
@@ -776,7 +780,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -776,7 +780,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_struct_union_predeclaration
(
self
,
entry
,
code
):
def
generate_struct_union_predeclaration
(
self
,
entry
,
code
):
type
=
entry
.
type
type
=
entry
.
type
if
type
.
is_cpp_class
and
type
.
templates
:
if
type
.
is_cpp_class
and
type
.
templates
:
code
.
putln
(
"template <typename %s>"
%
", typename "
.
join
([
T
.
declaration_code
(
""
)
for
T
in
type
.
templates
]))
code
.
putln
(
"template <typename %s>"
%
", typename "
.
join
([
T
.
empty_declaration_code
(
)
for
T
in
type
.
templates
]))
code
.
putln
(
self
.
sue_predeclaration
(
type
,
type
.
kind
,
type
.
cname
))
code
.
putln
(
self
.
sue_predeclaration
(
type
,
type
.
kind
,
type
.
cname
))
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
...
@@ -826,12 +830,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -826,12 +830,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
scope
=
type
.
scope
scope
=
type
.
scope
if
scope
:
if
scope
:
if
type
.
templates
:
if
type
.
templates
:
code
.
putln
(
"template <class %s>"
%
", class "
.
join
([
T
.
declaration_code
(
""
)
for
T
in
type
.
templates
]))
code
.
putln
(
"template <class %s>"
%
", class "
.
join
([
T
.
empty_declaration_code
(
)
for
T
in
type
.
templates
]))
# Just let everything be public.
# Just let everything be public.
code
.
put
(
"struct %s"
%
type
.
cname
)
code
.
put
(
"struct %s"
%
type
.
cname
)
if
type
.
base_classes
:
if
type
.
base_classes
:
base_class_decl
=
", public "
.
join
(
base_class_decl
=
", public "
.
join
(
[
base_class
.
declaration_code
(
""
)
for
base_class
in
type
.
base_classes
])
[
base_class
.
empty_declaration_code
(
)
for
base_class
in
type
.
base_classes
])
code
.
put
(
" : public %s"
%
base_class_decl
)
code
.
put
(
" : public %s"
%
base_class_decl
)
code
.
putln
(
" {"
)
code
.
putln
(
" {"
)
has_virtual_methods
=
False
has_virtual_methods
=
False
...
@@ -1124,7 +1128,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1124,7 +1128,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
code
.
putln
(
"%s = (%s)o;"
%
(
"%s = (%s)o;"
%
(
type
.
declaration_code
(
"p"
),
type
.
declaration_code
(
"p"
),
type
.
declaration_code
(
""
)))
type
.
empty_declaration_code
(
)))
def
generate_new_function
(
self
,
scope
,
code
,
cclass_entry
):
def
generate_new_function
(
self
,
scope
,
code
,
cclass_entry
):
tp_slot
=
TypeSlots
.
ConstructorSlot
(
"tp_new"
,
'__new__'
)
tp_slot
=
TypeSlots
.
ConstructorSlot
(
"tp_new"
,
'__new__'
)
...
@@ -1226,7 +1230,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1226,7 +1230,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
entry
in
cpp_class_attrs
:
for
entry
in
cpp_class_attrs
:
code
.
putln
(
"new((void*)&(p->%s)) %s();"
%
code
.
putln
(
"new((void*)&(p->%s)) %s();"
%
(
entry
.
cname
,
entry
.
type
.
declaration_code
(
""
)))
(
entry
.
cname
,
entry
.
type
.
empty_declaration_code
(
)))
for
entry
in
py_attrs
:
for
entry
in
py_attrs
:
code
.
put_init_var_to_py_none
(
entry
,
"p->%s"
,
nanny
=
False
)
code
.
put_init_var_to_py_none
(
entry
,
"p->%s"
,
nanny
=
False
)
...
@@ -2427,7 +2431,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -2427,7 +2431,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
entries
:
if
entries
:
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"VoidPtrExport"
,
"ImportExport.c"
))
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"VoidPtrExport"
,
"ImportExport.c"
))
for
entry
in
entries
:
for
entry
in
entries
:
signature
=
entry
.
type
.
declaration_code
(
""
)
signature
=
entry
.
type
.
empty_declaration_code
(
)
name
=
code
.
intern_identifier
(
entry
.
name
)
name
=
code
.
intern_identifier
(
entry
.
name
)
code
.
putln
(
'if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s'
%
(
code
.
putln
(
'if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s'
%
(
name
,
entry
.
cname
,
signature
,
name
,
entry
.
cname
,
signature
,
...
@@ -2495,7 +2499,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -2495,7 +2499,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
cname
=
entry
.
cname
cname
=
entry
.
cname
else
:
else
:
cname
=
module
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
cname
=
module
.
mangle
(
Naming
.
varptr_prefix
,
entry
.
name
)
signature
=
entry
.
type
.
declaration_code
(
""
)
signature
=
entry
.
type
.
empty_declaration_code
(
)
code
.
putln
(
code
.
putln
(
'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s'
%
(
'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s'
%
(
temp
,
entry
.
name
,
cname
,
signature
,
temp
,
entry
.
name
,
cname
,
signature
,
...
...
Cython/Compiler/Nodes.py
View file @
0527db06
...
@@ -832,7 +832,7 @@ class CArgDeclNode(Node):
...
@@ -832,7 +832,7 @@ class CArgDeclNode(Node):
if
self
.
base_type
.
is_basic_c_type
:
if
self
.
base_type
.
is_basic_c_type
:
# char, short, long called "int"
# char, short, long called "int"
type
=
self
.
base_type
.
analyse
(
env
,
could_be_name
=
True
)
type
=
self
.
base_type
.
analyse
(
env
,
could_be_name
=
True
)
arg_name
=
type
.
declaration_code
(
""
)
arg_name
=
type
.
empty_declaration_code
(
)
else
:
else
:
arg_name
=
self
.
base_type
.
name
arg_name
=
self
.
base_type
.
name
self
.
declarator
.
name
=
EncodedString
(
arg_name
)
self
.
declarator
.
name
=
EncodedString
(
arg_name
)
...
@@ -1165,6 +1165,25 @@ class CComplexBaseTypeNode(CBaseTypeNode):
...
@@ -1165,6 +1165,25 @@ class CComplexBaseTypeNode(CBaseTypeNode):
return
type
return
type
class
CTupleBaseTypeNode
(
CBaseTypeNode
):
# components [CBaseTypeNode]
child_attrs
=
[
"components"
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
component_types
=
[]
for
c
in
self
.
components
:
type
=
c
.
analyse
(
env
)
if
type
.
is_pyobject
:
error
(
type_node
.
pos
,
"Tuple types can't (yet) contain Python objects."
)
return
PyrexType
.
error_type
component_types
.
append
(
type
)
type
=
PyrexTypes
.
c_tuple_type
(
component_types
)
entry
=
env
.
declare_tuple_type
(
self
.
pos
,
type
)
entry
.
used
=
True
return
type
class
FusedTypeNode
(
CBaseTypeNode
):
class
FusedTypeNode
(
CBaseTypeNode
):
"""
"""
Represents a fused type in a ctypedef statement:
Represents a fused type in a ctypedef statement:
...
@@ -1184,7 +1203,7 @@ class FusedTypeNode(CBaseTypeNode):
...
@@ -1184,7 +1203,7 @@ class FusedTypeNode(CBaseTypeNode):
# Omit the typedef declaration that self.declarator would produce
# Omit the typedef declaration that self.declarator would produce
entry
.
in_cinclude
=
True
entry
.
in_cinclude
=
True
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
types
=
[]
types
=
[]
for
type_node
in
self
.
types
:
for
type_node
in
self
.
types
:
type
=
type_node
.
analyse_as_type
(
env
)
type
=
type_node
.
analyse_as_type
(
env
)
...
@@ -1793,7 +1812,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1793,7 +1812,7 @@ class FuncDefNode(StatNode, BlockNode):
slot_func_cname
=
'%s->tp_new'
%
lenv
.
scope_class
.
type
.
typeptr_cname
slot_func_cname
=
'%s->tp_new'
%
lenv
.
scope_class
.
type
.
typeptr_cname
code
.
putln
(
"%s = (%s)%s(%s, %s, NULL);"
%
(
code
.
putln
(
"%s = (%s)%s(%s, %s, NULL);"
%
(
Naming
.
cur_scope_cname
,
Naming
.
cur_scope_cname
,
lenv
.
scope_class
.
type
.
declaration_code
(
''
),
lenv
.
scope_class
.
type
.
empty_declaration_code
(
),
slot_func_cname
,
slot_func_cname
,
lenv
.
scope_class
.
type
.
typeptr_cname
,
lenv
.
scope_class
.
type
.
typeptr_cname
,
Naming
.
empty_tuple
))
Naming
.
empty_tuple
))
...
@@ -1815,12 +1834,12 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1815,12 +1834,12 @@ class FuncDefNode(StatNode, BlockNode):
if
self
.
is_cyfunction
:
if
self
.
is_cyfunction
:
code
.
putln
(
"%s = (%s) __Pyx_CyFunction_GetClosure(%s);"
%
(
code
.
putln
(
"%s = (%s) __Pyx_CyFunction_GetClosure(%s);"
%
(
outer_scope_cname
,
outer_scope_cname
,
cenv
.
scope_class
.
type
.
declaration_code
(
''
),
cenv
.
scope_class
.
type
.
empty_declaration_code
(
),
Naming
.
self_cname
))
Naming
.
self_cname
))
else
:
else
:
code
.
putln
(
"%s = (%s) %s;"
%
(
code
.
putln
(
"%s = (%s) %s;"
%
(
outer_scope_cname
,
outer_scope_cname
,
cenv
.
scope_class
.
type
.
declaration_code
(
''
),
cenv
.
scope_class
.
type
.
empty_declaration_code
(
),
Naming
.
self_cname
))
Naming
.
self_cname
))
if
lenv
.
is_passthrough
:
if
lenv
.
is_passthrough
:
code
.
putln
(
"%s = %s;"
%
(
Naming
.
cur_scope_cname
,
outer_scope_cname
))
code
.
putln
(
"%s = %s;"
%
(
Naming
.
cur_scope_cname
,
outer_scope_cname
))
...
@@ -4657,7 +4676,7 @@ class AssignmentNode(StatNode):
...
@@ -4657,7 +4676,7 @@ class AssignmentNode(StatNode):
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
node
=
self
.
analyse_types
(
env
)
node
=
self
.
analyse_types
(
env
)
if
isinstance
(
node
,
AssignmentNode
):
if
isinstance
(
node
,
AssignmentNode
)
and
not
isinstance
(
node
,
ParallelAssignmentNode
)
:
if
node
.
rhs
.
type
.
is_ptr
and
node
.
rhs
.
is_ephemeral
():
if
node
.
rhs
.
type
.
is_ptr
and
node
.
rhs
.
is_ephemeral
():
error
(
self
.
pos
,
"Storing unsafe C derivative of temporary Python reference"
)
error
(
self
.
pos
,
"Storing unsafe C derivative of temporary Python reference"
)
return
node
return
node
...
@@ -4763,11 +4782,19 @@ class SingleAssignmentNode(AssignmentNode):
...
@@ -4763,11 +4782,19 @@ class SingleAssignmentNode(AssignmentNode):
self
.
lhs
.
analyse_target_declaration
(
env
)
self
.
lhs
.
analyse_target_declaration
(
env
)
def
analyse_types
(
self
,
env
,
use_temp
=
0
):
def
analyse_types
(
self
,
env
,
use_temp
=
0
):
from
.
import
ExprNodes
from
.
import
ExprNodes
,
UtilNodes
self
.
rhs
=
self
.
rhs
.
analyse_types
(
env
)
self
.
rhs
=
self
.
rhs
.
analyse_types
(
env
)
unrolled_assignment
=
self
.
unroll_rhs
(
env
)
if
unrolled_assignment
:
return
unrolled_assignment
self
.
lhs
=
self
.
lhs
.
analyse_target_types
(
env
)
self
.
lhs
=
self
.
lhs
.
analyse_target_types
(
env
)
self
.
lhs
.
gil_assignment_check
(
env
)
self
.
lhs
.
gil_assignment_check
(
env
)
unrolled_assignment
=
self
.
unroll_lhs
(
env
)
if
unrolled_assignment
:
return
unrolled_assignment
if
self
.
lhs
.
memslice_broadcast
or
self
.
rhs
.
memslice_broadcast
:
if
self
.
lhs
.
memslice_broadcast
or
self
.
rhs
.
memslice_broadcast
:
self
.
lhs
.
memslice_broadcast
=
True
self
.
lhs
.
memslice_broadcast
=
True
...
@@ -4801,6 +4828,130 @@ class SingleAssignmentNode(AssignmentNode):
...
@@ -4801,6 +4828,130 @@ class SingleAssignmentNode(AssignmentNode):
self
.
rhs
=
rhs
self
.
rhs
=
rhs
return
self
return
self
def
unroll
(
self
,
node
,
target_size
,
env
):
from
.
import
ExprNodes
,
UtilNodes
if
node
.
type
.
is_ctuple
:
if
node
.
type
.
size
==
target_size
:
base
=
node
start_node
=
None
stop_node
=
None
step_node
=
None
check_node
=
None
else
:
error
(
self
.
pos
,
"Unpacking type %s requires exactly %s arguments."
%
(
node
.
type
,
node
.
type
.
size
))
return
elif
node
.
type
.
is_ptr
:
if
isinstance
(
node
,
ExprNodes
.
SliceIndexNode
):
base
=
node
.
base
start_node
=
node
.
start
if
start_node
:
start_node
=
start_node
.
coerce_to
(
PyrexTypes
.
c_py_ssize_t_type
,
env
)
stop_node
=
node
.
stop
if
stop_node
:
stop_node
=
stop_node
.
coerce_to
(
PyrexTypes
.
c_py_ssize_t_type
,
env
)
else
:
if
node
.
type
.
is_array
and
node
.
type
.
size
:
stop_node
=
ExprNodes
.
IntNode
(
pos
=
self
.
pos
,
value
=
str
(
rhs
.
type
.
size
))
else
:
error
(
self
.
pos
,
"C array iteration requires known end index"
)
return
step_node
=
None
#node.step
if
step_node
:
step_node
=
step_node
.
coerce_to
(
PyrexTypes
.
c_py_ssize_t_type
,
env
)
# TODO: Factor out SliceIndexNode.generate_slice_guard_code() for use here.
def
get_const
(
node
,
none_value
):
if
node
is
None
:
return
none_value
elif
node
.
has_constant_result
:
node
.
calculate_constant_result
()
return
node
.
constant_result
else
:
raise
ValueError
,
"Not a constant."
try
:
slice_size
=
(
get_const
(
stop_node
,
None
)
-
get_const
(
start_node
,
0
))
/
get_const
(
step_node
,
1
)
if
target_size
!=
slice_size
:
error
(
self
.
pos
,
"Assignment to/from slice of wrong length, expected %d, got %d"
%
(
slice_size
,
target_size
))
except
ValueError
:
error
(
self
.
pos
,
"C array assignment currently requires known endpoints"
)
return
check_node
=
None
else
:
return
else
:
return
items
=
[]
base_ref
=
UtilNodes
.
LetRefNode
(
base
)
refs
=
[
base_ref
]
if
start_node
:
start_node
=
UtilNodes
.
LetRefNode
(
start_node
)
refs
.
append
(
start_node
)
if
stop_node
:
stop_node
=
UtilNodes
.
LetRefNode
(
stop_node
)
refs
.
append
(
stop_node
)
if
step_node
:
step_node
=
UtilNodes
.
LetRefNode
(
step_node
)
refs
.
append
(
step_node
)
for
ix
in
range
(
target_size
):
ix_node
=
ExprNodes
.
IntNode
(
pos
=
self
.
pos
,
value
=
str
(
ix
))
if
step_node
is
not
None
:
ix_node
=
ExprNodes
.
MulNode
(
pos
=
self
.
pos
,
operator
=
'*'
,
operand1
=
step_node
,
operand2
=
ix_node
).
analyse_types
(
env
)
if
start_node
is
not
None
:
ix_node
=
ExprNodes
.
AddNode
(
pos
=
self
.
pos
,
operator
=
'+'
,
operand1
=
start_node
,
operand2
=
ix_node
).
analyse_types
(
env
)
items
.
append
(
ExprNodes
.
IndexNode
(
pos
=
self
.
pos
,
base
=
base_ref
,
index
=
ix_node
))
return
check_node
,
refs
,
items
def
unroll_assignments
(
self
,
refs
,
check_node
,
lhs_list
,
rhs_list
,
env
):
from
.
import
ExprNodes
,
UtilNodes
assignments
=
[]
for
lhs
,
rhs
in
zip
(
lhs_list
,
rhs_list
):
assignments
.
append
(
SingleAssignmentNode
(
pos
=
self
.
pos
,
lhs
=
lhs
,
rhs
=
rhs
,
first
=
self
.
first
))
all
=
ParallelAssignmentNode
(
pos
=
self
.
pos
,
stats
=
assignments
).
analyse_expressions
(
env
)
if
check_node
:
all
=
StatListNode
(
pos
=
self
.
pos
,
stats
=
[
check_node
,
all
])
for
ref
in
refs
:
all
=
UtilNodes
.
LetNode
(
ref
,
all
)
return
all
def
unroll_rhs
(
self
,
env
):
from
.
import
ExprNodes
,
UtilNodes
if
not
isinstance
(
self
.
lhs
,
ExprNodes
.
TupleNode
):
return
for
arg
in
self
.
lhs
.
args
:
if
arg
.
is_starred
:
return
unrolled
=
self
.
unroll
(
self
.
rhs
,
len
(
self
.
lhs
.
args
),
env
)
if
not
unrolled
:
return
check_node
,
refs
,
rhs
=
unrolled
return
self
.
unroll_assignments
(
refs
,
check_node
,
self
.
lhs
.
args
,
rhs
,
env
)
def
unroll_lhs
(
self
,
env
):
if
self
.
lhs
.
type
.
is_ctuple
:
# Handled directly.
return
from
.
import
ExprNodes
,
UtilNodes
if
not
isinstance
(
self
.
rhs
,
ExprNodes
.
TupleNode
):
return
unrolled
=
self
.
unroll
(
self
.
lhs
,
len
(
self
.
rhs
.
args
),
env
)
if
not
unrolled
:
return
check_node
,
refs
,
lhs
=
unrolled
return
self
.
unroll_assignments
(
refs
,
check_node
,
lhs
,
self
.
rhs
.
args
,
env
)
def
generate_rhs_evaluation_code
(
self
,
code
):
def
generate_rhs_evaluation_code
(
self
,
code
):
self
.
rhs
.
generate_evaluation_code
(
code
)
self
.
rhs
.
generate_evaluation_code
(
code
)
...
@@ -5471,7 +5622,7 @@ class AssertStatNode(StatNode):
...
@@ -5471,7 +5622,7 @@ class AssertStatNode(StatNode):
# prevent tuple values from being interpreted as argument value tuples
# prevent tuple values from being interpreted as argument value tuples
from
.ExprNodes
import
TupleNode
from
.ExprNodes
import
TupleNode
value
=
TupleNode
(
value
.
pos
,
args
=
[
value
],
slow
=
True
)
value
=
TupleNode
(
value
.
pos
,
args
=
[
value
],
slow
=
True
)
self
.
value
=
value
.
analyse_types
(
env
,
skip_children
=
True
)
self
.
value
=
value
.
analyse_types
(
env
,
skip_children
=
True
)
.
coerce_to_pyobject
(
env
)
else
:
else
:
self
.
value
=
value
.
coerce_to_pyobject
(
env
)
self
.
value
=
value
.
coerce_to_pyobject
(
env
)
return
self
return
self
...
@@ -7691,7 +7842,7 @@ class ParallelStatNode(StatNode, ParallelNode):
...
@@ -7691,7 +7842,7 @@ class ParallelStatNode(StatNode, ParallelNode):
if
not
lastprivate
or
entry
.
type
.
is_pyobject
:
if
not
lastprivate
or
entry
.
type
.
is_pyobject
:
continue
continue
type_decl
=
entry
.
type
.
declaration_code
(
""
)
type_decl
=
entry
.
type
.
empty_declaration_code
(
)
temp_cname
=
"__pyx_parallel_temp%d"
%
temp_count
temp_cname
=
"__pyx_parallel_temp%d"
%
temp_count
private_cname
=
entry
.
cname
private_cname
=
entry
.
cname
...
...
Cython/Compiler/Optimize.py
View file @
0527db06
...
@@ -2593,7 +2593,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
...
@@ -2593,7 +2593,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
constant_result
=
orig_index_type
.
signed
and
1
or
0
,
constant_result
=
orig_index_type
.
signed
and
1
or
0
,
type
=
PyrexTypes
.
c_int_type
),
type
=
PyrexTypes
.
c_int_type
),
ExprNodes
.
RawCNameExprNode
(
index
.
pos
,
PyrexTypes
.
c_void_type
,
ExprNodes
.
RawCNameExprNode
(
index
.
pos
,
PyrexTypes
.
c_void_type
,
orig_index_type
.
declaration_code
(
""
)),
orig_index_type
.
empty_declaration_code
(
)),
ExprNodes
.
RawCNameExprNode
(
index
.
pos
,
conversion_type
,
convert_func
)],
ExprNodes
.
RawCNameExprNode
(
index
.
pos
,
conversion_type
,
convert_func
)],
may_return_none
=
True
,
may_return_none
=
True
,
is_temp
=
node
.
is_temp
,
is_temp
=
node
.
is_temp
,
...
...
Cython/Compiler/Parsing.py
View file @
0527db06
...
@@ -2038,9 +2038,21 @@ def p_c_complex_base_type(s, templates = None):
...
@@ -2038,9 +2038,21 @@ def p_c_complex_base_type(s, templates = None):
s
.
next
()
s
.
next
()
base_type
=
p_c_base_type
(
s
,
templates
=
templates
)
base_type
=
p_c_base_type
(
s
,
templates
=
templates
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
s
.
expect
(
')'
)
type_node
=
Nodes
.
CComplexBaseTypeNode
(
pos
,
type_node
=
Nodes
.
CComplexBaseTypeNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
)
base_type
=
base_type
,
declarator
=
declarator
)
if
s
.
sy
==
','
:
components
=
[
type_node
]
while
s
.
sy
==
','
:
s
.
next
()
if
s
.
sy
==
')'
:
break
base_type
=
p_c_base_type
(
s
,
templates
=
templates
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
components
.
append
(
Nodes
.
CComplexBaseTypeNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
))
type_node
=
Nodes
.
CTupleBaseTypeNode
(
pos
,
components
=
components
)
s
.
expect
(
')'
)
if
s
.
sy
==
'['
:
if
s
.
sy
==
'['
:
if
is_memoryviewslice_access
(
s
):
if
is_memoryviewslice_access
(
s
):
type_node
=
p_memoryviewslice_access
(
s
,
type_node
)
type_node
=
p_memoryviewslice_access
(
s
,
type_node
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
0527db06
...
@@ -6,6 +6,7 @@ from __future__ import absolute_import
...
@@ -6,6 +6,7 @@ from __future__ import absolute_import
import
re
import
re
import
copy
import
copy
import
re
from
.Code
import
UtilityCode
,
LazyUtilityCode
,
TempitaUtilityCode
from
.Code
import
UtilityCode
,
LazyUtilityCode
,
TempitaUtilityCode
from
.
import
StringEncoding
from
.
import
StringEncoding
...
@@ -20,18 +21,24 @@ class BaseType(object):
...
@@ -20,18 +21,24 @@ class BaseType(object):
# List of attribute names of any subtypes
# List of attribute names of any subtypes
subtypes
=
[]
subtypes
=
[]
_empty_declaration
=
None
def
can_coerce_to_pyobject
(
self
,
env
):
def
can_coerce_to_pyobject
(
self
,
env
):
return
False
return
False
def
cast_code
(
self
,
expr_code
):
def
cast_code
(
self
,
expr_code
):
return
"((%s)%s)"
%
(
self
.
declaration_code
(
""
),
expr_code
)
return
"((%s)%s)"
%
(
self
.
empty_declaration_code
(),
expr_code
)
def
empty_declaration_code
(
self
):
if
self
.
_empty_declaration
is
None
:
self
.
_empty_declaration
=
self
.
declaration_code
(
''
)
return
self
.
_empty_declaration
def
specialization_name
(
self
):
def
specialization_name
(
self
):
# This is not entirely robust.
# This is not entirely robust.
safe
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789'
safe
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789'
all
=
[]
all
=
[]
for
c
in
self
.
declaration_code
(
""
).
replace
(
"unsigned "
,
"unsigned_"
).
replace
(
"long long"
,
"long_long"
).
replace
(
" "
,
"__"
):
for
c
in
self
.
empty_declaration_code
(
).
replace
(
"unsigned "
,
"unsigned_"
).
replace
(
"long long"
,
"long_long"
).
replace
(
" "
,
"__"
):
if
c
in
safe
:
if
c
in
safe
:
all
.
append
(
c
)
all
.
append
(
c
)
else
:
else
:
...
@@ -225,6 +232,7 @@ class PyrexType(BaseType):
...
@@ -225,6 +232,7 @@ class PyrexType(BaseType):
is_returncode
=
0
is_returncode
=
0
is_error
=
0
is_error
=
0
is_buffer
=
0
is_buffer
=
0
is_ctuple
=
0
is_memoryviewslice
=
0
is_memoryviewslice
=
0
has_attributes
=
0
has_attributes
=
0
default_value
=
""
default_value
=
""
...
@@ -373,7 +381,7 @@ class CTypedefType(BaseType):
...
@@ -373,7 +381,7 @@ class CTypedefType(BaseType):
def
_create_utility_code
(
self
,
template_utility_code
,
def
_create_utility_code
(
self
,
template_utility_code
,
template_function_name
):
template_function_name
):
type_name
=
self
.
typedef_cname
.
replace
(
" "
,
"_"
).
replace
(
"::"
,
"__"
)
type_name
=
type_identifier
(
self
.
typedef_cname
)
utility_code
=
template_utility_code
.
specialize
(
utility_code
=
template_utility_code
.
specialize
(
type
=
self
.
typedef_cname
,
type
=
self
.
typedef_cname
,
TypeName
=
type_name
)
TypeName
=
type_name
)
...
@@ -388,7 +396,7 @@ class CTypedefType(BaseType):
...
@@ -388,7 +396,7 @@ class CTypedefType(BaseType):
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
"CIntToPy"
,
"TypeConversion.c"
,
"CIntToPy"
,
"TypeConversion.c"
,
context
=
{
"TYPE"
:
self
.
declaration_code
(
''
),
context
=
{
"TYPE"
:
self
.
empty_declaration_code
(
),
"TO_PY_FUNCTION"
:
self
.
to_py_function
}))
"TO_PY_FUNCTION"
:
self
.
to_py_function
}))
return
True
return
True
elif
base_type
.
is_float
:
elif
base_type
.
is_float
:
...
@@ -410,7 +418,7 @@ class CTypedefType(BaseType):
...
@@ -410,7 +418,7 @@ class CTypedefType(BaseType):
self
.
from_py_function
=
"__Pyx_PyInt_As_"
+
self
.
specialization_name
()
self
.
from_py_function
=
"__Pyx_PyInt_As_"
+
self
.
specialization_name
()
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
"CIntFromPy"
,
"TypeConversion.c"
,
"CIntFromPy"
,
"TypeConversion.c"
,
context
=
{
"TYPE"
:
self
.
declaration_code
(
''
),
context
=
{
"TYPE"
:
self
.
empty_declaration_code
(
),
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
return
True
return
True
elif
base_type
.
is_float
:
elif
base_type
.
is_float
:
...
@@ -440,7 +448,7 @@ class CTypedefType(BaseType):
...
@@ -440,7 +448,7 @@ class CTypedefType(BaseType):
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"
))
type
=
self
.
declaration_code
(
""
)
type
=
self
.
empty_declaration_code
(
)
name
=
self
.
specialization_name
()
name
=
self
.
specialization_name
()
if
binop
==
"lshift"
:
if
binop
==
"lshift"
:
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
...
@@ -701,7 +709,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -701,7 +709,7 @@ class MemoryViewSliceType(PyrexType):
buf_flag
=
self
.
flags
,
buf_flag
=
self
.
flags
,
ndim
=
self
.
ndim
,
ndim
=
self
.
ndim
,
axes_specs
=
', '
.
join
(
self
.
axes_to_code
()),
axes_specs
=
', '
.
join
(
self
.
axes_to_code
()),
dtype_typedecl
=
self
.
dtype
.
declaration_code
(
""
),
dtype_typedecl
=
self
.
dtype
.
empty_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
,
funcname
=
funcname
,
funcname
=
funcname
,
...
@@ -753,7 +761,7 @@ class MemoryViewSliceType(PyrexType):
...
@@ -753,7 +761,7 @@ class MemoryViewSliceType(PyrexType):
context
.
update
(
context
.
update
(
to_py_function
=
self
.
dtype
.
to_py_function
,
to_py_function
=
self
.
dtype
.
to_py_function
,
from_py_function
=
self
.
dtype
.
from_py_function
,
from_py_function
=
self
.
dtype
.
from_py_function
,
dtype
=
self
.
dtype
.
declaration_code
(
""
),
dtype
=
self
.
dtype
.
empty_declaration_code
(
),
error_condition
=
error_condition
,
error_condition
=
error_condition
,
)
)
...
@@ -1472,7 +1480,7 @@ class CIntType(CNumericType):
...
@@ -1472,7 +1480,7 @@ class CIntType(CNumericType):
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
self
.
to_py_function
=
"__Pyx_PyInt_From_"
+
self
.
specialization_name
()
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
"CIntToPy"
,
"TypeConversion.c"
,
"CIntToPy"
,
"TypeConversion.c"
,
context
=
{
"TYPE"
:
self
.
declaration_code
(
''
),
context
=
{
"TYPE"
:
self
.
empty_declaration_code
(
),
"TO_PY_FUNCTION"
:
self
.
to_py_function
}))
"TO_PY_FUNCTION"
:
self
.
to_py_function
}))
return
True
return
True
...
@@ -1481,7 +1489,7 @@ class CIntType(CNumericType):
...
@@ -1481,7 +1489,7 @@ class CIntType(CNumericType):
self
.
from_py_function
=
"__Pyx_PyInt_As_"
+
self
.
specialization_name
()
self
.
from_py_function
=
"__Pyx_PyInt_As_"
+
self
.
specialization_name
()
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
"CIntFromPy"
,
"TypeConversion.c"
,
"CIntFromPy"
,
"TypeConversion.c"
,
context
=
{
"TYPE"
:
self
.
declaration_code
(
''
),
context
=
{
"TYPE"
:
self
.
empty_declaration_code
(
),
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
"FROM_PY_FUNCTION"
:
self
.
from_py_function
}))
return
True
return
True
...
@@ -1516,7 +1524,7 @@ class CIntType(CNumericType):
...
@@ -1516,7 +1524,7 @@ class CIntType(CNumericType):
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"
))
type
=
self
.
declaration_code
(
""
)
type
=
self
.
empty_declaration_code
(
)
name
=
self
.
specialization_name
()
name
=
self
.
specialization_name
()
if
binop
==
"lshift"
:
if
binop
==
"lshift"
:
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
env
.
use_utility_code
(
TempitaUtilityCode
.
load
(
...
@@ -1807,7 +1815,7 @@ class CComplexType(CNumericType):
...
@@ -1807,7 +1815,7 @@ class CComplexType(CNumericType):
env
.
use_utility_code
(
env
.
use_utility_code
(
utility_code
.
specialize
(
utility_code
.
specialize
(
self
,
self
,
real_type
=
self
.
real_type
.
declaration_code
(
''
),
real_type
=
self
.
real_type
.
empty_declaration_code
(
),
m
=
self
.
funcsuffix
,
m
=
self
.
funcsuffix
,
is_float
=
self
.
real_type
.
is_float
))
is_float
=
self
.
real_type
.
is_float
))
return
True
return
True
...
@@ -1828,7 +1836,7 @@ class CComplexType(CNumericType):
...
@@ -1828,7 +1836,7 @@ class CComplexType(CNumericType):
env
.
use_utility_code
(
env
.
use_utility_code
(
utility_code
.
specialize
(
utility_code
.
specialize
(
self
,
self
,
real_type
=
self
.
real_type
.
declaration_code
(
''
),
real_type
=
self
.
real_type
.
empty_declaration_code
(
),
m
=
self
.
funcsuffix
,
m
=
self
.
funcsuffix
,
is_float
=
self
.
real_type
.
is_float
))
is_float
=
self
.
real_type
.
is_float
))
self
.
from_py_function
=
"__Pyx_PyComplex_As_"
+
self
.
specialization_name
()
self
.
from_py_function
=
"__Pyx_PyComplex_As_"
+
self
.
specialization_name
()
...
@@ -2683,7 +2691,7 @@ class CFuncType(CType):
...
@@ -2683,7 +2691,7 @@ class CFuncType(CType):
func_name
,
arg_code
,
trailer
)
func_name
,
arg_code
,
trailer
)
def
signature_string
(
self
):
def
signature_string
(
self
):
s
=
self
.
declaration_code
(
""
)
s
=
self
.
empty_declaration_code
(
)
return
s
return
s
def
signature_cast_string
(
self
):
def
signature_cast_string
(
self
):
...
@@ -3042,7 +3050,7 @@ class ToPyStructUtilityCode(object):
...
@@ -3042,7 +3050,7 @@ class ToPyStructUtilityCode(object):
# This is a bit of a hack, we need a forward declaration
# This is a bit of a hack, we need a forward declaration
# due to the way things are ordered in the module...
# due to the way things are ordered in the module...
if
self
.
forward_decl
:
if
self
.
forward_decl
:
proto
.
putln
(
self
.
type
.
declaration_code
(
''
)
+
';'
)
proto
.
putln
(
self
.
type
.
empty_declaration_code
(
)
+
';'
)
proto
.
putln
(
self
.
header
+
";"
)
proto
.
putln
(
self
.
header
+
";"
)
def
inject_tree_and_scope_into
(
self
,
module_node
):
def
inject_tree_and_scope_into
(
self
,
module_node
):
...
@@ -3171,8 +3179,8 @@ class CStructOrUnionType(CType):
...
@@ -3171,8 +3179,8 @@ class CStructOrUnionType(CType):
if
len
(
fields
)
!=
2
:
return
False
if
len
(
fields
)
!=
2
:
return
False
a
,
b
=
fields
a
,
b
=
fields
return
(
a
.
type
.
is_float
and
b
.
type
.
is_float
and
return
(
a
.
type
.
is_float
and
b
.
type
.
is_float
and
a
.
type
.
declaration_code
(
""
)
==
a
.
type
.
empty_declaration_code
(
)
==
b
.
type
.
declaration_code
(
""
))
b
.
type
.
empty_declaration_code
(
))
def
struct_nesting_depth
(
self
):
def
struct_nesting_depth
(
self
):
child_depths
=
[
x
.
type
.
struct_nesting_depth
()
child_depths
=
[
x
.
type
.
struct_nesting_depth
()
...
@@ -3264,21 +3272,21 @@ class CppClassType(CType):
...
@@ -3264,21 +3272,21 @@ class CppClassType(CType):
except_clause
=
"? %s"
%
except_clause
except_clause
=
"? %s"
%
except_clause
declarations
.
append
(
declarations
.
append
(
" ctypedef %s %s '%s'"
%
(
" ctypedef %s %s '%s'"
%
(
except_type
.
declaration_code
(
""
,
for_display
=
True
),
X
[
ix
],
T
.
declaration_code
(
""
)))
except_type
.
declaration_code
(
""
,
for_display
=
True
),
X
[
ix
],
T
.
empty_declaration_code
(
)))
else
:
else
:
except_clause
=
"*"
except_clause
=
"*"
declarations
.
append
(
declarations
.
append
(
" ctypedef struct %s '%s':
\
n
pass"
%
(
" ctypedef struct %s '%s':
\
n
pass"
%
(
X
[
ix
],
T
.
declaration_code
(
""
)))
X
[
ix
],
T
.
empty_declaration_code
(
)))
declarations
.
append
(
declarations
.
append
(
" cdef %s %s_from_py '%s' (object) except %s"
%
(
" cdef %s %s_from_py '%s' (object) except %s"
%
(
X
[
ix
],
X
[
ix
],
T
.
from_py_function
,
except_clause
))
X
[
ix
],
X
[
ix
],
T
.
from_py_function
,
except_clause
))
if
self
.
cname
in
cpp_string_conversions
:
if
self
.
cname
in
cpp_string_conversions
:
cls
=
'string'
cls
=
'string'
tags
=
self
.
cname
.
replace
(
':'
,
'_'
),
tags
=
type_identifier
(
self
),
else
:
else
:
cls
=
self
.
cname
[
5
:]
cls
=
self
.
cname
[
5
:]
cname
=
'__pyx_convert_%s_from_py_%s'
%
(
cls
,
'__
_
_'
.
join
(
tags
))
cname
=
'__pyx_convert_%s_from_py_%s'
%
(
cls
,
'__
and
_'
.
join
(
tags
))
context
=
{
context
=
{
'template_type_declarations'
:
'
\
n
'
.
join
(
declarations
),
'template_type_declarations'
:
'
\
n
'
.
join
(
declarations
),
'cname'
:
cname
,
'cname'
:
cname
,
...
@@ -3304,14 +3312,14 @@ class CppClassType(CType):
...
@@ -3304,14 +3312,14 @@ class CppClassType(CType):
tags
.
append
(
T
.
specialization_name
())
tags
.
append
(
T
.
specialization_name
())
declarations
.
append
(
declarations
.
append
(
" ctypedef struct %s '%s':
\
n
pass"
%
(
" ctypedef struct %s '%s':
\
n
pass"
%
(
X
[
ix
],
T
.
declaration_code
(
""
)))
X
[
ix
],
T
.
empty_declaration_code
(
)))
declarations
.
append
(
declarations
.
append
(
" cdef object %s_to_py '%s' (%s)"
%
(
" cdef object %s_to_py '%s' (%s)"
%
(
X
[
ix
],
T
.
to_py_function
,
X
[
ix
]))
X
[
ix
],
T
.
to_py_function
,
X
[
ix
]))
if
self
.
cname
in
cpp_string_conversions
:
if
self
.
cname
in
cpp_string_conversions
:
cls
=
'string'
cls
=
'string'
prefix
=
'PyObject_'
# gets specialised by explicit type casts in CoerceToPyTypeNode
prefix
=
'PyObject_'
# gets specialised by explicit type casts in CoerceToPyTypeNode
tags
=
self
.
cname
.
replace
(
':'
,
'_'
),
tags
=
type_identifier
(
self
),
else
:
else
:
cls
=
self
.
cname
[
5
:]
cls
=
self
.
cname
[
5
:]
prefix
=
''
prefix
=
''
...
@@ -3331,6 +3339,17 @@ class CppClassType(CType):
...
@@ -3331,6 +3339,17 @@ class CppClassType(CType):
def
is_template_type
(
self
):
def
is_template_type
(
self
):
return
self
.
templates
is
not
None
and
self
.
template_type
is
None
return
self
.
templates
is
not
None
and
self
.
template_type
is
None
def
get_fused_types
(
self
,
result
=
None
,
seen
=
None
):
if
result
is
None
:
result
=
[]
seen
=
set
()
if
self
.
namespace
:
self
.
namespace
.
get_fused_types
(
result
,
seen
)
if
self
.
templates
:
for
T
in
self
.
templates
:
T
.
get_fused_types
(
result
,
seen
)
return
result
def
specialize_here
(
self
,
pos
,
template_values
=
None
):
def
specialize_here
(
self
,
pos
,
template_values
=
None
):
if
not
self
.
is_template_type
():
if
not
self
.
is_template_type
():
error
(
pos
,
"'%s' type is not a template"
%
self
)
error
(
pos
,
"'%s' type is not a template"
%
self
)
...
@@ -3363,16 +3382,16 @@ class CppClassType(CType):
...
@@ -3363,16 +3382,16 @@ class CppClassType(CType):
# Need to do these *after* self.specializations[key] is set
# Need to do these *after* self.specializations[key] is set
# to avoid infinite recursion on circular references.
# to avoid infinite recursion on circular references.
specialized
.
base_classes
=
[
b
.
specialize
(
values
)
for
b
in
self
.
base_classes
]
specialized
.
base_classes
=
[
b
.
specialize
(
values
)
for
b
in
self
.
base_classes
]
specialized
.
scope
=
self
.
scope
.
specialize
(
values
,
specialized
)
if
self
.
namespace
is
not
None
:
if
self
.
namespace
is
not
None
:
specialized
.
namespace
=
self
.
namespace
.
specialize
(
values
)
specialized
.
namespace
=
self
.
namespace
.
specialize
(
values
)
specialized
.
scope
=
self
.
scope
.
specialize
(
values
,
specialized
)
return
specialized
return
specialized
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
if
self
==
actual
:
if
self
==
actual
:
return
{}
return
{}
# TODO(robertwb): Actual type equality.
# TODO(robertwb): Actual type equality.
elif
self
.
declaration_code
(
""
)
==
actual
.
template_type
.
declaration_code
(
""
):
elif
self
.
empty_declaration_code
()
==
actual
.
template_type
.
empty_declaration_code
(
):
return
reduce
(
return
reduce
(
merge_template_deductions
,
merge_template_deductions
,
[
formal_param
.
deduce_template_params
(
actual_param
)
for
(
formal_param
,
actual_param
)
in
zip
(
self
.
templates
,
actual
.
templates
)],
[
formal_param
.
deduce_template_params
(
actual_param
)
for
(
formal_param
,
actual_param
)
in
zip
(
self
.
templates
,
actual
.
templates
)],
...
@@ -3397,7 +3416,7 @@ class CppClassType(CType):
...
@@ -3397,7 +3416,7 @@ class CppClassType(CType):
else
:
else
:
base_code
=
"%s%s"
%
(
self
.
cname
,
templates
)
base_code
=
"%s%s"
%
(
self
.
cname
,
templates
)
if
self
.
namespace
is
not
None
:
if
self
.
namespace
is
not
None
:
base_code
=
"%s::%s"
%
(
self
.
namespace
.
declaration_code
(
''
),
base_code
)
base_code
=
"%s::%s"
%
(
self
.
namespace
.
empty_declaration_code
(
),
base_code
)
base_code
=
public_decl
(
base_code
,
dll_linkage
)
base_code
=
public_decl
(
base_code
,
dll_linkage
)
return
self
.
base_declaration_code
(
base_code
,
entity_code
)
return
self
.
base_declaration_code
(
base_code
,
entity_code
)
...
@@ -3541,6 +3560,87 @@ class CEnumType(CType):
...
@@ -3541,6 +3560,87 @@ class CEnumType(CType):
' %s'
%
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
' %s'
%
code
.
error_goto_if
(
error_condition
or
self
.
error_condition
(
result_code
),
error_pos
))
class
CTupleType
(
CType
):
# components [PyrexType]
is_ctuple
=
True
def
__init__
(
self
,
cname
,
components
):
self
.
cname
=
cname
self
.
components
=
components
self
.
size
=
len
(
components
)
self
.
to_py_function
=
"%s_to_py_%s"
%
(
Naming
.
convert_func_prefix
,
self
.
cname
)
self
.
from_py_function
=
"%s_from_py_%s"
%
(
Naming
.
convert_func_prefix
,
self
.
cname
)
self
.
exception_check
=
True
self
.
_convert_to_py_code
=
None
self
.
_convert_from_py_code
=
None
def
__str__
(
self
):
return
"(%s)"
%
", "
.
join
(
str
(
c
)
for
c
in
self
.
components
)
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
if
pyrex
or
for_display
:
return
str
(
self
)
else
:
return
self
.
base_declaration_code
(
self
.
cname
,
entity_code
)
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
_convert_to_py_code
is
False
:
return
None
# tri-state-ish
if
self
.
_convert_to_py_code
is
None
:
for
component
in
self
.
components
:
if
not
component
.
create_to_py_utility_code
(
env
):
self
.
to_py_function
=
None
self
.
_convert_to_py_code
=
False
return
False
context
=
dict
(
struct_type_decl
=
self
.
empty_declaration_code
(),
components
=
self
.
components
,
funcname
=
self
.
to_py_function
,
size
=
len
(
self
.
components
)
)
self
.
_convert_to_py_code
=
TempitaUtilityCode
.
load
(
"ToPyCTupleUtility"
,
"TypeConversion.c"
,
context
=
context
)
env
.
use_utility_code
(
self
.
_convert_to_py_code
)
return
True
def
create_from_py_utility_code
(
self
,
env
):
if
self
.
_convert_from_py_code
is
False
:
return
None
# tri-state-ish
if
self
.
_convert_from_py_code
is
None
:
for
component
in
self
.
components
:
if
not
component
.
create_from_py_utility_code
(
env
):
self
.
from_py_function
=
None
self
.
_convert_from_py_code
=
False
return
False
context
=
dict
(
struct_type_decl
=
self
.
empty_declaration_code
(),
components
=
self
.
components
,
funcname
=
self
.
from_py_function
,
size
=
len
(
self
.
components
)
)
self
.
_convert_from_py_code
=
TempitaUtilityCode
.
load
(
"FromPyCTupleUtility"
,
"TypeConversion.c"
,
context
=
context
)
env
.
use_utility_code
(
self
.
_convert_from_py_code
)
return
True
c_tuple_types
=
{}
def
c_tuple_type
(
components
):
components
=
tuple
(
components
)
tuple_type
=
c_tuple_types
.
get
(
components
)
if
tuple_type
is
None
:
cname
=
'__pyx_tuple_'
+
type_list_identifier
(
components
)
tuple_type
=
c_tuple_types
[
components
]
=
CTupleType
(
cname
,
components
)
return
tuple_type
class
UnspecifiedType
(
PyrexType
):
class
UnspecifiedType
(
PyrexType
):
# Used as a placeholder until the type can be determined.
# Used as a placeholder until the type can be determined.
...
@@ -3819,7 +3919,7 @@ def best_match(args, functions, pos=None, env=None):
...
@@ -3819,7 +3919,7 @@ def best_match(args, functions, pos=None, env=None):
from
.Symtab
import
Entry
from
.Symtab
import
Entry
specialization
=
Entry
(
specialization
=
Entry
(
name
=
func
.
name
+
"[%s]"
%
","
.
join
([
str
(
t
)
for
t
in
type_list
]),
name
=
func
.
name
+
"[%s]"
%
","
.
join
([
str
(
t
)
for
t
in
type_list
]),
cname
=
func
.
cname
+
"<%s>"
%
","
.
join
([
t
.
declaration_code
(
""
)
for
t
in
type_list
]),
cname
=
func
.
cname
+
"<%s>"
%
","
.
join
([
t
.
empty_declaration_code
(
)
for
t
in
type_list
]),
type
=
func_type
.
specialize
(
deductions
),
type
=
func_type
.
specialize
(
deductions
),
pos
=
func
.
pos
)
pos
=
func
.
pos
)
candidates
.
append
((
specialization
,
specialization
.
type
))
candidates
.
append
((
specialization
,
specialization
.
type
))
...
@@ -4138,3 +4238,37 @@ def typecast(to_type, from_type, expr_code):
...
@@ -4138,3 +4238,37 @@ def typecast(to_type, from_type, expr_code):
else
:
else
:
#print "typecast: to", to_type, "from", from_type ###
#print "typecast: to", to_type, "from", from_type ###
return
to_type
.
cast_code
(
expr_code
)
return
to_type
.
cast_code
(
expr_code
)
def
type_list_identifier
(
types
):
return
cap_length
(
'__and_'
.
join
(
type_identifier
(
type
)
for
type
in
types
))
_type_identifier_cache
=
{}
def
type_identifier
(
type
):
decl
=
type
.
empty_declaration_code
()
safe
=
_type_identifier_cache
.
get
(
decl
)
if
safe
is
None
:
safe
=
decl
safe
=
re
.
sub
(
' +'
,
' '
,
safe
)
safe
=
re
.
sub
(
' ([^a-zA-Z0-9_])'
,
r'\1'
,
safe
)
safe
=
re
.
sub
(
'([^a-zA-Z0-9_]) '
,
r'\1'
,
safe
)
safe
=
(
safe
.
replace
(
'__'
,
'__dunder'
)
.
replace
(
' '
,
'__space_'
)
.
replace
(
'*'
,
'__ptr'
)
.
replace
(
'&'
,
'__ref'
)
.
replace
(
'['
,
'__lArr'
)
.
replace
(
']'
,
'__rArr'
)
.
replace
(
'<'
,
'__lAng'
)
.
replace
(
'>'
,
'__rAng'
)
.
replace
(
'('
,
'__lParen'
)
.
replace
(
')'
,
'__rParen'
)
.
replace
(
','
,
'__comma_'
)
.
replace
(
'::'
,
'__in_'
))
safe
=
cap_length
(
re
.
sub
(
'[^a-zA-Z0-9_]'
,
lambda
x
:
'__%X'
%
ord
(
x
.
group
(
0
)),
safe
))
_type_identifier_cache
[
decl
]
=
safe
return
safe
def
cap_length
(
s
,
max_prefix
=
63
,
max_len
=
1024
):
if
len
(
s
)
<=
max_prefix
:
return
s
else
:
return
'%x__%s__etc'
%
(
abs
(
hash
(
s
))
%
(
1
<<
20
),
s
[:
max_len
-
17
])
Cython/Compiler/Symtab.py
View file @
0527db06
...
@@ -606,6 +606,9 @@ class Scope(object):
...
@@ -606,6 +606,9 @@ class Scope(object):
self
.
sue_entries
.
append
(
entry
)
self
.
sue_entries
.
append
(
entry
)
return
entry
return
entry
def
declare_tuple_type
(
self
,
pos
,
type
):
return
self
.
outer_scope
.
declare_tuple_type
(
pos
,
type
)
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
...
@@ -1061,6 +1064,18 @@ class ModuleScope(Scope):
...
@@ -1061,6 +1064,18 @@ class ModuleScope(Scope):
return
self
.
outer_scope
.
lookup
(
name
,
language_level
=
language_level
)
return
self
.
outer_scope
.
lookup
(
name
,
language_level
=
language_level
)
def
declare_tuple_type
(
self
,
pos
,
type
):
cname
=
type
.
cname
if
not
self
.
lookup_here
(
cname
):
scope
=
StructOrUnionScope
(
cname
)
for
ix
,
component
in
enumerate
(
type
.
components
):
scope
.
declare_var
(
name
=
"f%s"
%
ix
,
type
=
component
,
pos
=
pos
)
struct_entry
=
self
.
declare_struct_or_union
(
cname
+
'_struct'
,
'struct'
,
scope
,
typedef_flag
=
True
,
pos
=
pos
,
cname
=
cname
)
self
.
type_entries
.
remove
(
struct_entry
)
type
.
struct_entry
=
struct_entry
type
.
entry
=
self
.
declare_type
(
cname
,
type
,
pos
,
cname
)
return
type
.
entry
def
declare_builtin
(
self
,
name
,
pos
):
def
declare_builtin
(
self
,
name
,
pos
):
if
not
hasattr
(
builtins
,
name
)
\
if
not
hasattr
(
builtins
,
name
)
\
and
name
not
in
Code
.
non_portable_builtins_map
\
and
name
not
in
Code
.
non_portable_builtins_map
\
...
@@ -2114,8 +2129,8 @@ class CppClassScope(Scope):
...
@@ -2114,8 +2129,8 @@ class CppClassScope(Scope):
entry
=
self
.
declare
(
name
,
cname
,
type
,
pos
,
visibility
)
entry
=
self
.
declare
(
name
,
cname
,
type
,
pos
,
visibility
)
entry
.
is_variable
=
1
entry
.
is_variable
=
1
if
type
.
is_cfunction
and
self
.
type
:
if
type
.
is_cfunction
and
self
.
type
:
if
not
self
.
type
.
templates
or
not
any
(
T
.
is_fused
for
T
in
self
.
type
.
templates
)
:
if
not
self
.
type
.
get_fused_types
:
entry
.
func_cname
=
"%s::%s"
%
(
self
.
type
.
declaration_code
(
""
),
cname
)
entry
.
func_cname
=
"%s::%s"
%
(
self
.
type
.
empty_declaration_code
(
),
cname
)
if
name
!=
"this"
and
(
defining
or
name
!=
"<init>"
):
if
name
!=
"this"
and
(
defining
or
name
!=
"<init>"
):
self
.
var_entries
.
append
(
entry
)
self
.
var_entries
.
append
(
entry
)
if
type
.
is_pyobject
and
not
allow_pyobject
:
if
type
.
is_pyobject
and
not
allow_pyobject
:
...
...
Cython/Utility/TypeConversion.c
View file @
0527db06
...
@@ -309,6 +309,55 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
...
@@ -309,6 +309,55 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
static
CYTHON_INLINE
PyObject
*
__Pyx_PyInt_FromSize_t
(
size_t
ival
)
{
static
CYTHON_INLINE
PyObject
*
__Pyx_PyInt_FromSize_t
(
size_t
ival
)
{
return
PyInt_FromSize_t
(
ival
);
return
PyInt_FromSize_t
(
ival
);
}
}
/////////////// ToPyCTupleUtility.proto ///////////////
static
PyObject
*
{{
funcname
}}({{
struct_type_decl
}});
/////////////// ToPyCTupleUtility ///////////////
static
PyObject
*
{{
funcname
}}({{
struct_type_decl
}}
value
)
{
PyObject
*
item
=
NULL
;
PyObject
*
result
=
PyTuple_New
({{
size
}});
if
(
!
result
)
goto
bad
;
{{
for
ix
,
component
in
enumerate
(
components
)
:
}}
{{
py
:
attr
=
"value.f%s"
%
ix
}}
item
=
{{
component
.
to_py_function
}}({{
attr
}});
if
(
!
item
)
goto
bad
;
PyTuple_SET_ITEM
(
result
,
{{
ix
}},
item
);
{{
endfor
}}
return
result
;
bad:
Py_XDECREF
(
item
);
Py_XDECREF
(
result
);
return
NULL
;
}
/////////////// FromPyCTupleUtility.proto ///////////////
static
{{
struct_type_decl
}}
{{
funcname
}}(
PyObject
*
);
/////////////// FromPyCTupleUtility ///////////////
static
{{
struct_type_decl
}}
{{
funcname
}}(
PyObject
*
o
)
{
{{
struct_type_decl
}}
result
;
if
(
!
PyTuple_Check
(
o
)
||
PyTuple_GET_SIZE
(
o
)
!=
{{
size
}})
{
PyErr_Format
(
PyExc_TypeError
,
"Expected %.16s of size %.8d, got %.200s"
,
"a tuple"
,
{{
size
}},
Py_TYPE
(
o
)
->
tp_name
);
goto
bad
;
}
{{
for
ix
,
component
in
enumerate
(
components
)
:
}}
{{
py
:
attr
=
"result.f%s"
%
ix
}}
{{
attr
}}
=
{{
component
.
from_py_function
}}(
PyTuple_GET_ITEM
(
o
,
{{
ix
}}));
if
({{
component
.
error_condition
(
attr
)}})
goto
bad
;
{{
endfor
}}
return
result
;
bad:
return
result
;
}
/////////////// ObjectAsUCS4.proto ///////////////
/////////////// ObjectAsUCS4.proto ///////////////
...
...
tests/run/arrayassign.pyx
View file @
0527db06
...
@@ -141,6 +141,24 @@ def test_ptr_literal_list_slice_end():
...
@@ -141,6 +141,24 @@ def test_ptr_literal_list_slice_end():
a
[:
5
]
=
[
1
,
2
,
3
,
4
,
5
]
a
[:
5
]
=
[
1
,
2
,
3
,
4
,
5
]
return
(
a
[
0
],
a
[
1
],
a
[
2
],
a
[
3
],
a
[
4
])
return
(
a
[
0
],
a
[
1
],
a
[
2
],
a
[
3
],
a
[
4
])
def
test_multiple_from_slice
():
"""
>>> test_multiple_from_slice()
(5, 4, 3)
"""
cdef
int
*
a
=
[
6
,
5
,
4
,
3
,
2
,
1
]
x
,
y
,
z
=
a
[
1
:
4
]
return
x
,
y
,
z
def
test_slice_from_multiple
():
"""
>>> test_slice_from_multiple()
(6, -1, -2, -3, 2, 1)
"""
cdef
int
*
a
=
[
6
,
5
,
4
,
3
,
2
,
1
]
a
[
1
:
4
]
=
-
1
,
-
2
,
-
3
return
a
[
0
],
a
[
1
],
a
[
2
],
a
[
3
],
a
[
4
],
a
[
5
]
def
test_literal_tuple
():
def
test_literal_tuple
():
"""
"""
>>> test_literal_tuple()
>>> test_literal_tuple()
...
...
tests/run/ctuple.pyx
0 → 100644
View file @
0527db06
import
cython
def
simple_convert
(
*
o
):
"""
>>> simple_convert(1, 2)
(1, 2.0)
>>> simple_convert(1)
Traceback (most recent call last):
...
TypeError: Expected a tuple of size 2, got tuple
>>> simple_convert(1, 2, 3)
Traceback (most recent call last):
...
TypeError: Expected a tuple of size 2, got tuple
"""
cdef
(
int
,
double
)
xy
=
o
return
xy
def
indexing
((
int
,
double
)
xy
):
"""
>>> indexing((1, 2))
(2, 3.0)
"""
x
=
xy
[
0
]
y
=
xy
[
1
]
xy
[
0
]
=
x
+
1
xy
[
1
]
=
y
+
1
return
xy
def
unpacking
((
int
,
double
)
xy
):
"""
>>> unpacking((1, 2))
(1, 2.0)
"""
x
,
y
=
xy
return
x
,
y
cdef
(
int
,
double
)
side_effect
((
int
,
double
)
xy
):
print
"called with"
,
xy
return
xy
def
unpacking_with_side_effect
((
int
,
double
)
xy
):
"""
>>> unpacking_with_side_effect((1, 2))
called with (1, 2.0)
(1, 2.0)
"""
x
,
y
=
side_effect
(
xy
)
return
x
,
y
def
packing_tuple
(
int
x
,
double
y
):
"""
>>> packing_tuple(1, 2)
(1, 2.0)
"""
cdef
(
int
,
double
)
xy
=
(
x
,
y
)
return
xy
def
coerce_packing_tuple
(
int
x
,
int
y
):
cdef
(
int
,
double
)
xy
=
(
x
,
y
)
"""
>>> coerce_packing_tuple(1, 2)
(1, 2.0)
"""
return
xy
def
c_types
(
int
a
,
double
b
):
"""
>>> c_types(1, 2)
(1, 2.0)
"""
cdef
int
*
a_ptr
cdef
double
*
b_ptr
cdef
(
int
*
,
double
*
)
ab
=
(
&
a
,
&
b
)
a_ptr
,
b_ptr
=
ab
return
a_ptr
[
0
],
b_ptr
[
0
]
cdef
(
int
,
int
*
)
cdef
_ctuple_return_type
(
int
x
,
int
*
x_ptr
):
return
x
,
x_ptr
def
call_cdef_ctuple_return_type
(
int
x
):
"""
>>> call_cdef_ctuple_return_type(2)
(2, 2)
"""
cdef
(
int
,
int
*
)
res
=
cdef
_ctuple_return_type
(
x
,
&
x
)
return
res
[
0
],
res
[
1
][
0
]
cpdef
(
int
,
double
)
cpdef
_ctuple_return_type
(
int
x
,
double
y
):
"""
>>> cpdef_ctuple_return_type(1, 2)
(1, 2.0)
"""
return
x
,
y
@
cython
.
infer_types
(
True
)
def
test_type_inference
():
"""
>>> test_type_inference()
"""
cdef
int
x
=
1
cdef
double
y
=
2
cdef
object
o
=
3
xy
=
(
x
,
y
)
assert
cython
.
typeof
(
xy
)
==
"(int, double)"
,
cython
.
typeof
(
xy
)
xo
=
(
x
,
o
)
assert
cython
.
typeof
(
xo
)
==
"tuple object"
,
cython
.
typeof
(
xo
)
def
test_equality
((
int
,
int
)
ab
,
(
int
,
int
)
cd
,
(
int
,
int
)
ef
):
"""
>>> test_equality((1, 2), (3, 4), (5, 6))
True
>>> test_equality((1, 2), (3, 4), (3, 4))
True
>>> test_equality((3, 4), (3, 4), (3, 4))
False
"""
return
ab
<
cd
<=
ef
def
test_binop
((
int
,
int
)
ab
,
(
double
,
double
)
cd
):
"""
>>> test_binop((1, 2), (3, 4))
(1, 2, 3.0, 4.0)
"""
return
ab
+
cd
def
test_mul
((
int
,
int
)
ab
,
int
c
):
"""
>>> test_mul((1, 2), 3)
(1, 2, 1, 2, 1, 2)
"""
return
ab
*
c
def
test_unop
((
int
,
int
)
ab
):
"""
>>> test_unop((1, 2))
True
"""
return
not
ab
tests/run/type_inference.pyx
View file @
0527db06
...
@@ -32,8 +32,10 @@ def simple():
...
@@ -32,8 +32,10 @@ def simple():
assert
typeof
(
u
)
==
"unicode object"
,
typeof
(
u
)
assert
typeof
(
u
)
==
"unicode object"
,
typeof
(
u
)
L
=
[
1
,
2
,
3
]
L
=
[
1
,
2
,
3
]
assert
typeof
(
L
)
==
"list object"
,
typeof
(
L
)
assert
typeof
(
L
)
==
"list object"
,
typeof
(
L
)
t
=
(
4
,
5
,
6
)
t
=
(
4
,
5
,
6
,()
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
t2
=
(
4
,
5.0
,
6
)
assert
typeof
(
t2
)
==
"(long, double, long)"
,
typeof
(
t
)
def
builtin_types
():
def
builtin_types
():
"""
"""
...
@@ -80,7 +82,7 @@ def slicing():
...
@@ -80,7 +82,7 @@ def slicing():
assert
typeof
(
L1
)
==
"list object"
,
typeof
(
L1
)
assert
typeof
(
L1
)
==
"list object"
,
typeof
(
L1
)
L2
=
L
[
1
:
2
:
2
]
L2
=
L
[
1
:
2
:
2
]
assert
typeof
(
L2
)
==
"list object"
,
typeof
(
L2
)
assert
typeof
(
L2
)
==
"list object"
,
typeof
(
L2
)
t
=
(
4
,
5
,
6
)
t
=
(
4
,
5
,
6
,()
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
t1
=
t
[
1
:
2
]
t1
=
t
[
1
:
2
]
assert
typeof
(
t1
)
==
"tuple object"
,
typeof
(
t1
)
assert
typeof
(
t1
)
==
"tuple object"
,
typeof
(
t1
)
...
@@ -107,7 +109,7 @@ def indexing():
...
@@ -107,7 +109,7 @@ def indexing():
assert
typeof
(
L
)
==
"list object"
,
typeof
(
L
)
assert
typeof
(
L
)
==
"list object"
,
typeof
(
L
)
L1
=
L
[
1
]
L1
=
L
[
1
]
assert
typeof
(
L1
)
==
"Python object"
,
typeof
(
L1
)
assert
typeof
(
L1
)
==
"Python object"
,
typeof
(
L1
)
t
=
(
4
,
5
,
6
)
t
=
(
4
,
5
,
()
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
assert
typeof
(
t
)
==
"tuple object"
,
typeof
(
t
)
t1
=
t
[
1
]
t1
=
t
[
1
]
assert
typeof
(
t1
)
==
"long"
,
typeof
(
t1
)
assert
typeof
(
t1
)
==
"long"
,
typeof
(
t1
)
...
...
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