Commit 36c54dda authored by Stefan Behnel's avatar Stefan Behnel

merge with latest cython-devel

parents 9d84198a 5ef8c817
......@@ -3957,8 +3957,7 @@ class TypecastNode(ExprNode):
if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
if to_py and not from_py:
if (self.operand.type.to_py_function and
self.operand.type.create_to_py_utility_code(env)):
if self.operand.type.create_to_py_utility_code(env):
self.result_ctype = py_object_type
self.operand = self.operand.coerce_to_pyobject(env)
else:
......@@ -3966,7 +3965,7 @@ class TypecastNode(ExprNode):
warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
self.operand = self.operand.coerce_to_simple(env)
elif from_py and not to_py:
if self.type.from_py_function:
if self.type.create_from_py_utility_code(env):
self.operand = self.operand.coerce_to(self.type, env)
elif self.type.is_ptr and not (self.type.base_type.is_void or self.type.base_type.is_struct):
error(self.pos, "Python objects cannot be casted to pointers of primitive types")
......
......@@ -35,6 +35,12 @@ def dumptree(t):
print t.dump()
return t
def abort_on_errors(node):
# Stop the pipeline if there are any errors.
if Errors.num_errors != 0:
raise InternalError, "abort"
return node
class CompilationData(object):
# Bundles the information that is passed from transform to transform.
# (For now, this is only)
......@@ -86,7 +92,7 @@ class Context(object):
from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform
from Optimize import OptimizeBuiltinCalls, ConstantFolding, FinalOptimizePhase
from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_declarations
from ModuleNode import check_c_declarations, check_c_declarations_pxd
# Temporary hack that can be used to ensure that all result_code's
# are generated at code generation time.
......@@ -98,7 +104,7 @@ class Context(object):
return node
if pxd:
_check_c_declarations = None
_check_c_declarations = check_c_declarations_pxd
_specific_post_parse = PxdPostParse(self)
else:
_check_c_declarations = check_c_declarations
......@@ -160,6 +166,7 @@ class Context(object):
create_parse(self),
] + self.create_pipeline(pxd=False, py=py) + [
inject_pxd_code,
abort_on_errors,
generate_pyx_code,
])
......
......@@ -28,6 +28,10 @@ from Code import UtilityCode
from StringEncoding import escape_byte_string, EncodedString
def check_c_declarations_pxd(module_node):
module_node.scope.check_c_classes_pxd()
return module_node
def check_c_declarations(module_node):
module_node.scope.check_c_classes()
module_node.scope.check_c_functions()
......@@ -799,6 +803,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"%s;" %
attr.type.declaration_code(attr.cname))
code.putln(footer)
if type.objtypedef_cname is not None:
# Only for exposing public typedef name.
code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
def generate_global_declarations(self, env, code, definition):
code.putln("")
......@@ -1625,6 +1632,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("{")
tempdecl_code = code.insertion_point()
self.generate_filename_init_call(code)
code.putln("#ifdef CYTHON_REFNANNY")
code.putln("void* __pyx_refchk = NULL;")
code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
......@@ -1646,7 +1654,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Library function declarations ---*/")
env.generate_library_function_declarations(code)
self.generate_filename_init_call(code)
code.putln("/*--- Threads initialization code ---*/")
code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
......@@ -1655,12 +1662,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#endif")
code.putln("#endif")
code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code)
code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
if Options.cache_builtins:
code.putln("/*--- Builtin init code ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
......@@ -1699,9 +1706,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_label(code.error_label)
for cname, type in code.funcstate.all_managed_temps():
code.put_xdecref(cname, type)
code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
code.putln('if (%s) {' % env.module_cname)
code.putln('__Pyx_AddTraceback("init %s");' % env.qualified_name)
env.use_utility_code(Nodes.traceback_utility_code)
code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
code.putln('} else if (!PyErr_Occurred()) {')
code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
code.putln('}')
code.put_label(code.return_label)
code.put_finish_refcount_context()
......
......@@ -983,8 +983,10 @@ class FuncDefNode(StatNode, BlockNode):
def analyse_default_values(self, env):
genv = env.global_scope()
default_seen = 0
for arg in self.args:
if arg.default:
default_seen = 1
if arg.is_generic:
arg.default.analyse_types(env)
arg.default = arg.default.coerce_to(arg.type, genv)
......@@ -992,6 +994,10 @@ class FuncDefNode(StatNode, BlockNode):
error(arg.pos,
"This argument cannot have a default value")
arg.default = None
elif arg.kw_only:
default_seen = 1
elif default_seen:
error(arg.pos, "Non-default argument following default argument")
def need_gil_acquisition(self, lenv):
return 0
......@@ -1064,7 +1070,7 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Extern library function declarations
lenv.generate_library_function_declarations(code)
# ----- GIL acquisition
acquire_gil = self.need_gil_acquisition(lenv)
acquire_gil = self.acquire_gil
if acquire_gil:
env.use_utility_code(force_init_threads_utility_code)
code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
......@@ -1403,6 +1409,7 @@ class CFuncDefNode(FuncDefNode):
self.py_func.analyse_expressions(env)
else:
self.analyse_default_values(env)
self.acquire_gil = self.need_gil_acquisition(self.local_scope)
def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
arg_decls = []
......@@ -1576,6 +1583,7 @@ class DefNode(FuncDefNode):
is_wrapper = 0
decorators = None
entry = None
acquire_gil = 0
def __init__(self, pos, **kwds):
......@@ -1911,8 +1919,9 @@ class DefNode(FuncDefNode):
or self.starstar_arg is not None or has_kwonly_args
for arg in self.args:
if not arg.type.is_pyobject and arg.type.from_py_function is None:
arg.type.create_from_py_utility_code(env)
if not arg.type.is_pyobject:
done = arg.type.create_from_py_utility_code(env)
if not done: pass # will fail later
if not self.signature_has_generic_args():
if has_star_or_kw_args:
......@@ -1926,12 +1935,10 @@ class DefNode(FuncDefNode):
else:
positional_args = []
kw_only_args = []
default_seen = 0
for arg in self.args:
arg_entry = arg.entry
if arg.is_generic:
if arg.default:
default_seen = 1
if not arg.is_self_arg:
if arg.kw_only:
kw_only_args.append(arg)
......@@ -1939,9 +1946,6 @@ class DefNode(FuncDefNode):
positional_args.append(arg)
elif arg.kw_only:
kw_only_args.append(arg)
default_seen = 1
elif default_seen:
error(arg.pos, "Non-default argument following default argument")
elif not arg.is_self_arg:
positional_args.append(arg)
......
......@@ -703,6 +703,9 @@ property NAME:
return None
def visit_CEnumDefNode(self, node):
if node.visibility == 'public':
return node
else:
return None
def visit_CStructOrUnionDefNode(self, node):
......
This diff is collapsed.
......@@ -243,6 +243,7 @@ class Scope(object):
self.pystring_entries = []
self.buffer_entries = []
self.control_flow = ControlFlow.LinearControlFlow()
self.return_type = None
def start_branching(self, pos):
self.control_flow = self.control_flow.start_branch(pos)
......@@ -837,6 +838,17 @@ class ModuleScope(Scope):
module_name = None, base_type = None, objstruct_cname = None,
typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
buffer_defaults = None):
# If this is a non-extern typedef class, expose the typedef, but use
# the non-typedef struct internally to avoid needing forward
# declarations for anonymous structs.
if typedef_flag and visibility != 'extern':
if visibility != 'public':
warning(pos, "ctypedef only valid for public and extern classes", 2)
objtypedef_cname = objstruct_cname
objstruct_cname = None
typedef_flag = 0
else:
objtypedef_cname = None
#
# Look for previous declaration as a type
#
......@@ -861,6 +873,8 @@ class ModuleScope(Scope):
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type.pos = pos
type.buffer_defaults = buffer_defaults
if objtypedef_cname is not None:
type.objtypedef_cname = objtypedef_cname
if visibility == 'extern':
type.module_name = module_name
else:
......@@ -941,6 +955,22 @@ class ModuleScope(Scope):
type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
def check_c_classes_pxd(self):
# Performs post-analysis checking and finishing up of extension types
# being implemented in this module. This is called only for the .pxd.
#
# Checks all extension types declared in this scope to
# make sure that:
#
# * The extension type is fully declared
#
# Also allocates a name for the vtable if needed.
#
for entry in self.c_class_entries:
# Check defined
if not entry.type.scope:
error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
def check_c_classes(self):
# Performs post-analysis checking and finishing up of extension types
# being implemented in this module. This is called only for the main
......@@ -1204,7 +1234,8 @@ class CClassScope(ClassScope):
# If the type or any of its base types have Python-valued
# C attributes, then it needs to participate in GC.
return self.has_pyobject_attrs or \
(self.parent_type.base_type and \
(self.parent_type.base_type and
self.parent_type.base_type.scope is not None and
self.parent_type.base_type.scope.needs_gc())
def declare_var(self, name, type, pos,
......@@ -1214,7 +1245,7 @@ class CClassScope(ClassScope):
if self.defined:
error(pos,
"C attributes cannot be added in implementation part of"
" extension type")
" extension type defined in a pxd")
if get_special_method_signature(name):
error(pos,
"The name '%s' is reserved for a special method."
......
......@@ -87,7 +87,7 @@ cdef extern from "Python.h":
# needs to handle exceptions or by code that needs to save and
# restore the error indicator temporarily.
void PyErr_Restore(object type, object value, object traceback)
void PyErr_Restore(PyObject* type, PyObject* value, PyObject* traceback)
# Set the error indicator from the three objects. If the error
# indicator is already set, it is cleared first. If the objects
# are NULL, the error indicator is cleared. Do not pass a NULL
......
......@@ -59,7 +59,7 @@ class Context(object):
else:
return None
cpdef report_unraisable(e):
cdef void report_unraisable(object e):
try:
print "refnanny raised an exception: %s" % e
except:
......@@ -84,7 +84,7 @@ cdef PyObject* NewContext(char* funcname, int lineno, char* filename) except NUL
result = <PyObject*>ctx
except Exception, e:
report_unraisable(e)
PyErr_Restore(<object>type, <object>value, <object>tb)
PyErr_Restore(type, value, tb)
return result
cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno):
......@@ -98,7 +98,7 @@ cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno):
(<object>ctx).regref(<object>p_obj, lineno, False)
except Exception, e:
report_unraisable(e)
PyErr_Restore(<object>type, <object>value, <object>tb)
PyErr_Restore(type, value, tb)
cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno):
if ctx == NULL: return 1
......@@ -112,7 +112,7 @@ cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno):
decref_ok = (<object>ctx).delref(<object>p_obj, lineno, False)
except Exception, e:
report_unraisable(e)
PyErr_Restore(<object>type, <object>value, <object>tb)
PyErr_Restore(type, value, tb)
return decref_ok
cdef void GIVEREF(PyObject* ctx, PyObject* p_obj, int lineno):
......@@ -141,7 +141,7 @@ cdef void FinishContext(PyObject** ctx):
report_unraisable(e)
Py_DECREF(<object>ctx[0])
ctx[0] = NULL
PyErr_Restore(<object>type, <object>value, <object>tb)
PyErr_Restore(type, value, tb)
cdef extern from "Python.h":
object PyCObject_FromVoidPtr(void*, void (*)(void*))
......
......@@ -3,7 +3,6 @@
methodmangling_T5
class_attribute_init_values_T18
return_outside_function_T135
builtin_types_none_T166
numpy_ValueError_T172
unsignedbehaviour_T184
......
ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
cdef public double seconds
ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
cdef public Time time
ctypedef public class Time [type MyTime_Type, object MyTimeObject]:
def __init__(self, seconds):
self.seconds = seconds
ctypedef public class Event [type MyEvent_Type, object MyEventObject]:
def __init__(self, Time time):
self.time = time
......@@ -11,6 +11,7 @@ cdef class Grail:
_ERRORS = u"""
1:10: Non-default argument follows default argument
9:16: This argument cannot have a default value
1:36: Non-default argument following default argument
4:23: Non-default argument following default argument
9:16: This argument cannot have a default value
"""
ctypedef struct Spam
ctypedef class Eggs
cdef extern from *:
ctypedef struct Ham
......@@ -7,12 +6,7 @@ cdef extern from *:
ctypedef struct Spam:
int i
ctypedef class Eggs:
pass
ctypedef struct Spam
ctypedef class Eggs
_ERRORS = u"""
1:0: Forward-referenced type must use 'cdef', not 'ctypedef'
2:0: Forward-referenced type must use 'cdef', not 'ctypedef'
"""
......@@ -8,16 +8,10 @@ ctypedef struct Blarg:
cdef struct Blarg
cdef class Spam
ctypedef class Spam:
pass
cdef Foo f
cdef Blarg b
_ERRORS = u"""
3:0: 'Foo' previously declared using 'cdef'
9:5: 'Blarg' previously declared using 'ctypedef'
13:0: 'Spam' previously declared using 'cdef'
"""
......@@ -8,13 +8,11 @@ def f(a):
del f() # error
del i # error: deletion of non-Python object
del j # error: deletion of non-Python object
del a # error: deletion of local name not supported
del x[i] # error: deletion of non-Python object
del s.m # error: deletion of non-Python object
_ERRORS = u"""
8:6: Cannot assign to or delete this
9:45: Deletion of non-Python object
11:6: Deletion of non-Python object
12:6: Deletion of non-Python object
13:6: Deletion of non-Python object
11:52: Deletion of local or C global name not supported
"""
# Errors reported during code generation.
cdef int i
def f(a):
del a # error: deletion of local name not supported
del i # error: deletion of local name not supported
_ERRORS = u"""
6:52: Deletion of local or C global name not supported
7:52: Deletion of local or C global name not supported
"""
......@@ -109,9 +109,9 @@ _ERRORS = u"""
37:15: Converting to Python object not allowed without gil
37:17: Converting to Python object not allowed without gil
38:11: Accessing Python attribute not allowed without gil
39:9: Constructing Python tuple not allowed without gil
40:8: Constructing Python list not allowed without gil
41:8: Constructing Python dict not allowed without gil
39: 9: Constructing Python tuple not allowed without gil
40: 8: Constructing Python list not allowed without gil
41: 8: Constructing Python dict not allowed without gil
42:12: Truth-testing Python object not allowed without gil
43:13: Python type test not allowed without gil
45:10: Operation not allowed without gil
......
cdef class A:
pass
_ERRORS = u"""
1:5: C class 'A' is declared but not defined
"""
This diff is collapsed.
typedef signed char SChar;
typedef unsigned char UChar;
typedef signed short SShort;
typedef unsigned short UShort;
typedef signed int SInt;
typedef unsigned int UInt;
typedef signed long SLong;
typedef unsigned long ULong;
typedef signed long long SLongLong;
typedef unsigned long long ULongLong;
cdef extern from "ctypedef_int_types_chdr_T333.h":
ctypedef int SChar ## "signed char"
ctypedef int UChar ## "unsigned char"
ctypedef int SShort ## "signed short"
ctypedef int UShort ## "unsigned short"
ctypedef int SInt ## "signed int"
ctypedef int UInt ## "unsigned int"
ctypedef int SLong ## "signed long"
ctypedef int ULong ## "unsigned long"
ctypedef int SLongLong ## "signed PY_LONG_LONG"
ctypedef int ULongLong ## "unsigned PY_LONG_LONG"
cdef extern from *:
ctypedef int ExtSInt "signed short"
ctypedef int ExtUInt "unsigned short"
__doc__ = u"""
>>> BAR
3
"""
cdef public enum FOO:
BAR = 3
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