Commit d683abd3 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

merge

parents 31b7fc8e cdafb863
...@@ -368,8 +368,12 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos, ...@@ -368,8 +368,12 @@ def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos,
code.putln("%s = %d;" % (tmp_cname, dim)) code.putln("%s = %d;" % (tmp_cname, dim))
code.put("} else ") code.put("} else ")
# check bounds in positive direction # check bounds in positive direction
if signed != 0:
cast = ""
else:
cast = "(size_t)"
code.putln("if (%s) %s = %d;" % ( code.putln("if (%s) %s = %d;" % (
code.unlikely("%s >= %s" % (cname, shape.cname)), code.unlikely("%s >= %s%s" % (cname, cast, shape.cname)),
tmp_cname, dim)) tmp_cname, dim))
code.globalstate.use_utility_code(raise_indexerror_code) code.globalstate.use_utility_code(raise_indexerror_code)
code.putln("if (%s) {" % code.unlikely("%s != -1" % tmp_cname)) code.putln("if (%s) {" % code.unlikely("%s != -1" % tmp_cname))
......
...@@ -10,7 +10,7 @@ debug_temp_code_comments = 0 ...@@ -10,7 +10,7 @@ debug_temp_code_comments = 0
debug_trace_code_generation = 0 debug_trace_code_generation = 0
# Do not replace exceptions with user-friendly error messages # Do not replace exceptions with user-friendly error messages
debug_no_exception_intercept = 1 debug_no_exception_intercept = 0
# Print a message each time a new stage in the pipeline is entered # Print a message each time a new stage in the pipeline is entered
debug_verbose_pipeline = 0 debug_verbose_pipeline = 0
...@@ -1934,7 +1934,6 @@ class IndexNode(ExprNode): ...@@ -1934,7 +1934,6 @@ class IndexNode(ExprNode):
self.index.type) self.index.type)
elif self.base.type.is_cpp_class: elif self.base.type.is_cpp_class:
function = env.lookup_operator("[]", [self.base, self.index]) function = env.lookup_operator("[]", [self.base, self.index])
function = self.base.type.scope.lookup("operator[]")
if function is None: if function is None:
error(self.pos, "Indexing '%s' not supported for index type '%s'" % (self.base.type, self.index.type)) error(self.pos, "Indexing '%s' not supported for index type '%s'" % (self.base.type, self.index.type))
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
...@@ -1946,7 +1945,7 @@ class IndexNode(ExprNode): ...@@ -1946,7 +1945,7 @@ class IndexNode(ExprNode):
self.index = self.index.coerce_to(func_type.args[0].type, env) self.index = self.index.coerce_to(func_type.args[0].type, env)
self.type = func_type.return_type self.type = func_type.return_type
if setting and not func_type.return_type.is_reference: if setting and not func_type.return_type.is_reference:
error(self.pos, "Can't set non-reference '%s'" % self.type) error(self.pos, "Can't set non-reference result '%s'" % self.type)
else: else:
error(self.pos, error(self.pos,
"Attempting to index non-array type '%s'" % "Attempting to index non-array type '%s'" %
...@@ -2464,6 +2463,9 @@ class CallNode(ExprNode): ...@@ -2464,6 +2463,9 @@ class CallNode(ExprNode):
self.function.set_cname(type.declaration_code("")) self.function.set_cname(type.declaration_code(""))
self.analyse_c_function_call(env) self.analyse_c_function_call(env)
return True return True
def is_lvalue(self):
return self.type.is_reference
def nogil_check(self, env): def nogil_check(self, env):
func_type = self.function_type() func_type = self.function_type()
...@@ -4205,7 +4207,7 @@ class UnopNode(ExprNode): ...@@ -4205,7 +4207,7 @@ class UnopNode(ExprNode):
def is_cpp_operation(self): def is_cpp_operation(self):
type = self.operand.type type = self.operand.type
return type.is_cpp_class or type.is_reference and type.base_type.is_cpp_class return type.is_cpp_class
def coerce_operand_to_pyobject(self, env): def coerce_operand_to_pyobject(self, env):
self.operand = self.operand.coerce_to_pyobject(env) self.operand = self.operand.coerce_to_pyobject(env)
...@@ -4232,7 +4234,7 @@ class UnopNode(ExprNode): ...@@ -4232,7 +4234,7 @@ class UnopNode(ExprNode):
def analyse_cpp_operation(self, env): def analyse_cpp_operation(self, env):
type = self.operand.type type = self.operand.type
if type.is_ptr or type.is_reference: if type.is_ptr:
type = type.base_type type = type.base_type
function = type.scope.lookup("operator%s" % self.operator) function = type.scope.lookup("operator%s" % self.operator)
if not function: if not function:
...@@ -4749,14 +4751,8 @@ class BinopNode(ExprNode): ...@@ -4749,14 +4751,8 @@ class BinopNode(ExprNode):
return type1.is_pyobject or type2.is_pyobject return type1.is_pyobject or type2.is_pyobject
def is_cpp_operation(self): def is_cpp_operation(self):
type1 = self.operand1.type return (self.operand1.type.is_cpp_class
type2 = self.operand2.type or self.operand2.type.is_cpp_class)
if type1.is_reference:
type1 = type1.base_type
if type2.is_reference:
type2 = type2.base_type
return (type1.is_cpp_class
or type2.is_cpp_class)
def analyse_cpp_operation(self, env): def analyse_cpp_operation(self, env):
type1 = self.operand1.type type1 = self.operand1.type
...@@ -5405,13 +5401,7 @@ class CmpNode(object): ...@@ -5405,13 +5401,7 @@ class CmpNode(object):
return result return result
def is_cpp_comparison(self): def is_cpp_comparison(self):
type1 = self.operand1.type return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
type2 = self.operand2.type
if type1.is_reference:
type1 = type1.base_type
if type2.is_reference:
type2 = type2.base_type
return type1.is_cpp_class or type2.is_cpp_class
def find_common_int_type(self, env, op, operand1, operand2): def find_common_int_type(self, env, op, operand1, operand2):
# type1 != type2 and at least one of the types is not a C int # type1 != type2 and at least one of the types is not a C int
......
...@@ -9,5 +9,6 @@ def _get_feature(name): ...@@ -9,5 +9,6 @@ def _get_feature(name):
unicode_literals = _get_feature("unicode_literals") unicode_literals = _get_feature("unicode_literals")
with_statement = _get_feature("with_statement") with_statement = _get_feature("with_statement")
division = _get_feature("division") division = _get_feature("division")
print_function = _get_feature("print_function")
del _get_feature del _get_feature
...@@ -426,6 +426,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -426,6 +426,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
code.put(""" code.put("""
#include <stddef.h> /* For offsetof */
#ifndef offsetof
#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
#endif
#ifndef PY_LONG_LONG #ifndef PY_LONG_LONG
#define PY_LONG_LONG LONG_LONG #define PY_LONG_LONG LONG_LONG
#endif #endif
...@@ -903,7 +908,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -903,7 +908,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_descr_set_function(scope, code) self.generate_descr_set_function(scope, code)
self.generate_property_accessors(scope, code) self.generate_property_accessors(scope, code)
self.generate_method_table(scope, code) self.generate_method_table(scope, code)
self.generate_member_table(scope, code)
self.generate_getset_table(scope, code) self.generate_getset_table(scope, code)
self.generate_typeobj_definition(full_module_name, entry, code) self.generate_typeobj_definition(full_module_name, entry, code)
...@@ -1529,34 +1533,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1529,34 +1533,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"};") "};")
def generate_member_table(self, env, code):
#print "ModuleNode.generate_member_table: scope =", env ###
if env.public_attr_entries:
code.putln("")
code.putln(
"static struct PyMemberDef %s[] = {" %
env.member_table_cname)
type = env.parent_type
if type.typedef_flag:
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
for entry in env.public_attr_entries:
type_code = entry.type.pymemberdef_typecode
if entry.visibility == 'readonly':
flags = "READONLY"
else:
flags = "0"
code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
entry.name,
type_code,
"offsetof(%s, %s)" % (objstruct, entry.cname),
flags))
code.putln(
"{0, 0, 0, 0, 0}")
code.putln(
"};")
def generate_getset_table(self, env, code): def generate_getset_table(self, env, code):
if env.property_entries: if env.property_entries:
code.putln("") code.putln("")
......
...@@ -891,13 +891,13 @@ class CVarDefNode(StatNode): ...@@ -891,13 +891,13 @@ class CVarDefNode(StatNode):
# declarators [CDeclaratorNode] # declarators [CDeclaratorNode]
# in_pxd boolean # in_pxd boolean
# api boolean # api boolean
# need_properties [entry] # properties [entry]
# decorators [cython.locals(...)] or None # decorators [cython.locals(...)] or None
# directive_locals { string : NameNode } locals defined by cython.locals(...) # directive_locals { string : NameNode } locals defined by cython.locals(...)
child_attrs = ["base_type", "declarators"] child_attrs = ["base_type", "declarators"]
need_properties = () properties = ()
decorators = None decorators = None
directive_locals = {} directive_locals = {}
...@@ -912,15 +912,12 @@ class CVarDefNode(StatNode): ...@@ -912,15 +912,12 @@ class CVarDefNode(StatNode):
# so do conversion ourself rather than rely on the CPython mechanism (through # so do conversion ourself rather than rely on the CPython mechanism (through
# a property; made in AnalyseDeclarationsTransform). # a property; made in AnalyseDeclarationsTransform).
if (dest_scope.is_c_class_scope if (dest_scope.is_c_class_scope
and self.visibility == 'public' and self.visibility in ('public', 'readonly')):
and base_type.is_pyobject self.properties = []
and (base_type.is_builtin_type or base_type.is_extension_type)):
self.need_properties = []
need_property = True need_property = True
visibility = 'private'
else: else:
need_property = False need_property = False
visibility = self.visibility visibility = self.visibility
for declarator in self.declarators: for declarator in self.declarators:
name_declarator, type = declarator.analyse(base_type, env) name_declarator, type = declarator.analyse(base_type, env)
...@@ -951,8 +948,7 @@ class CVarDefNode(StatNode): ...@@ -951,8 +948,7 @@ class CVarDefNode(StatNode):
entry = dest_scope.declare_var(name, type, declarator.pos, entry = dest_scope.declare_var(name, type, declarator.pos,
cname = cname, visibility = visibility, is_cdef = 1) cname = cname, visibility = visibility, is_cdef = 1)
if need_property: if need_property:
self.need_properties.append(entry) self.properties.append(entry)
entry.needs_property = 1
class CStructOrUnionDefNode(StatNode): class CStructOrUnionDefNode(StatNode):
...@@ -5134,10 +5130,10 @@ static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) { ...@@ -5134,10 +5130,10 @@ static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
return -1; return -1;
end_string = PyUnicode_FromStringAndSize(" ", 1); end_string = PyUnicode_FromStringAndSize(" ", 1);
if (unlikely(!end_string)) if (unlikely(!end_string))
goto bad; return -1;
if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) { if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
Py_DECREF(end_string); Py_DECREF(end_string);
goto bad; return -1;
} }
Py_DECREF(end_string); Py_DECREF(end_string);
} }
......
...@@ -952,6 +952,11 @@ property NAME: ...@@ -952,6 +952,11 @@ property NAME:
def __set__(self, value): def __set__(self, value):
ATTR = value ATTR = value
""", level='c_class') """, level='c_class')
basic_property_ro = TreeFragment(u"""
property NAME:
def __get__(self):
return ATTR
""", level='c_class')
def __call__(self, root): def __call__(self, root):
self.env_stack = [root.scope] self.env_stack = [root.scope]
...@@ -1037,12 +1042,9 @@ property NAME: ...@@ -1037,12 +1042,9 @@ property NAME:
# to ensure all CNameDeclaratorNodes are visited. # to ensure all CNameDeclaratorNodes are visited.
self.visitchildren(node) self.visitchildren(node)
if node.need_properties: if node.properties:
# cdef public attributes may need type testing on
# assignment, so we create a property accesss
# mechanism for them.
stats = [] stats = []
for entry in node.need_properties: for entry in node.properties:
property = self.create_Property(entry) property = self.create_Property(entry)
property.analyse_declarations(node.dest_scope) property.analyse_declarations(node.dest_scope)
self.visit(property) self.visit(property)
...@@ -1052,13 +1054,34 @@ property NAME: ...@@ -1052,13 +1054,34 @@ property NAME:
return None return None
def create_Property(self, entry): def create_Property(self, entry):
template = self.basic_property if entry.visibility == 'public':
template = self.basic_property
elif entry.visibility == 'readonly':
template = self.basic_property_ro
property = template.substitute({ property = template.substitute({
u"ATTR": AttributeNode(pos=entry.pos, u"ATTR": AttributeNode(pos=entry.pos,
obj=NameNode(pos=entry.pos, name="self"), obj=NameNode(pos=entry.pos, name="self"),
attribute=entry.name), attribute=entry.name),
}, pos=entry.pos).stats[0] }, pos=entry.pos).stats[0]
property.name = entry.name property.name = entry.name
# ---------------------------------------
# XXX This should go to AutoDocTransforms
# ---------------------------------------
if self.current_directives['embedsignature']:
attr_name = entry.name
type_name = entry.type.declaration_code("", for_display=1)
default_value = ''
if not entry.type.is_pyobject:
type_name = "'%s'" % type_name
elif entry.type.is_extension_type:
type_name = entry.type.module_name + '.' + type_name
if entry.init is not None:
default_value = ' = ' + entry.init
elif entry.init_to_none:
default_value = ' = ' + repr(None)
docstring = attr_name + ': ' + type_name + default_value
property.doc = EncodedString(docstring)
# ---------------------------------------
return property return property
class AnalyseExpressionsTransform(CythonTransform): class AnalyseExpressionsTransform(CythonTransform):
......
...@@ -13,10 +13,10 @@ import sys ...@@ -13,10 +13,10 @@ import sys
try: try:
from __builtin__ import set from __builtin__ import set
except ImportError: except (ImportError, AttributeError):
try: try:
from builtins import set from builtins import set
except ImportError: except (ImportError, AttributeError):
from sets import Set as set from sets import Set as set
from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
...@@ -1745,13 +1745,13 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None): ...@@ -1745,13 +1745,13 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
# Make sure this is not a declaration of a variable or function. # Make sure this is not a declaration of a variable or function.
if s.sy == '(': if s.sy == '(':
s.next() s.next()
if s.sy == '*' or s.sy == '**': if s.sy == '*' or s.sy == '**' or s.sy == '&':
s.put_back('(', '(') s.put_back('(', '(')
else: else:
s.put_back('(', '(') s.put_back('(', '(')
s.put_back('IDENT', name) s.put_back('IDENT', name)
name = None name = None
elif s.sy not in ('*', '**', '['): elif s.sy not in ('*', '**', '[', '&'):
s.put_back('IDENT', name) s.put_back('IDENT', name)
name = None name = None
...@@ -1984,7 +1984,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, ...@@ -1984,7 +1984,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
error(s.position(), "Declarator should be empty") error(s.position(), "Declarator should be empty")
s.next() s.next()
cname = p_opt_cname(s) cname = p_opt_cname(s)
if s.sy == '=' and assignable: if name != "operator" and s.sy == '=' and assignable:
s.next() s.next()
rhs = p_simple_expr(s) rhs = p_simple_expr(s)
else: else:
......
...@@ -56,7 +56,6 @@ class PyrexType(BaseType): ...@@ -56,7 +56,6 @@ class PyrexType(BaseType):
# is_buffer boolean Is buffer access type # is_buffer boolean Is buffer access type
# has_attributes boolean Has C dot-selectable attributes # has_attributes boolean Has C dot-selectable attributes
# default_value string Initial value # default_value string Initial value
# pymemberdef_typecode string Type code for PyMemberDef struct
# #
# declaration_code(entity_code, # declaration_code(entity_code,
# for_display = 0, dll_linkage = None, pyrex = 0) # for_display = 0, dll_linkage = None, pyrex = 0)
...@@ -109,7 +108,6 @@ class PyrexType(BaseType): ...@@ -109,7 +108,6 @@ class PyrexType(BaseType):
is_buffer = 0 is_buffer = 0
has_attributes = 0 has_attributes = 0
default_value = "" default_value = ""
pymemberdef_typecode = None
def resolve(self): def resolve(self):
# If a typedef, returns the base type. # If a typedef, returns the base type.
...@@ -198,18 +196,6 @@ class CTypedefType(BaseType): ...@@ -198,18 +196,6 @@ class CTypedefType(BaseType):
self.typedef_cname = cname self.typedef_cname = cname
self.typedef_base_type = base_type self.typedef_base_type = base_type
self.typedef_is_external = is_external self.typedef_is_external = is_external
# Make typecodes in external typedefs use typesize-neutral macros
if is_external:
typecode = None
if base_type.is_int:
if base_type.signed == 0:
typecode = "__Pyx_T_UNSIGNED_INT"
else:
typecode = "__Pyx_T_SIGNED_INT"
elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
typecode = "__Pyx_T_FLOATING"
if typecode:
self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
def resolve(self): def resolve(self):
return self.typedef_base_type.resolve() return self.typedef_base_type.resolve()
...@@ -228,8 +214,9 @@ class CTypedefType(BaseType): ...@@ -228,8 +214,9 @@ class CTypedefType(BaseType):
def cast_code(self, expr_code): def cast_code(self, expr_code):
# If self is really an array (rather than pointer), we can't cast. # If self is really an array (rather than pointer), we can't cast.
# For example, the gmp mpz_t. # For example, the gmp mpz_t.
if self.typedef_base_type.is_ptr: if self.typedef_base_type.is_array:
return self.typedef_base_type.cast_code(expr_code) base_type = self.typedef_base_type.base_type
return CPtrType(base_type).cast_code(expr_code)
else: else:
return BaseType.cast_code(self, expr_code) return BaseType.cast_code(self, expr_code)
...@@ -348,7 +335,6 @@ class PyObjectType(PyrexType): ...@@ -348,7 +335,6 @@ class PyObjectType(PyrexType):
name = "object" name = "object"
is_pyobject = 1 is_pyobject = 1
default_value = "0" default_value = "0"
pymemberdef_typecode = "T_OBJECT"
buffer_defaults = None buffer_defaults = None
is_extern = False is_extern = False
is_subclassed = False is_subclassed = False
...@@ -617,10 +603,9 @@ class CNumericType(CType): ...@@ -617,10 +603,9 @@ class CNumericType(CType):
sign_words = ("unsigned ", "", "signed ") sign_words = ("unsigned ", "", "signed ")
def __init__(self, rank, signed = 1, pymemberdef_typecode = None): def __init__(self, rank, signed = 1):
self.rank = rank self.rank = rank
self.signed = signed self.signed = signed
self.pymemberdef_typecode = pymemberdef_typecode
def sign_and_name(self): def sign_and_name(self):
s = self.sign_words[self.signed] s = self.sign_words[self.signed]
...@@ -786,8 +771,8 @@ class CIntType(CNumericType): ...@@ -786,8 +771,8 @@ class CIntType(CNumericType):
from_py_function = "__Pyx_PyInt_AsInt" from_py_function = "__Pyx_PyInt_AsInt"
exception_value = -1 exception_value = -1
def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0): def __init__(self, rank, signed, is_returncode = 0):
CNumericType.__init__(self, rank, signed, pymemberdef_typecode) CNumericType.__init__(self, rank, signed)
self.is_returncode = is_returncode self.is_returncode = is_returncode
if self.from_py_function == "__Pyx_PyInt_AsInt": if self.from_py_function == "__Pyx_PyInt_AsInt":
self.from_py_function = self.get_type_conversion() self.from_py_function = self.get_type_conversion()
...@@ -886,8 +871,8 @@ class CFloatType(CNumericType): ...@@ -886,8 +871,8 @@ class CFloatType(CNumericType):
exception_value = -1 exception_value = -1
def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''): def __init__(self, rank, math_h_modifier = ''):
CNumericType.__init__(self, rank, 1, pymemberdef_typecode) CNumericType.__init__(self, rank, 1)
self.math_h_modifier = math_h_modifier self.math_h_modifier = math_h_modifier
def assignable_from_resolved_type(self, src_type): def assignable_from_resolved_type(self, src_type):
...@@ -1353,43 +1338,40 @@ class CNullPtrType(CPtrType): ...@@ -1353,43 +1338,40 @@ class CNullPtrType(CPtrType):
is_null_ptr = 1 is_null_ptr = 1
class CReferenceType(CType): class CReferenceType(BaseType):
is_reference = 1 is_reference = 1
def __init__(self, base_type): def __init__(self, base_type):
self.base_type = base_type self.ref_base_type = base_type
def __repr__(self): def __repr__(self):
return "<CReferenceType %s>" % repr(self.base_type) return "<CReferenceType %s>" % repr(self.ref_base_type)
def same_as_resolved_type(self, other_type):
return other_type.is_reference and self.base_type.same_as(other_type.base_type)
def __str__(self):
return "%s &" % self.ref_base_type
def as_argument_type(self):
return self
def declaration_code(self, entity_code, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
#print "CReferenceType.declaration_code: pointer to", self.base_type ### #print "CReferenceType.declaration_code: pointer to", self.base_type ###
return self.base_type.declaration_code( return self.ref_base_type.declaration_code(
"&%s" % entity_code, "&%s" % entity_code,
for_display, dll_linkage, pyrex) for_display, dll_linkage, pyrex)
def assignable_from_resolved_type(self, other_type):
if other_type is error_type:
return 1
elif other_type.is_reference and self.base_type == other_type.base_type:
return 1
elif other_type == self.base_type:
return 1
else: #for now
return 0
def specialize(self, values): def specialize(self, values):
base_type = self.base_type.specialize(values) base_type = self.ref_base_type.specialize(values)
if base_type == self.base_type: if base_type == self.ref_base_type:
return self return self
else: else:
return CReferenceType(base_type) return CReferenceType(base_type)
def __getattr__(self, name):
return getattr(self.ref_base_type, name)
class CFuncType(CType): class CFuncType(CType):
# return_type CType # return_type CType
# args [CFuncTypeArg] # args [CFuncTypeArg]
...@@ -1990,7 +1972,6 @@ class CStringType(object): ...@@ -1990,7 +1972,6 @@ class CStringType(object):
class CUTF8CharArrayType(CStringType, CArrayType): class CUTF8CharArrayType(CStringType, CArrayType):
# C 'char []' type. # C 'char []' type.
pymemberdef_typecode = "T_STRING_INPLACE"
is_unicode = 1 is_unicode = 1
to_py_function = "PyUnicode_DecodeUTF8" to_py_function = "PyUnicode_DecodeUTF8"
...@@ -2002,8 +1983,6 @@ class CUTF8CharArrayType(CStringType, CArrayType): ...@@ -2002,8 +1983,6 @@ class CUTF8CharArrayType(CStringType, CArrayType):
class CCharArrayType(CStringType, CArrayType): class CCharArrayType(CStringType, CArrayType):
# C 'char []' type. # C 'char []' type.
pymemberdef_typecode = "T_STRING_INPLACE"
def __init__(self, size): def __init__(self, size):
CArrayType.__init__(self, c_char_type, size) CArrayType.__init__(self, c_char_type, size)
...@@ -2011,8 +1990,6 @@ class CCharArrayType(CStringType, CArrayType): ...@@ -2011,8 +1990,6 @@ class CCharArrayType(CStringType, CArrayType):
class CCharPtrType(CStringType, CPtrType): class CCharPtrType(CStringType, CPtrType):
# C 'char *' type. # C 'char *' type.
pymemberdef_typecode = "T_STRING"
def __init__(self): def __init__(self):
CPtrType.__init__(self, c_char_type) CPtrType.__init__(self, c_char_type)
...@@ -2020,8 +1997,6 @@ class CCharPtrType(CStringType, CPtrType): ...@@ -2020,8 +1997,6 @@ class CCharPtrType(CStringType, CPtrType):
class CUCharPtrType(CStringType, CPtrType): class CUCharPtrType(CStringType, CPtrType):
# C 'unsigned char *' type. # C 'unsigned char *' type.
pymemberdef_typecode = "T_STRING"
to_py_function = "__Pyx_PyBytes_FromUString" to_py_function = "__Pyx_PyBytes_FromUString"
from_py_function = "__Pyx_PyBytes_AsUString" from_py_function = "__Pyx_PyBytes_AsUString"
...@@ -2087,30 +2062,30 @@ c_void_type = CVoidType() ...@@ -2087,30 +2062,30 @@ c_void_type = CVoidType()
c_void_ptr_type = CPtrType(c_void_type) c_void_ptr_type = CPtrType(c_void_type)
c_void_ptr_ptr_type = CPtrType(c_void_ptr_type) c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
c_uchar_type = CIntType(0, 0, "T_UBYTE") c_uchar_type = CIntType(0, 0)
c_ushort_type = CIntType(1, 0, "T_USHORT") c_ushort_type = CIntType(1, 0)
c_uint_type = CUIntType(2, 0, "T_UINT") c_uint_type = CUIntType(2, 0)
c_ulong_type = CULongType(3, 0, "T_ULONG") c_ulong_type = CULongType(3, 0)
c_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG") c_ulonglong_type = CULongLongType(6, 0)
c_char_type = CIntType(0, 1, "T_CHAR") c_char_type = CIntType(0, 1)
c_short_type = CIntType(1, 1, "T_SHORT") c_short_type = CIntType(1, 1)
c_int_type = CIntType(2, 1, "T_INT") c_int_type = CIntType(2, 1)
c_long_type = CLongType(3, 1, "T_LONG") c_long_type = CLongType(3, 1)
c_longlong_type = CLongLongType(6, 1, "T_LONGLONG") c_longlong_type = CLongLongType(6, 1)
c_bint_type = CBIntType(2, 1, "T_INT") c_bint_type = CBIntType(2, 1)
c_schar_type = CIntType(0, 2, "T_CHAR") c_schar_type = CIntType(0, 2)
c_sshort_type = CIntType(1, 2, "T_SHORT") c_sshort_type = CIntType(1, 2)
c_sint_type = CIntType(2, 2, "T_INT") c_sint_type = CIntType(2, 2)
c_slong_type = CLongType(3, 2, "T_LONG") c_slong_type = CLongType(3, 2)
c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG") c_slonglong_type = CLongLongType(6, 2)
c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET") c_py_ssize_t_type = CPySSizeTType(4, 2)
c_size_t_type = CSizeTType(5, 0, "T_SIZET") c_size_t_type = CSizeTType(5, 0)
c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f') c_float_type = CFloatType(7, math_h_modifier='f')
c_double_type = CFloatType(8, "T_DOUBLE") c_double_type = CFloatType(8)
c_longdouble_type = CFloatType(9, math_h_modifier='l') c_longdouble_type = CFloatType(9, math_h_modifier='l')
c_double_complex_type = CComplexType(c_double_type) c_double_complex_type = CComplexType(c_double_type)
...@@ -2125,7 +2100,7 @@ c_int_ptr_type = CPtrType(c_int_type) ...@@ -2125,7 +2100,7 @@ c_int_ptr_type = CPtrType(c_int_type)
c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
c_size_t_ptr_type = CPtrType(c_size_t_type) c_size_t_ptr_type = CPtrType(c_size_t_type)
c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1) c_returncode_type = CIntType(2, 1, is_returncode = 1)
c_anon_enum_type = CAnonEnumType(-1, 1) c_anon_enum_type = CAnonEnumType(-1, 1)
...@@ -2304,9 +2279,7 @@ def best_match(args, functions, pos=None): ...@@ -2304,9 +2279,7 @@ def best_match(args, functions, pos=None):
src_type = args[i].type src_type = args[i].type
dst_type = func_type.args[i].type dst_type = func_type.args[i].type
if dst_type.assignable_from(src_type): if dst_type.assignable_from(src_type):
if src_type == dst_type or (dst_type.is_reference and \ if src_type == dst_type or dst_type.same_as(src_type):
src_type == dst_type.base_type) \
or dst_type.same_as(src_type):
pass # score 0 pass # score 0
elif is_promotion(src_type, dst_type): elif is_promotion(src_type, dst_type):
score[2] += 1 score[2] += 1
...@@ -2496,68 +2469,6 @@ type_conversion_predeclarations = """ ...@@ -2496,68 +2469,6 @@ type_conversion_predeclarations = """
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
#if !defined(T_PYSSIZET)
#if PY_VERSION_HEX < 0x02050000
#define T_PYSSIZET T_INT
#elif !defined(T_LONGLONG)
#define T_PYSSIZET \\
((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
#else
#define T_PYSSIZET \\
((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\
((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
#endif
#endif
#if !defined(T_ULONGLONG)
#define __Pyx_T_UNSIGNED_INT(x) \\
((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : -1))))
#else
#define __Pyx_T_UNSIGNED_INT(x) \\
((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : \\
((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
#endif
#if !defined(T_LONGLONG)
#define __Pyx_T_SIGNED_INT(x) \\
((sizeof(x) == sizeof(char)) ? T_BYTE : \\
((sizeof(x) == sizeof(short)) ? T_SHORT : \\
((sizeof(x) == sizeof(int)) ? T_INT : \\
((sizeof(x) == sizeof(long)) ? T_LONG : -1))))
#else
#define __Pyx_T_SIGNED_INT(x) \\
((sizeof(x) == sizeof(char)) ? T_BYTE : \\
((sizeof(x) == sizeof(short)) ? T_SHORT : \\
((sizeof(x) == sizeof(int)) ? T_INT : \\
((sizeof(x) == sizeof(long)) ? T_LONG : \\
((sizeof(x) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))))
#endif
#define __Pyx_T_FLOATING(x) \\
((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
#if !defined(T_SIZET)
#if !defined(T_ULONGLONG)
#define T_SIZET \\
((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
#else
#define T_SIZET \\
((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\
((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
#endif
#endif
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*); static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
......
...@@ -10,13 +10,15 @@ import codecs ...@@ -10,13 +10,15 @@ import codecs
from time import time from time import time
import cython import cython
cython.declare(EncodedString=object, string_prefixes=object, raw_prefixes=object, IDENT=object) cython.declare(EncodedString=object, string_prefixes=object, raw_prefixes=object, IDENT=object,
print_function=object)
from Cython import Plex, Utils from Cython import Plex, Utils
from Cython.Plex.Scanners import Scanner from Cython.Plex.Scanners import Scanner
from Cython.Plex.Errors import UnrecognizedInput from Cython.Plex.Errors import UnrecognizedInput
from Errors import CompileError, error from Errors import CompileError, error
from Lexicon import string_prefixes, raw_prefixes, make_lexicon, IDENT from Lexicon import string_prefixes, raw_prefixes, make_lexicon, IDENT
from Future import print_function
from StringEncoding import EncodedString from StringEncoding import EncodedString
...@@ -61,7 +63,7 @@ def build_resword_dict(): ...@@ -61,7 +63,7 @@ def build_resword_dict():
d[word] = 1 d[word] = 1
return d return d
cython.declare(resword_dict=object) cython.declare(resword_dict=dict)
resword_dict = build_resword_dict() resword_dict = build_resword_dict()
#------------------------------------------------------------------ #------------------------------------------------------------------
...@@ -345,7 +347,11 @@ class PyrexScanner(Scanner): ...@@ -345,7 +347,11 @@ class PyrexScanner(Scanner):
self.error("Unrecognized character") self.error("Unrecognized character")
if sy == IDENT: if sy == IDENT:
if systring in resword_dict: if systring in resword_dict:
sy = systring if systring == 'print' and \
print_function in self.context.future_directives:
systring = EncodedString(systring)
else:
sy = systring
else: else:
systring = EncodedString(systring) systring = EncodedString(systring)
self.sy = sy self.sy = sy
......
...@@ -605,8 +605,6 @@ class Scope(object): ...@@ -605,8 +605,6 @@ class Scope(object):
def lookup_operator(self, operator, operands): def lookup_operator(self, operator, operands):
if operands[0].type.is_cpp_class: if operands[0].type.is_cpp_class:
obj_type = operands[0].type obj_type = operands[0].type
if obj_type.is_reference:
obj_type = obj_type.base_type
method = obj_type.scope.lookup("operator%s" % operator) method = obj_type.scope.lookup("operator%s" % operator)
if method is not None: if method is not None:
res = PyrexTypes.best_match(operands[1:], method.all_alternatives()) res = PyrexTypes.best_match(operands[1:], method.all_alternatives())
...@@ -793,7 +791,7 @@ class ModuleScope(Scope): ...@@ -793,7 +791,7 @@ class ModuleScope(Scope):
self.doc_cname = Naming.moddoc_cname self.doc_cname = Naming.moddoc_cname
self.utility_code_list = [] self.utility_code_list = []
self.module_entries = {} self.module_entries = {}
self.python_include_files = ["Python.h", "structmember.h"] self.python_include_files = ["Python.h"]
self.include_files = [] self.include_files = []
self.type_names = dict(outer_scope.type_names) self.type_names = dict(outer_scope.type_names)
self.pxd_file_loaded = 0 self.pxd_file_loaded = 0
...@@ -1323,10 +1321,8 @@ class CClassScope(ClassScope): ...@@ -1323,10 +1321,8 @@ class CClassScope(ClassScope):
# #typeobj_cname string or None # #typeobj_cname string or None
# #objstruct_cname string # #objstruct_cname string
# method_table_cname string # method_table_cname string
# member_table_cname string
# getset_table_cname string # getset_table_cname string
# has_pyobject_attrs boolean Any PyObject attributes? # has_pyobject_attrs boolean Any PyObject attributes?
# public_attr_entries boolean public/readonly attrs
# property_entries [Entry] # property_entries [Entry]
# defined boolean Defined in .pxd file # defined boolean Defined in .pxd file
# implemented boolean Defined in .pyx file # implemented boolean Defined in .pyx file
...@@ -1338,10 +1334,8 @@ class CClassScope(ClassScope): ...@@ -1338,10 +1334,8 @@ class CClassScope(ClassScope):
ClassScope.__init__(self, name, outer_scope) ClassScope.__init__(self, name, outer_scope)
if visibility != 'extern': if visibility != 'extern':
self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name) self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name) self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
self.has_pyobject_attrs = 0 self.has_pyobject_attrs = 0
self.public_attr_entries = []
self.property_entries = [] self.property_entries = []
self.inherited_var_entries = [] self.inherited_var_entries = []
self.defined = 0 self.defined = 0
...@@ -1382,16 +1376,14 @@ class CClassScope(ClassScope): ...@@ -1382,16 +1376,14 @@ class CClassScope(ClassScope):
error(pos, error(pos,
"Attribute of extension type cannot be declared %s" % visibility) "Attribute of extension type cannot be declared %s" % visibility)
if visibility in ('public', 'readonly'): if visibility in ('public', 'readonly'):
if type.pymemberdef_typecode: if name == "__weakref__":
self.public_attr_entries.append(entry) error(pos, "Special attribute __weakref__ cannot be exposed to Python")
if name == "__weakref__": if not type.is_pyobject:
error(pos, "Special attribute __weakref__ cannot be exposed to Python") if (not type.create_to_py_utility_code(self) or
else: (visibility=='public' and not
error(pos, type.create_from_py_utility_code(self))):
"C attribute of type '%s' cannot be accessed from Python" % type) error(pos,
if visibility == 'public' and type.is_extension_type: "C attribute of type '%s' cannot be accessed from Python" % type)
error(pos,
"Non-generic Python attribute cannot be exposed for writing from Python")
return entry return entry
else: else:
if type is unspecified_type: if type is unspecified_type:
...@@ -1563,7 +1555,6 @@ class CppClassScope(Scope): ...@@ -1563,7 +1555,6 @@ class CppClassScope(Scope):
error(pos, "no matching function for call to " \ error(pos, "no matching function for call to " \
"%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name)) "%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name))
elif not self.default_constructor: elif not self.default_constructor:
print 5
error(pos, "no matching function for call to %s::%s()" % error(pos, "no matching function for call to %s::%s()" %
(self.default_constructor, self.default_constructor)) (self.default_constructor, self.default_constructor))
...@@ -1610,11 +1601,16 @@ class CppClassScope(Scope): ...@@ -1610,11 +1601,16 @@ class CppClassScope(Scope):
entry.pos, entry.pos,
entry.cname) entry.cname)
else: else:
scope.declare_var(entry.name, # scope.declare_var(entry.name,
entry.type.specialize(values), # entry.type.specialize(values),
entry.pos, # entry.pos,
entry.cname, # entry.cname,
entry.visibility) # entry.visibility)
for e in entry.all_alternatives():
scope.declare_cfunction(e.name,
e.type.specialize(values),
e.pos,
e.cname)
return scope return scope
......
...@@ -277,10 +277,14 @@ def find_spanning_type(type1, type2): ...@@ -277,10 +277,14 @@ def find_spanning_type(type1, type2):
def aggressive_spanning_type(types, might_overflow): def aggressive_spanning_type(types, might_overflow):
result_type = reduce(find_spanning_type, types) result_type = reduce(find_spanning_type, types)
if result_type.is_reference:
result_type = result_type.ref_base_type
return result_type return result_type
def safe_spanning_type(types, might_overflow): def safe_spanning_type(types, might_overflow):
result_type = reduce(find_spanning_type, types) result_type = reduce(find_spanning_type, types)
if result_type.is_reference:
result_type = result_type.ref_base_type
if result_type.is_pyobject: if result_type.is_pyobject:
# any specific Python type is always safe to infer # any specific Python type is always safe to infer
return result_type return result_type
......
...@@ -370,10 +370,7 @@ class MemberTableSlot(SlotDescriptor): ...@@ -370,10 +370,7 @@ class MemberTableSlot(SlotDescriptor):
# Slot descriptor for the table of Python-accessible attributes. # Slot descriptor for the table of Python-accessible attributes.
def slot_code(self, scope): def slot_code(self, scope):
if scope.public_attr_entries: return "0"
return scope.member_table_cname
else:
return "0"
class GetSetSlot(SlotDescriptor): class GetSetSlot(SlotDescriptor):
......
from pair cimport pair
cdef extern from "<deque>" namespace "std":
cdef cppclass deque[T]:
cppclass iterator:
T operator*()
iterator operator++()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
deque()
deque(deque&)
deque(size_t, T& val = T())
#deque(input_iterator, input_iterator)
TYPE& operator[]( size_type index )
const TYPE& operator[]( size_type index ) const
#deque& operator=(deque&)
bool operator==(deque&, deque&)
bool operator!=(deque&, deque&)
bool operator<(deque&, deque&)
bool operator>(deque&, deque&)
bool operator<=(deque&, deque&)
bool operator>=(deque&, deque&)
void assign(size_t, TYPE&)
void assign(input_iterator, input_iterator)
T& at(size_t)
T& back()
iterator begin()
const_iterator begin()
void clear()
bool empty()
iterator end()
const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
iterator insert(iterator, T&)
void insert(iterator, size_t, T&)
void insert(iterator, input_iterator, input_iterator)
size_t max_size()
void pop_back()
void pop_front()
void push_back(T&)
void push_front(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
void resize(size_t, T val = T())
size_t size()
void swap(deque&)
cdef extern from "pair.h":
cdef cppclass pair[T, U]:
T first
U second
pair()
pair(T&, U&)
from pair cimport pair
cdef extern from "<queue>" namespace "std":
cdef cppclass queue[T]:
queue()
#queue(Container&)
T& back()
bool empty()
T& front()
void pop()
void push(T&)
size_t size()
from pair cimport pair
cdef extern from "<set>" namespace "std":
cdef cppclass set[T]:
cppclass iterator:
T operator*()
iterator operator++()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
set()
set(set&)
#set set(key_compare&)
#set& operator=(set&)
bool operator==(set&, set&)
bool operator!=(set&, set&)
bool operator<(set&, set&)
bool operator>(set&, set&)
bool operator<=(set&, set&)
bool operator>=(set&, set&)
iterator begin()
const_iterator begin()
void clear()
#size_t count(key_type&)
bool empty()
iterator end()
const_iterator end()
#pair[iterator, iterator] equal_range(key_type&)
#pair[const_iterator, const_iterator] equal_range(key_type&)
void erase(iterator)
void erase(iterator, iterator)
#size_t erase(key_type&)
#iterator find(key_type&)
#const_iterator find(key_type&)
#pair[iterator, bool] insert(T&)
iterator insert(iterator, T&)
#void insert(input_iterator, input_iterator)
#key_compare key_comp()
#iterator lower_bound(key_type&)
#const_iterator lower_bound(key_type&)
size_t max_size()
reverse_iterator rbegin()
const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
size_t size()
void swap(set&)
#iterator upper_bound(key_type&)
#const_iterator upper_bound(key_type&)
#value_compare value_comp()
from pair cimport pair
cdef extern from "<list>" namespace "std":
cdef cppclass list[T]:
cppclass iterator:
T operator*()
iterator operator++()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
list()
list(list&)
list(size_t, T&)
#list operator=(list&)
bool operator==(list&, list&)
bool operator!=(list&, list&)
bool operator<(list&, list&)
bool operator>(list&, list&)
bool operator<=(list&, list&)
bool operator>=(list&, list&)
void assign(size_t, T&)
T& back()
iterator begin()
const_iterator begin()
bool empty()
iterator end()
const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
iterator insert(iterator, T&)
void insert(iterator, size_t, T&)
size_t max_size()
void merge(list&)
#voide merge(list&, BinPred)
void pop_back()
void pop_front()
void push_back(T&)
void push_front(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
void remove(T&)
#void remove_if(UnPred)
reverse_iterator rend()
const_reverse_iterator rend()
void resize(size_t, T&)
void reverse()
size_t size()
void sort()
#void sort(BinPred)
void splice(iterator, list&)
void splice(iterator, list&, iterator)
void splice(iterator, list&, iterator, iterator)
void swap(list&)
void unique()
#void unique(BinPred)
from pair cimport pair
cdef extern from "<vector>" namespace "std":
cdef cppclass vector[T]:
cppclass iterator:
T operator*()
iterator operator++()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
#cppclass input_iterator(iterator):
# pass
vector()
#vector(vector&)
#vector(size_t, T&)
#vector[input_iterator](input_iterator, input_iterator)
T& operator[](size_t)
#vector& operator=(vector&)
bool operator==(vector&, vector&)
bool operator!=(vector&, vector&)
bool operator<(vector&, vector&)
bool operator>(vector&, vector&)
bool operator<=(vector&, vector&)
bool operator>=(vector&, vector&)
void assign(size_t, T&)
#void assign(input_iterator, input_iterator)
T& at(size_t)
T& back()
iterator begin()
const_iterator begin()
size_t capacity()
void clear()
bool empty()
iterator end()
const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
iterator insert(iterator, T&)
void insert(iterator, size_t, T&)
void insert(iterator, iterator, iterator)
size_t max_size()
void pop_back()
void push_back(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
void reserve(size_t)
void resize(size_t, T)
size_t size()
void swap(vector&)
import sys
sys.stderr = sys.stdout
from TransitionMaps import TransitionMap
m = TransitionMap()
print m
def add(c, s):
print
print "adding", repr(c), "-->", repr(s)
m.add_transition(c, s)
print m
print "keys:", m.keys()
add('a','alpha')
add('e', 'eta')
add('f', 'foo')
add('i', 'iota')
add('i', 'imp')
add('eol', 'elephant')
...@@ -59,8 +59,11 @@ class Context(object): ...@@ -59,8 +59,11 @@ class Context(object):
else: else:
return None return None
cdef void report_unraisable(object e): cdef void report_unraisable(object e=None):
try: try:
if e is None:
import sys
e = sys.exc_info()[1]
print u"refnanny raised an exception: %s" % e print u"refnanny raised an exception: %s" % e
except: except:
pass # We absolutely cannot exit with an exception pass # We absolutely cannot exit with an exception
...@@ -92,12 +95,16 @@ cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno): ...@@ -92,12 +95,16 @@ cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno):
cdef PyObject* type = NULL, *value = NULL, *tb = NULL cdef PyObject* type = NULL, *value = NULL, *tb = NULL
PyErr_Fetch(&type, &value, &tb) PyErr_Fetch(&type, &value, &tb)
try: try:
if p_obj is NULL: try:
(<object>ctx).regref(None, lineno, True) if p_obj is NULL:
else: (<object>ctx).regref(None, lineno, True)
(<object>ctx).regref(<object>p_obj, lineno, False) else:
except Exception, e: (<object>ctx).regref(<object>p_obj, lineno, False)
report_unraisable(e) except:
report_unraisable()
except:
# __Pyx_GetException may itself raise errors
pass
PyErr_Restore(type, value, tb) PyErr_Restore(type, value, tb)
cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno): cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno):
...@@ -106,12 +113,16 @@ cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno): ...@@ -106,12 +113,16 @@ cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno):
cdef bint decref_ok = False cdef bint decref_ok = False
PyErr_Fetch(&type, &value, &tb) PyErr_Fetch(&type, &value, &tb)
try: try:
if p_obj is NULL: try:
decref_ok = (<object>ctx).delref(None, lineno, True) if p_obj is NULL:
else: decref_ok = (<object>ctx).delref(None, lineno, True)
decref_ok = (<object>ctx).delref(<object>p_obj, lineno, False) else:
except Exception, e: decref_ok = (<object>ctx).delref(<object>p_obj, lineno, False)
report_unraisable(e) except:
report_unraisable()
except:
# __Pyx_GetException may itself raise errors
pass
PyErr_Restore(type, value, tb) PyErr_Restore(type, value, tb)
return decref_ok return decref_ok
...@@ -132,13 +143,17 @@ cdef void FinishContext(PyObject** ctx): ...@@ -132,13 +143,17 @@ cdef void FinishContext(PyObject** ctx):
cdef object errors = None cdef object errors = None
PyErr_Fetch(&type, &value, &tb) PyErr_Fetch(&type, &value, &tb)
try: try:
errors = (<object>ctx[0]).end() try:
pos = (<object>ctx[0]).filename, (<object>ctx[0]).name errors = (<object>ctx[0]).end()
if errors: pos = (<object>ctx[0]).filename, (<object>ctx[0]).name
print u"%s: %s()" % pos if errors:
print errors print u"%s: %s()" % pos
except Exception, e: print errors
report_unraisable(e) except:
report_unraisable()
except:
# __Pyx_GetException may itself raise errors
pass
Py_DECREF(<object>ctx[0]) Py_DECREF(<object>ctx[0])
ctx[0] = NULL ctx[0] = NULL
PyErr_Restore(type, value, tb) PyErr_Restore(type, value, tb)
......
...@@ -208,7 +208,9 @@ class _XMLTestResult(_TextTestResult): ...@@ -208,7 +208,9 @@ class _XMLTestResult(_TextTestResult):
xml_testsuite.appendChild(testcase) xml_testsuite.appendChild(testcase)
testcase.setAttribute('classname', str(suite_name)) testcase.setAttribute('classname', str(suite_name))
testcase.setAttribute('name', str(test_result.test_method.shortDescription() or test_result.test_method._testMethodName)) testcase.setAttribute('name', test_result.test_method.shortDescription()
or getattr(test_result.test_method, '_testMethodName',
str(test_result.test_method)))
testcase.setAttribute('time', '%.3f' % test_result.get_elapsed_time()) testcase.setAttribute('time', '%.3f' % test_result.get_elapsed_time())
if (test_result.outcome != _TestInfo.SUCCESS): if (test_result.outcome != _TestInfo.SUCCESS):
......
# Makefile for creating our standalone Cython program # Makefile for creating our standalone Cython program
PYVERSION=$(shell python -c "import sys; print(sys.version[:3])") PYTHON=python
PYPREFIX=$(shell python -c "import sys; print(sys.prefix)") PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])")
LINKFORSHARED=$(shell python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKFORSHARED'))") PYPREFIX=$(shell $(PYTHON) -c "import sys; print(sys.prefix)")
LINKFORSHARED=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKFORSHARED'))")
INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION) INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION)
embedded: embedded.o embedded: embedded.o
...@@ -11,7 +12,7 @@ embedded.o: embedded.c ...@@ -11,7 +12,7 @@ embedded.o: embedded.c
gcc -c $^ $(INCLUDES) gcc -c $^ $(INCLUDES)
embedded.c: embedded.pyx embedded.c: embedded.pyx
@python ../../cython.py --embed embedded.pyx @$(PYTHON) ../../cython.py --embed embedded.pyx
all: embedded all: embedded
...@@ -21,4 +22,4 @@ clean: ...@@ -21,4 +22,4 @@ clean:
test: clean all test: clean all
./embedded > test.output ./embedded > test.output
python assert_equal.py embedded.output test.output $(PYTHON) assert_equal.py embedded.output test.output
...@@ -22,7 +22,7 @@ repo: .hg ...@@ -22,7 +22,7 @@ repo: .hg
clean: clean:
@echo Cleaning Source @echo Cleaning Source
@rm -fr build @rm -fr build
@rm -f *.pyc */*.pyc */*/*.pyc @rm -f *.py[co] */*.py[co] */*/*.py[co] */*/*/*.py[co]
@rm -f *.so */*.so */*/*.so @rm -f *.so */*.so */*/*.so
@rm -f *.pyd */*.pyd */*/*.pyd @rm -f *.pyd */*.pyd */*/*.pyd
@rm -f *~ */*~ */*/*~ @rm -f *~ */*~ */*/*~
......
...@@ -48,8 +48,12 @@ EXT_DEP_INCLUDES = [ ...@@ -48,8 +48,12 @@ EXT_DEP_INCLUDES = [
] ]
VER_DEP_MODULES = { VER_DEP_MODULES = {
# tests are excluded if 'CurrentPythonVersion OP VersionTuple', i.e.
# (2,4) : (operator.le, ...) excludes ... when PyVer <= 2.4.x
(2,4) : (operator.le, lambda x: x in ['run.extern_builtins_T258' (2,4) : (operator.le, lambda x: x in ['run.extern_builtins_T258'
]), ]),
(2,6) : (operator.lt, lambda x: x in ['run.print_function'
]),
(3,): (operator.ge, lambda x: x in ['run.non_future_division', (3,): (operator.ge, lambda x: x in ['run.non_future_division',
'compile.extsetslice', 'compile.extsetslice',
'compile.extdelslice']), 'compile.extdelslice']),
...@@ -615,17 +619,24 @@ class EmbedTest(unittest.TestCase): ...@@ -615,17 +619,24 @@ class EmbedTest(unittest.TestCase):
def setUp(self): def setUp(self):
self.old_dir = os.getcwd() self.old_dir = os.getcwd()
os.chdir(self.working_dir) os.chdir(self.working_dir)
os.system("make clean > /dev/null") os.system(
"make PYTHON='%s' clean > /dev/null" % sys.executable)
def tearDown(self): def tearDown(self):
try: try:
os.system("make clean > /dev/null") os.system(
"make PYTHON='%s' clean > /dev/null" % sys.executable)
except: except:
pass pass
os.chdir(self.old_dir) os.chdir(self.old_dir)
def test_embed(self): def test_embed(self):
self.assert_(os.system("make test > make.output") == 0) self.assert_(os.system(
"make PYTHON='%s' test > make.output" % sys.executable) == 0)
try:
os.remove('make.output')
except OSError:
pass
class MissingDependencyExcluder: class MissingDependencyExcluder:
def __init__(self, deps): def __init__(self, deps):
......
...@@ -3,9 +3,9 @@ from distutils.sysconfig import get_python_lib ...@@ -3,9 +3,9 @@ from distutils.sysconfig import get_python_lib
import os, os.path import os, os.path
import sys import sys
if 'sdist' in sys.argv and sys.platform != "win32": if 'sdist' in sys.argv and sys.platform != "win32" and sys.version_info >= (2,4):
# Record the current revision in .hgrev # Record the current revision in .hgrev
import subprocess # os.popen is cleaner but depricated import subprocess # os.popen is cleaner but deprecated
changset = subprocess.Popen("hg log --rev tip | grep changeset", changset = subprocess.Popen("hg log --rev tip | grep changeset",
shell=True, shell=True,
stdout=subprocess.PIPE).stdout.read() stdout=subprocess.PIPE).stdout.read()
...@@ -14,10 +14,6 @@ if 'sdist' in sys.argv and sys.platform != "win32": ...@@ -14,10 +14,6 @@ if 'sdist' in sys.argv and sys.platform != "win32":
hgrev.write(rev) hgrev.write(rev)
hgrev.close() hgrev.close()
compiler_dir = os.path.join(get_python_lib(prefix=''), 'Cython/Compiler')
if sys.platform == "win32":
compiler_dir = compiler_dir[len(sys.prefix)+1:]
if sys.platform == "darwin": if sys.platform == "darwin":
# Don't create resource files on OS X tar. # Don't create resource files on OS X tar.
os.environ['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true' os.environ['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
...@@ -43,16 +39,16 @@ if sys.version_info[0] >= 3: ...@@ -43,16 +39,16 @@ if sys.version_info[0] >= 3:
if sys.version_info < (2,4): if sys.version_info < (2,4):
install_base_dir = get_python_lib(prefix='')
import glob import glob
cython_dir = os.path.join(get_python_lib(prefix=''), 'Cython')
compiler_dir = os.path.join(cython_dir, 'Compiler')
setup_args['data_files'] = [ setup_args['data_files'] = [
(cython_dir, [ f for pattern in (os.path.dirname(os.path.join(install_base_dir, pattern)),
['Cython/Includes/*.pxd', [ f for f in glob.glob(pattern) ])
for pattern in ['Cython/Includes/*.pxd',
'Cython/Plex/*.pxd', 'Cython/Plex/*.pxd',
'Cython/Compiler/*.pxd', 'Cython/Compiler/*.pxd',
'Cython/Runtime/*.pyx'] 'Cython/Runtime/*.pyx']
for f in glob.glob(pattern) ])] ]
else: else:
setup_args['package_data'] = {'Cython' : ['Includes/*.pxd', setup_args['package_data'] = {'Cython' : ['Includes/*.pxd',
'Plex/*.pxd', 'Plex/*.pxd',
......
cdef extern from "cast_ctypedef_array_T518_helper.h":
cdef struct __foo_struct:
int i, j
ctypedef __foo_struct foo_t[1]
void foo_init(foo_t)
void foo_clear(foo_t)
cdef foo_t value
foo_init(value)
foo_clear(value)
cdef void *pointer = <void*> value
foo_init(<foo_t>pointer)
foo_clear(<foo_t>pointer)
struct __foo_struct { int i, j; };
typedef struct __foo_struct foo_t[1];
static void foo_init (foo_t v) { v[0].i = 0; v[0].j = 0; }
static void foo_clear (foo_t v) { v[0].i = 0; v[0].j = 0; }
...@@ -8,7 +8,7 @@ cdef class Spam: ...@@ -8,7 +8,7 @@ cdef class Spam:
cdef public float f cdef public float f
cdef public double d cdef public double d
cdef public char *s cdef public char *s
cdef public char a[42] cdef readonly char a[42]
cdef public object o cdef public object o
cdef readonly int r cdef readonly int r
cdef readonly Spam e cdef readonly Spam e
ctypedef void* VoidP
cdef class Spam:
cdef VoidP vp0
cdef readonly VoidP vp2
cdef public VoidP vp1
ctypedef struct Foo:
int i
cdef class Bar:
cdef Foo foo0
cdef readonly Foo foo2
cdef public Foo foo1
pass
_ERRORS = u"""
5:24: C attribute of type 'VoidP' cannot be accessed from Python
5:24: Cannot convert 'VoidP' to Python object
6:24: C attribute of type 'VoidP' cannot be accessed from Python
6:24: Cannot convert 'VoidP' to Python object
6:24: Cannot convert Python object to 'VoidP'
14:22: C attribute of type 'Foo' cannot be accessed from Python
14:22: Cannot convert Python object to 'Foo'
"""
...@@ -13,7 +13,10 @@ cdef void f(): ...@@ -13,7 +13,10 @@ cdef void f():
x = c.__weakref__ x = c.__weakref__
c.__weakref__ = x c.__weakref__ = x
_ERRORS = u""" _ERRORS = u"""
5:20: Illegal use of special attribute __weakref__
5:20: Illegal use of special attribute __weakref__
5:20: Special attribute __weakref__ cannot be exposed to Python 5:20: Special attribute __weakref__ cannot be exposed to Python
8:22: Illegal use of special attribute __weakref__
8:22: Special attribute __weakref__ cannot be exposed to Python 8:22: Special attribute __weakref__ cannot be exposed to Python
13:6: Illegal use of special attribute __weakref__ 13:6: Illegal use of special attribute __weakref__
14:2: Illegal use of special attribute __weakref__ 14:2: Illegal use of special attribute __weakref__
......
#cython: embedsignature=True
__doc__ = u"""
>>> a = A()
>>> a.h = 7
>>> a.i = 127
>>> a.l = 255
>>> a.q = 255
>>> a.f = 1.0/2.0
>>> a.d = 1/2.0 + 1/4.0
>>> a.g = 1/2.0 + 1/4.0 + 1/8.0
>>> a.Zf = 1+2j
>>> a.Zd = 3+4j
>>> a.Zg = 5+6j
>>> a.h, a.i, a.l
(7, 127, 255)
>>> a.ro_h, a.ro_i, a.ro_l
(7, 127, 255)
>>> a.f, a.d, a.g
(0.5, 0.75, 0.875)
>>> a.ro_f, a.ro_d, a.ro_g
(0.5, 0.75, 0.875)
>>> a.Zf, a.Zd, a.Zg
((1+2j), (3+4j), (5+6j))
>>> a.ro_Zf, a.ro_Zd, a.ro_Zg
((1+2j), (3+4j), (5+6j))
>>> b = B()
>>> b.a0 #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
>>> b.b0 #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
>>> b.c0 #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
>>> isinstance(b.a1, type(None))
True
>>> isinstance(b.a2, type(None))
True
>>> isinstance(b.b1, list)
True
>>> isinstance(b.b2, list)
True
>>> isinstance(b.c1, A)
True
>>> isinstance(b.c2, A)
True
>>> b.a1 = a
>>> b.a1 is not b.a2
True
>>> b.b1 = 1 #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: ...
>>> b.c1 = 1 #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: ...
>>> b.a2 = None #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
>>> b.b2 = [] #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
>>> b.c2 = A() #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: ...
"""
cdef class A:
cdef public short h
cdef public int i
cdef public long l
cdef public long long q
cdef public float f
cdef public double d
cdef public long double g
cdef public float complex Zf
cdef public double complex Zd
cdef public long double complex Zg
cdef readonly short ro_h
cdef readonly int ro_i
cdef readonly long ro_l
cdef readonly long long ro_q
cdef readonly float ro_f
cdef readonly double ro_d
cdef readonly long double ro_g
cdef readonly float complex ro_Zf
cdef readonly double complex ro_Zd
cdef readonly long double complex ro_Zg
def __cinit__(self):
self.ro_h = 7
self.ro_i = 127
self.ro_l = 255
self.ro_q = 255
self.ro_f = 1.0/2.0
self.ro_d = 1/2.0 + 1/4.0
self.ro_g = 1/2.0 + 1/4.0 + 1/8.0
self.ro_Zf = 1+2j
self.ro_Zd = 3+4j
self.ro_Zg = 5+6j
cdef class B:
cdef object a0
cdef public object a1
cdef readonly object a2
cdef list b0
cdef public list b1
cdef readonly list b2
cdef A c0
cdef public A c1
cdef readonly A c2
def __cinit__(self):
self.b0 = self.b1 = self.b2 = []
self.c0 = self.c1 = self.c2 = A()
from cython.operator cimport dereference as d
cdef extern from "<vector>" namespace "std": cdef extern from "<vector>" namespace "std":
cdef cppclass vector[T]: cdef cppclass vector[T]:
void push_back(T) void push_back(T)
size_t size() size_t size()
T operator[](size_t) T& operator[](size_t)
def simple_test(double x): def simple_test(double x):
""" """
>>> simple_test(55) >>> simple_test(55)
3 3
""" """
cdef vector[double] *v
try: try:
v = new vector[double]() v = new vector[double]()
v.push_back(1.0) v.push_back(1.0)
...@@ -30,7 +31,6 @@ def list_test(L): ...@@ -30,7 +31,6 @@ def list_test(L):
>>> list_test([-1] * 1000) >>> list_test([-1] * 1000)
(1000, 1000) (1000, 1000)
""" """
cdef vector[int] *v
try: try:
v = new vector[int]() v = new vector[int]()
for a in L: for a in L:
...@@ -46,7 +46,6 @@ def index_test(L): ...@@ -46,7 +46,6 @@ def index_test(L):
>>> index_test([1.25]) >>> index_test([1.25])
(1.25, 1.25) (1.25, 1.25)
""" """
cdef vector[double] *v
try: try:
v = new vector[double]() v = new vector[double]()
for a in L: for a in L:
...@@ -54,3 +53,21 @@ def index_test(L): ...@@ -54,3 +53,21 @@ def index_test(L):
return v[0][0], v[0][len(L)-1] return v[0][0], v[0][len(L)-1]
finally: finally:
del v del v
def index_set_test(L):
"""
>>> index_set_test([1,2,4,8])
(-1.0, -8.0)
>>> index_set_test([1.25])
(-1.25, -1.25)
"""
try:
v = new vector[double]()
for a in L:
v.push_back(a)
for i in range(v.size()):
d(v)[i] = -d(v)[i]
return d(v)[0], d(v)[v.size()-1]
finally:
del v
...@@ -5,6 +5,15 @@ __doc__ = ur""" ...@@ -5,6 +5,15 @@ __doc__ = ur"""
>>> print (Ext.__doc__) >>> print (Ext.__doc__)
Ext(a, b, c=None) Ext(a, b, c=None)
>>> print (Ext.attr0.__doc__)
attr0: 'int'
>>> print (Ext.attr1.__doc__)
attr1: object
>>> print (Ext.attr2.__doc__)
attr2: list
>>> print (Ext.attr3.__doc__)
attr3: embedsignatures.Ext
>>> print (Ext.a.__doc__) >>> print (Ext.a.__doc__)
Ext.a(self) Ext.a(self)
...@@ -145,6 +154,11 @@ __doc__ = ur""" ...@@ -145,6 +154,11 @@ __doc__ = ur"""
cdef class Ext: cdef class Ext:
cdef public int attr0
cdef public attr1
cdef public list attr2
cdef public Ext attr3
def __init__(self, a, b, c=None): def __init__(self, a, b, c=None):
pass pass
......
# Py2.6 and later only!
from __future__ import print_function
def print_to_stdout(a, b):
"""
>>> print_to_stdout(1, 'test')
<BLANKLINE>
1
1 test
1 test
1 test 42 spam
"""
print()
print(a)
print(a, end=' ')
print(b)
print(a, b)
print(a, b, end=' ')
print(42, u"spam")
def print_assign(a, b):
"""
>>> print_assign(1, 'test')
<BLANKLINE>
1
1 test
1 test
1 test 42 spam
"""
x = print
x()
x(a)
x(a, end=' ')
x(b)
x(a, b)
x(a, b, end=' ')
x(42, u"spam")
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
def print_to_stringio(stream, a, b):
"""
>>> stream = StringIO()
>>> print_to_stringio(stream, 1, 'test')
>>> print(stream.getvalue())
<BLANKLINE>
1
1 test
1 test
1 test 42 spam
<BLANKLINE>
"""
print(file=stream)
print(a, file=stream)
print(a, end=' ', file=stream)
print(b, file=stream)
print(a, b, file=stream)
print(a, b, end=' ', file=stream)
print(42, u"spam", file=stream)
__doc__ = """ __doc__ = """
>>> readonly() >>> readonly() #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: readonly attribute TypeError: ...
""" """
import sys import sys
if sys.version_info[0] >= 3: if sys.version_info[0:2] >= (2,4):
__doc__ = __doc__.replace(u'TypeError:', u'AttributeError:') __doc__ = __doc__.replace(u'TypeError:', u'AttributeError:')
...@@ -51,9 +51,7 @@ def f(): ...@@ -51,9 +51,7 @@ def f():
def longdouble_access(): def longdouble_access():
""" """
>>> longdouble_access() >>> longdouble_access()
Traceback (most recent call last): 42.0
...
SystemError: bad memberdescr type
""" """
cdef object c = MyClass() cdef object c = MyClass()
print c.float_isreally_longdouble print c.float_isreally_longdouble
......
cimport cython
cdef extern from "cpp_references_helper.h":
cdef int& ref_func(int&)
cdef int ref_var_value
cdef int& ref_var
def test_ref_func(int x):
"""
>>> test_ref_func(2)
2
>>> test_ref_func(3)
3
"""
return ref_func(x)
def test_ref_func_address(int x):
"""
>>> test_ref_func_address(5)
5
>>> test_ref_func_address(7)
7
"""
cdef int* i_ptr = &ref_func(x)
return i_ptr[0]
def test_ref_var(int x):
"""
>>> test_ref_func(11)
11
>>> test_ref_func(13)
13
"""
ref_var = x
return ref_var_value
def test_ref_assign(int x):
"""
>>> test_ref_assign(17)
17.0
>>> test_ref_assign(19)
19.0
"""
cdef double d = ref_func(x)
return d
@cython.infer_types(True)
def test_ref_inference(int x):
"""
>>> test_ref_inference(23)
23
>>> test_ref_inference(29)
29
"""
z = ref_func(x)
assert cython.typeof(z) == "int", cython.typeof(z)
return z
int ref_var_value = 10;
int& ref_var = ref_var_value;
int& ref_func(int& x) { return x; }
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