Commit 0a8ea6e7 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents d4970237 0066fe43
......@@ -2538,7 +2538,11 @@ class GeneralCallNode(CallNode):
self.keyword_args.analyse_types(env)
if self.starstar_arg:
self.starstar_arg.analyse_types(env)
self.function = self.function.coerce_to_pyobject(env)
if not self.function.type.is_pyobject:
if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
error(self.pos, "Keyword arguments not allowed in cdef functions.")
else:
self.function = self.function.coerce_to_pyobject(env)
self.positional_args = \
self.positional_args.coerce_to_pyobject(env)
if self.starstar_arg:
......
......@@ -1601,6 +1601,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
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")
code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
code.putln("PyEval_InitThreads();")
code.putln("#endif")
code.putln("#endif")
code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
......
......@@ -1080,6 +1080,7 @@ class FuncDefNode(StatNode, BlockNode):
# ----- GIL acquisition
acquire_gil = self.need_gil_acquisition(lenv)
if acquire_gil:
env.use_utility_code(py23_init_threads_utility_code)
code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
# ----- Automatic lead-ins for certain special functions
if not lenv.nogil:
......@@ -4540,6 +4541,7 @@ class GILStatNode(TryFinallyStatNode):
finally_clause = GILExitNode(pos, state = state))
def analyse_expressions(self, env):
env.use_utility_code(py23_init_threads_utility_code)
was_nogil = env.nogil
env.nogil = 1
TryFinallyStatNode.analyse_expressions(self, env)
......@@ -5634,3 +5636,16 @@ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb)
""")
#------------------------------------------------------------------------------------
py23_init_threads_utility_code = UtilityCode(
proto="""
#ifndef __PYX_FORCE_INIT_THREADS
#if PY_VERSION_HEX < 0x02040200
#define __PYX_FORCE_INIT_THREADS 1
#else
#define __PYX_FORCE_INIT_THREADS 0
#endif
#endif
""")
#------------------------------------------------------------------------------------
......@@ -658,6 +658,8 @@ class DecoratorTransform(CythonTransform, SkipDeclarations):
rhs = decorator_result)
return [func_node, reassignment]
ERR_DEC_AFTER = "cdef variable '%s' declared after it is used"
class AnalyseDeclarationsTransform(CythonTransform):
basic_property = TreeFragment(u"""
......@@ -670,14 +672,23 @@ property NAME:
def __call__(self, root):
self.env_stack = [root.scope]
# needed to determine if a cdef var is declared after it's used.
self.local_scope_stack = []
return super(AnalyseDeclarationsTransform, self).__call__(root)
def visit_NameNode(self, node):
self.local_scope_stack[-1].add(node.name)
return node
def visit_ModuleNode(self, node):
self.local_scope_stack.append(set())
node.analyse_declarations(self.env_stack[-1])
self.visitchildren(node)
self.local_scope_stack.pop()
return node
def visit_FuncDefNode(self, node):
self.local_scope_stack.append(set())
lenv = node.create_local_scope(self.env_stack[-1])
node.body.analyse_control_flow(lenv) # this will be totally refactored
node.declare_arguments(lenv)
......@@ -692,6 +703,7 @@ property NAME:
self.env_stack.append(lenv)
self.visitchildren(node)
self.env_stack.pop()
self.local_scope_stack.pop()
return node
# Some nodes are no longer needed after declaration
......@@ -699,6 +711,8 @@ property NAME:
# on these nodes in a seperate recursive process from the
# enclosing function or module, so we can simply drop them.
def visit_CDeclaratorNode(self, node):
# necessary to ensure that all CNameDeclaratorNodes are visited.
self.visitchildren(node)
return node
def visit_CTypeDefNode(self, node):
......@@ -713,7 +727,18 @@ property NAME:
def visit_CStructOrUnionDefNode(self, node):
return None
def visit_CNameDeclaratorNode(self, node):
if node.name in self.local_scope_stack[-1]:
# cdef variable declared after it's used.
error(node.pos, ERR_DEC_AFTER % node.name)
self.visitchildren(node)
return node
def visit_CVarDefNode(self, node):
# to ensure all CNameDeclaratorNodes are visited.
self.visitchildren(node)
if node.need_properties:
# cdef public attributes may need type testing on
# assignment, so we create a property accesss
......
......@@ -84,7 +84,7 @@ def open_pickled_lexicon(expected_hash):
print("Lexicon hash mismatch:") ###
print(" expected " + expected_hash) ###
print(" got " + actual_hash) ###
except IOError, e:
except (IOError, pickle.UnpicklingError), e:
print("Warning: Unable to read pickled lexicon " + lexicon_pickle)
print(e)
if f:
......@@ -102,7 +102,12 @@ def try_to_unpickle_lexicon():
if notify_lexicon_unpickling:
t0 = time()
print("Unpickling lexicon...")
lexicon = pickle.load(f)
try:
lexicon = pickle.load(f)
except Exception, e:
print "WARNING: Exception while loading lexicon pickle, regenerating"
print e
lexicon = None
f.close()
if notify_lexicon_unpickling:
t1 = time()
......
__doc__ = u"""
>>> set_attr(5)
>>> get_attr()
None
"""
cdef class MyExt:
cdef object attr
def set_attr(value):
MyExt().attr = value
def get_attr():
return MyExt().attr
__doc__ = u"""
>>> add_large_pow() == 2**31 + 2**31
True
>>> add_large_pow() == 2**32
True
>>> add_large() == 2147483647 + 2147483647
True
"""
def add_large():
return 2147483647 + 2147483647
def add_large_pow():
return 2**31 + 2**31
def mult_decl_test():
print "%s" % vv
print "%s" % s
cdef str s, vv = "Test"
def def_test():
cdef int j = 10
i[0] = j
cdef int *i = NULL # pointer variables are special case
cdef cdef_test():
cdef int j = 10
i[0] = j
print "%d" % i[0]
cdef int *i = NULL
cpdef cpdef_test():
cdef int j = 10
i[0] = j
print "%d" % i[0]
cdef int *i = NULL
s.upper()
cdef str s = "Test"
class Foo(object):
def bar(self, x, y):
cdef unsigned long w = 20
z = w + t
cdef int t = 10
cdef class Foo2(object):
print '%s' % r # check error inside class scope
cdef str r
def bar(self, x, y):
cdef unsigned long w = 20
self.r = c'r'
print self.r
z = w + g(t)
cdef int t = 10
def g(x):
return x
cdef int d = 20
baz[0] = d
cdef int *baz
print var[0][0]
cdef unsigned long long var[100][100]
_ERRORS = u"""
4:13: cdef variable 's' declared after it is used
4:16: cdef variable 'vv' declared after it is used
9:14: cdef variable 'i' declared after it is used
15:14: cdef variable 'i' declared after it is used
21:14: cdef variable 'i' declared after it is used
24:9: cdef variable 's' declared after it is used
30:17: cdef variable 't' declared after it is used
34:13: cdef variable 'r' declared after it is used
40:17: cdef variable 't' declared after it is used
47:10: cdef variable 'baz' declared after it is used
50:24: cdef variable 'var' declared after it is used
"""
cdef some_function(x, y):
pass
cdef class A:
cdef some_method(self, x, y=1):
pass
some_function(1, 2)
some_function(1, y=2)
cdef A a = A()
a.some_method(1)
a.some_method(1, 2)
a.some_method(1, y=2)
_ERRORS = u"""
:9:13: Keyword arguments not allowed in cdef functions.
:14:13: Keyword arguments not allowed in cdef functions.
"""
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