Commit a17c79d6 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents 6f95c7e3 81161bc8
......@@ -328,10 +328,7 @@ class ExprNode(Node):
# we ensure that all disposal has been done by the
# time we get the result.
self.analyse_types(env)
bool = self.coerce_to_boolean(env)
if not bool.is_simple():
bool = bool.coerce_to_temp(env)
return bool
return self.coerce_to_boolean(env).coerce_to_simple(env)
# --------------- Type Inference -----------------
......@@ -6435,7 +6432,7 @@ class CoerceToBooleanNode(CoercionNode):
self.is_temp = 1
def nogil_check(self, env):
if self.arg.type.is_pyobject:
if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
self.gil_error()
gil_message = "Truth-testing Python object"
......
......@@ -1771,7 +1771,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if not Options.generate_cleanup_code:
return
code.globalstate.use_utility_code(register_cleanup_utility_code)
code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
code.putln('static PyObject *%s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused) {' %
Naming.cleanup_cname)
if Options.generate_cleanup_code >= 2:
code.putln("/*--- Global cleanup code ---*/")
rev_entries = list(env.var_entries)
......@@ -2330,9 +2331,9 @@ bad:
register_cleanup_utility_code = UtilityCode(
proto = """
static int __Pyx_RegisterCleanup(void); /*proto*/
static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
""",
static PyObject* %(module_cleanup)s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&%(module_cleanup)s, METH_NOARGS, 0};
""" % {'module_cleanup': Naming.cleanup_cname},
impl = """
static int __Pyx_RegisterCleanup(void) {
/* Don't use Py_AtExit because that has a 32-call limit
......
......@@ -1209,6 +1209,12 @@ class FuncDefNode(StatNode, BlockNode):
is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
self.entry.scope.is_c_class_scope)
is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
self.entry.scope.is_c_class_scope)
is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
if is_buffer_slot:
if 'cython_unused' not in self.modifiers:
self.modifiers = self.modifiers + ['cython_unused']
profile = code.globalstate.directives['profile']
if profile:
......@@ -2200,14 +2206,16 @@ class DefNode(FuncDefNode):
arg_code_list.append(
arg.hdr_type.declaration_code(arg.hdr_cname))
if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
arg_code_list.append("PyObject *unused")
arg_code_list.append("CYTHON_UNUSED PyObject *unused")
if sig.has_generic_args:
arg_code_list.append(
"PyObject *%s, PyObject *%s"
% (Naming.args_cname, Naming.kwds_cname))
arg_code = ", ".join(arg_code_list)
dc = self.return_type.declaration_code(self.entry.func_cname)
header = "static %s(%s)" % (dc, arg_code)
mf = " ".join(self.modifiers).upper()
if mf: mf += " "
header = "static %s%s(%s)" % (mf, dc, arg_code)
code.putln("%s; /*proto*/" % header)
if proto_only:
return
......@@ -4039,24 +4047,8 @@ class IfStatNode(StatNode):
if self.else_clause:
self.else_clause.analyse_expressions(env)
# eliminate dead code based on constant condition results
if_clauses = []
condition_result = None
for if_clause in self.if_clauses:
condition_result = if_clause.get_constant_condition_result()
if condition_result != False:
if_clauses.append(if_clause)
if condition_result == True:
# other conditions can no longer apply
self.else_clause = None
break
self.if_clauses = if_clauses
# FIXME: if only one active code body is left here, we can
# replace the whole node
def generate_execution_code(self, code):
code.mark_pos(self.pos)
if self.if_clauses:
end_label = code.new_label()
for if_clause in self.if_clauses:
if_clause.generate_execution_code(code, end_label)
......@@ -4065,8 +4057,6 @@ class IfStatNode(StatNode):
self.else_clause.generate_execution_code(code)
code.putln("}")
code.put_label(end_label)
elif self.else_clause:
self.else_clause.generate_execution_code(code)
def generate_function_definitions(self, env, code):
for clause in self.if_clauses:
......@@ -4103,7 +4093,7 @@ class IfClauseNode(Node):
def get_constant_condition_result(self):
if self.condition.has_constant_result():
return self.condition.constant_result
return bool(self.condition.constant_result)
else:
return None
......@@ -5261,6 +5251,7 @@ class FromImportStatNode(StatNode):
utility_function_predeclarations = \
"""
/* inline attribute */
#ifndef CYTHON_INLINE
#if defined(__GNUC__)
#define CYTHON_INLINE __inline__
......@@ -5273,6 +5264,21 @@ utility_function_predeclarations = \
#endif
#endif
/* unused attribute */
#ifndef CYTHON_UNUSED
# if defined(__GNUC__)
# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
# define CYTHON_UNUSED __attribute__ ((__unused__))
# else
# define CYTHON_UNUSED
# endif
# elif defined(__ICC) || defined(__INTEL_COMPILER)
# define CYTHON_UNUSED __attribute__ ((__unused__))
# else
# define CYTHON_UNUSED
# endif
#endif
typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
"""
......
......@@ -2570,6 +2570,34 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
#new_node = new_node.coerce_to(node.type, self.current_scope)
return new_node
def visit_PrimaryCmpNode(self, node):
self._calculate_const(node)
if node.constant_result is ExprNodes.not_a_constant:
return node
bool_result = bool(node.constant_result)
return ExprNodes.BoolNode(node.pos, value=bool_result,
constant_result=bool_result)
def visit_IfStatNode(self, node):
self.visitchildren(node)
# eliminate dead code based on constant condition results
if_clauses = []
for if_clause in node.if_clauses:
condition_result = if_clause.get_constant_condition_result()
if condition_result is None:
# unknown result => normal runtime evaluation
if_clauses.append(if_clause)
elif condition_result == True:
# subsequent clauses can safely be dropped
node.else_clause = if_clause.body
break
else:
assert condition_result == False
if not if_clauses:
return node.else_clause
node.if_clauses = if_clauses
return node
# in the future, other nodes can have their own handler method here
# that can replace them with a constant result node
......
......@@ -1312,7 +1312,8 @@ class TransformBuiltinMethods(EnvTransform):
elif attribute == u'NULL':
node = NullNode(node.pos)
elif attribute in (u'set', u'frozenset'):
node = NameNode(node.pos, name=EncodedString(attribute))
node = NameNode(node.pos, name=EncodedString(attribute),
entry=self.current_env().builtin_scope().lookup_here(attribute))
elif not PyrexTypes.parse_basic_type(attribute):
error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute)
return node
......@@ -1322,7 +1323,7 @@ class TransformBuiltinMethods(EnvTransform):
# locals builtin
if isinstance(node.function, ExprNodes.NameNode):
if node.function.name == 'locals':
lenv = self.env_stack[-1]
lenv = self.current_env()
entry = lenv.lookup_here('locals')
if entry:
# not the builtin 'locals'
......@@ -1348,7 +1349,7 @@ class TransformBuiltinMethods(EnvTransform):
if len(node.args) != 2:
error(node.function.pos, u"cast() takes exactly two arguments")
else:
type = node.args[0].analyse_as_type(self.env_stack[-1])
type = node.args[0].analyse_as_type(self.current_env())
if type:
node = TypecastNode(node.function.pos, type=type, operand=node.args[1])
else:
......@@ -1357,7 +1358,7 @@ class TransformBuiltinMethods(EnvTransform):
if len(node.args) != 1:
error(node.function.pos, u"sizeof() takes exactly one argument")
else:
type = node.args[0].analyse_as_type(self.env_stack[-1])
type = node.args[0].analyse_as_type(self.current_env())
if type:
node = SizeofTypeNode(node.function.pos, arg_type=type)
else:
......
......@@ -2454,7 +2454,7 @@ def p_def_statement(s, decorators=None):
args, star_arg, starstar_arg = p_varargslist(s, terminator=')')
s.expect(')')
if p_nogil(s):
error(s.pos, "Python function cannot be declared nogil")
error(pos, "Python function cannot be declared nogil")
return_type_annotation = None
if s.sy == '->':
s.next()
......
......@@ -950,7 +950,7 @@ class CSSizeTType(CIntType):
from_py_function = "PyInt_AsSsize_t"
def sign_and_name(self):
return "ssize_t"
return "Py_ssize_t"
class CSizeTType(CIntType):
......
cdef object f(object x) nogil:
pass
cdef void g(int x) nogil:
cdef object z
z = None
cdef void h(int x) nogil:
p()
cdef object p() nogil:
pass
cdef void r() nogil:
q()
cdef void (*fp)()
cdef void (*fq)() nogil
cdef extern void u()
cdef object m():
global fp, fq
cdef object x, y, obj
cdef int i, j, k
global fred
q()
with nogil:
r()
q()
i = 42
obj = None
17L
7j
asdf
`"Hello"`
import fred
from fred import obj
for x in obj:
pass
obj[i]
obj[i:j]
obj[i:j:k]
obj.fred
(x, y)
[x, y]
{x: y}
obj and x
t(obj)
f(42)
x + obj
-obj
x = y = obj
x, y = y, x
obj[i] = x
obj.fred = x
print obj
del fred
return obj
raise obj
if obj:
pass
while obj:
pass
for x <= obj <= y:
pass
try:
pass
except:
pass
try:
pass
finally:
pass
fq = u
fq = fp
cdef void q():
pass
cdef class C:
pass
cdef void t(C c) nogil:
pass
cdef int raiseit():
raise IndexError
if False: raiseit()
try: raiseit()
except: pass
_ERRORS = u"""
FIXME: provide a good error message here.
......
def test() nogil:
pass
_ERRORS = """
2:0: Python function cannot be declared nogil
"""
def _runtime_True():
return True
return 'bar'
class A:
......@@ -19,20 +22,20 @@ for i in (1,2):
while True:
return None
if True:
if _runtime_True():
return None
else:
return None
_ERRORS = u'''
2:0: Return not inside a function body
5:4: Return not inside a function body
5:0: Return not inside a function body
8:4: Return not inside a function body
10:5: Return not inside a function body
11:4: Return not inside a function body
13:5: Return not inside a function body
17:4: Return not inside a function body
16:5: Return not inside a function body
20:4: Return not inside a function body
23:4: Return not inside a function body
25:4: Return not inside a function body
26:4: Return not inside a function body
28:4: Return not inside a function body
'''
# -*- coding: utf-8 -*-
cimport cython
unicode_str = u'ab jd üöä ôñ ÄÖ'
bytes_str = b'ab jd sdflk as sa sadas asdas fsdf '
_frozenset = frozenset
_set = set
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_unicode(unicode s):
"""
>>> len(unicode_str)
16
>>> len_unicode(unicode_str)
16
>>> len_unicode(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_bytes(bytes s):
"""
>>> len(bytes_str)
37
>>> len_bytes(bytes_str)
37
>>> len_bytes(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_str(str s):
"""
>>> len('abcdefg')
7
>>> len_str('abcdefg')
7
>>> len_unicode(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_list(list s):
"""
>>> l = [1,2,3,4]
>>> len(l)
4
>>> len_list(l)
4
>>> len_list(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_tuple(tuple s):
"""
>>> t = (1,2,3,4)
>>> len(t)
4
>>> len_tuple(t)
4
>>> len_tuple(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_dict(dict s):
"""
>>> d = dict(a=1, b=2, c=3, d=4)
>>> len(d)
4
>>> len_dict(d)
4
>>> len_dict(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_set(set s):
"""
>>> s = _set((1,2,3,4))
>>> len(s)
4
>>> len_set(s)
4
>>> len_set(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
@cython.test_assert_path_exists(
"//CoerceToPyTypeNode",
"//PythonCapiCallNode")
def len_frozenset(frozenset s):
"""
>>> s = _frozenset((1,2,3,4))
>>> len(s)
4
>>> len_frozenset(s)
4
>>> len_set(None)
Traceback (most recent call last):
TypeError: object of type 'NoneType' has no len()
"""
return len(s)
......@@ -24,6 +24,23 @@ def if_list(list obj):
else:
return False
def if_list_nogil(list obj):
"""
>>> if_list_nogil( [] )
False
>>> if_list_nogil( [1] )
True
>>> if_list_nogil(None)
False
"""
cdef bint result
with nogil:
if obj:
result = True
else:
result = False
return result
def if_list_literal(t):
"""
>>> if_list_literal(True)
......
......@@ -8,6 +8,7 @@ DEF INT_VAL = 1
def _func(a,b,c):
return a+b+c
@cython.test_fail_if_path_exists("//BinopNode")
def add():
"""
>>> add() == 1+2+3+4
......@@ -15,6 +16,7 @@ def add():
"""
return 1+2+3+4
@cython.test_fail_if_path_exists("//BinopNode")
def add_var(a):
"""
>>> add_var(10) == 1+2+10+3+4
......@@ -22,6 +24,7 @@ def add_var(a):
"""
return 1+2 +a+ 3+4
@cython.test_fail_if_path_exists("//BinopNode")
def neg():
"""
>>> neg() == -1 -2 - (-3+4)
......@@ -29,6 +32,7 @@ def neg():
"""
return -1 -2 - (-3+4)
@cython.test_fail_if_path_exists("//BinopNode")
def long_int_mix():
"""
>>> long_int_mix() == 1 + (2 * 3) // 2
......@@ -39,6 +43,7 @@ def long_int_mix():
"""
return 1L + (2 * 3L) // 2
@cython.test_fail_if_path_exists("//BinopNode")
def char_int_mix():
"""
>>> char_int_mix() == 1 + (ord(' ') * 3) // 2 + ord('A')
......@@ -46,6 +51,7 @@ def char_int_mix():
"""
return 1L + (c' ' * 3L) // 2 + c'A'
@cython.test_fail_if_path_exists("//BinopNode")
def int_cast():
"""
>>> int_cast() == 1 + 2 * 6000
......@@ -53,6 +59,7 @@ def int_cast():
"""
return <int>(1 + 2 * 6000)
@cython.test_fail_if_path_exists("//BinopNode")
def mul():
"""
>>> mul() == 1*60*1000
......@@ -60,6 +67,7 @@ def mul():
"""
return 1*60*1000
@cython.test_fail_if_path_exists("//BinopNode")
def arithm():
"""
>>> arithm() == 9*2+3*8//6-10
......@@ -67,6 +75,7 @@ def arithm():
"""
return 9*2+3*8//6-10
@cython.test_fail_if_path_exists("//BinopNode")
def parameters():
"""
>>> parameters() == _func(-1 -2, - (-3+4), 1*2*3)
......@@ -74,6 +83,7 @@ def parameters():
"""
return _func(-1 -2, - (-3+4), 1*2*3)
@cython.test_fail_if_path_exists("//BinopNode")
def lists():
"""
>>> lists() == [1,2,3] + [4,5,6]
......@@ -81,61 +91,7 @@ def lists():
"""
return [1,2,3] + [4,5,6]
def int_bool_result():
"""
>>> int_bool_result()
True
"""
if 5:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def if_compare_true():
"""
>>> if_compare_true()
True
"""
if 0 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def if_compare_false():
"""
>>> if_compare_false()
False
"""
if 0 == 1 or 1 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def if_compare_cascaded():
"""
>>> if_compare_cascaded()
True
"""
if 0 < 1 < 2 < 3:
return True
else:
return False
@cython.test_fail_if_path_exists("//CoerceToBooleanNode",
"//ListNode")
def list_bool_result():
"""
>>> list_bool_result()
True
"""
if [1,2,3]:
return True
else:
return False
def compile_time_DEF():
"""
>>> compile_time_DEF()
......@@ -144,12 +100,9 @@ def compile_time_DEF():
return INT_VAL, INT_VAL == 0, INT_VAL != 0, INT_VAL == 1, INT_VAL != 1
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def compile_time_DEF_if():
def cascaded_compare():
"""
>>> compile_time_DEF_if()
>>> cascaded_compare()
True
"""
if INT_VAL != 0:
return True
else:
return False
return 1 < 2 < 3 < 4
cimport cython
DEF INT_VAL = 1
def _not_constant_but_False():
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def int_bool_result():
"""
>>> int_bool_result()
True
"""
if 5:
return True
else:
return False
@cython.test_fail_if_path_exists("//IfStatNode")
def constant_if_elif_else():
"""
>>> constant_if_elif_else()
True
"""
if 0:
return False
elif 5:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrintStatNode")
@cython.test_assert_path_exists("//IfStatNode",
"//IfClauseNode")
def non_constant_if_elif_else1():
"""
>>> non_constant_if_elif_else1()
True
"""
if _not_constant_but_False():
return False
elif 5:
return True
else:
print(False)
@cython.test_fail_if_path_exists("//PrintStatNode")
@cython.test_assert_path_exists("//IfStatNode",
"//IfClauseNode")
def non_constant_if_elif_else2():
"""
>>> non_constant_if_elif_else2()
True
"""
if _not_constant_but_False():
return False
elif 0:
print(False)
else:
return True
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_not_compare_true():
"""
>>> if_not_compare_true()
False
"""
if not 0 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_true():
"""
>>> if_compare_true()
True
"""
if 0 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_false():
"""
>>> if_compare_false()
False
"""
if 0 == 1:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_or_true():
"""
>>> if_compare_or_true()
True
"""
if 0 == 1 or 1 == 1:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_or_false():
"""
>>> if_compare_or_false()
False
"""
if 0 == 1 or 1 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_and_true():
"""
>>> if_compare_and_true()
True
"""
if 0 == 0 and 1 == 1:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_and_false():
"""
>>> if_compare_and_false()
False
"""
if 1 == 1 and 1 == 0:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def if_compare_cascaded():
"""
>>> if_compare_cascaded()
True
"""
if 0 < 1 < 2 < 3:
return True
else:
return False
@cython.test_fail_if_path_exists("//CoerceToBooleanNode",
"//ListNode",
"//IfStatNode")
def list_bool_result_true():
"""
>>> list_bool_result_true()
True
"""
if [1,2,3]:
return True
else:
return False
@cython.test_fail_if_path_exists("//CoerceToBooleanNode",
"//ListNode",
"//IfStatNode")
def list_bool_result_false():
"""
>>> list_bool_result_false()
False
"""
if []:
return True
else:
return False
@cython.test_fail_if_path_exists("//PrimaryCmpNode",
"//IfStatNode")
def compile_time_DEF_if():
"""
>>> compile_time_DEF_if()
True
"""
if INT_VAL != 0:
return True
else:
return False
"""
>>> import sys
>>> 'numpy' in sys.modules
True
"""
cimport numpy as np
include "numpy_common.pxi"
......@@ -326,6 +326,10 @@ def inc1_float64_t(np.ndarray[np.float64_t] arr): arr[1] += 1
def test_dtype(dtype, inc1):
if dtype in ("g", np.longdouble,
"G", np.clongdouble):
if sizeof(double) == sizeof(long double): # MSVC
return
if dtype in (b'F', b'D', b'G'):
a = np.array([0, 10+10j], dtype=dtype)
inc1(a)
......
......@@ -12,6 +12,14 @@ def cython_set():
assert set is cython.set
return cython.set
def cython_set_override():
"""
>>> cython_set_override() is _set
True
"""
set = 1
return cython.set
def test_set_literal():
"""
>>> type(test_set_literal()) is _set
......
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