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

merge

parents 61ce9ded aebbb878
...@@ -4206,14 +4206,19 @@ class TypecastNode(ExprNode): ...@@ -4206,14 +4206,19 @@ class TypecastNode(ExprNode):
self.result_ctype = py_object_type self.result_ctype = py_object_type
self.operand = self.operand.coerce_to_pyobject(env) self.operand = self.operand.coerce_to_pyobject(env)
else: else:
if not (self.operand.type.is_ptr and self.operand.type.base_type.is_void): if self.operand.type.is_ptr:
if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
error(self.pos, "Python objects cannot be cast from pointers of primitive types")
else:
# Should this be an error?
warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type)) 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) self.operand = self.operand.coerce_to_simple(env)
elif from_py and not to_py: elif from_py and not to_py:
if self.type.create_from_py_utility_code(env): if self.type.create_from_py_utility_code(env):
self.operand = self.operand.coerce_to(self.type, 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): elif self.type.is_ptr:
error(self.pos, "Python objects cannot be casted to pointers of primitive types") if not (self.type.base_type.is_void or self.type.base_type.is_struct):
error(self.pos, "Python objects cannot be cast to pointers of primitive types")
else: else:
warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type)) warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
elif from_py and to_py: elif from_py and to_py:
...@@ -4839,11 +4844,9 @@ class BoolBinopNode(ExprNode): ...@@ -4839,11 +4844,9 @@ class BoolBinopNode(ExprNode):
subexprs = ['operand1', 'operand2'] subexprs = ['operand1', 'operand2']
def infer_type(self, env): def infer_type(self, env):
if (self.operand1.infer_type(env).is_pyobject or type1 = self.operand1.infer_type(env)
self.operand2.infer_type(env).is_pyobject): type2 = self.operand2.infer_type(env)
return py_object_type return PyrexTypes.spanning_type(type1, type2)
else:
return PyrexTypes.c_bint_type
def calculate_constant_result(self): def calculate_constant_result(self):
if self.operator == 'and': if self.operator == 'and':
...@@ -4872,22 +4875,14 @@ class BoolBinopNode(ExprNode): ...@@ -4872,22 +4875,14 @@ class BoolBinopNode(ExprNode):
def analyse_types(self, env): def analyse_types(self, env):
self.operand1.analyse_types(env) self.operand1.analyse_types(env)
self.operand2.analyse_types(env) self.operand2.analyse_types(env)
if self.operand1.type.is_pyobject or \ self.type = PyrexTypes.spanning_type(self.operand1.type, self.operand2.type)
self.operand2.type.is_pyobject: self.operand1 = self.operand1.coerce_to(self.type, env)
self.operand1 = self.operand1.coerce_to_pyobject(env) self.operand2 = self.operand2.coerce_to(self.type, env)
self.operand2 = self.operand2.coerce_to_pyobject(env)
self.type = py_object_type
else:
self.operand1 = self.operand1.coerce_to_boolean(env)
self.operand2 = self.operand2.coerce_to_boolean(env)
self.type = PyrexTypes.c_bint_type
# Below disabled for
# For what we're about to do, it's vital that # For what we're about to do, it's vital that
# both operands be temp nodes. # both operands be temp nodes.
# self.operand1 = self.operand1.coerce_to_temp(env) #CTT self.operand1 = self.operand1.coerce_to_simple(env)
# self.operand2 = self.operand2.coerce_to_temp(env) self.operand2 = self.operand2.coerce_to_simple(env)
self.is_temp = 1 self.is_temp = 1
gil_message = "Truth-testing Python object" gil_message = "Truth-testing Python object"
...@@ -4896,14 +4891,6 @@ class BoolBinopNode(ExprNode): ...@@ -4896,14 +4891,6 @@ class BoolBinopNode(ExprNode):
self.operand1.check_const() self.operand1.check_const()
self.operand2.check_const() self.operand2.check_const()
def calculate_result_code(self):
return "(%s %s %s)" % (
self.operand1.result(),
self.py_to_c_op[self.operator],
self.operand2.result())
py_to_c_op = {'and': "&&", 'or': "||"}
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
code.mark_pos(self.pos) code.mark_pos(self.pos)
self.operand1.generate_evaluation_code(code) self.operand1.generate_evaluation_code(code)
......
...@@ -387,7 +387,7 @@ class CythonRunTestCase(CythonCompileTestCase): ...@@ -387,7 +387,7 @@ class CythonRunTestCase(CythonCompileTestCase):
pass pass
def run_doctests(self, module_name, result): def run_doctests(self, module_name, result):
if sys.version_info[0] >= 3 or not hasattr(os, 'fork'): if sys.version_info[0] >= 3 or not hasattr(os, 'forkx'):
doctest.DocTestSuite(module_name).run(result) doctest.DocTestSuite(module_name).run(result)
return return
......
...@@ -116,7 +116,9 @@ _ERRORS = u""" ...@@ -116,7 +116,9 @@ _ERRORS = u"""
39: 9: Constructing Python tuple not allowed without gil 39: 9: Constructing Python tuple not allowed without gil
40: 8: Constructing Python list not allowed without gil 40: 8: Constructing Python list not allowed without gil
41: 8: Constructing Python dict not allowed without gil 41: 8: Constructing Python dict not allowed without gil
42:12: Creating temporary Python reference not allowed without gil
42:12: Truth-testing Python object not allowed without gil 42:12: Truth-testing Python object not allowed without gil
42:17: Creating temporary Python reference not allowed without gil
43:13: Python type test not allowed without gil 43:13: Python type test not allowed without gil
45:10: Operation not allowed without gil 45:10: Operation not allowed without gil
46:8: Operation not allowed without gil 46:8: Operation not allowed without gil
......
...@@ -5,5 +5,5 @@ cdef void* allowed = <void*>a ...@@ -5,5 +5,5 @@ cdef void* allowed = <void*>a
cdef double* disallowed = <double*>a cdef double* disallowed = <double*>a
_ERRORS = u""" _ERRORS = u"""
5:26: Python objects cannot be casted to pointers of primitive types 5:26: Python objects cannot be cast to pointers of primitive types
""" """
__doc__ = u""" __doc__ = u"""
>>> foo(True, False, 23, 'test', 1) >>> foo(True, False, 23, 'test', 1)
(0, 1, False, False) (0.0, 1.0, False, False)
""" """
def foo(obj1, obj2, obj3, obj4, obj5): def foo(obj1, obj2, obj3, obj4, obj5):
cdef int bool1, bool2, bool3, bool4 cdef int bool1, bool2
cdef char *ptr cdef float bool3, bool4
cdef char *ptr1, *ptr2, *ptr0
cdef float f cdef float f
bool1 = 1 bool1 = 1
bool2 = 0 bool2 = 0
ptr = NULL ptr1 = ptr2 = NULL
f = 0.0 f = 0.0
bool3 = bool1 and bool2 bool3 = bool1 and bool2
bool3 = bool1 or bool2 bool3 = bool1 or bool2
bool3 = obj1 and obj2 bool3 = obj1 and obj2
bool3 = bool1 and ptr ptr0 = ptr1 and ptr2
bool3 = bool1 and f bool3 = bool1 and f
bool4 = bool1 and bool2 and bool3 bool4 = bool1 and bool2 and bool3
bool4 = bool1 or bool2 and bool3 bool4 = bool1 or bool2 and bool3
......
cdef long foo(long x):
print "foo(%s)" % x
return x
def test_or(long a, long b):
"""
>>> test_or(1,2)
foo(1)
1
>>> test_or(1,0)
foo(1)
1
>>> test_or(0,2)
foo(0)
foo(2)
2
>>> test_or(0,0)
foo(0)
foo(0)
0
"""
print foo(a) or foo(b)
def test_and(long a, long b):
"""
>>> test_and(1,2)
foo(1)
foo(2)
2
>>> test_and(1,0)
foo(1)
foo(0)
0
>>> test_and(0,2)
foo(0)
0
>>> test_and(0,0)
foo(0)
0
"""
print foo(a) and foo(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