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
Boxiang Sun
cython
Commits
be4b27c7
Commit
be4b27c7
authored
Mar 28, 2016
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
produce lots of code churn to clean up pylint warnings (almost exclusively whitespace)
parent
89b54e29
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
406 additions
and
457 deletions
+406
-457
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+406
-457
No files found.
Cython/Compiler/Nodes.py
View file @
be4b27c7
...
...
@@ -15,11 +15,6 @@ cython.declare(sys=object, os=object, copy=object,
import
sys
,
os
,
copy
from
itertools
import
chain
if
sys
.
version_info
[
0
]
>=
3
:
_py_int_types
=
int
else
:
_py_int_types
=
(
int
,
long
)
from
.
import
Builtin
from
.Errors
import
error
,
warning
,
InternalError
,
CompileError
from
.
import
Naming
...
...
@@ -27,7 +22,7 @@ from . import PyrexTypes
from
.
import
TypeSlots
from
.PyrexTypes
import
py_object_type
,
error_type
from
.Symtab
import
(
ModuleScope
,
LocalScope
,
ClosureScope
,
StructOrUnionScope
,
PyClassScope
,
CppClassScope
,
TemplateScope
)
StructOrUnionScope
,
PyClassScope
,
CppClassScope
,
TemplateScope
)
from
.Code
import
UtilityCode
from
.StringEncoding
import
EncodedString
from
.
import
Future
...
...
@@ -37,6 +32,11 @@ from ..Utils import add_metaclass
absolute_path_length
=
0
if
sys
.
version_info
[
0
]
>=
3
:
_py_int_types
=
int
else
:
_py_int_types
=
(
int
,
long
)
def
relative_position
(
pos
):
"""
...
...
@@ -55,7 +55,7 @@ def relative_position(pos):
AUTHOR: William Stein
"""
global
absolute_path_length
if
absolute_path_length
==
0
:
if
absolute_path_length
==
0
:
absolute_path_length
=
len
(
os
.
path
.
abspath
(
os
.
getcwd
()))
return
(
pos
[
0
].
get_filenametable_entry
()[
absolute_path_length
+
1
:],
pos
[
1
])
...
...
@@ -342,10 +342,9 @@ class Node(object):
if
not
self
.
pos
:
return
u''
source_desc
,
line
,
col
=
self
.
pos
contents
=
source_desc
.
get_lines
(
encoding
=
'ASCII'
,
error_handling
=
'ignore'
)
contents
=
source_desc
.
get_lines
(
encoding
=
'ASCII'
,
error_handling
=
'ignore'
)
# line numbers start at 1
lines
=
contents
[
max
(
0
,
line
-
3
):
line
]
lines
=
contents
[
max
(
0
,
line
-
3
):
line
]
current
=
lines
[
-
1
]
if
mark_column
:
current
=
current
[:
col
]
+
marker
+
current
[
col
:]
...
...
@@ -426,8 +425,8 @@ class StatListNode(Node):
def
analyse_expressions
(
self
,
env
):
#print "StatListNode.analyse_expressions" ###
self
.
stats
=
[
stat
.
analyse_expressions
(
env
)
for
stat
in
self
.
stats
]
self
.
stats
=
[
stat
.
analyse_expressions
(
env
)
for
stat
in
self
.
stats
]
return
self
def
generate_function_definitions
(
self
,
env
,
code
):
...
...
@@ -512,6 +511,7 @@ class CDeclaratorNode(Node):
# Only C++ functions have templates.
return
None
class
CNameDeclaratorNode
(
CDeclaratorNode
):
# name string The Cython name being declared
# cname string or None C name, if specified
...
...
@@ -521,7 +521,7 @@ class CNameDeclaratorNode(CDeclaratorNode):
default
=
None
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
if
nonempty
and
self
.
name
==
''
:
# May have mistaken the name for the type.
if
base_type
.
is_ptr
or
base_type
.
is_array
or
base_type
.
is_buffer
:
...
...
@@ -538,29 +538,30 @@ class CNameDeclaratorNode(CDeclaratorNode):
self
.
type
=
base_type
return
self
,
base_type
class
CPtrDeclaratorNode
(
CDeclaratorNode
):
# base CDeclaratorNode
child_attrs
=
[
"base"
]
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
"Pointer base type cannot be a Python object"
)
error
(
self
.
pos
,
"Pointer base type cannot be a Python object"
)
ptr_type
=
PyrexTypes
.
c_ptr_type
(
base_type
)
return
self
.
base
.
analyse
(
ptr_type
,
env
,
nonempty
=
nonempty
)
return
self
.
base
.
analyse
(
ptr_type
,
env
,
nonempty
=
nonempty
)
class
CReferenceDeclaratorNode
(
CDeclaratorNode
):
# base CDeclaratorNode
child_attrs
=
[
"base"
]
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
"Reference base type cannot be a Python object"
)
error
(
self
.
pos
,
"Reference base type cannot be a Python object"
)
ref_type
=
PyrexTypes
.
c_ref_type
(
base_type
)
return
self
.
base
.
analyse
(
ref_type
,
env
,
nonempty
=
nonempty
)
return
self
.
base
.
analyse
(
ref_type
,
env
,
nonempty
=
nonempty
)
class
CArrayDeclaratorNode
(
CDeclaratorNode
):
# base CDeclaratorNode
...
...
@@ -568,7 +569,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
child_attrs
=
[
"base"
,
"dimension"
]
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
if
(
base_type
.
is_cpp_class
and
base_type
.
is_template_type
())
or
base_type
.
is_cfunction
:
from
.ExprNodes
import
TupleNode
if
isinstance
(
self
.
dimension
,
TupleNode
):
...
...
@@ -582,7 +583,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
base_type
=
error_type
else
:
base_type
=
base_type
.
specialize_here
(
self
.
pos
,
values
)
return
self
.
base
.
analyse
(
base_type
,
env
,
nonempty
=
nonempty
)
return
self
.
base
.
analyse
(
base_type
,
env
,
nonempty
=
nonempty
)
if
self
.
dimension
:
self
.
dimension
=
self
.
dimension
.
analyse_const_expression
(
env
)
if
not
self
.
dimension
.
type
.
is_int
:
...
...
@@ -597,16 +598,13 @@ class CArrayDeclaratorNode(CDeclaratorNode):
else
:
size
=
None
if
not
base_type
.
is_complete
():
error
(
self
.
pos
,
"Array element type '%s' is incomplete"
%
base_type
)
error
(
self
.
pos
,
"Array element type '%s' is incomplete"
%
base_type
)
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
"Array element cannot be a Python object"
)
error
(
self
.
pos
,
"Array element cannot be a Python object"
)
if
base_type
.
is_cfunction
:
error
(
self
.
pos
,
"Array element cannot be a function"
)
error
(
self
.
pos
,
"Array element cannot be a function"
)
array_type
=
PyrexTypes
.
c_array_type
(
base_type
,
size
)
return
self
.
base
.
analyse
(
array_type
,
env
,
nonempty
=
nonempty
)
return
self
.
base
.
analyse
(
array_type
,
env
,
nonempty
=
nonempty
)
class
CFuncDeclaratorNode
(
CDeclaratorNode
):
...
...
@@ -657,7 +655,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
func_type_args
=
[]
for
i
,
arg_node
in
enumerate
(
self
.
args
):
name_declarator
,
type
=
arg_node
.
analyse
(
env
,
nonempty
=
nonempty
,
is_self_arg
=
(
i
==
0
and
env
.
is_c_class_scope
and
'staticmethod'
not
in
env
.
directives
))
env
,
nonempty
=
nonempty
,
is_self_arg
=
(
i
==
0
and
env
.
is_c_class_scope
and
'staticmethod'
not
in
env
.
directives
))
name
=
name_declarator
.
name
if
name
in
directive_locals
:
type_node
=
directive_locals
[
name
]
...
...
@@ -671,9 +670,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
else
:
type
=
other_type
if
name_declarator
.
cname
:
error
(
self
.
pos
,
"Function argument cannot have C name specification"
)
if
i
==
0
and
env
.
is_c_class_scope
and
type
.
is_unspecified
:
error
(
self
.
pos
,
"Function argument cannot have C name specification"
)
if
i
==
0
and
env
.
is_c_class_scope
and
type
.
is_unspecified
:
# fix the type of self
type
=
env
.
parent_type
# Turn *[] argument into **
...
...
@@ -699,8 +697,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if
(
return_type
.
is_pyobject
and
(
self
.
exception_value
or
self
.
exception_check
)
and
self
.
exception_check
!=
'+'
):
error
(
self
.
pos
,
"Exception clause not allowed for function returning Python object"
)
error
(
self
.
pos
,
"Exception clause not allowed for function returning Python object"
)
else
:
if
self
.
exception_value
:
self
.
exception_value
=
self
.
exception_value
.
analyse_const_expression
(
env
)
...
...
@@ -727,16 +724,15 @@ class CFuncDeclaratorNode(CDeclaratorNode):
"Exception value incompatible with function return type"
)
exc_check
=
self
.
exception_check
if
return_type
.
is_cfunction
:
error
(
self
.
pos
,
"Function cannot return a function"
)
error
(
self
.
pos
,
"Function cannot return a function"
)
func_type
=
PyrexTypes
.
CFuncType
(
return_type
,
func_type_args
,
self
.
has_varargs
,
optional_arg_count
=
self
.
optional_arg_count
,
exception_value
=
exc_val
,
exception_check
=
exc_check
,
calling_convention
=
self
.
base
.
calling_convention
,
nogil
=
self
.
nogil
,
with_gil
=
self
.
with_gil
,
is_overridable
=
self
.
overridable
,
is_const_method
=
self
.
is_const_method
,
templates
=
self
.
templates
)
optional_arg_count
=
self
.
optional_arg_count
,
exception_value
=
exc_val
,
exception_check
=
exc_check
,
calling_convention
=
self
.
base
.
calling_convention
,
nogil
=
self
.
nogil
,
with_gil
=
self
.
with_gil
,
is_overridable
=
self
.
overridable
,
is_const_method
=
self
.
is_const_method
,
templates
=
self
.
templates
)
if
self
.
optional_arg_count
:
if
func_type
.
is_fused
:
...
...
@@ -770,8 +766,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
arg_count_member
=
'%sn'
%
Naming
.
pyrex_prefix
scope
.
declare_var
(
arg_count_member
,
PyrexTypes
.
c_int_type
,
self
.
pos
)
for
arg
in
func_type
.
args
[
len
(
func_type
.
args
)
-
self
.
optional_arg_count
:]:
scope
.
declare_var
(
arg
.
name
,
arg
.
type
,
arg
.
pos
,
allow_pyobject
=
1
)
for
arg
in
func_type
.
args
[
len
(
func_type
.
args
)
-
self
.
optional_arg_count
:]:
scope
.
declare_var
(
arg
.
name
,
arg
.
type
,
arg
.
pos
,
allow_pyobject
=
1
)
struct_cname
=
env
.
mangle
(
Naming
.
opt_arg_prefix
,
self
.
base
.
name
)
...
...
@@ -779,12 +775,12 @@ class CFuncDeclaratorNode(CDeclaratorNode):
struct_cname
=
PyrexTypes
.
get_fused_cname
(
fused_cname
,
struct_cname
)
op_args_struct
=
env
.
global_scope
().
declare_struct_or_union
(
name
=
struct_cname
,
kind
=
'struct'
,
scope
=
scope
,
typedef_flag
=
0
,
pos
=
self
.
pos
,
cname
=
struct_cname
)
name
=
struct_cname
,
kind
=
'struct'
,
scope
=
scope
,
typedef_flag
=
0
,
pos
=
self
.
pos
,
cname
=
struct_cname
)
op_args_struct
.
defined_in_pxd
=
1
op_args_struct
.
used
=
1
...
...
@@ -797,12 +793,12 @@ class CConstDeclaratorNode(CDeclaratorNode):
child_attrs
=
[
"base"
]
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
def
analyse
(
self
,
base_type
,
env
,
nonempty
=
0
):
if
base_type
.
is_pyobject
:
error
(
self
.
pos
,
"Const base type cannot be a Python object"
)
const
=
PyrexTypes
.
c_const_type
(
base_type
)
return
self
.
base
.
analyse
(
const
,
env
,
nonempty
=
nonempty
)
return
self
.
base
.
analyse
(
const
,
env
,
nonempty
=
nonempty
)
class
CArgDeclNode
(
Node
):
...
...
@@ -835,7 +831,7 @@ class CArgDeclNode(Node):
annotation
=
None
is_dynamic
=
0
def
analyse
(
self
,
env
,
nonempty
=
0
,
is_self_arg
=
False
):
def
analyse
(
self
,
env
,
nonempty
=
0
,
is_self_arg
=
False
):
if
is_self_arg
:
self
.
base_type
.
is_self_arg
=
self
.
is_self_arg
=
True
if
self
.
type
is
None
:
...
...
@@ -936,7 +932,7 @@ class CAnalysedBaseTypeNode(Node):
child_attrs
=
[]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
return
self
.
type
...
...
@@ -956,7 +952,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
is_basic_c_type
=
False
complex
=
False
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
# Return type descriptor.
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
type
=
None
...
...
@@ -1039,7 +1035,7 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
name
=
'memoryview'
child_attrs
=
[
'base_type_node'
,
'axes'
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base_type
=
self
.
base_type_node
.
analyse
(
env
)
if
base_type
.
is_error
:
return
base_type
...
...
@@ -1075,7 +1071,7 @@ class CNestedBaseTypeNode(CBaseTypeNode):
child_attrs
=
[
'base_type'
]
def
analyse
(
self
,
env
,
could_be_name
=
None
):
def
analyse
(
self
,
env
,
could_be_name
=
None
):
base_type
=
self
.
base_type
.
analyse
(
env
)
if
base_type
is
PyrexTypes
.
error_type
:
return
PyrexTypes
.
error_type
...
...
@@ -1105,7 +1101,7 @@ class TemplatedTypeNode(CBaseTypeNode):
name
=
None
def
analyse
(
self
,
env
,
could_be_name
=
False
,
base_type
=
None
):
def
analyse
(
self
,
env
,
could_be_name
=
False
,
base_type
=
None
):
if
base_type
is
None
:
base_type
=
self
.
base_type_node
.
analyse
(
env
)
if
base_type
.
is_error
:
return
base_type
...
...
@@ -1138,8 +1134,8 @@ class TemplatedTypeNode(CBaseTypeNode):
if
sys
.
version_info
[
0
]
<
3
:
# Py 2.x enforces byte strings as keyword arguments ...
options
=
dict
([
(
name
.
encode
(
'ASCII'
),
value
)
for
name
,
value
in
options
.
items
()
])
options
=
dict
([(
name
.
encode
(
'ASCII'
),
value
)
for
name
,
value
in
options
.
items
()
])
self
.
type
=
PyrexTypes
.
BufferType
(
base_type
,
**
options
)
...
...
@@ -1156,9 +1152,10 @@ class TemplatedTypeNode(CBaseTypeNode):
dimension
=
None
else
:
dimension
=
self
.
positional_args
[
0
]
self
.
array_declarator
=
CArrayDeclaratorNode
(
self
.
pos
,
base
=
empty_declarator
,
dimension
=
dimension
)
self
.
array_declarator
=
CArrayDeclaratorNode
(
self
.
pos
,
base
=
empty_declarator
,
dimension
=
dimension
)
self
.
type
=
self
.
array_declarator
.
analyse
(
base_type
,
env
)[
1
]
if
self
.
type
.
is_fused
and
env
.
fused_to_specific
:
...
...
@@ -1166,13 +1163,14 @@ class TemplatedTypeNode(CBaseTypeNode):
return
self
.
type
class
CComplexBaseTypeNode
(
CBaseTypeNode
):
# base_type CBaseTypeNode
# declarator CDeclaratorNode
child_attrs
=
[
"base_type"
,
"declarator"
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
_
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
return
type
...
...
@@ -1215,7 +1213,7 @@ class FusedTypeNode(CBaseTypeNode):
# Omit the typedef declaration that self.declarator would produce
entry
.
in_cinclude
=
True
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
types
=
[]
for
type_node
in
self
.
types
:
type
=
type_node
.
analyse_as_type
(
env
)
...
...
@@ -1240,7 +1238,7 @@ class CConstTypeNode(CBaseTypeNode):
child_attrs
=
[
"base_type"
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
if
base
.
is_pyobject
:
error
(
self
.
pos
,
...
...
@@ -1267,7 +1265,7 @@ class CVarDefNode(StatNode):
decorators
=
None
directive_locals
=
None
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
def
analyse_declarations
(
self
,
env
,
dest_scope
=
None
):
if
self
.
directive_locals
is
None
:
self
.
directive_locals
=
{}
if
not
dest_scope
:
...
...
@@ -1301,15 +1299,16 @@ class CVarDefNode(StatNode):
for
declarator
in
self
.
declarators
:
if
(
len
(
self
.
declarators
)
>
1
and
not
isinstance
(
declarator
,
CNameDeclaratorNode
)
and
env
.
directives
[
'warn.multiple_declarators'
]):
warning
(
declarator
.
pos
,
"Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). "
+
and
not
isinstance
(
declarator
,
CNameDeclaratorNode
)
and
env
.
directives
[
'warn.multiple_declarators'
]):
warning
(
declarator
.
pos
,
"Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). "
"Each pointer declaration should be on its own line."
,
1
)
create_extern_wrapper
=
(
self
.
overridable
and
self
.
visibility
==
'extern'
and
env
.
is_module_scope
)
and
self
.
visibility
==
'extern'
and
env
.
is_module_scope
)
if
create_extern_wrapper
:
declarator
.
overridable
=
False
if
isinstance
(
declarator
,
CFuncDeclaratorNode
):
...
...
@@ -1318,11 +1317,9 @@ class CVarDefNode(StatNode):
name_declarator
,
type
=
declarator
.
analyse
(
base_type
,
env
)
if
not
type
.
is_complete
():
if
not
(
self
.
visibility
==
'extern'
and
type
.
is_array
or
type
.
is_memoryviewslice
):
error
(
declarator
.
pos
,
"Variable type '%s' is incomplete"
%
type
)
error
(
declarator
.
pos
,
"Variable type '%s' is incomplete"
%
type
)
if
self
.
visibility
==
'extern'
and
type
.
is_pyobject
:
error
(
declarator
.
pos
,
"Python object cannot be declared extern"
)
error
(
declarator
.
pos
,
"Python object cannot be declared extern"
)
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
if
name
==
''
:
...
...
@@ -1331,7 +1328,8 @@ class CVarDefNode(StatNode):
if
type
.
is_cfunction
:
if
'staticmethod'
in
env
.
directives
:
type
.
is_static_method
=
True
self
.
entry
=
dest_scope
.
declare_cfunction
(
name
,
type
,
declarator
.
pos
,
self
.
entry
=
dest_scope
.
declare_cfunction
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
,
modifiers
=
self
.
modifiers
,
overridable
=
self
.
overridable
)
if
self
.
entry
is
not
None
:
...
...
@@ -1342,9 +1340,10 @@ class CVarDefNode(StatNode):
else
:
if
self
.
directive_locals
:
error
(
self
.
pos
,
"Decorators can only be followed by functions"
)
self
.
entry
=
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
,
is_cdef
=
1
)
self
.
entry
=
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
visibility
,
in_pxd
=
self
.
in_pxd
,
api
=
self
.
api
,
is_cdef
=
1
)
if
Options
.
docstrings
:
self
.
entry
.
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
...
...
@@ -1366,8 +1365,8 @@ class CStructOrUnionDefNode(StatNode):
def
declare
(
self
,
env
,
scope
=
None
):
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
packed
=
self
.
packed
)
self
.
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
packed
=
self
.
packed
)
def
analyse_declarations
(
self
,
env
):
scope
=
None
...
...
@@ -1418,8 +1417,8 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
if
num_optional_templates
and
not
all
(
required
for
_
,
required
in
self
.
templates
[:
-
num_optional_templates
]):
error
(
self
.
pos
,
"Required template parameters must precede optional template parameters."
)
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
)
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
)
def
analyse_declarations
(
self
,
env
):
if
self
.
templates
is
None
:
...
...
@@ -1430,7 +1429,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
for
template_name
,
required
in
self
.
templates
]
scope
=
None
if
self
.
attributes
is
not
None
:
scope
=
CppClassScope
(
self
.
name
,
env
,
templates
=
template_names
)
scope
=
CppClassScope
(
self
.
name
,
env
,
templates
=
template_names
)
def
base_ok
(
base_class
):
if
base_class
.
is_cpp_class
or
base_class
.
is_struct
:
return
True
...
...
@@ -1439,7 +1438,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
base_class_types
=
filter
(
base_ok
,
[
b
.
analyse
(
scope
or
env
)
for
b
in
self
.
base_classes
])
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
scope
,
self
.
pos
,
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
)
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
)
if
self
.
entry
is
None
:
return
self
.
entry
.
is_cpp_class
=
1
...
...
@@ -1493,10 +1492,11 @@ class CEnumDefNode(StatNode):
child_attrs
=
[
"items"
]
def
declare
(
self
,
env
):
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
create_wrapper
=
self
.
create_wrapper
and
self
.
name
is
None
)
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
create_wrapper
=
self
.
create_wrapper
and
self
.
name
is
None
)
def
analyse_declarations
(
self
,
env
):
if
self
.
items
is
not
None
:
...
...
@@ -1505,15 +1505,14 @@ class CEnumDefNode(StatNode):
for
item
in
self
.
items
:
item
.
analyse_declarations
(
env
,
self
.
entry
)
if
self
.
name
is
not
None
:
self
.
entry
.
type
.
values
=
set
(
(
item
.
name
)
for
item
in
self
.
items
)
self
.
entry
.
type
.
values
=
set
(
item
.
name
for
item
in
self
.
items
)
if
self
.
create_wrapper
and
self
.
name
is
not
None
:
from
.UtilityCode
import
CythonUtilityCode
env
.
use_utility_code
(
CythonUtilityCode
.
load
(
"EnumType"
,
"CpdefEnums.pyx"
,
context
=
{
"name"
:
self
.
name
,
"items"
:
tuple
(
item
.
name
for
item
in
self
.
items
)},
outer_module_scope
=
env
.
global_scope
()))
"EnumType"
,
"CpdefEnums.pyx"
,
context
=
{
"name"
:
self
.
name
,
"items"
:
tuple
(
item
.
name
for
item
in
self
.
items
)},
outer_module_scope
=
env
.
global_scope
()))
def
analyse_expressions
(
self
,
env
):
return
self
...
...
@@ -1524,15 +1523,15 @@ class CEnumDefNode(StatNode):
temp
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
py_object_type
,
manage_ref
=
True
)
for
item
in
self
.
entry
.
enum_values
:
code
.
putln
(
"%s = PyInt_FromLong(%s); %s"
%
(
temp
,
item
.
cname
,
code
.
error_goto_if_null
(
temp
,
item
.
pos
)))
temp
,
item
.
cname
,
code
.
error_goto_if_null
(
temp
,
item
.
pos
)))
code
.
put_gotref
(
temp
)
code
.
putln
(
'if (PyDict_SetItemString(%s, "%s", %s) < 0) %s'
%
(
Naming
.
moddict_cname
,
item
.
name
,
temp
,
code
.
error_goto
(
item
.
pos
)))
Naming
.
moddict_cname
,
item
.
name
,
temp
,
code
.
error_goto
(
item
.
pos
)))
code
.
put_decref_clear
(
temp
,
PyrexTypes
.
py_object_type
)
code
.
funcstate
.
release_temp
(
temp
)
...
...
@@ -1550,10 +1549,11 @@ class CEnumDefItemNode(StatNode):
if
not
self
.
value
.
type
.
is_int
:
self
.
value
=
self
.
value
.
coerce_to
(
PyrexTypes
.
c_int_type
,
env
)
self
.
value
=
self
.
value
.
analyse_const_expression
(
env
)
entry
=
env
.
declare_const
(
self
.
name
,
enum_entry
.
type
,
self
.
value
,
self
.
pos
,
cname
=
self
.
cname
,
visibility
=
enum_entry
.
visibility
,
api
=
enum_entry
.
api
,
create_wrapper
=
enum_entry
.
create_wrapper
and
enum_entry
.
name
is
None
)
entry
=
env
.
declare_const
(
self
.
name
,
enum_entry
.
type
,
self
.
value
,
self
.
pos
,
cname
=
self
.
cname
,
visibility
=
enum_entry
.
visibility
,
api
=
enum_entry
.
api
,
create_wrapper
=
enum_entry
.
create_wrapper
and
enum_entry
.
name
is
None
)
enum_entry
.
enum_values
.
append
(
entry
)
if
enum_entry
.
name
:
enum_entry
.
type
.
values
.
append
(
entry
.
cname
)
...
...
@@ -1574,8 +1574,9 @@ class CTypeDefNode(StatNode):
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
entry
=
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
)
entry
=
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
)
if
type
.
is_fused
:
entry
.
in_cinclude
=
True
...
...
@@ -1634,8 +1635,7 @@ class FuncDefNode(StatNode, BlockNode):
arg
.
default
=
arg
.
default
.
analyse_types
(
env
)
arg
.
default
=
arg
.
default
.
coerce_to
(
arg
.
type
,
env
)
else
:
error
(
arg
.
pos
,
"This argument cannot have a default value"
)
error
(
arg
.
pos
,
"This argument cannot have a default value"
)
arg
.
default
=
None
elif
arg
.
kw_only
:
default_seen
=
1
...
...
@@ -1663,8 +1663,7 @@ class FuncDefNode(StatNode, BlockNode):
return
arg
if
other_type
is
None
:
error
(
type_node
.
pos
,
"Not a type"
)
elif
(
orig_type
is
not
PyrexTypes
.
py_object_type
and
not
orig_type
.
same_as
(
other_type
)):
elif
orig_type
is
not
py_object_type
and
not
orig_type
.
same_as
(
other_type
):
error
(
arg
.
base_type
.
pos
,
"Signature does not agree with previous declaration"
)
error
(
type_node
.
pos
,
"Previous declaration here"
)
else
:
...
...
@@ -1680,8 +1679,8 @@ class FuncDefNode(StatNode, BlockNode):
genv
=
genv
.
outer_scope
if
self
.
needs_closure
:
lenv
=
ClosureScope
(
name
=
self
.
entry
.
name
,
outer_scope
=
genv
,
parent_scope
=
env
,
outer_scope
=
genv
,
parent_scope
=
env
,
scope_name
=
self
.
entry
.
cname
)
else
:
lenv
=
LocalScope
(
name
=
self
.
entry
.
name
,
...
...
@@ -1749,11 +1748,9 @@ class FuncDefNode(StatNode, BlockNode):
with_pymethdef
=
(
self
.
needs_assignment_synthesis
(
env
,
code
)
or
self
.
pymethdef_required
)
if
self
.
py_func
:
self
.
py_func
.
generate_function_header
(
code
,
with_pymethdef
=
with_pymethdef
,
proto_only
=
True
)
self
.
generate_function_header
(
code
,
with_pymethdef
=
with_pymethdef
)
self
.
py_func
.
generate_function_header
(
code
,
with_pymethdef
=
with_pymethdef
,
proto_only
=
True
)
self
.
generate_function_header
(
code
,
with_pymethdef
=
with_pymethdef
)
# ----- Local variable declarations
# Find function scope
cenv
=
env
...
...
@@ -1782,10 +1779,9 @@ class FuncDefNode(StatNode, BlockNode):
elif
self
.
return_type
.
is_memoryviewslice
:
init
=
' = '
+
MemoryView
.
memslice_entry_init
code
.
putln
(
"%s%s;"
%
(
self
.
return_type
.
declaration_code
(
Naming
.
retval_cname
),
init
))
code
.
putln
(
"%s%s;"
%
(
self
.
return_type
.
declaration_code
(
Naming
.
retval_cname
),
init
))
tempvardecl_code
=
code
.
insertion_point
()
self
.
generate_keyword_list
(
code
)
...
...
@@ -1810,12 +1806,12 @@ class FuncDefNode(StatNode, BlockNode):
used_buffer_entries
=
[
entry
for
entry
in
lenv
.
buffer_entries
if
entry
.
used
]
acquire_gil_for_var_decls_only
=
(
lenv
.
nogil
and
lenv
.
has_with_gil_block
and
(
have_object_args
or
used_buffer_entries
))
lenv
.
nogil
and
lenv
.
has_with_gil_block
and
(
have_object_args
or
used_buffer_entries
))
acquire_gil_for_refnanny_only
=
(
lenv
.
nogil
and
lenv
.
has_with_gil_block
and
not
acquire_gil_for_var_decls_only
)
lenv
.
nogil
and
lenv
.
has_with_gil_block
and
not
acquire_gil_for_var_decls_only
)
use_refnanny
=
not
lenv
.
nogil
or
lenv
.
has_with_gil_block
...
...
@@ -2038,16 +2034,13 @@ class FuncDefNode(StatNode, BlockNode):
# See if our return value is uninitialized on non-error return
# from . import MemoryView
# MemoryView.err_if_nogil_initialized_check(self.pos, env)
cond
=
code
.
unlikely
(
self
.
return_type
.
error_condition
(
Naming
.
retval_cname
))
cond
=
code
.
unlikely
(
self
.
return_type
.
error_condition
(
Naming
.
retval_cname
))
code
.
putln
(
'if (%s) {'
%
cond
)
if
env
.
nogil
:
code
.
put_ensure_gil
()
code
.
putln
(
'PyErr_SetString('
'PyExc_TypeError,'
'"Memoryview return value is not initialized");'
)
'PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");'
)
if
env
.
nogil
:
code
.
put_release_ensured_gil
()
code
.
putln
(
...
...
@@ -2061,8 +2054,7 @@ class FuncDefNode(StatNode, BlockNode):
continue
if
entry
.
type
.
is_memoryviewslice
:
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
have_gil
=
not
lenv
.
nogil
)
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
have_gil
=
not
lenv
.
nogil
)
elif
entry
.
type
.
is_pyobject
:
if
not
entry
.
is_arg
or
len
(
entry
.
cf_assignments
)
>
1
:
if
entry
.
xdecref_cleanup
:
...
...
@@ -2073,8 +2065,7 @@ class FuncDefNode(StatNode, BlockNode):
# Decref any increfed args
for
entry
in
lenv
.
arg_entries
:
if
entry
.
type
.
is_pyobject
:
if
((
acquire_gil
or
len
(
entry
.
cf_assignments
)
>
1
)
and
not
entry
.
in_closure
):
if
(
acquire_gil
or
len
(
entry
.
cf_assignments
)
>
1
)
and
not
entry
.
in_closure
:
code
.
put_var_decref
(
entry
)
elif
(
entry
.
type
.
is_memoryviewslice
and
(
not
is_cdef
or
len
(
entry
.
cf_assignments
)
>
1
)):
...
...
@@ -2099,7 +2090,7 @@ class FuncDefNode(StatNode, BlockNode):
# Returning -1 for __hash__ is supposed to signal an error
# We do as Python instances and coerce -1 into -2.
code
.
putln
(
"if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;"
%
(
Naming
.
retval_cname
,
Naming
.
retval_cname
))
Naming
.
retval_cname
,
Naming
.
retval_cname
))
if
profile
or
linetrace
:
code
.
funcstate
.
can_trace
=
False
...
...
@@ -2140,8 +2131,7 @@ class FuncDefNode(StatNode, BlockNode):
if
arg
.
type
.
is_void
:
error
(
arg
.
pos
,
"Invalid use of 'void'"
)
elif
not
arg
.
type
.
is_complete
()
and
not
(
arg
.
type
.
is_array
or
arg
.
type
.
is_memoryviewslice
):
error
(
arg
.
pos
,
"Argument type '%s' is incomplete"
%
arg
.
type
)
error
(
arg
.
pos
,
"Argument type '%s' is incomplete"
%
arg
.
type
)
return
env
.
declare_arg
(
arg
.
name
,
arg
.
type
,
arg
.
pos
)
def
generate_arg_type_test
(
self
,
arg
,
code
):
...
...
@@ -2160,8 +2150,7 @@ class FuncDefNode(StatNode, BlockNode):
arg
.
type
.
is_builtin_type
,
code
.
error_goto
(
arg
.
pos
)))
else
:
error
(
arg
.
pos
,
"Cannot test type of extern C class "
"without type object name specification"
)
error
(
arg
.
pos
,
"Cannot test type of extern C class without type object name specification"
)
def
generate_arg_none_check
(
self
,
arg
,
code
):
# Generate None check for one argument.
...
...
@@ -2282,14 +2271,14 @@ class CFuncDefNode(FuncDefNode):
self
.
is_static_method
=
'staticmethod'
in
env
.
directives
and
not
env
.
lookup_here
(
'staticmethod'
)
# The 2 here is because we need both function and argument names.
if
isinstance
(
self
.
declarator
,
CFuncDeclaratorNode
):
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
2
*
(
self
.
body
is
not
None
),
directive_locals
=
self
.
directive_locals
)
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
2
*
(
self
.
body
is
not
None
),
directive_locals
=
self
.
directive_locals
)
else
:
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
2
*
(
self
.
body
is
not
None
))
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
2
*
(
self
.
body
is
not
None
))
if
not
type
.
is_cfunction
:
error
(
self
.
pos
,
"Suite attached to non-function declaration"
)
error
(
self
.
pos
,
"Suite attached to non-function declaration"
)
# Remember the actual type according to the function header
# written here, because the type in the symbol table entry
# may be different if we're overriding a C method inherited
...
...
@@ -2306,10 +2295,9 @@ class CFuncDefNode(FuncDefNode):
opt_arg_count
=
self
.
cfunc_declarator
.
optional_arg_count
if
(
self
.
visibility
==
'public'
or
self
.
api
)
and
opt_arg_count
:
error
(
self
.
cfunc_declarator
.
pos
,
"Function with optional arguments may not be declared "
"public or api"
)
"Function with optional arguments may not be declared public or api"
)
if
(
type
.
exception_check
==
'+'
and
self
.
visibility
!=
'extern'
)
:
if
type
.
exception_check
==
'+'
and
self
.
visibility
!=
'extern'
:
warning
(
self
.
cfunc_declarator
.
pos
,
"Only extern functions can throw C++ exceptions."
)
...
...
@@ -2330,8 +2318,7 @@ class CFuncDefNode(FuncDefNode):
if
type_arg
.
type
.
is_buffer
:
if
self
.
type
.
nogil
:
error
(
formal_arg
.
pos
,
"Buffer may not be acquired without the GIL. "
"Consider using memoryview slices instead."
)
"Buffer may not be acquired without the GIL. Consider using memoryview slices instead."
)
elif
'inline'
in
self
.
modifiers
:
warning
(
formal_arg
.
pos
,
"Buffer unpacking not optimized away."
,
1
)
...
...
@@ -2350,8 +2337,7 @@ class CFuncDefNode(FuncDefNode):
self
.
entry
.
inline_func_in_pxd
=
self
.
inline_in_pxd
self
.
return_type
=
type
.
return_type
if
self
.
return_type
.
is_array
and
self
.
visibility
!=
'extern'
:
error
(
self
.
pos
,
"Function cannot return an array"
)
error
(
self
.
pos
,
"Function cannot return an array"
)
if
self
.
return_type
.
is_cpp_class
:
self
.
return_type
.
check_nullary_constructor
(
self
.
pos
,
"used as a return value"
)
...
...
@@ -2369,33 +2355,33 @@ class CFuncDefNode(FuncDefNode):
# TODO(robertwb): Finish this up, perhaps via more function refactoring.
error
(
self
.
pos
,
"static cpdef methods not yet supported"
)
name
=
self
.
entry
.
name
py_func_body
=
self
.
call_self_node
(
is_module_scope
=
env
.
is_module_scope
)
py_func_body
=
self
.
call_self_node
(
is_module_scope
=
env
.
is_module_scope
)
if
self
.
is_static_method
:
from
.ExprNodes
import
NameNode
decorators
=
[
DecoratorNode
(
self
.
pos
,
decorator
=
NameNode
(
self
.
pos
,
name
=
'staticmethod'
))]
decorators
[
0
].
decorator
.
analyse_types
(
env
)
else
:
decorators
=
[]
self
.
py_func
=
DefNode
(
pos
=
self
.
pos
,
name
=
self
.
entry
.
name
,
args
=
self
.
args
,
star_arg
=
None
,
starstar_arg
=
None
,
doc
=
self
.
doc
,
body
=
py_func_body
,
decorators
=
decorators
,
is_wrapper
=
1
)
self
.
py_func
=
DefNode
(
pos
=
self
.
pos
,
name
=
self
.
entry
.
name
,
args
=
self
.
args
,
star_arg
=
None
,
starstar_arg
=
None
,
doc
=
self
.
doc
,
body
=
py_func_body
,
decorators
=
decorators
,
is_wrapper
=
1
)
self
.
py_func
.
is_module_scope
=
env
.
is_module_scope
self
.
py_func
.
analyse_declarations
(
env
)
self
.
py_func_stat
=
StatListNode
(
pos
=
self
.
pos
,
stats
=
[
self
.
py_func
])
self
.
py_func_stat
=
StatListNode
(
self
.
pos
,
stats
=
[
self
.
py_func
])
self
.
py_func
.
type
=
PyrexTypes
.
py_object_type
self
.
entry
.
as_variable
=
self
.
py_func
.
entry
self
.
entry
.
used
=
self
.
entry
.
as_variable
.
used
=
True
# Reset scope entry the above cfunction
env
.
entries
[
name
]
=
self
.
entry
if
(
not
self
.
entry
.
is_final_cmethod
and
(
not
env
.
is_module_scope
or
Options
.
lookup_module_cpdef
)):
self
.
override
=
OverrideCheckNode
(
self
.
pos
,
py_func
=
self
.
py_func
)
(
not
env
.
is_module_scope
or
Options
.
lookup_module_cpdef
)):
self
.
override
=
OverrideCheckNode
(
self
.
pos
,
py_func
=
self
.
py_func
)
self
.
body
=
StatListNode
(
self
.
pos
,
stats
=
[
self
.
override
,
self
.
body
])
def
_validate_type_visibility
(
self
,
type
,
pos
,
env
):
...
...
@@ -2408,8 +2394,7 @@ class CFuncDefNode(FuncDefNode):
if
public_or_api
and
entry
and
env
.
is_module_scope
:
if
not
(
entry
.
visibility
in
(
'public'
,
'extern'
)
or
entry
.
api
or
entry
.
in_cinclude
):
error
(
pos
,
"Function declared public or api may not have "
"private types"
)
error
(
pos
,
"Function declared public or api may not have private types"
)
def
call_self_node
(
self
,
omit_optional_args
=
0
,
is_module_scope
=
0
):
from
.
import
ExprNodes
...
...
@@ -2476,7 +2461,7 @@ class CFuncDefNode(FuncDefNode):
def
needs_assignment_synthesis
(
self
,
env
,
code
=
None
):
return
False
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
with_opt_args
=
1
,
with_dispatch
=
1
,
cname
=
None
):
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
with_opt_args
=
1
,
with_dispatch
=
1
,
cname
=
None
):
scope
=
self
.
local_scope
arg_decls
=
[]
type
=
self
.
type
...
...
@@ -2517,7 +2502,8 @@ class CFuncDefNode(FuncDefNode):
code
.
globalstate
.
parts
[
'module_declarations'
].
putln
(
self
.
template_declaration
)
code
.
putln
(
self
.
template_declaration
)
if
needs_proto
:
code
.
globalstate
.
parts
[
'module_declarations'
].
putln
(
"%s%s%s; /* proto*/"
%
(
storage_class
,
modifiers
,
header
))
code
.
globalstate
.
parts
[
'module_declarations'
].
putln
(
"%s%s%s; /* proto*/"
%
(
storage_class
,
modifiers
,
header
))
code
.
putln
(
"%s%s%s {"
%
(
storage_class
,
modifiers
,
header
))
def
generate_argument_declarations
(
self
,
env
,
code
):
...
...
@@ -2606,11 +2592,11 @@ class CFuncDefNode(FuncDefNode):
entry
=
entry
.
prev_entry
entry
.
func_cname
=
"%s%swrap_%s"
%
(
self
.
entry
.
func_cname
,
Naming
.
pyrex_prefix
,
k
)
code
.
putln
()
self
.
generate_function_header
(
code
,
0
,
with_dispatch
=
entry
.
type
.
is_overridable
,
with_opt_args
=
entry
.
type
.
optional_arg_count
,
cname
=
entry
.
func_cname
)
self
.
generate_function_header
(
code
,
0
,
with_dispatch
=
entry
.
type
.
is_overridable
,
with_opt_args
=
entry
.
type
.
optional_arg_count
,
cname
=
entry
.
func_cname
)
if
not
self
.
return_type
.
is_void
:
code
.
put
(
'return '
)
args
=
self
.
type
.
args
...
...
@@ -2641,6 +2627,7 @@ class PyArgDeclNode(Node):
def
generate_function_definitions
(
self
,
env
,
code
):
self
.
entry
.
generate_function_definitions
(
env
,
code
)
class
DecoratorNode
(
Node
):
# A decorator
#
...
...
@@ -2717,18 +2704,18 @@ class DefNode(FuncDefNode):
cfunc_args
=
[]
for
formal_arg
in
self
.
args
:
name_declarator
,
type
=
formal_arg
.
analyse
(
scope
,
nonempty
=
1
)
cfunc_args
.
append
(
PyrexTypes
.
CFuncTypeArg
(
name
=
name_declarator
.
name
,
cname
=
None
,
type
=
py_object_type
,
pos
=
formal_arg
.
pos
))
cfunc_type
=
PyrexTypes
.
CFuncType
(
return_type
=
py_object_type
,
args
=
cfunc_args
,
has_varargs
=
False
,
exception_value
=
None
,
exception_check
=
False
,
nogil
=
False
,
with_gil
=
False
,
is_overridable
=
overridable
)
cfunc_args
.
append
(
PyrexTypes
.
CFuncTypeArg
(
name
=
name_declarator
.
name
,
cname
=
None
,
type
=
py_object_type
,
pos
=
formal_arg
.
pos
))
cfunc_type
=
PyrexTypes
.
CFuncType
(
return_type
=
py_object_type
,
args
=
cfunc_args
,
has_varargs
=
False
,
exception_value
=
None
,
exception_check
=
False
,
nogil
=
False
,
with_gil
=
False
,
is_overridable
=
overridable
)
cfunc
=
CVarDefNode
(
self
.
pos
,
type
=
cfunc_type
)
else
:
if
scope
is
None
:
...
...
@@ -2739,7 +2726,7 @@ class DefNode(FuncDefNode):
error
(
cfunc
.
pos
,
"previous declaration here"
)
for
i
,
(
formal_arg
,
type_arg
)
in
enumerate
(
zip
(
self
.
args
,
cfunc_type
.
args
)):
name_declarator
,
type
=
formal_arg
.
analyse
(
scope
,
nonempty
=
1
,
is_self_arg
=
(
i
==
0
and
scope
.
is_c_class_scope
))
is_self_arg
=
(
i
==
0
and
scope
.
is_c_class_scope
))
if
type
is
None
or
type
is
PyrexTypes
.
py_object_type
:
formal_arg
.
type
=
type_arg
.
type
formal_arg
.
name_declarator
=
name_declarator
...
...
@@ -2747,29 +2734,30 @@ class DefNode(FuncDefNode):
if
cfunc_type
.
exception_value
is
None
:
exception_value
=
None
else
:
exception_value
=
ExprNodes
.
ConstNode
(
self
.
pos
,
value
=
cfunc_type
.
exception_value
,
type
=
cfunc_type
.
return_type
)
exception_value
=
ExprNodes
.
ConstNode
(
self
.
pos
,
value
=
cfunc_type
.
exception_value
,
type
=
cfunc_type
.
return_type
)
declarator
=
CFuncDeclaratorNode
(
self
.
pos
,
base
=
CNameDeclaratorNode
(
self
.
pos
,
name
=
self
.
name
,
cname
=
None
),
args
=
self
.
args
,
has_varargs
=
False
,
exception_check
=
cfunc_type
.
exception_check
,
exception_value
=
exception_value
,
with_gil
=
cfunc_type
.
with_gil
,
nogil
=
cfunc_type
.
nogil
)
base
=
CNameDeclaratorNode
(
self
.
pos
,
name
=
self
.
name
,
cname
=
None
),
args
=
self
.
args
,
has_varargs
=
False
,
exception_check
=
cfunc_type
.
exception_check
,
exception_value
=
exception_value
,
with_gil
=
cfunc_type
.
with_gil
,
nogil
=
cfunc_type
.
nogil
)
return
CFuncDefNode
(
self
.
pos
,
modifiers
=
modifiers
or
[],
base_type
=
CAnalysedBaseTypeNode
(
self
.
pos
,
type
=
cfunc_type
.
return_type
),
declarator
=
declarator
,
body
=
self
.
body
,
doc
=
self
.
doc
,
overridable
=
cfunc_type
.
is_overridable
,
type
=
cfunc_type
,
with_gil
=
cfunc_type
.
with_gil
,
nogil
=
cfunc_type
.
nogil
,
visibility
=
'private'
,
api
=
False
,
directive_locals
=
getattr
(
cfunc
,
'directive_locals'
,
{}),
directive_returns
=
returns
)
modifiers
=
modifiers
or
[],
base_type
=
CAnalysedBaseTypeNode
(
self
.
pos
,
type
=
cfunc_type
.
return_type
),
declarator
=
declarator
,
body
=
self
.
body
,
doc
=
self
.
doc
,
overridable
=
cfunc_type
.
is_overridable
,
type
=
cfunc_type
,
with_gil
=
cfunc_type
.
with_gil
,
nogil
=
cfunc_type
.
nogil
,
visibility
=
'private'
,
api
=
False
,
directive_locals
=
getattr
(
cfunc
,
'directive_locals'
,
{}),
directive_returns
=
returns
)
def
is_cdef_func_compatible
(
self
):
"""Determines if the function's signature is compatible with a
...
...
@@ -2850,8 +2838,7 @@ class DefNode(FuncDefNode):
self
.
align_argument_type
(
env
,
arg
)
if
name_declarator
and
name_declarator
.
cname
:
error
(
self
.
pos
,
"Python function argument cannot have C name specification"
)
error
(
self
.
pos
,
"Python function argument cannot have C name specification"
)
arg
.
type
=
arg
.
type
.
as_argument_type
()
arg
.
hdr_type
=
None
arg
.
needs_conversion
=
0
...
...
@@ -2863,7 +2850,7 @@ class DefNode(FuncDefNode):
elif
arg
.
not_none
:
arg
.
accept_none
=
False
elif
(
arg
.
type
.
is_extension_type
or
arg
.
type
.
is_builtin_type
or
arg
.
type
.
is_buffer
or
arg
.
type
.
is_memoryviewslice
):
or
arg
.
type
.
is_buffer
or
arg
.
type
.
is_memoryviewslice
):
if
arg
.
default
and
arg
.
default
.
constant_result
is
None
:
# special case: def func(MyType obj = None)
arg
.
accept_none
=
True
...
...
@@ -2903,8 +2890,8 @@ class DefNode(FuncDefNode):
sig
=
self
.
entry
.
signature
nfixed
=
sig
.
num_fixed_args
()
if
sig
is
TypeSlots
.
pymethod_signature
and
nfixed
==
1
\
and
len
(
self
.
args
)
==
0
and
self
.
star_arg
:
if
(
sig
is
TypeSlots
.
pymethod_signature
and
nfixed
==
1
and
len
(
self
.
args
)
==
0
and
self
.
star_arg
)
:
# this is the only case where a diverging number of
# arguments is not an error - when we have no explicit
# 'self' parameter as in method(*args)
...
...
@@ -2922,7 +2909,7 @@ class DefNode(FuncDefNode):
sig
.
has_generic_args
=
True
if
((
self
.
is_classmethod
or
self
.
is_staticmethod
)
and
self
.
has_fused_arguments
and
env
.
is_c_class_scope
):
self
.
has_fused_arguments
and
env
.
is_c_class_scope
):
del
self
.
decorator_indirection
.
stats
[:]
for
i
in
range
(
min
(
nfixed
,
len
(
self
.
args
))):
...
...
@@ -2955,8 +2942,7 @@ class DefNode(FuncDefNode):
if
not
sig
.
has_generic_args
:
self
.
bad_signature
()
for
arg
in
self
.
args
:
if
arg
.
is_generic
and
\
(
arg
.
type
.
is_extension_type
or
arg
.
type
.
is_builtin_type
):
if
arg
.
is_generic
and
(
arg
.
type
.
is_extension_type
or
arg
.
type
.
is_builtin_type
):
arg
.
needs_type_test
=
1
def
bad_signature
(
self
):
...
...
@@ -2969,10 +2955,8 @@ class DefNode(FuncDefNode):
desc
=
"Special method"
else
:
desc
=
"Method"
error
(
self
.
pos
,
"%s %s has wrong number of arguments "
"(%d declared, %s expected)"
%
(
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
error
(
self
.
pos
,
"%s %s has wrong number of arguments (%d declared, %s expected)"
%
(
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
def
declare_pyfunction
(
self
,
env
):
#print "DefNode.declare_pyfunction:", self.name, "in", env ###
...
...
@@ -2981,8 +2965,7 @@ class DefNode(FuncDefNode):
if
entry
:
if
entry
.
is_final_cmethod
and
not
env
.
parent_type
.
is_final_type
:
error
(
self
.
pos
,
"Only final types can have final Python (def/cpdef) methods"
)
if
(
entry
.
type
.
is_cfunction
and
not
entry
.
is_builtin_cmethod
and
not
self
.
is_wrapper
):
if
entry
.
type
.
is_cfunction
and
not
entry
.
is_builtin_cmethod
and
not
self
.
is_wrapper
:
warning
(
self
.
pos
,
"Overriding cdef method with def method."
,
5
)
entry
=
env
.
declare_pyfunction
(
name
,
self
.
pos
,
allow_redefine
=
not
self
.
is_wrapper
)
self
.
entry
=
entry
...
...
@@ -2992,7 +2975,8 @@ class DefNode(FuncDefNode):
entry
.
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
entry
.
doc_cname
=
Naming
.
funcdoc_prefix
+
prefix
+
name
if
entry
.
is_special
:
if
entry
.
name
in
TypeSlots
.
invisible
or
not
entry
.
doc
or
(
entry
.
name
in
'__getattr__'
and
env
.
directives
[
'fast_getattr'
]):
if
entry
.
name
in
TypeSlots
.
invisible
or
not
entry
.
doc
or
(
entry
.
name
in
'__getattr__'
and
env
.
directives
[
'fast_getattr'
]):
entry
.
wrapperbase_cname
=
None
else
:
entry
.
wrapperbase_cname
=
Naming
.
wrapperbase_prefix
+
prefix
+
name
...
...
@@ -3314,14 +3298,14 @@ class DefNodeWrapper(FuncDefNode):
arg_code_list
.
append
(
"CYTHON_UNUSED PyObject *unused"
)
if
sig
.
has_generic_args
:
arg_code_list
.
append
(
"PyObject *%s, PyObject *%s"
%
(
Naming
.
args_cname
,
Naming
.
kwds_cname
))
"PyObject *%s, PyObject *%s"
%
(
Naming
.
args_cname
,
Naming
.
kwds_cname
))
arg_code
=
", "
.
join
(
arg_code_list
)
# Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__'
mf
=
""
if
(
entry
.
name
in
(
"__getbuffer__"
,
"__releasebuffer__"
)
and
entry
.
scope
.
is_c_class_scope
):
and
entry
.
scope
.
is_c_class_scope
):
mf
=
"CYTHON_UNUSED "
with_pymethdef
=
False
...
...
@@ -3335,7 +3319,7 @@ class DefNodeWrapper(FuncDefNode):
# want the prototype for the "fused cpdef", in case we're
# checking to see if our method was overridden in Python
self
.
target
.
fused_py_func
.
generate_function_header
(
code
,
with_pymethdef
,
proto_only
=
True
)
code
,
with_pymethdef
,
proto_only
=
True
)
return
if
(
Options
.
docstrings
and
entry
.
doc
and
...
...
@@ -3361,8 +3345,7 @@ class DefNodeWrapper(FuncDefNode):
if
with_pymethdef
or
self
.
target
.
fused_py_func
:
code
.
put
(
"static PyMethodDef %s = "
%
entry
.
pymethdef_cname
)
"static PyMethodDef %s = "
%
entry
.
pymethdef_cname
)
code
.
put_pymethoddef
(
self
.
target
.
entry
,
";"
,
allow_skip
=
False
)
code
.
putln
(
"%s {"
%
header
)
...
...
@@ -3391,7 +3374,7 @@ class DefNodeWrapper(FuncDefNode):
for
arg
in
self
.
args
:
if
not
arg
.
type
.
is_pyobject
:
if
not
arg
.
type
.
create_from_py_utility_code
(
env
):
pass
# will fail later
pass
# will fail later
if
not
self
.
signature_has_generic_args
():
if
has_star_or_kw_args
:
...
...
@@ -3438,7 +3421,7 @@ class DefNodeWrapper(FuncDefNode):
code
.
putln
(
"if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {"
%
Naming
.
args_cname
)
code
.
put
(
'__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;'
%
(
self
.
name
,
Naming
.
args_cname
,
self
.
error_value
()))
self
.
name
,
Naming
.
args_cname
,
self
.
error_value
()))
code
.
putln
(
"}"
)
if
self
.
starstar_arg
:
...
...
@@ -3460,10 +3443,10 @@ class DefNodeWrapper(FuncDefNode):
if
all
(
ref
.
node
.
allow_null
for
ref
in
self
.
starstar_arg
.
entry
.
cf_references
):
code
.
putln
(
"if (%s) {"
%
kwarg_check
)
code
.
putln
(
"%s = PyDict_Copy(%s); if (unlikely(!%s)) return %s;"
%
(
self
.
starstar_arg
.
entry
.
cname
,
Naming
.
kwds_cname
,
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
self
.
starstar_arg
.
entry
.
cname
,
Naming
.
kwds_cname
,
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
code
.
put_gotref
(
self
.
starstar_arg
.
entry
.
cname
)
code
.
putln
(
"} else {"
)
code
.
putln
(
"%s = NULL;"
%
(
self
.
starstar_arg
.
entry
.
cname
,))
...
...
@@ -3471,20 +3454,20 @@ class DefNodeWrapper(FuncDefNode):
self
.
starstar_arg
.
entry
.
xdecref_cleanup
=
1
else
:
code
.
put
(
"%s = (%s) ? PyDict_Copy(%s) : PyDict_New(); "
%
(
self
.
starstar_arg
.
entry
.
cname
,
Naming
.
kwds_cname
,
Naming
.
kwds_cname
))
self
.
starstar_arg
.
entry
.
cname
,
Naming
.
kwds_cname
,
Naming
.
kwds_cname
))
code
.
putln
(
"if (unlikely(!%s)) return %s;"
%
(
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
self
.
starstar_arg
.
entry
.
xdecref_cleanup
=
0
code
.
put_gotref
(
self
.
starstar_arg
.
entry
.
cname
)
if
self
.
self_in_stararg
and
not
self
.
target
.
is_staticmethod
:
# need to create a new tuple with 'self' inserted as first item
code
.
put
(
"%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) "
%
(
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
,
self
.
star_arg
.
entry
.
cname
))
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
,
self
.
star_arg
.
entry
.
cname
))
if
self
.
starstar_arg
and
self
.
starstar_arg
.
entry
.
cf_used
:
code
.
putln
(
"{"
)
code
.
put_xdecref_clear
(
self
.
starstar_arg
.
entry
.
cname
,
py_object_type
)
...
...
@@ -3512,8 +3495,8 @@ class DefNodeWrapper(FuncDefNode):
elif
self
.
star_arg
:
code
.
put_incref
(
Naming
.
args_cname
,
py_object_type
)
code
.
putln
(
"%s = %s;"
%
(
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
))
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
))
self
.
star_arg
.
entry
.
xdecref_cleanup
=
0
def
generate_tuple_and_keyword_parsing_code
(
self
,
args
,
success_label
,
code
):
...
...
@@ -3558,8 +3541,8 @@ class DefNodeWrapper(FuncDefNode):
all_args
=
tuple
(
positional_args
)
+
tuple
(
kw_only_args
)
code
.
putln
(
"static PyObject **%s[] = {%s,0};"
%
(
Naming
.
pykwdlist_cname
,
','
.
join
([
'&%s'
%
code
.
intern_identifier
(
arg
.
name
)
for
arg
in
all_args
])))
','
.
join
([
'&%s'
%
code
.
intern_identifier
(
arg
.
name
)
for
arg
in
all_args
])))
# Before being converted and assigned to the target variables,
# borrowed references to all unpacked argument values are
...
...
@@ -3589,14 +3572,14 @@ class DefNodeWrapper(FuncDefNode):
else
:
compare
=
'<'
code
.
putln
(
'} else if (PyTuple_GET_SIZE(%s) %s %d) {'
%
(
Naming
.
args_cname
,
compare
,
min_positional_args
))
Naming
.
args_cname
,
compare
,
min_positional_args
))
code
.
put_goto
(
argtuple_error_label
)
if
self
.
num_required_kw_args
:
# pure error case: keywords required but not passed
if
max_positional_args
>
min_positional_args
and
not
self
.
star_arg
:
code
.
putln
(
'} else if (PyTuple_GET_SIZE(%s) > %d) {'
%
(
Naming
.
args_cname
,
max_positional_args
))
Naming
.
args_cname
,
max_positional_args
))
code
.
put_goto
(
argtuple_error_label
)
code
.
putln
(
'} else {'
)
for
i
,
arg
in
enumerate
(
kw_only_args
):
...
...
@@ -3604,8 +3587,8 @@ class DefNodeWrapper(FuncDefNode):
pystring_cname
=
code
.
intern_identifier
(
arg
.
name
)
# required keyword-only argument missing
code
.
put
(
'__Pyx_RaiseKeywordRequired("%s", %s); '
%
(
self
.
name
,
pystring_cname
))
self
.
name
,
pystring_cname
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
break
...
...
@@ -3657,9 +3640,9 @@ class DefNodeWrapper(FuncDefNode):
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"RaiseArgTupleInvalid"
,
"FunctionArguments.c"
))
code
.
put
(
'__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); '
%
(
self
.
name
,
has_fixed_positional_count
,
min_positional_args
,
max_positional_args
,
Naming
.
args_cname
))
self
.
name
,
has_fixed_positional_count
,
min_positional_args
,
max_positional_args
,
Naming
.
args_cname
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
def
generate_arg_assignment
(
self
,
arg
,
item
,
code
):
...
...
@@ -3684,10 +3667,9 @@ class DefNodeWrapper(FuncDefNode):
code
.
error_goto_if
(
arg
.
type
.
error_condition
(
arg
.
entry
.
cname
),
arg
.
pos
)))
if
arg
.
default
:
code
.
putln
(
'} else {'
)
code
.
putln
(
"%s = %s;"
%
(
arg
.
entry
.
cname
,
arg
.
calculate_default_value_code
(
code
)))
code
.
putln
(
"%s = %s;"
%
(
arg
.
entry
.
cname
,
arg
.
calculate_default_value_code
(
code
)))
if
arg
.
type
.
is_memoryviewslice
:
code
.
put_incref_memoryviewslice
(
arg
.
entry
.
cname
,
have_gil
=
True
)
...
...
@@ -3699,18 +3681,18 @@ class DefNodeWrapper(FuncDefNode):
if
self
.
starstar_arg
:
self
.
starstar_arg
.
entry
.
xdecref_cleanup
=
0
code
.
putln
(
'%s = PyDict_New(); if (unlikely(!%s)) return %s;'
%
(
self
.
starstar_arg
.
entry
.
cname
,
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
self
.
starstar_arg
.
entry
.
cname
,
self
.
starstar_arg
.
entry
.
cname
,
self
.
error_value
()))
code
.
put_gotref
(
self
.
starstar_arg
.
entry
.
cname
)
if
self
.
star_arg
:
self
.
star_arg
.
entry
.
xdecref_cleanup
=
0
code
.
putln
(
'if (PyTuple_GET_SIZE(%s) > %d) {'
%
(
Naming
.
args_cname
,
max_positional_args
))
Naming
.
args_cname
,
max_positional_args
))
code
.
putln
(
'%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));'
%
(
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
,
max_positional_args
,
Naming
.
args_cname
))
self
.
star_arg
.
entry
.
cname
,
Naming
.
args_cname
,
max_positional_args
,
Naming
.
args_cname
))
code
.
putln
(
"if (unlikely(!%s)) {"
%
self
.
star_arg
.
entry
.
cname
)
if
self
.
starstar_arg
:
code
.
put_decref_clear
(
self
.
starstar_arg
.
entry
.
cname
,
py_object_type
)
...
...
@@ -3754,7 +3736,7 @@ class DefNodeWrapper(FuncDefNode):
for
i
in
range
(
max_positional_args
-
1
,
-
1
,
-
1
):
code
.
put
(
'case %2d: '
%
(
i
+
1
))
code
.
putln
(
"values[%d] = PyTuple_GET_ITEM(%s, %d);"
%
(
i
,
Naming
.
args_cname
,
i
))
i
,
Naming
.
args_cname
,
i
))
code
.
putln
(
'case 0: break;'
)
if
not
self
.
star_arg
:
code
.
put
(
'default: '
)
# more arguments than allowed
...
...
@@ -3813,14 +3795,14 @@ class DefNodeWrapper(FuncDefNode):
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"RaiseArgTupleInvalid"
,
"FunctionArguments.c"
))
code
.
put
(
'__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); '
%
(
self
.
name
,
has_fixed_positional_count
,
min_positional_args
,
max_positional_args
,
i
))
self
.
name
,
has_fixed_positional_count
,
min_positional_args
,
max_positional_args
,
i
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
putln
(
'}'
)
elif
arg
.
kw_only
:
code
.
putln
(
'else {'
)
code
.
put
(
'__Pyx_RaiseKeywordRequired("%s", %s); '
%
(
self
.
name
,
pystring_cname
))
code
.
put
(
'__Pyx_RaiseKeywordRequired("%s", %s); '
%
(
self
.
name
,
pystring_cname
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
putln
(
'}'
)
if
max_positional_args
>
0
:
...
...
@@ -3843,20 +3825,19 @@ class DefNodeWrapper(FuncDefNode):
pos_arg_count
=
"0"
elif
self
.
star_arg
:
code
.
putln
(
"const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;"
%
(
max_positional_args
,
max_positional_args
))
max_positional_args
,
max_positional_args
))
pos_arg_count
=
"used_pos_args"
else
:
pos_arg_count
=
"pos_args"
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"ParseKeywords"
,
"FunctionArguments.c"
))
code
.
putln
(
'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s'
%
(
Naming
.
kwds_cname
,
Naming
.
pykwdlist_cname
,
self
.
starstar_arg
and
self
.
starstar_arg
.
entry
.
cname
or
'0'
,
pos_arg_count
,
self
.
name
,
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s'
%
(
Naming
.
kwds_cname
,
Naming
.
pykwdlist_cname
,
self
.
starstar_arg
and
self
.
starstar_arg
.
entry
.
cname
or
'0'
,
pos_arg_count
,
self
.
name
,
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
'}'
)
def
generate_optional_kwonly_args_unpacking_code
(
self
,
all_args
,
code
):
...
...
@@ -3913,12 +3894,9 @@ class DefNodeWrapper(FuncDefNode):
self
.
generate_arg_conversion_to_pyobject
(
arg
,
code
)
else
:
if
new_type
.
assignable_from
(
old_type
):
code
.
putln
(
"%s = %s;"
%
(
arg
.
entry
.
cname
,
arg
.
hdr_cname
))
code
.
putln
(
"%s = %s;"
%
(
arg
.
entry
.
cname
,
arg
.
hdr_cname
))
else
:
error
(
arg
.
pos
,
"Cannot convert 1 argument from '%s' to '%s'"
%
(
old_type
,
new_type
))
error
(
arg
.
pos
,
"Cannot convert 1 argument from '%s' to '%s'"
%
(
old_type
,
new_type
))
def
generate_arg_conversion_from_pyobject
(
self
,
arg
,
code
):
new_type
=
arg
.
type
...
...
@@ -3934,9 +3912,7 @@ class DefNodeWrapper(FuncDefNode):
rhs
,
code
.
error_goto_if
(
new_type
.
error_condition
(
arg
.
entry
.
cname
),
arg
.
pos
)))
else
:
error
(
arg
.
pos
,
"Cannot convert Python object argument to type '%s'"
%
new_type
)
error
(
arg
.
pos
,
"Cannot convert Python object argument to type '%s'"
%
new_type
)
def
generate_arg_conversion_to_pyobject
(
self
,
arg
,
code
):
old_type
=
arg
.
hdr_type
...
...
@@ -3949,9 +3925,7 @@ class DefNodeWrapper(FuncDefNode):
code
.
error_goto_if_null
(
arg
.
entry
.
cname
,
arg
.
pos
)))
code
.
put_var_gotref
(
arg
.
entry
)
else
:
error
(
arg
.
pos
,
"Cannot convert argument of type '%s' to Python object"
%
old_type
)
error
(
arg
.
pos
,
"Cannot convert argument of type '%s' to Python object"
%
old_type
)
def
generate_argument_type_tests
(
self
,
code
):
# Generate type tests for args whose signature
...
...
@@ -4199,12 +4173,12 @@ class OverrideCheckNode(StatNode):
self
.
func_node
=
ExprNodes
.
RawCNameExprNode
(
self
.
pos
,
py_object_type
)
call_node
=
ExprNodes
.
SimpleCallNode
(
self
.
pos
,
function
=
self
.
func_node
,
args
=
[
ExprNodes
.
NameNode
(
self
.
pos
,
name
=
arg
.
name
)
for
arg
in
self
.
args
[
first_arg
:]
])
args
=
[
ExprNodes
.
NameNode
(
self
.
pos
,
name
=
arg
.
name
)
for
arg
in
self
.
args
[
first_arg
:]
])
if
env
.
return_type
.
is_void
or
env
.
return_type
.
is_returncode
:
self
.
body
=
StatListNode
(
self
.
pos
,
stats
=
[
ExprStatNode
(
self
.
pos
,
expr
=
call_node
),
ReturnStatNode
(
self
.
pos
,
value
=
None
)])
ExprStatNode
(
self
.
pos
,
expr
=
call_node
),
ReturnStatNode
(
self
.
pos
,
value
=
None
)])
else
:
self
.
body
=
ReturnStatNode
(
self
.
pos
,
value
=
call_node
)
self
.
body
=
self
.
body
.
analyse_expressions
(
env
)
...
...
@@ -4378,21 +4352,21 @@ class PyClassDefNode(ClassDefNode):
return
None
return
CClassDefNode
(
self
.
pos
,
visibility
=
'private'
,
module_name
=
None
,
class_name
=
self
.
name
,
base_class_module
=
base_class_module
,
base_class_name
=
base_class_name
,
decorators
=
self
.
decorators
,
body
=
self
.
body
,
in_pxd
=
False
,
doc
=
self
.
doc
)
visibility
=
'private'
,
module_name
=
None
,
class_name
=
self
.
name
,
base_class_module
=
base_class_module
,
base_class_name
=
base_class_name
,
decorators
=
self
.
decorators
,
body
=
self
.
body
,
in_pxd
=
False
,
doc
=
self
.
doc
)
def
create_scope
(
self
,
env
):
genv
=
env
while
genv
.
is_py_class_scope
or
genv
.
is_c_class_scope
:
genv
=
genv
.
outer_scope
cenv
=
self
.
scope
=
PyClassScope
(
name
=
self
.
name
,
outer_scope
=
genv
)
cenv
=
self
.
scope
=
PyClassScope
(
name
=
self
.
name
,
outer_scope
=
genv
)
return
cenv
def
analyse_declarations
(
self
,
env
):
...
...
@@ -4402,8 +4376,8 @@ class PyClassDefNode(ClassDefNode):
for
decorator
in
self
.
decorators
[::
-
1
]:
class_result
=
SimpleCallNode
(
decorator
.
pos
,
function
=
decorator
.
decorator
,
args
=
[
class_result
])
function
=
decorator
.
decorator
,
args
=
[
class_result
])
self
.
decorators
=
None
self
.
class_result
=
class_result
self
.
class_result
.
analyse_declarations
(
env
)
...
...
@@ -4422,7 +4396,6 @@ class PyClassDefNode(ClassDefNode):
self
.
mkw
=
self
.
mkw
.
analyse_expressions
(
env
)
self
.
dict
=
self
.
dict
.
analyse_expressions
(
env
)
self
.
class_result
=
self
.
class_result
.
analyse_expressions
(
env
)
genv
=
env
.
global_scope
()
cenv
=
self
.
scope
self
.
body
=
self
.
body
.
analyse_expressions
(
cenv
)
self
.
target
.
analyse_target_expression
(
env
,
self
.
classobj
)
...
...
@@ -4520,19 +4493,19 @@ class CClassDefNode(ClassDefNode):
home_scope
=
env
self
.
entry
=
home_scope
.
declare_c_class
(
name
=
self
.
class_name
,
pos
=
self
.
pos
,
defining
=
0
,
implementing
=
0
,
module_name
=
self
.
module_name
,
base_type
=
None
,
objstruct_cname
=
self
.
objstruct_name
,
typeobj_cname
=
self
.
typeobj_name
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
name
=
self
.
class_name
,
pos
=
self
.
pos
,
defining
=
0
,
implementing
=
0
,
module_name
=
self
.
module_name
,
base_type
=
None
,
objstruct_cname
=
self
.
objstruct_name
,
typeobj_cname
=
self
.
typeobj_name
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
def
analyse_declarations
(
self
,
env
):
#print "CClassDefNode.analyse_declarations:", self.class_name
...
...
@@ -4540,11 +4513,9 @@ class CClassDefNode(ClassDefNode):
#print "...module_name =", self.module_name
if
env
.
in_cinclude
and
not
self
.
objstruct_name
:
error
(
self
.
pos
,
"Object struct name specification required for "
"C class defined in 'extern from' block"
)
error
(
self
.
pos
,
"Object struct name specification required for C class defined in 'extern from' block"
)
if
self
.
decorators
:
error
(
self
.
pos
,
"Decorators not allowed on cdef classes (used on type '%s')"
%
self
.
class_name
)
error
(
self
.
pos
,
"Decorators not allowed on cdef classes (used on type '%s')"
%
self
.
class_name
)
self
.
base_type
=
None
# Now that module imports are cached, we need to
# import the modules for extern classes.
...
...
@@ -4611,24 +4582,24 @@ class CClassDefNode(ClassDefNode):
if
self
.
visibility
==
'extern'
:
if
(
self
.
module_name
==
'__builtin__'
and
self
.
class_name
in
Builtin
.
builtin_types
and
env
.
qualified_name
[:
8
]
!=
'cpython.'
):
# allow overloaded names for cimporting from cpython
self
.
class_name
in
Builtin
.
builtin_types
and
env
.
qualified_name
[:
8
]
!=
'cpython.'
):
# allow overloaded names for cimporting from cpython
warning
(
self
.
pos
,
"%s already a builtin Cython type"
%
self
.
class_name
,
1
)
self
.
entry
=
home_scope
.
declare_c_class
(
name
=
self
.
class_name
,
pos
=
self
.
pos
,
defining
=
has_body
and
self
.
in_pxd
,
implementing
=
has_body
and
not
self
.
in_pxd
,
module_name
=
self
.
module_name
,
base_type
=
self
.
base_type
,
objstruct_cname
=
self
.
objstruct_name
,
typeobj_cname
=
self
.
typeobj_name
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
name
=
self
.
class_name
,
pos
=
self
.
pos
,
defining
=
has_body
and
self
.
in_pxd
,
implementing
=
has_body
and
not
self
.
in_pxd
,
module_name
=
self
.
module_name
,
base_type
=
self
.
base_type
,
objstruct_cname
=
self
.
objstruct_name
,
typeobj_cname
=
self
.
typeobj_name
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
if
self
.
shadow
:
home_scope
.
lookup
(
self
.
class_name
).
as_variable
=
self
.
entry
...
...
@@ -4760,11 +4731,11 @@ class ExprStatNode(StatNode):
if
type
is
None
:
error
(
type_node
.
pos
,
"Unknown type"
)
else
:
env
.
declare_var
(
var
.
value
,
type
,
var
.
pos
,
is_cdef
=
True
)
env
.
declare_var
(
var
.
value
,
type
,
var
.
pos
,
is_cdef
=
True
)
self
.
__class__
=
PassStatNode
def
analyse_expressions
(
self
,
env
):
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
self
.
expr
.
result_is_used
=
False
# hint that .result() may safely be left empty
self
.
expr
=
self
.
expr
.
analyse_expressions
(
env
)
return
self
...
...
@@ -5242,13 +5213,13 @@ class ParallelAssignmentNode(AssignmentNode):
stat
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
self
.
stats
=
[
stat
.
analyse_types
(
env
,
use_temp
=
1
)
for
stat
in
self
.
stats
]
self
.
stats
=
[
stat
.
analyse_types
(
env
,
use_temp
=
1
)
for
stat
in
self
.
stats
]
return
self
# def analyse_expressions(self, env):
# for stat in self.stats:
# stat.analyse_expressions_1(env, use_temp
=
1)
# stat.analyse_expressions_1(env, use_temp
=
1)
# for stat in self.stats:
# stat.analyse_expressions_2(env)
...
...
@@ -5429,11 +5400,10 @@ class ExecStatNode(StatNode):
args
=
[]
for
arg
in
self
.
args
:
arg
.
generate_evaluation_code
(
code
)
args
.
append
(
arg
.
py_result
()
)
args
.
append
(
arg
.
py_result
()
)
args
=
tuple
(
args
+
[
'0'
,
'0'
][:
3
-
len
(
args
)])
temp_result
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
py_object_type
,
manage_ref
=
True
)
code
.
putln
(
"%s = __Pyx_PyExec3(%s, %s, %s);"
%
(
(
temp_result
,)
+
args
))
code
.
putln
(
"%s = __Pyx_PyExec3(%s, %s, %s);"
%
((
temp_result
,)
+
args
))
for
arg
in
self
.
args
:
arg
.
generate_disposal_code
(
code
)
arg
.
free_temps
(
code
)
...
...
@@ -5463,8 +5433,7 @@ class DelStatNode(StatNode):
def
analyse_expressions
(
self
,
env
):
for
i
,
arg
in
enumerate
(
self
.
args
):
arg
=
self
.
args
[
i
]
=
arg
.
analyse_target_expression
(
env
,
None
)
if
arg
.
type
.
is_pyobject
or
(
arg
.
is_name
and
arg
.
type
.
is_memoryviewslice
):
if
arg
.
type
.
is_pyobject
or
(
arg
.
is_name
and
arg
.
type
.
is_memoryviewslice
):
if
arg
.
is_name
and
arg
.
entry
.
is_cglobal
:
error
(
arg
.
pos
,
"Deletion of global C variable"
)
elif
arg
.
type
.
is_ptr
and
arg
.
type
.
base_type
.
is_cpp_class
:
...
...
@@ -5579,15 +5548,14 @@ class ReturnStatNode(StatNode):
if
self
.
value
:
self
.
value
=
self
.
value
.
analyse_types
(
env
)
if
return_type
.
is_void
or
return_type
.
is_returncode
:
error
(
self
.
value
.
pos
,
"Return with value in void function"
)
error
(
self
.
value
.
pos
,
"Return with value in void function"
)
else
:
self
.
value
=
self
.
value
.
coerce_to
(
env
.
return_type
,
env
)
else
:
if
(
not
return_type
.
is_void
and
not
return_type
.
is_pyobject
and
not
return_type
.
is_returncode
):
error
(
self
.
pos
,
"Return value required"
)
and
not
return_type
.
is_pyobject
and
not
return_type
.
is_returncode
):
error
(
self
.
pos
,
"Return value required"
)
return
self
def
nogil_check
(
self
,
env
):
...
...
@@ -5610,12 +5578,12 @@ class ReturnStatNode(StatNode):
if
self
.
return_type
.
is_memoryviewslice
:
from
.
import
MemoryView
MemoryView
.
put_acquire_memoryviewslice
(
lhs_cname
=
Naming
.
retval_cname
,
lhs_type
=
self
.
return_type
,
lhs_pos
=
self
.
value
.
pos
,
rhs
=
self
.
value
,
code
=
code
,
have_gil
=
self
.
in_nogil_context
)
lhs_cname
=
Naming
.
retval_cname
,
lhs_type
=
self
.
return_type
,
lhs_pos
=
self
.
value
.
pos
,
rhs
=
self
.
value
,
code
=
code
,
have_gil
=
self
.
in_nogil_context
)
elif
self
.
in_generator
:
# return value == raise StopIteration(value), but uncatchable
code
.
globalstate
.
use_utility_code
(
...
...
@@ -5626,10 +5594,9 @@ class ReturnStatNode(StatNode):
self
.
value
.
generate_disposal_code
(
code
)
else
:
self
.
value
.
make_owned_reference
(
code
)
code
.
putln
(
"%s = %s;"
%
(
Naming
.
retval_cname
,
self
.
value
.
result_as
(
self
.
return_type
)))
code
.
putln
(
"%s = %s;"
%
(
Naming
.
retval_cname
,
self
.
value
.
result_as
(
self
.
return_type
)))
self
.
value
.
generate_post_assignment_code
(
code
)
self
.
value
.
free_temps
(
code
)
else
:
...
...
@@ -5690,9 +5657,8 @@ class RaiseStatNode(StatNode):
exc
=
self
.
exc_type
from
.
import
ExprNodes
if
(
isinstance
(
exc
,
ExprNodes
.
SimpleCallNode
)
and
not
(
exc
.
args
or
(
exc
.
arg_tuple
is
not
None
and
exc
.
arg_tuple
.
args
))):
exc
=
exc
.
function
# extract the exception type
not
(
exc
.
args
or
(
exc
.
arg_tuple
is
not
None
and
exc
.
arg_tuple
.
args
))):
exc
=
exc
.
function
# extract the exception type
if
exc
.
is_name
and
exc
.
entry
.
is_builtin
:
self
.
builtin_exc_name
=
exc
.
name
if
self
.
builtin_exc_name
==
'MemoryError'
:
...
...
@@ -5823,20 +5789,18 @@ class AssertStatNode(StatNode):
code
.
mark_pos
(
self
.
pos
)
self
.
cond
.
generate_evaluation_code
(
code
)
code
.
putln
(
"if (unlikely(!%s)) {"
%
self
.
cond
.
result
())
"if (unlikely(!%s)) {"
%
self
.
cond
.
result
())
if
self
.
value
:
self
.
value
.
generate_evaluation_code
(
code
)
code
.
putln
(
"PyErr_SetObject(PyExc_AssertionError, %s);"
%
self
.
value
.
py_result
())
"PyErr_SetObject(PyExc_AssertionError, %s);"
%
self
.
value
.
py_result
())
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
free_temps
(
code
)
else
:
code
.
putln
(
"PyErr_SetNone(PyExc_AssertionError);"
)
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
error_goto
(
self
.
pos
))
code
.
putln
(
"}"
)
self
.
cond
.
generate_disposal_code
(
code
)
...
...
@@ -6045,8 +6009,7 @@ class WhileStatNode(LoopNode, StatNode):
self
.
condition
.
generate_evaluation_code
(
code
)
self
.
condition
.
generate_disposal_code
(
code
)
code
.
putln
(
"if (!%s) break;"
%
self
.
condition
.
result
())
"if (!%s) break;"
%
self
.
condition
.
result
())
self
.
condition
.
free_temps
(
code
)
self
.
body
.
generate_execution_code
(
code
)
code
.
put_label
(
code
.
continue_label
)
...
...
@@ -6091,15 +6054,15 @@ class DictIterationNextNode(Node):
key_target
,
value_target
,
tuple_target
,
is_dict_flag
):
Node
.
__init__
(
self
,
dict_obj
.
pos
,
dict_obj
=
dict_obj
,
expected_size
=
expected_size
,
pos_index_var
=
pos_index_var
,
key_target
=
key_target
,
value_target
=
value_target
,
tuple_target
=
tuple_target
,
is_dict_flag
=
is_dict_flag
,
is_temp
=
True
,
type
=
PyrexTypes
.
c_bint_type
)
dict_obj
=
dict_obj
,
expected_size
=
expected_size
,
pos_index_var
=
pos_index_var
,
key_target
=
key_target
,
value_target
=
value_target
,
tuple_target
=
tuple_target
,
is_dict_flag
=
is_dict_flag
,
is_temp
=
True
,
type
=
PyrexTypes
.
c_bint_type
)
def
analyse_expressions
(
self
,
env
):
from
.
import
ExprNodes
...
...
@@ -6350,7 +6313,8 @@ class ForFromStatNode(LoopNode, StatNode):
self
.
bound2
=
self
.
bound2
.
analyse_types
(
env
)
if
self
.
step
is
not
None
:
if
isinstance
(
self
.
step
,
ExprNodes
.
UnaryMinusNode
):
warning
(
self
.
step
.
pos
,
"Probable infinite loop in for-from-by statement. Consider switching the directions of the relations."
,
2
)
warning
(
self
.
step
.
pos
,
"Probable infinite loop in for-from-by statement. "
"Consider switching the directions of the relations."
,
2
)
self
.
step
=
self
.
step
.
analyse_types
(
env
)
if
self
.
target
.
type
.
is_numeric
:
...
...
@@ -6374,8 +6338,7 @@ class ForFromStatNode(LoopNode, StatNode):
target_type
=
self
.
target
.
type
if
not
(
target_type
.
is_pyobject
or
target_type
.
is_numeric
):
error
(
self
.
target
.
pos
,
"for-from loop variable must be c numeric type or Python object"
)
error
(
self
.
target
.
pos
,
"for-from loop variable must be c numeric type or Python object"
)
if
target_type
.
is_numeric
:
self
.
is_py_target
=
False
if
isinstance
(
self
.
target
,
ExprNodes
.
BufferIndexNode
):
...
...
@@ -6418,25 +6381,23 @@ class ForFromStatNode(LoopNode, StatNode):
# is within step of 0.
if
not
self
.
step
:
step
=
1
code
.
putln
(
"for (%s = %s%s + %s; %s %s %s + %s; ) { %s%s;"
%
(
loopvar_name
,
self
.
bound1
.
result
(),
offset
,
step
,
loopvar_name
,
self
.
relation2
,
self
.
bound2
.
result
(),
step
,
loopvar_name
,
incop
))
code
.
putln
(
"for (%s = %s%s + %s; %s %s %s + %s; ) { %s%s;"
%
(
loopvar_name
,
self
.
bound1
.
result
(),
offset
,
step
,
loopvar_name
,
self
.
relation2
,
self
.
bound2
.
result
(),
step
,
loopvar_name
,
incop
))
else
:
code
.
putln
(
"for (%s = %s%s; %s %s %s; %s%s) {"
%
(
loopvar_name
,
self
.
bound1
.
result
(),
offset
,
loopvar_name
,
self
.
relation2
,
self
.
bound2
.
result
(),
loopvar_name
,
incop
))
code
.
putln
(
"for (%s = %s%s; %s %s %s; %s%s) {"
%
(
loopvar_name
,
self
.
bound1
.
result
(),
offset
,
loopvar_name
,
self
.
relation2
,
self
.
bound2
.
result
(),
loopvar_name
,
incop
))
if
self
.
py_loopvar_node
:
self
.
py_loopvar_node
.
generate_evaluation_code
(
code
)
self
.
target
.
generate_assignment_code
(
self
.
py_loopvar_node
,
code
)
elif
from_range
:
code
.
putln
(
"%s = %s;"
%
(
self
.
target
.
result
(),
loopvar_name
))
self
.
target
.
result
(),
loopvar_name
))
self
.
body
.
generate_execution_code
(
code
)
code
.
put_label
(
code
.
continue_label
)
if
self
.
py_loopvar_node
:
...
...
@@ -6503,7 +6464,7 @@ class ForFromStatNode(LoopNode, StatNode):
'<='
:
(
""
,
"++"
),
'<'
:
(
"+1"
,
"++"
),
'>='
:
(
""
,
"--"
),
'>'
:
(
"-1"
,
"--"
)
'>'
:
(
"-1"
,
"--"
)
,
}
def
generate_function_definitions
(
self
,
env
,
code
):
...
...
@@ -6912,8 +6873,8 @@ class ExceptClauseNode(Node):
# exception and stores it in the thread state.
code
.
globalstate
.
use_utility_code
(
get_exception_utility_code
)
exc_args
=
"&%s, &%s, &%s"
%
tuple
(
exc_vars
)
code
.
putln
(
"if (__Pyx_GetException(%s) < 0) %s"
%
(
exc_args
,
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
"if (__Pyx_GetException(%s) < 0) %s"
%
(
exc_args
,
code
.
error_goto
(
self
.
pos
)))
for
x
in
exc_vars
:
code
.
put_gotref
(
x
)
if
self
.
target
:
...
...
@@ -7253,7 +7214,8 @@ class GILStatNode(NogilTryFinallyStatNode):
def
__init__
(
self
,
pos
,
state
,
body
):
self
.
state
=
state
self
.
create_state_temp_if_needed
(
pos
,
state
,
body
)
TryFinallyStatNode
.
__init__
(
self
,
pos
,
TryFinallyStatNode
.
__init__
(
self
,
pos
,
body
=
body
,
finally_clause
=
GILExitNode
(
pos
,
state
=
state
,
state_temp
=
self
.
state_temp
))
...
...
@@ -7712,18 +7674,14 @@ class ParallelStatNode(StatNode, ParallelNode):
self
.
analyse_sharing_attributes
(
env
)
if
self
.
num_threads
is
not
None
:
if
(
self
.
parent
and
self
.
parent
.
num_threads
is
not
None
and
not
self
.
parent
.
is_prange
):
error
(
self
.
pos
,
"num_threads already declared in outer section"
)
if
self
.
parent
and
self
.
parent
.
num_threads
is
not
None
and
not
self
.
parent
.
is_prange
:
error
(
self
.
pos
,
"num_threads already declared in outer section"
)
elif
self
.
parent
and
not
self
.
parent
.
is_prange
:
error
(
self
.
pos
,
"num_threads must be declared in the parent parallel section"
)
error
(
self
.
pos
,
"num_threads must be declared in the parent parallel section"
)
elif
(
self
.
num_threads
.
type
.
is_int
and
self
.
num_threads
.
is_literal
and
self
.
num_threads
.
compile_time_value
(
env
)
<=
0
):
error
(
self
.
pos
,
"argument to num_threads must be greater than 0"
)
self
.
num_threads
.
is_literal
and
self
.
num_threads
.
compile_time_value
(
env
)
<=
0
):
error
(
self
.
pos
,
"argument to num_threads must be greater than 0"
)
if
not
self
.
num_threads
.
is_simple
():
self
.
num_threads
=
self
.
num_threads
.
coerce_to
(
...
...
@@ -7743,8 +7701,7 @@ class ParallelStatNode(StatNode, ParallelNode):
# assigning to privates in the with parallel block (we
# consider it too implicit and magicky for users)
if
entry
in
self
.
parent
.
assignments
:
error
(
pos
,
"Cannot assign to private of outer parallel block"
)
error
(
pos
,
"Cannot assign to private of outer parallel block"
)
continue
if
not
self
.
is_prange
and
op
:
...
...
@@ -7882,8 +7839,7 @@ class ParallelStatNode(StatNode, ParallelNode):
Write self.num_threads if set as the num_threads OpenMP directive
"""
if
self
.
num_threads
is
not
None
:
code
.
put
(
" num_threads(%s)"
%
self
.
evaluate_before_block
(
code
,
self
.
num_threads
))
code
.
put
(
" num_threads(%s)"
%
self
.
evaluate_before_block
(
code
,
self
.
num_threads
))
def
declare_closure_privates
(
self
,
code
):
...
...
@@ -8105,8 +8061,7 @@ class ParallelStatNode(StatNode, ParallelNode):
that the breaking thread has well-defined values of the lastprivate
variables, so we keep those values.
"""
section_name
=
(
"__pyx_parallel_lastprivates%d"
%
self
.
critical_section_counter
)
section_name
=
"__pyx_parallel_lastprivates%d"
%
self
.
critical_section_counter
code
.
putln_openmp
(
"#pragma omp critical(%s)"
%
section_name
)
ParallelStatNode
.
critical_section_counter
+=
1
...
...
@@ -8226,11 +8181,8 @@ class ParallelStatNode(StatNode, ParallelNode):
# Firstly, always prefer errors over returning, continue or break
if
self
.
error_label_used
:
c
.
putln
(
"const char *%s = NULL; int %s = 0, %s = 0;"
%
self
.
parallel_pos_info
)
c
.
putln
(
"PyObject *%s = NULL, *%s = NULL, *%s = NULL;"
%
self
.
parallel_exc
)
c
.
putln
(
"const char *%s = NULL; int %s = 0, %s = 0;"
%
self
.
parallel_pos_info
)
c
.
putln
(
"PyObject *%s = NULL, *%s = NULL, *%s = NULL;"
%
self
.
parallel_exc
)
code
.
putln
(
"if (%s) {"
%
Naming
.
parallel_exc_type
)
...
...
@@ -8324,7 +8276,7 @@ class ParallelWithBlockNode(ParallelStatNode):
if
self
.
privates
:
privates
=
[
e
.
cname
for
e
in
self
.
privates
if
not
e
.
type
.
is_pyobject
]
if
not
e
.
type
.
is_pyobject
]
code
.
put
(
'private(%s)'
%
', '
.
join
(
sorted
(
privates
)))
self
.
privatization_insertion_point
=
code
.
insertion_point
()
...
...
@@ -8333,7 +8285,7 @@ class ParallelWithBlockNode(ParallelStatNode):
code
.
putln
(
"#endif /* _OPENMP */"
)
code
.
begin_block
()
# parallel block
code
.
begin_block
()
# parallel block
self
.
begin_parallel_block
(
code
)
self
.
initialize_privates_to_nan
(
code
)
code
.
funcstate
.
start_collecting_temps
()
...
...
@@ -8341,7 +8293,7 @@ class ParallelWithBlockNode(ParallelStatNode):
self
.
trap_parallel_exit
(
code
)
self
.
privatize_temps
(
code
)
self
.
end_parallel_block
(
code
)
code
.
end_block
()
# end parallel block
code
.
end_block
()
# end parallel block
continue_
=
code
.
label_used
(
code
.
continue_label
)
break_
=
code
.
label_used
(
code
.
break_label
)
...
...
@@ -8401,10 +8353,8 @@ class ParallelRangeNode(ParallelStatNode):
if
hasattr
(
self
.
schedule
,
'decode'
):
self
.
schedule
=
self
.
schedule
.
decode
(
'ascii'
)
if
self
.
schedule
not
in
(
None
,
'static'
,
'dynamic'
,
'guided'
,
'runtime'
):
error
(
self
.
pos
,
"Invalid schedule argument to prange: %s"
%
(
self
.
schedule
,))
if
self
.
schedule
not
in
(
None
,
'static'
,
'dynamic'
,
'guided'
,
'runtime'
):
error
(
self
.
pos
,
"Invalid schedule argument to prange: %s"
%
(
self
.
schedule
,))
def
analyse_expressions
(
self
,
env
):
was_nogil
=
env
.
nogil
...
...
@@ -8451,7 +8401,7 @@ class ParallelRangeNode(ParallelStatNode):
# As we range from 0 to nsteps, computing the index along the
# way, we need a fitting type for 'i' and 'nsteps'
self
.
index_type
=
PyrexTypes
.
widest_numeric_type
(
self
.
index_type
,
node
.
type
)
self
.
index_type
,
node
.
type
)
if
self
.
else_clause
is
not
None
:
self
.
else_clause
=
self
.
else_clause
.
analyse_expressions
(
env
)
...
...
@@ -8674,8 +8624,7 @@ class ParallelRangeNode(ParallelStatNode):
if
self
.
schedule
:
if
self
.
chunksize
:
chunksize
=
", %s"
%
self
.
evaluate_before_block
(
code
,
self
.
chunksize
)
chunksize
=
", %s"
%
self
.
evaluate_before_block
(
code
,
self
.
chunksize
)
else
:
chunksize
=
""
...
...
@@ -8687,7 +8636,7 @@ class ParallelRangeNode(ParallelStatNode):
code
.
putln
(
"#endif /* _OPENMP */"
)
code
.
put
(
"for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)"
%
fmt_dict
)
code
.
begin_block
()
# for loop block
code
.
begin_block
()
# for loop block
guard_around_body_codepoint
=
code
.
insertion_point
()
...
...
@@ -8710,13 +8659,13 @@ class ParallelRangeNode(ParallelStatNode):
# exceptions might be used
guard_around_body_codepoint
.
putln
(
"if (%s < 2)"
%
Naming
.
parallel_why
)
code
.
end_block
()
# end guard around loop body
code
.
end_block
()
# end for loop block
code
.
end_block
()
# end guard around loop body
code
.
end_block
()
# end for loop block
if
self
.
is_parallel
:
# Release the GIL and deallocate the thread state
self
.
end_parallel_block
(
code
)
code
.
end_block
()
# pragma omp parallel end block
code
.
end_block
()
# pragma omp parallel end block
class
CnameDecoratorNode
(
StatNode
):
...
...
@@ -8743,8 +8692,7 @@ class CnameDecoratorNode(StatNode):
node
=
node
.
body
.
stats
[
0
]
self
.
is_function
=
isinstance
(
node
,
FuncDefNode
)
is_struct_or_enum
=
isinstance
(
node
,
(
CStructOrUnionDefNode
,
CEnumDefNode
))
is_struct_or_enum
=
isinstance
(
node
,
(
CStructOrUnionDefNode
,
CEnumDefNode
))
e
=
node
.
entry
if
self
.
is_function
:
...
...
@@ -8792,7 +8740,7 @@ class CnameDecoratorNode(StatNode):
if
isinstance
(
self
.
node
,
DefNode
):
self
.
node
.
generate_function_header
(
h_code
,
with_pymethdef
=
False
,
proto_only
=
True
)
h_code
,
with_pymethdef
=
False
,
proto_only
=
True
)
else
:
from
.
import
ModuleNode
entry
=
self
.
node
.
entry
...
...
@@ -8800,10 +8748,10 @@ class CnameDecoratorNode(StatNode):
entry
.
cname
=
entry
.
func_cname
ModuleNode
.
generate_cfunction_declaration
(
entry
,
env
.
global_scope
(),
h_code
,
definition
=
True
)
entry
,
env
.
global_scope
(),
h_code
,
definition
=
True
)
entry
.
cname
=
cname
...
...
@@ -8860,14 +8808,15 @@ traceback_utility_code = UtilityCode.load_cached("AddTraceback", "Exceptions.c")
#------------------------------------------------------------------------------------
get_exception_tuple_utility_code
=
UtilityCode
(
proto
=
"""
get_exception_tuple_utility_code
=
UtilityCode
(
proto
=
"""
static PyObject *__Pyx_GetExceptionTuple(PyThreadState *__pyx_tstate); /*proto*/
"""
,
# I doubt that calling __Pyx_GetException() here is correct as it moves
# the exception from tstate->curexc_* to tstate->exc_*, which prevents
# exception handlers later on from receiving it.
# NOTE: "__pyx_tstate" may be used by __Pyx_GetException() macro
impl
=
"""
# I doubt that calling __Pyx_GetException() here is correct as it moves
# the exception from tstate->curexc_* to tstate->exc_*, which prevents
# exception handlers later on from receiving it.
# NOTE: "__pyx_tstate" may be used by __Pyx_GetException() macro
impl
=
"""
static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tstate) {
PyObject *type = NULL, *value = NULL, *tb = NULL;
if (__Pyx_GetException(&type, &value, &tb) == 0) {
...
...
@@ -8885,4 +8834,4 @@ static PyObject *__Pyx_GetExceptionTuple(CYTHON_UNUSED PyThreadState *__pyx_tsta
return NULL;
}
"""
,
requires
=
[
get_exception_utility_code
])
requires
=
[
get_exception_utility_code
])
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