-from Visitor import CythonTransform
-from ModuleNode import ModuleNode
-from ExprNodes import *
-from Errors import CompileError
-from UtilityCode import CythonUtilityCode
-from Code import UtilityCode, TempitaUtilityCode
-import Interpreter
-import PyrexTypes
-import Naming
-import Symtab
+from Cython.Compiler.Visitor import CythonTransform
+from Cython.Compiler.ModuleNode import ModuleNode
+from Cython.Compiler.Errors import CompileError
+from Cython.Compiler.UtilityCode import CythonUtilityCode
+from Cython.Compiler.Code import UtilityCode, TempitaUtilityCode
+
+from Cython.Compiler import Options
+from Cython.Compiler import Interpreter
+from Cython.Compiler import PyrexTypes
+from Cython.Compiler import Naming
+from Cython.Compiler import Symtab
def dedent(text, reindent=0):
unicode_type, str_type, bytes_type, type_type
import Builtin
import Symtab
-import Options
from Cython import Utils
from Annotate import AnnotationItem
from Cython.Compiler import Future
def type_dependencies(self, env):
# Returns the list of entries whose types must be determined
- # before the type of self can be infered.
+ # before the type of self can be inferred.
if hasattr(self, 'type') and self.type is not None:
return ()
return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
#
src = self
src_type = self.type
- src_is_py_type = src_type.is_pyobject
- dst_is_py_type = dst_type.is_pyobject
if self.check_for_coercion_error(dst_type):
return self
suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
else:
# C literal or Python literal - split at 32bit boundary
- if self.constant_result >= -2**31 and self.constant_result < 2**31:
+ if -2**31 <= self.constant_result < 2**31:
if self.type and self.type.is_int:
suitable_type = self.type
else:
# (DC00-DFFF) is likely there, too. If we don't find it,
# any second code unit cannot make for a surrogate pair by
# itself.
- if c >= 0xD800 and c <= 0xDBFF:
+ if 0xD800 <= c <= 0xDBFF:
return True
return False
Naming.module_cname,
interned_cname))
if not self.cf_is_null:
- code.putln("}");
+ code.putln("}")
code.putln(code.error_goto_if_null(self.result(), self.pos))
code.put_gotref(self.py_result())
# __import__(module_name, globals(), None, name_list, level)
#
# module_name StringNode dotted name of module. Empty module
- # name means importing the parent package accourding
+ # name means importing the parent package according
# to level
# name_list ListNode or None list of names to be imported
# level int relative import level:
# iterator IteratorNode
def __init__(self, iterator):
- self.pos = iterator.pos
+ AtomicExprNode.__init__(self, iterator.pos)
self.iterator = iterator
def type_dependencies(self, env):
subexprs = []
def __init__(self, pos, type=None, cname=None):
- self.pos = pos
- self.type = type
+ ExprNode.__init__(self, pos, type=type)
if cname is not None:
self.cname = cname
# set by SingleAssignmentNode after analyse_types()
is_memslice_scalar_assignment = False
- def __init__(self, pos, index, *args, **kw):
- ExprNode.__init__(self, pos, index=index, *args, **kw)
+ def __init__(self, pos, index, **kw):
+ ExprNode.__init__(self, pos, index=index, **kw)
self._index = index
def calculate_constant_result(self):
return base_type
elif isinstance(self.base, BytesNode):
#if env.global_scope().context.language_level >= 3:
- # # infering 'char' can be made to work in Python 3 mode
+ # # inferring 'char' can be made to work in Python 3 mode
# return PyrexTypes.c_char_type
# Py2/3 return different types on indexing bytes objects
return py_object_type
code.putln("%s = %s;" % (temp, index.result()))
# Generate buffer access code using these temps
- import Buffer, MemoryView
-
+ import Buffer
buffer_entry = self.buffer_entry()
-
if buffer_entry.type.is_buffer:
negative_indices = buffer_entry.type.negative_indices
else:
class PythonCapiFunctionNode(ExprNode):
subexprs = []
+
def __init__(self, pos, py_name, cname, func_type, utility_code = None):
- self.pos = pos
- self.name = py_name
- self.cname = cname
- self.type = func_type
- self.utility_code = utility_code
+ ExprNode.__init__(self, pos, name=py_name, cname=cname,
+ type=func_type, utility_code=utility_code)
def analyse_types(self, env):
pass
def calculate_result_code(self):
return self.cname
+
class PythonCapiCallNode(SimpleCallNode):
# Python C-API Function call (only created in transforms)
subexprs = ['arg']
def calculate_constant_result(self):
- self.constant_result = tuple(self.base.constant_result)
+ self.constant_result = tuple(self.arg.constant_result)
def compile_time_value(self, denv):
arg = self.arg.compile_time_value(denv)
else:
self.op = "."
if obj_type.has_attributes:
- entry = None
if obj_type.attributes_known():
if (obj_type.is_memoryviewslice and not
obj_type.scope.lookup_here(self.attribute)):
is_temp = 1
def __init__(self, pos, target):
- self.pos = pos
+ ExprNode.__init__(self, pos)
self.target = target
def analyse_declarations(self, env):
'if (!%s) { PyErr_SetString(PyExc_SystemError, '
'"super(): empty __class__ cell"); %s }' % (
self.result(),
- code.error_goto(self.pos)));
+ code.error_goto(self.pos)))
code.put_incref(self.result(), py_object_type)
def self_result_code(self):
if self.needs_self_code:
- return "((PyObject*)%s)" % (Naming.cur_scope_cname)
+ return "((PyObject*)%s)" % Naming.cur_scope_cname
return "NULL"
+
class CodeObjectNode(ExprNode):
# Create a PyCodeObject for a CyFunction instance.
#
code.putln("/* return from generator, yielding value */")
code.putln("%s->resume_label = %d;" % (
Naming.generator_cname, self.label_num))
- code.putln("return %s;" % Naming.retval_cname);
+ code.putln("return %s;" % Naming.retval_cname)
code.put_label(self.label_name)
for cname, save_cname, type in saved:
def analyse_types(self, env):
self.type = self.pyclass_dict.type
- self.is_tmep = 0
+ self.is_temp = False
def result(self):
return self.pyclass_dict.result()
def get_constant_c_result_code(self):
value = self.operand.get_constant_c_result_code()
if value:
- return "(-%s)" % (value)
+ return "(-%s)" % value
class TildeNode(UnopNode):
# unary '~' operator
base_type = self.operand.type
if not self.operand.type.is_ptr and not self.operand.type.is_array:
- return error(self.operand.pos, ERR_NOT_POINTER)
+ error(self.operand.pos, ERR_NOT_POINTER)
+ return
# Dimension sizes of C array
array_dimension_sizes = []
elif base_type.is_ptr:
base_type = base_type.base_type
else:
- return error()
+ error(self.pos, "unexpected base type %s found" % base_type)
+ return
if not (base_type.same_as(array_dtype) or base_type.is_void):
- return error(self.operand.pos, ERR_BASE_TYPE)
+ error(self.operand.pos, ERR_BASE_TYPE)
+ return
elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
- return error(self.operand.pos,
- "Expected %d dimensions, array has %d dimensions" %
+ error(self.operand.pos,
+ "Expected %d dimensions, array has %d dimensions" %
(ndim, len(array_dimension_sizes)))
+ return
# Verify the start, stop and step values
# In case of a C array, use the size of C array in each dimension to
# get an automatic cast
for axis_no, axis in enumerate(axes):
if not axis.start.is_none:
- return error(axis.start.pos, ERR_START)
+ error(axis.start.pos, ERR_START)
+ return
if axis.stop.is_none:
if array_dimension_sizes:
constant_result=dimsize,
type=PyrexTypes.c_int_type)
else:
- return error(axis.pos, ERR_NOT_STOP)
+ error(axis.pos, ERR_NOT_STOP)
+ return
axis.stop.analyse_types(env)
shape = axis.stop.coerce_to(self.shape_type, env)
axis.step.analyse_types(env)
if (not axis.step.type.is_int and axis.step.is_literal and not
axis.step.type.is_error):
- return error(axis.step.pos, "Expected an integer literal")
+ error(axis.step.pos, "Expected an integer literal")
+ return
if axis.step.compile_time_value(env) != 1:
- return error(axis.step.pos, ERR_STEPS)
+ error(axis.step.pos, ERR_STEPS)
+ return
if axis_no == 0:
self.mode = "fortran"
elif not axis.step.is_none and not first_or_last:
# step provided in some other dimension
- return error(axis.step.pos, ERR_STEPS)
+ error(axis.step.pos, ERR_STEPS)
+ return
if not self.operand.is_name:
self.operand = self.operand.coerce_to_temp(env)
or self.operand2.type.is_cpp_class)
def analyse_cpp_operation(self, env):
- type1 = self.operand1.type
- type2 = self.operand2.type
entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
if not entry:
self.type_error()
super(NumBinopNode, self).generate_result_code(code)
if self.overflow_check:
self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
- code.putln("%s = 0;" % self.overflow_bit);
+ code.putln("%s = 0;" % self.overflow_bit)
code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
code.putln("if (unlikely(%s)) {" % self.overflow_bit)
code.putln('PyErr_Format(PyExc_OverflowError, "value too large");')
BinopNode.is_py_operation_types(self, type1, type2))
def py_operation_function(self):
- fuction = self.py_functions[self.operator]
+ function_name = self.py_functions[self.operator]
if self.inplace:
- fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
- return fuction
+ function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
+ return function_name
py_functions = {
"|": "PyNumber_Or",
code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
self.operand1.result(),
self.operand2.result()))
- code.putln(code.set_error_info(self.pos));
+ code.putln(code.set_error_info(self.pos))
code.put("if (__Pyx_cdivision_warning(%(FILENAME)s, "
"%(LINENO)s)) " % {
'FILENAME': Naming.filename_cname,
def type_error(self):
if not (self.true_val.type.is_error or self.false_val.type.is_error):
- error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
+ error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
(self.true_val.type, self.false_val.type))
self.type = PyrexTypes.error_type
constant_result = not_a_constant
def __init__(self, arg):
- self.pos = arg.pos
+ super(CoercionNode, self).__init__(arg.pos)
self.arg = arg
if debug_coercion:
print("%s Coercing %s" % (self, self.arg))
absolute_path_length=cython.Py_ssize_t)
import sys, os, copy
+from itertools import chain
import Builtin
from Errors import error, warning, InternalError, CompileError
from StringEncoding import EncodedString, escape_byte_string, split_string_literal
import Options
import DebugFlags
-from Cython.Compiler import Errors
-from itertools import chain
absolute_path_length = 0
def relative_position(pos):
"""
We embed the relative filename in the generated C file, since we
- don't want to have to regnerate and compile all the source code
+ don't want to have to regenerate and compile all the source code
whenever the Python install directory moves (which could happen,
e.g,. when distributing binaries.)
encoding = docstring.encoding
if encoding is not None:
try:
- encoded_bytes = pos_line.encode(encoding)
+ pos_line.encode(encoding)
except UnicodeEncodeError:
encoding = None
is_terminator = 0
temps = None
- # All descandants should set child_attrs to a list of the attributes
+ # All descendants should set child_attrs to a list of the attributes
# containing nodes considered "children" in the tree. Each such attribute
# can either contain a single node or a list of nodes. See Visitor.py.
child_attrs = None
"""Clone the node. This is defined as a shallow copy, except for member lists
amongst the child attributes (from get_child_accessors) which are also
copied. Lists containing child nodes are thus seen as a way for the node
- to hold multiple children directly; the list is not treated as a seperate
+ to hold multiple children directly; the list is not treated as a separate
level in the tree."""
result = copy.copy(self)
for attrname in result.child_attrs:
if is_self_arg:
self.base_type.is_self_arg = self.is_self_arg = True
if self.type is None:
- # The parser may missinterpret names as types...
- # We fix that here.
+ # The parser may misinterpret names as types. We fix that here.
if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
if nonempty:
if self.base_type.is_basic_c_type:
# name string
# base_type CBaseTypeNode
+
child_attrs = ['base_type']
+
def analyse(self, env, could_be_name = None):
base_type = self.base_type.analyse(env)
if base_type is PyrexTypes.error_type:
# After analysis:
# type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
-
child_attrs = ["base_type_node", "positional_args",
"keyword_args", "dtype_node"]
if base_type.is_cpp_class:
# Templated class
if self.keyword_args and self.keyword_args.key_value_pairs:
- error(self.pos, "c++ templates cannot take keyword arguments");
+ error(self.pos, "c++ templates cannot take keyword arguments")
self.type = PyrexTypes.error_type
else:
template_types = []
cenv.scope_class.type.declaration_code(''),
Naming.self_cname))
if lenv.is_passthrough:
- code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
+ code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname))
elif self.needs_closure:
# inner closures own a reference to their outer parent
code.put_incref(outer_scope_cname, cenv.scope_class.type)
default_retval = self.return_type.default_value
err_val = self.error_value()
if err_val is None and default_retval:
- err_val = default_retval
+ err_val = default_retval # FIXME: why is err_val not used?
if self.return_type.is_pyobject:
code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
code.put_trace_return("Py_None")
if not lenv.nogil:
- # GIL holding funcion
+ # GIL holding function
code.put_finish_refcount_context()
if acquire_gil or (lenv.nogil and lenv.has_with_gil_block):
self.py_wrapper.analyse_declarations(env)
def analyse_argument_types(self, env):
- directive_locals = self.directive_locals = env.directives['locals']
+ self.directive_locals = env.directives['locals']
allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
f2s = env.fused_to_specific
sig = self.entry.signature
expected_str = "%d" % sig.num_fixed_args()
if sig.has_generic_args:
- expected_str = expected_str + " or more"
+ expected_str += " or more"
name = self.name
if name.startswith("__") and name.endswith("__"):
desc = "Special method"
return
arg_code_list = []
if self.entry.signature.has_dummy_arg:
- if self.needs_outer_scope:
- self_arg = 'PyObject *%s' % Naming.self_cname
- else:
- self_arg = 'CYTHON_UNUSED PyObject *%s' % Naming.self_cname
+ self_arg = 'PyObject *%s' % Naming.self_cname
+ if not self.needs_outer_scope:
+ self_arg = 'CYTHON_UNUSED ' + self_arg
arg_code_list.append(self_arg)
def arg_decl_code(arg):
else:
cname = entry.cname
decl = entry.type.declaration_code(cname)
- if entry.cf_used:
- return decl
- return 'CYTHON_UNUSED ' + decl
+ if not entry.cf_used:
+ decl = 'CYTHON_UNUSED ' + decl
+ return decl
for arg in self.args:
arg_code_list.append(arg_decl_code(arg))
code.put_incref(classobj_cname, py_object_type)
code.put_giveref(classobj_cname)
code.put_finish_refcount_context()
- code.putln('return (PyObject *) gen;');
+ code.putln('return (PyObject *) gen;')
code.putln('}')
def generate_function_definitions(self, env, code):
if proto:
code.putln('%s; /* proto */' % header)
else:
- code.putln('%s /* generator body */\n{' % header);
+ code.putln('%s /* generator body */\n{' % header)
def generate_function_definitions(self, env, code):
lenv = self.local_scope
first_arg = 1
import ExprNodes
self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
- call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
- call_node = ExprNodes.SimpleCallNode(self.pos,
- function=self.func_node,
- args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
+ call_node = ExprNodes.SimpleCallNode(
+ self.pos, function=self.func_node,
+ args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
self.body = ReturnStatNode(self.pos, value=call_node)
self.body.analyse_expressions(env)
self_arg = "((PyObject *)%s)" % self.args[0].cname
code.putln("/* Check if called by wrapper */")
code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
- code.putln("/* Check if overriden in Python */")
+ code.putln("/* Check if overridden in Python */")
if self.py_func.is_module_scope:
code.putln("else {")
else:
if not base_class_entry.is_type:
error(self.pos, "'%s' is not a type name" % self.base_class_name)
elif not base_class_entry.type.is_extension_type and \
- not (base_class_entry.type.is_builtin_type and \
+ not (base_class_entry.type.is_builtin_type and
base_class_entry.type.objstruct_cname):
error(self.pos, "'%s' is not an extension type" % self.base_class_name)
elif not base_class_entry.type.is_complete():
def annotate(self, code):
for i in range(len(self.lhs_list)):
- lhs = self.lhs_list[i].annotate(code)
- rhs = self.coerced_rhs_list[i].annotate(code)
+ self.lhs_list[i].annotate(code)
+ self.coerced_rhs_list[i].annotate(code)
self.rhs.annotate(code)
self.bound2.analyse_types(env)
if self.step is not None:
if isinstance(self.step, ExprNodes.UnaryMinusNode):
- warning(self.step.pos, "Probable infinite loop in for-from-by statment. 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.analyse_types(env)
- target_type = self.target.type
if self.target.type.is_numeric:
loop_type = self.target.type
else:
try_end_label = code.new_label('try_end')
exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
- for i in xrange(3)]
+ for _ in xrange(3)]
code.putln("{")
code.putln("__Pyx_ExceptionSave(%s);" %
', '.join(['&%s' % var for var in exc_save_vars]))
self.body.analyse_declarations(env)
def analyse_expressions(self, env):
- import ExprNodes
- genv = env.global_scope()
self.function_name = env.qualified_name
if self.pattern:
# normalise/unpack self.pattern into a list
self.pattern[i] = pattern.coerce_to_pyobject(env)
if self.target:
+ import ExprNodes
self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
self.target.analyse_target_expression(env, self.exc_value)
if self.excinfo_target is not None:
import ExprNodes
self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
- ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
+ ExprNodes.ExcValueNode(pos=self.pos, env=env) for _ in range(3)])
self.excinfo_tuple.analyse_expressions(env)
self.body.analyse_expressions(env)
exc_vars = [code.funcstate.allocate_temp(py_object_type,
manage_ref=True)
- for i in xrange(3)]
+ for _ in xrange(3)]
code.put_add_traceback(self.function_name)
# We always have to fetch the exception value even if
# there is no target, because this also normalises the
code.globalstate.use_utility_code(
invalid_values_utility_code)
first = False
-
- have_invalid_values = True
code.putln("%s = %s;" % (entry.cname,
entry.type.cast_code(invalid_value)))
"""
self.modified_entries = []
- for entry, (pos, op) in self.assignments.iteritems():
+ for entry in self.assignments:
if entry.from_closure or entry.in_closure:
self._allocate_closure_temp(code, entry)
"""
save_lastprivates_label = code.new_label()
dont_return_label = code.new_label()
- insertion_point = code.insertion_point()
self.any_label_used = False
self.breaking_label_used = False
(self.schedule,))
def analyse_expressions(self, env):
+ was_nogil = env.nogil
if self.nogil:
- was_nogil = env.nogil
env.nogil = True
if self.target is None:
if entry.func_cname:
entry.func_cname = self.mangle(entry.cname)
if entry.pyfunc_cname:
- old = entry.pyfunc_cname
entry.pyfunc_cname = self.mangle(entry.pyfunc_cname)
def mangle(self, cname):
has_attributes = 1
scope = None
- # These are specialcased in Defnode
+ # These are special cased in Defnode
from_py_function = None
to_py_function = None
subtypes = ['dtype']
def __init__(self, base_dtype, axes):
- '''
+ """
MemoryViewSliceType(base, axes)
Base is the C base type; axes is a list of (access, packing) strings,
Fortran-contiguous memory has 'direct' as the access spec, 'contig' as
the *first* axis' packing spec and 'follow' for all other packing
specs.
- '''
+ """
import MemoryView
self.dtype = base_dtype
return "__pyx_memoryview_fromslice(%s, %s, %s, %s, %d);" % tup
def dtype_object_conversion_funcs(self, env):
- import MemoryView, Code
-
get_function = "__pyx_memview_get_%s" % self.dtype_name
set_function = "__pyx_memview_set_%s" % self.dtype_name
return get_function, set_function
def axes_to_code(self):
- "Return a list of code constants for each axis"
+ """Return a list of code constants for each axis"""
import MemoryView
d = MemoryView._spec_to_const
return ["(%s | %s)" % (d[a], d[p]) for a, p in self.axes]
def axes_to_name(self):
- "Return an abbreviated name for our axes"
+ """Return an abbreviated name for our axes"""
import MemoryView
d = MemoryView._spec_to_abbrev
return "".join(["%s%s" % (d[a], d[p]) for a, p in self.axes])
return "%s[%s]" % (dtype_name, ", ".join(axes_code_list))
def specialize(self, values):
- "This does not validate the base type!!"
+ """This does not validate the base type!!"""
dtype = self.dtype.specialize(values)
if dtype is not self.dtype:
return MemoryViewSliceType(dtype, self.axes)
return True
def default_coerced_ctype(self):
- "The default C type that this Python type coerces to, or None."
+ """The default C type that this Python type coerces to, or None."""
return None
def assignable_from(self, src_type):
type_check = self.type_check_function(exact=True)
check = 'likely(%s(%s))' % (type_check, arg)
if not notnone:
- check = check + ('||((%s) == Py_None)' % arg)
+ check += '||((%s) == Py_None)' % arg
error = '(PyErr_Format(PyExc_TypeError, "Expected %s, got %%.200s", Py_TYPE(%s)->tp_name), 0)' % (self.name, arg)
return check + '||' + error
if base_type == self.const_base_type:
return self
else:
- return ConstType(base_type)
+ return CConstType(base_type)
def create_to_py_utility_code(self, env):
if self.const_base_type.create_to_py_utility_code(env):
visibility="extern")
scope.parent_type = self
scope.directives = {}
- entry = scope.declare_cfunction(
+ scope.declare_cfunction(
"conjugate",
CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
pos=None,
return True
def __lt__(self, other):
- "Sort based on rank, preferring signed over unsigned"
+ """Sort based on rank, preferring signed over unsigned"""
if other.is_numeric:
return self.rank > other.rank and self.signed >= other.signed
scope.directives = {}
scope.declare_var("real", self.real_type, None, cname="real", is_cdef=True)
scope.declare_var("imag", self.real_type, None, cname="imag", is_cdef=True)
- entry = scope.declare_cfunction(
+ scope.declare_cfunction(
"conjugate",
CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
pos=None,
return result
def get_fused_types(self, result=None, seen=None, subtypes=None):
- "Return fused types in the order they appear as parameter types"
+ """Return fused types in the order they appear as parameter types"""
return super(CFuncType, self).get_fused_types(result, seen,
subtypes=['args'])
def specialize_here(self, pos, template_values = None):
if self.templates is None:
- error(pos, "'%s' type is not a template" % self);
- return PyrexTypes.error_type
+ error(pos, "'%s' type is not a template" % self)
+ return error_type
if len(self.templates) != len(template_values):
error(pos, "%s templated type receives %d arguments, got %d" %
(self.name, len(self.templates), len(template_values)))
the same weight, we return None (as there is no best match). If pos
is not None, we also generate an error.
"""
- from Cython import Utils
-
# TODO: args should be a list of types, not a list of Nodes.
actual_nargs = len(args)