Commit 1b78c83c authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

merge

parents 7fa1a3b4 139823ed
...@@ -23,4 +23,27 @@ class CythonScope(ModuleScope): ...@@ -23,4 +23,27 @@ class CythonScope(ModuleScope):
return type return type
def create_cython_scope(context): def create_cython_scope(context):
create_utility_scope(context)
return CythonScope(context) return CythonScope(context)
def create_utility_scope(context):
global utility_scope
utility_scope = ModuleScope(u'utility', None, context)
# These are used to optimize isinstance in FinalOptimizePhase
type_object = utility_scope.declare_typedef('PyTypeObject',
base_type = c_void_type,
pos = None,
cname = 'PyTypeObject')
type_object.is_void = True
utility_scope.declare_cfunction(
'PyObject_TypeCheck',
CFuncType(c_bint_type, [CFuncTypeArg("o", py_object_type, None),
CFuncTypeArg("t", c_ptr_type(type_object), None)]),
pos = None,
defining = 1,
cname = 'PyObject_TypeCheck')
return utility_scope
This diff is collapsed.
...@@ -253,6 +253,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -253,6 +253,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.globalstate.use_utility_code(refcount_utility_code) code.globalstate.use_utility_code(refcount_utility_code)
code.putln('const char *%s = "%s";' % (Naming.modulename_cname, self.full_module_name))
code.putln("") code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name) code.putln("/* Implementation of %s */" % env.qualified_name)
......
...@@ -53,6 +53,7 @@ preimport_cname = pyrex_prefix + "i" ...@@ -53,6 +53,7 @@ preimport_cname = pyrex_prefix + "i"
moddict_cname = pyrex_prefix + "d" moddict_cname = pyrex_prefix + "d"
dummy_cname = pyrex_prefix + "dummy" dummy_cname = pyrex_prefix + "dummy"
filename_cname = pyrex_prefix + "filename" filename_cname = pyrex_prefix + "filename"
modulename_cname = pyrex_prefix + "modulename"
filetable_cname = pyrex_prefix + "f" filetable_cname = pyrex_prefix + "f"
filenames_cname = pyrex_prefix + "filenames" filenames_cname = pyrex_prefix + "filenames"
fileinit_cname = pyrex_prefix + "init_filenames" fileinit_cname = pyrex_prefix + "init_filenames"
......
...@@ -515,7 +515,8 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -515,7 +515,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if self.optional_arg_count: if self.optional_arg_count:
scope = StructOrUnionScope() scope = StructOrUnionScope()
scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos) arg_count_member = '%sn' % Naming.pyrex_prefix
scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]: 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)
...@@ -541,6 +542,7 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -541,6 +542,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
exc_val = self.exception_value.get_constant_result_code() exc_val = self.exception_value.get_constant_result_code()
if self.exception_check == '+': if self.exception_check == '+':
exc_val_type = self.exception_value.type exc_val_type = self.exception_value.type
env.add_include_file('stdexcept')
if not exc_val_type.is_error and \ if not exc_val_type.is_error and \
not exc_val_type.is_pyobject and \ not exc_val_type.is_pyobject and \
not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0): not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
...@@ -1354,6 +1356,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -1354,6 +1356,7 @@ class CFuncDefNode(FuncDefNode):
error(self.pos, "Function declared nogil has Python locals or temporaries") error(self.pos, "Function declared nogil has Python locals or temporaries")
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.local_scope.directives = env.directives
if self.py_func is not None: if self.py_func is not None:
# this will also analyse the default values # this will also analyse the default values
self.py_func.analyse_expressions(env) self.py_func.analyse_expressions(env)
...@@ -1410,6 +1413,8 @@ class CFuncDefNode(FuncDefNode): ...@@ -1410,6 +1413,8 @@ class CFuncDefNode(FuncDefNode):
code.putln('if (%s) {' % Naming.optional_args_cname) code.putln('if (%s) {' % Naming.optional_args_cname)
for arg in self.args: for arg in self.args:
if arg.default: if arg.default:
# FIXME: simple name prefixing doesn't work when
# argument name mangling is in place
code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i)) code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
declarator = arg.declarator declarator = arg.declarator
while not hasattr(declarator, 'name'): while not hasattr(declarator, 'name'):
...@@ -1778,6 +1783,7 @@ class DefNode(FuncDefNode): ...@@ -1778,6 +1783,7 @@ class DefNode(FuncDefNode):
env.control_flow.set_state((), (arg.name, 'initalized'), True) env.control_flow.set_state((), (arg.name, 'initalized'), True)
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.local_scope.directives = env.directives
self.analyse_default_values(env) self.analyse_default_values(env)
if env.is_py_class_scope: if env.is_py_class_scope:
self.synthesize_assignment_node(env) self.synthesize_assignment_node(env)
...@@ -4943,7 +4949,8 @@ static int __Pyx_PrintOne(PyObject *o) { ...@@ -4943,7 +4949,8 @@ static int __Pyx_PrintOne(PyObject *o) {
} }
#endif #endif
""") """,
requires=[printing_utility_code])
...@@ -5308,32 +5315,6 @@ bad: ...@@ -5308,32 +5315,6 @@ bad:
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
unraisable_exception_utility_code = UtilityCode(
proto = """
static void __Pyx_WriteUnraisable(const char *name); /*proto*/
""",
impl = """
static void __Pyx_WriteUnraisable(const char *name) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
__Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name);
#else
ctx = PyUnicode_FromString(name);
#endif
__Pyx_ErrRestore(old_exc, old_val, old_tb);
if (!ctx) {
PyErr_WriteUnraisable(Py_None);
} else {
PyErr_WriteUnraisable(ctx);
Py_DECREF(ctx);
}
}
""")
#------------------------------------------------------------------------------------
traceback_utility_code = UtilityCode( traceback_utility_code = UtilityCode(
proto = """ proto = """
static void __Pyx_AddTraceback(const char *funcname); /*proto*/ static void __Pyx_AddTraceback(const char *funcname); /*proto*/
...@@ -5478,6 +5459,33 @@ static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject ** ...@@ -5478,6 +5459,33 @@ static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
unraisable_exception_utility_code = UtilityCode(
proto = """
static void __Pyx_WriteUnraisable(const char *name); /*proto*/
""",
impl = """
static void __Pyx_WriteUnraisable(const char *name) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
__Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name);
#else
ctx = PyUnicode_FromString(name);
#endif
__Pyx_ErrRestore(old_exc, old_val, old_tb);
if (!ctx) {
PyErr_WriteUnraisable(Py_None);
} else {
PyErr_WriteUnraisable(ctx);
Py_DECREF(ctx);
}
}
""",
requires=[restore_exception_utility_code])
#------------------------------------------------------------------------------------
set_vtable_utility_code = UtilityCode( set_vtable_utility_code = UtilityCode(
proto = """ proto = """
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
......
...@@ -655,11 +655,9 @@ class FinalOptimizePhase(Visitor.CythonTransform): ...@@ -655,11 +655,9 @@ class FinalOptimizePhase(Visitor.CythonTransform):
if node.function.name == 'isinstance': if node.function.name == 'isinstance':
type_arg = node.args[1] type_arg = node.args[1]
if type_arg.type.is_builtin_type and type_arg.type.name == 'type': if type_arg.type.is_builtin_type and type_arg.type.name == 'type':
object_module = self.context.find_module('python_object') from CythonScope import utility_scope
node.function.entry = object_module.lookup('PyObject_TypeCheck') node.function.entry = utility_scope.lookup('PyObject_TypeCheck')
if node.function.entry is None:
return node # only happens when there was an error earlier
node.function.type = node.function.entry.type node.function.type = node.function.entry.type
PyTypeObjectPtr = PyrexTypes.CPtrType(object_module.lookup('PyTypeObject').type) PyTypeObjectPtr = PyrexTypes.CPtrType(utility_scope.lookup('PyTypeObject').type)
node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr) node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr)
return node return node
...@@ -62,6 +62,7 @@ option_defaults = { ...@@ -62,6 +62,7 @@ option_defaults = {
'locals' : {}, 'locals' : {},
'auto_cpdef': False, 'auto_cpdef': False,
'cdivision': True, # Will be False in 0.12 'cdivision': True, # Will be False in 0.12
'cdivision_warnings': False,
} }
# Override types possibilities above, if needed # Override types possibilities above, if needed
......
...@@ -23,6 +23,19 @@ except NameError: ...@@ -23,6 +23,19 @@ except NameError:
possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
ansi_c_keywords = set(
['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof',
'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
'volatile', 'while'])
def c_safe_identifier(cname):
# There are some C limitations on struct entry names.
if (cname[:2] == '__' and not cname.startswith(Naming.pyrex_prefix)) or cname in ansi_c_keywords:
cname = Naming.pyrex_prefix + cname
return cname
class BufferAux(object): class BufferAux(object):
writable_needed = False writable_needed = False
...@@ -1125,6 +1138,8 @@ class StructOrUnionScope(Scope): ...@@ -1125,6 +1138,8 @@ class StructOrUnionScope(Scope):
# Add an entry for an attribute. # Add an entry for an attribute.
if not cname: if not cname:
cname = name cname = name
if visibility == 'private':
cname = c_safe_identifier(cname)
if type.is_cfunction: if type.is_cfunction:
type = PyrexTypes.CPtrType(type) type = PyrexTypes.CPtrType(type)
entry = self.declare(name, cname, type, pos, visibility) entry = self.declare(name, cname, type, pos, visibility)
...@@ -1259,6 +1274,8 @@ class CClassScope(ClassScope): ...@@ -1259,6 +1274,8 @@ class CClassScope(ClassScope):
% name) % name)
if not cname: if not cname:
cname = name cname = name
if visibility == 'private':
cname = c_safe_identifier(cname)
entry = self.declare(name, cname, type, pos, visibility) entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1 entry.is_variable = 1
self.var_entries.append(entry) self.var_entries.append(entry)
......
...@@ -6,6 +6,19 @@ def empty_decorator(x): ...@@ -6,6 +6,19 @@ def empty_decorator(x):
def locals(**arg_types): def locals(**arg_types):
return empty_decorator return empty_decorator
# Special functions
def cdiv(a, b):
q = a / b
if q < 0:
q += 1
def cmod(a, b):
r = a % b
if (a*b) < 0:
r -= b
return r
# Emulated language constructs # Emulated language constructs
......
...@@ -106,6 +106,7 @@ setup( ...@@ -106,6 +106,7 @@ setup(
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: C", "Programming Language :: C",
"Programming Language :: Cython",
"Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Code Generators",
"Topic :: Software Development :: Compilers", "Topic :: Software Development :: Compilers",
"Topic :: Software Development :: Libraries :: Python Modules" "Topic :: Software Development :: Libraries :: Python Modules"
......
"""
>>> constants(4)
1
>>> constants(5)
10
>>> temps(4)
1
>>> temps(5)
10
>>> nested(1)
1
>>> nested(2)
2
>>> nested(3)
3
"""
def ident(x): return x
def constants(x):
a = 1 if x < 5 else 10
return a
def temps(x):
return ident(1) if ident(x) < ident(5) else ident(10)
def nested(x):
return 1 if x == 1 else (2 if x == 2 else 3)
cdef class Album
cdef class SessionStruct:
cdef Album _create_album(self, void* album, bint take_owner):
pass
cdef class Album(SessionStruct):
pass
_ERROR = u"""
"""
cdef f(void=None):
pass
cdef struct foo:
int void
cdef class Foo:
cdef int void
...@@ -23,9 +23,9 @@ else: ...@@ -23,9 +23,9 @@ else:
_ERRORS = u''' _ERRORS = u'''
2:0: break statement not inside loop 2:0: break statement not inside loop
5:4: break statement not inside loop 5:4: break statement not inside loop
8:4: break statement not inside loop 8:4: break statement not inside loop
11:4: break statement not inside loop 11:4: break statement not inside loop
16:5: break statement not inside loop 16:5: break statement not inside loop
20:4: break statement not inside loop 20:4: break statement not inside loop
......
...@@ -10,6 +10,6 @@ NEW_ERRORS = u""" ...@@ -10,6 +10,6 @@ NEW_ERRORS = u"""
""" """
_ERRORS = u""" _ERRORS = u"""
:5:16: Cannot coerce list to type 'list' 5:16: Cannot coerce list to type 'list'
""" """
...@@ -23,9 +23,9 @@ else: ...@@ -23,9 +23,9 @@ else:
_ERRORS = u''' _ERRORS = u'''
2:0: continue statement not inside loop 2:0: continue statement not inside loop
5:4: continue statement not inside loop 5:4: continue statement not inside loop
8:4: continue statement not inside loop 8:4: continue statement not inside loop
11:4: continue statement not inside loop 11:4: continue statement not inside loop
16:5: continue statement not inside loop 16:5: continue statement not inside loop
20:4: continue statement not inside loop 20:4: continue statement not inside loop
......
...@@ -5,6 +5,6 @@ cdef void foo(obj): ...@@ -5,6 +5,6 @@ cdef void foo(obj):
i1 = p1 # error i1 = p1 # error
p2 = obj # error p2 = obj # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_ass.pyx:5:16: Cannot assign type 'char *' to 'int' 5:16: Cannot assign type 'char *' to 'int'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_ass.pyx:6:17: Cannot convert Python object to 'int *' 6:17: Cannot convert Python object to 'int *'
""" """
cdef void spam(): cdef void spam():
None = 42 None = 42
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_assnone.pyx:2:1: Cannot assign to or delete this 2:1: Cannot assign to or delete this
""" """
...@@ -3,5 +3,5 @@ cdef struct Foo ...@@ -3,5 +3,5 @@ cdef struct Foo
def f(Foo *p): def f(Foo *p):
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_badpyparam.pyx:3:6: Cannot convert Python object argument to type 'Foo *' 3:6: Cannot convert Python object argument to type 'Foo *'
""" """
...@@ -3,5 +3,5 @@ def f(): ...@@ -3,5 +3,5 @@ def f():
cdef char *ptr cdef char *ptr
int1 = int2 | ptr # error int1 = int2 | ptr # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_bitop.pyx:4:13: Invalid operand types for '|' (int; char *) 4:13: Invalid operand types for '|' (int; char *)
""" """
...@@ -28,8 +28,8 @@ if union_not_boolean: ...@@ -28,8 +28,8 @@ if union_not_boolean:
_ERRORS = u""" _ERRORS = u"""
5:26: 'struct_type_not_boolean' is not a constant, variable or function identifier 5:26: 'struct_type_not_boolean' is not a constant, variable or function identifier
5:26: Type 'struct_type_not_boolean' not acceptable as a boolean 5:26: Type 'struct_type_not_boolean' not acceptable as a boolean
12:21: 'struct_not_boolean' is not a constant, variable or function identifier 12:21: 'struct_not_boolean' is not a constant, variable or function identifier
12:21: Type 'struct_not_boolean' not acceptable as a boolean 12:21: Type 'struct_not_boolean' not acceptable as a boolean
......
...@@ -14,6 +14,6 @@ a.some_method(1, 2) ...@@ -14,6 +14,6 @@ a.some_method(1, 2)
a.some_method(1, y=2) a.some_method(1, y=2)
_ERRORS = u""" _ERRORS = u"""
:9:13: Keyword arguments not allowed in cdef functions. 9:13: Keyword arguments not allowed in cdef functions.
:14:13: Keyword arguments not allowed in cdef functions. 14:13: Keyword arguments not allowed in cdef functions.
""" """
...@@ -3,5 +3,5 @@ cdef int ...@@ -3,5 +3,5 @@ cdef int
cdef extern from *: cdef extern from *:
void f(int) void f(int)
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_cdef_missing_declarator.pyx:1:8: Empty declarator 1:8: Empty declarator
""" """
...@@ -7,7 +7,7 @@ ctypedef union eggs: ...@@ -7,7 +7,7 @@ ctypedef union eggs:
cdef enum ham: cdef enum ham:
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cdefemptysue.pyx:1:5: Empty struct or union definition not allowed outside a 'cdef extern from' block 1:5: Empty struct or union definition not allowed outside a 'cdef extern from' block
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cdefemptysue.pyx:4:0: Empty struct or union definition not allowed outside a 'cdef extern from' block 4:0: Empty struct or union definition not allowed outside a 'cdef extern from' block
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cdefemptysue.pyx:7:5: Empty enum definition not allowed outside a 'cdef extern from' block 7:5: Empty enum definition not allowed outside a 'cdef extern from' block
""" """
...@@ -6,5 +6,5 @@ cdef void f(): ...@@ -6,5 +6,5 @@ cdef void f():
a = 42 # assignment to non-lvalue a = 42 # assignment to non-lvalue
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cenum.pyx:6:3: Assignment to non-lvalue 'a' 6:3: Assignment to non-lvalue 'a'
""" """
...@@ -6,6 +6,6 @@ cdef class D(C): ...@@ -6,6 +6,6 @@ cdef class D(C):
cdef void f(self, int x): cdef void f(self, int x):
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_cmethbasematch.pyx:6:6: Signature not compatible with previous declaration 6:6: Signature not compatible with previous declaration
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_cmethbasematch.pyx:2:6: Previous declaration is here 2:6: Previous declaration is here
""" """
...@@ -5,6 +5,6 @@ cdef void foo(): ...@@ -5,6 +5,6 @@ cdef void foo():
bool = int1 == ptr2 # error bool = int1 == ptr2 # error
bool = ptr2 == ptr3 # error bool = ptr2 == ptr3 # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cmp.pyx:5:13: Invalid types for '==' (int, char *) 5:13: Invalid types for '==' (int, char *)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cmp.pyx:6:13: Invalid types for '==' (char *, int *) 6:13: Invalid types for '==' (char *, int *)
""" """
...@@ -20,12 +20,12 @@ cdef void eggs(Spam s): ...@@ -20,12 +20,12 @@ cdef void eggs(Spam s):
j = gp.x # error - incomplete type j = gp.x # error - incomplete type
gp.x = j # error - incomplete type gp.x = j # error - incomplete type
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:5:36: C struct/union member cannot be a Python object 5:36: C struct/union member cannot be a Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:15:6: Object of type 'Spam' has no attribute 'k' 15:6: Object of type 'Spam' has no attribute 'k'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:16:6: Cannot assign type 'float *[42]' to 'int' 16:6: Cannot assign type 'float *[42]' to 'int'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:17:21: Cannot assign type 'int' to 'float *[42]' 17:21: Cannot assign type 'int' to 'float *[42]'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:18:6: Object of type 'int' has no attribute 'i' 18:6: Object of type 'int' has no attribute 'i'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:19:2: Object of type 'int' has no attribute 'i' 19:2: Object of type 'int' has no attribute 'i'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:20:7: Cannot select attribute of incomplete type 'Grail' 20:7: Cannot select attribute of incomplete type 'Grail'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_cstruct.pyx:21:3: Cannot select attribute of incomplete type 'Grail' 21:3: Cannot select attribute of incomplete type 'Grail'
""" """
...@@ -13,6 +13,6 @@ ctypedef class Eggs: ...@@ -13,6 +13,6 @@ ctypedef class Eggs:
ctypedef struct Spam ctypedef struct Spam
ctypedef class Eggs ctypedef class Eggs
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_ctypedefforward.pyx:1:0: Forward-referenced type must use 'cdef', not 'ctypedef' 1:0: Forward-referenced type must use 'cdef', not 'ctypedef'
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_ctypedefforward.pyx:2:0: Forward-referenced type must use 'cdef', not 'ctypedef' 2:0: Forward-referenced type must use 'cdef', not 'ctypedef'
""" """
...@@ -17,7 +17,7 @@ cdef Foo f ...@@ -17,7 +17,7 @@ cdef Foo f
cdef Blarg b cdef Blarg b
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_ctypedefornot.pyx:3:0: 'Foo' previously declared using 'cdef' 3:0: 'Foo' previously declared using 'cdef'
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_ctypedefornot.pyx:9:5: 'Blarg' previously declared using 'ctypedef' 9:5: 'Blarg' previously declared using 'ctypedef'
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_ctypedefornot.pyx:13:0: 'Spam' previously declared using 'cdef' 13:0: 'Spam' previously declared using 'cdef'
""" """
...@@ -8,9 +8,9 @@ cdef void f(): ...@@ -8,9 +8,9 @@ cdef void f():
h = <int ()()>f # this is an error h = <int ()()>f # this is an error
h = <int (*)()>f # this is OK h = <int (*)()>f # this is OK
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_declarations.pyx:1:19: Array element cannot be a function 1:19: Array element cannot be a function
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_declarations.pyx:2:18: Function cannot return an array 2:18: Function cannot return an array
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_declarations.pyx:3:18: Function cannot return a function 3:18: Function cannot return a function
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_declarations.pyx:8:10: Function cannot return a function 8:10: Function cannot return a function
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_declarations.pyx:8:5: Cannot cast to a function type 8:5: Cannot cast to a function type
""" """
...@@ -12,9 +12,9 @@ def f(a): ...@@ -12,9 +12,9 @@ def f(a):
del x[i] # error: deletion of non-Python object del x[i] # error: deletion of non-Python object
del s.m # error: deletion of non-Python object del s.m # error: deletion of non-Python object
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_del.pyx:8:6: Cannot assign to or delete this 8:6: Cannot assign to or delete this
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_del.pyx:9:45: Deletion of non-Python object 9:45: Deletion of non-Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_del.pyx:12:6: Deletion of non-Python object 12:6: Deletion of non-Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_del.pyx:13:6: Deletion of non-Python object 13:6: Deletion of non-Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_del.pyx:11:52: Deletion of local or C global name not supported 11:52: Deletion of local or C global name not supported
""" """
...@@ -11,6 +11,6 @@ except AttributeError: ...@@ -11,6 +11,6 @@ except AttributeError:
pass pass
_ERRORS = u""" _ERRORS = u"""
8:0: default 'except:' must be last 8:0: default 'except:' must be last
10:0: default 'except:' must be last 10:0: default 'except:' must be last
""" """
...@@ -7,6 +7,6 @@ cdef spamfunc spam ...@@ -7,6 +7,6 @@ cdef spamfunc spam
grail = spam # type mismatch grail = spam # type mismatch
spam = grail # type mismatch spam = grail # type mismatch
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_excvalfunctype.pyx:7:28: Cannot assign type 'e_excvalfunctype.spamfunc' to 'e_excvalfunctype.grailfunc' 7:28: Cannot assign type 'e_excvalfunctype.spamfunc' to 'e_excvalfunctype.grailfunc'
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_excvalfunctype.pyx:8:28: Cannot assign type 'e_excvalfunctype.grailfunc' to 'e_excvalfunctype.spamfunc' 8:28: Cannot assign type 'e_excvalfunctype.grailfunc' to 'e_excvalfunctype.spamfunc'
""" """
...@@ -13,8 +13,8 @@ cdef void f(): ...@@ -13,8 +13,8 @@ cdef void f():
x = c.__weakref__ x = c.__weakref__
c.__weakref__ = x c.__weakref__ = x
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_extweakref.pyx:5:20: Special attribute __weakref__ cannot be exposed to Python 5:20: Special attribute __weakref__ cannot be exposed to Python
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_extweakref.pyx:8:22: Special attribute __weakref__ cannot be exposed to Python 8:22: Special attribute __weakref__ cannot be exposed to Python
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_extweakref.pyx:13:6: Illegal use of special attribute __weakref__ 13:6: Illegal use of special attribute __weakref__
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_extweakref.pyx:14:2: Illegal use of special attribute __weakref__ 14:2: Illegal use of special attribute __weakref__
""" """
...@@ -7,8 +7,8 @@ def f(obj1, obj2): ...@@ -7,8 +7,8 @@ def f(obj1, obj2):
int1 = int2[int3] # error int1 = int2[int3] # error
obj1 = obj2[ptr1] # error obj1 = obj2[ptr1] # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_index.pyx:5:14: Invalid index type 'float' 5:14: Invalid index type 'float'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_index.pyx:6:14: Invalid index type 'float *' 6:14: Invalid index type 'float *'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_index.pyx:7:12: Attempting to index non-array type 'int' 7:12: Attempting to index non-array type 'int'
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_index.pyx:8:17: Cannot convert 'float *' to Python object 8:17: Cannot convert 'float *' to Python object
""" """
...@@ -3,5 +3,5 @@ def f(obj1a, obj1b): ...@@ -3,5 +3,5 @@ def f(obj1a, obj1b):
cdef int *ptr2 cdef int *ptr2
int1, int3, obj1a = int2, ptr2, obj1b # error int1, int3, obj1a = int2, ptr2, obj1b # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_multass.pyx:4:31: Cannot assign type 'int *' to 'int' 4:31: Cannot assign type 'int *' to 'int'
""" """
...@@ -8,9 +8,9 @@ cdef f(): ...@@ -8,9 +8,9 @@ cdef f():
spam() # too few args spam() # too few args
spam("blarg") # too few args spam("blarg") # too few args
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_nargs.pyx:5:6: Call with wrong number of arguments (expected 2, got 0) 5:6: Call with wrong number of arguments (expected 2, got 0)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_nargs.pyx:6:6: Call with wrong number of arguments (expected 2, got 1) 6:6: Call with wrong number of arguments (expected 2, got 1)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_nargs.pyx:7:6: Call with wrong number of arguments (expected 2, got 3) 7:6: Call with wrong number of arguments (expected 2, got 3)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_nargs.pyx:8:5: Call with wrong number of arguments (expected at least 2, got 0) 8:5: Call with wrong number of arguments (expected at least 2, got 0)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_nargs.pyx:9:5: Call with wrong number of arguments (expected at least 2, got 1) 9:5: Call with wrong number of arguments (expected at least 2, got 1)
""" """
...@@ -3,6 +3,6 @@ cdef class C: ...@@ -3,6 +3,6 @@ cdef class C:
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_nogilcmeth.pyx:2:6: Signature not compatible with previous declaration 2:6: Signature not compatible with previous declaration
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_nogilcmeth.pxd:2:12: Previous declaration is here 2:12: Previous declaration is here
""" """
...@@ -4,5 +4,5 @@ cdef extern from *: ...@@ -4,5 +4,5 @@ cdef extern from *:
fp = f fp = f
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors3/e_nogilfunctype.pyx:5:6: Cannot assign type 'void (void)' to 'void (*)(void) nogil' 5:6: Cannot assign type 'void (void)' to 'void (*)(void) nogil'
""" """
...@@ -3,5 +3,5 @@ cdef extern class Grail.Shrubbery ...@@ -3,5 +3,5 @@ cdef extern class Grail.Shrubbery
cdef void spam(Shrubbery sh not None): cdef void spam(Shrubbery sh not None):
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_notnone.pyx:3:15: 'not None' only allowed in Python functions 3:15: 'not None' only allowed in Python functions
""" """
def eggs(int x not None, y not None): def eggs(int x not None, y not None):
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_notnone2.pyx:1:0: Only extension type arguments can have 'not None' 1:0: Only extension type arguments can have 'not None'
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_notnone2.pyx:1:0: Only extension type arguments can have 'not None' 1:0: Only extension type arguments can have 'not None'
""" """
...@@ -3,5 +3,5 @@ def f(): ...@@ -3,5 +3,5 @@ def f():
cdef int *ptr cdef int *ptr
int1 = int2 * ptr # error int1 = int2 * ptr # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_numop.pyx:4:13: Invalid operand types for '*' (int; int *) 4:13: Invalid operand types for '*' (int; int *)
""" """
...@@ -7,5 +7,5 @@ def f(): ...@@ -7,5 +7,5 @@ def f():
cdef spam s cdef spam s
s.parrot = x s.parrot = x
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_pyobinstruct.pyx:4:8: C struct/union member cannot be a Python object 4:8: C struct/union member cannot be a Python object
""" """
...@@ -4,5 +4,5 @@ class C: ...@@ -4,5 +4,5 @@ class C:
def f(self): def f(self):
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_redeclmeth.pyx:4:1: 'f' already declared 4:1: 'f' already declared
""" """
...@@ -7,7 +7,7 @@ cdef int h(): ...@@ -7,7 +7,7 @@ cdef int h():
return # error return # error
return p # error return p # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_return.pyx:3:17: Return with value in void function 3:17: Return with value in void function
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_return.pyx:7:1: Return value required 7:1: Return value required
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_return.pyx:8:17: Cannot assign type 'int *' to 'int' 8:17: Cannot assign type 'int *' to 'int'
""" """
...@@ -2,5 +2,5 @@ cdef struct unbekannt ...@@ -2,5 +2,5 @@ cdef struct unbekannt
cdef int n cdef int n
n = sizeof(unbekannt) n = sizeof(unbekannt)
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_sizeofincomplete.pyx:3:4: Cannot take sizeof incomplete type 'unbekannt' 3:4: Cannot take sizeof incomplete type 'unbekannt'
""" """
...@@ -4,7 +4,7 @@ def f(obj2): ...@@ -4,7 +4,7 @@ def f(obj2):
obj1 = obj2[:ptr1:] # error obj1 = obj2[:ptr1:] # error
obj1 = obj2[::ptr1] # error obj1 = obj2[::ptr1] # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_slice.pyx:3:17: Cannot convert 'int *' to Python object 3:17: Cannot convert 'int *' to Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_slice.pyx:4:18: Cannot convert 'int *' to Python object 4:18: Cannot convert 'int *' to Python object
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_slice.pyx:5:19: Cannot convert 'int *' to Python object 5:19: Cannot convert 'int *' to Python object
""" """
...@@ -4,6 +4,6 @@ def f(): ...@@ -4,6 +4,6 @@ def f():
ptr1 = int2 - ptr3 # error ptr1 = int2 - ptr3 # error
ptr1 = ptr2 - ptr3 # error ptr1 = ptr2 - ptr3 # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_subop.pyx:4:13: Invalid operand types for '-' (int; char *) 4:13: Invalid operand types for '-' (int; char *)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_subop.pyx:5:13: Cannot assign type 'int' to 'char *' 5:13: Cannot assign type 'int' to 'char *'
""" """
...@@ -5,5 +5,5 @@ def foo(obj): ...@@ -5,5 +5,5 @@ def foo(obj):
p = <int *>blarg # okay p = <int *>blarg # okay
p = <int *>(foo + blarg) # error - temporary p = <int *>(foo + blarg) # error - temporary
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_tempcast.pyx:6:5: Casting temporary Python object to non-numeric non-Python type 6:5: Casting temporary Python object to non-numeric non-Python type
""" """
cdef class Spam cdef class Spam
cdef extern class external.Eggs cdef extern class external.Eggs
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_undefexttype.pyx:1:5: C class 'Spam' is declared but not defined 1:5: C class 'Spam' is declared but not defined
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_undefexttype.pyx:2:5: C class 'Eggs' is declared but not defined 2:5: C class 'Eggs' is declared but not defined
""" """
...@@ -4,6 +4,6 @@ def f(): ...@@ -4,6 +4,6 @@ def f():
int1 = -str2 # error int1 = -str2 # error
int1 = ~str2 # error int1 = ~str2 # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_unop.pyx:4:8: Invalid operand type for '-' (char *) 4:8: Invalid operand type for '-' (char *)
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_unop.pyx:5:8: Invalid operand type for '~' (char *) 5:8: Invalid operand type for '~' (char *)
""" """
...@@ -3,6 +3,6 @@ def f(a, b): ...@@ -3,6 +3,6 @@ def f(a, b):
break # error break # error
continue # error continue # error
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_while.pyx:3:1: break statement not inside loop 3:1: break statement not inside loop
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_while.pyx:4:1: continue statement not inside loop 4:1: continue statement not inside loop
""" """
...@@ -4,5 +4,5 @@ cdef class B: ...@@ -4,5 +4,5 @@ cdef class B:
pass pass
_ERRORS = u""" _ERRORS = u"""
:3:10: C method has no self argument 3:10: C method has no self argument
""" """
...@@ -78,9 +78,9 @@ cdef void t(C c) nogil: ...@@ -78,9 +78,9 @@ cdef void t(C c) nogil:
_ERRORS = u""" _ERRORS = u"""
1: 5: Function with Python return type cannot be declared nogil 1: 5: Function with Python return type cannot be declared nogil
6: 6: Assignment of Python object not allowed without gil 6: 6: Assignment of Python object not allowed without gil
4: 5: Function declared nogil has Python locals or temporaries 4: 5: Function declared nogil has Python locals or temporaries
11: 5: Function with Python return type cannot be declared nogil 11: 5: Function with Python return type cannot be declared nogil
15: 5: Calling gil-requiring function not allowed without gil 15: 5: Calling gil-requiring function not allowed without gil
24: 9: Calling gil-requiring function not allowed without gil 24: 9: Calling gil-requiring function not allowed without gil
......
...@@ -3,6 +3,6 @@ cdef class C: ...@@ -3,6 +3,6 @@ cdef class C:
pass pass
_ERRORS = u""" _ERRORS = u"""
nogilcmeth.pyx:2:9: Signature not compatible with previous declaration 2:9: Signature not compatible with previous declaration
nogilcmeth.pxd:2:15: Previous declaration is here 2:15: Previous declaration is here
""" """
...@@ -2,5 +2,5 @@ def f(): ...@@ -2,5 +2,5 @@ def f():
a = b # space space a = b # space space
c = d # space tab c = d # space tab
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_badindent.pyx:3:0: Mixed use of tabs and spaces 3:0: Mixed use of tabs and spaces
""" """
...@@ -2,6 +2,6 @@ def f(): ...@@ -2,6 +2,6 @@ def f():
a = b a = b
c = d c = d
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_badindent2.pyx:3:0: Possible inconsistent indentation 3:0: Possible inconsistent indentation
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_badindent2.pyx:3:0: Expected an identifier or literal 3:0: Expected an identifier or literal
""" """
...@@ -2,5 +2,5 @@ if x: ...@@ -2,5 +2,5 @@ if x:
def h(): def h():
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_conddef.pyx:2:1: def statement not allowed here 2:1: def statement not allowed here
""" """
...@@ -2,5 +2,5 @@ def f(): ...@@ -2,5 +2,5 @@ def f():
a = b # space space a = b # space space
c = d # tab c = d # tab
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_mixtabspace.pyx:3:0: Mixed use of tabs and spaces 3:0: Mixed use of tabs and spaces
""" """
...@@ -2,5 +2,5 @@ def f(): ...@@ -2,5 +2,5 @@ def f():
def g(): def g():
pass pass
_ERRORS = u""" _ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/se_nestdef.pyx:2:1: def statement not allowed here 2:1: def statement not allowed here
""" """
__doc__ = u"""
>>> cdiv_decorator(-12, 5)
-2
>>> pydiv_decorator(-12, 5)
-3
"""
cimport cython
@cython.cdivision(True)
cpdef cdiv_decorator(int a, int b):
return a / b
@cython.cdivision(False)
cpdef pydiv_decorator(int a, int b):
return a / b
...@@ -26,6 +26,28 @@ True ...@@ -26,6 +26,28 @@ True
>>> [test_cdiv_cmod(a, b) for a, b in v] >>> [test_cdiv_cmod(a, b) for a, b in v]
[(1, 7), (-1, -7), (1, -7), (-1, 7)] [(1, 7), (-1, -7), (1, -7), (-1, 7)]
>>> all([mod_int_py(a,b) == a % b for a in range(-10, 10) for b in range(-10, 10) if b != 0])
True
>>> all([div_int_py(a,b) == a // b for a in range(-10, 10) for b in range(-10, 10) if b != 0])
True
>>> def simple_warn(msg, *args): print msg
>>> import warnings
>>> warnings.showwarning = simple_warn
>>> mod_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-7
>>> div_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-1
>>> complex_expression(-150, 20, 20, -7)
verbose_call(-150)
division with oppositely signed operands, C and Python semantics differ
verbose_call(20)
division with oppositely signed operands, C and Python semantics differ
-2
""" """
cimport cython cimport cython
...@@ -73,3 +95,22 @@ def test_cdiv_cmod(short a, short b): ...@@ -73,3 +95,22 @@ def test_cdiv_cmod(short a, short b):
cdef short q = cython.cdiv(a, b) cdef short q = cython.cdiv(a, b)
cdef short r = cython.cmod(a, b) cdef short r = cython.cmod(a, b)
return q, r return q, r
@cython.cdivision(True)
@cython.cdivision_warnings(True)
def mod_int_c_warn(int a, int b):
return a % b
@cython.cdivision(True)
@cython.cdivision_warnings(True)
def div_int_c_warn(int a, int b):
return a // b
@cython.cdivision(False)
@cython.cdivision_warnings(True)
def complex_expression(int a, int b, int c, int d):
return (verbose_call(a) // b) % (verbose_call(c) // d)
cdef int verbose_call(int x):
print "verbose_call(%s)" % x
return x
__doc__ = u"""
>>> floor_div_float(2, 1.5)
1.0
>>> floor_div_float(2, -1.5)
-2.0
>>> floor_div_float(-2.3, 1.5)
-2.0
>>> floor_div_float(1e10, 1e-10)
1e+20
"""
def floor_div_float(double a, double b):
return a // b
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