Commit be4b27c7 authored by Stefan Behnel's avatar Stefan Behnel

produce lots of code churn to clean up pylint warnings (almost exclusively whitespace)

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