Commit 1c3855fb authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'master' of github.com:cython/cython

parents 77c95c8c 24463d45
......@@ -21,6 +21,13 @@ Features added
is raised only when such a pointer is assigned to a variable and
would thus exceed the lifetime of the string itself.
* The "and"/"or" operators try to avoid unnecessary coercions of their
arguments. They now evaluate the truth value of each argument
independently and only coerce the final result of the whole expression
to the target type (e.g. the type on the left side of an assignment).
This also avoids reference counting overhead for Python values during
evaluation and generally improves the code flow in the generated C code.
* Cascaded assignments (a = b = ...) try to minimise the number of
type coercions.
......
This diff is collapsed.
......@@ -816,6 +816,8 @@ class SwitchTransform(Visitor.CythonTransform):
if isinstance(cond, (ExprNodes.CoerceToTempNode,
ExprNodes.CoerceToBooleanNode)):
cond = cond.arg
elif isinstance(cond, ExprNodes.BoolBinopResultNode):
cond = cond.arg.arg
elif isinstance(cond, UtilNodes.EvalWithTempExprNode):
# this is what we get from the FlattenInListTransform
cond = cond.subexpression
......@@ -860,7 +862,7 @@ class SwitchTransform(Visitor.CythonTransform):
elif getattr(cond.operand1, 'entry', None) \
and cond.operand1.entry.is_const:
return not_in, cond.operand2, [cond.operand1]
elif isinstance(cond, ExprNodes.BoolBinopNode):
elif isinstance(cond, (ExprNodes.BoolBinopNode, ExprNodes.GenericBoolBinopNode)):
if cond.operator == 'or' or (allow_not_in and cond.operator == 'and'):
allow_not_in = (cond.operator == 'and')
not_in_1, t1, c1 = self.extract_conditions(cond.operand1, allow_not_in)
......
#!/usr/bin/env python
#
# Cython -- enhanced main program
#
if __name__ == '__main__':
from Cython.Build.Cythonize import main
main()
......@@ -74,14 +74,15 @@ if 'setuptools' in sys.modules:
setuptools_extra_args['entry_points'] = {
'console_scripts': [
'cython = Cython.Compiler.Main:setuptools_main',
'cythonize = Cython.Build.Cythonize:main'
]
}
scripts = []
else:
if os.name == "posix":
scripts = ["bin/cython"]
scripts = ["bin/cython", 'bin/cythonize']
else:
scripts = ["cython.py"]
scripts = ["cython.py", "cythonize.py"]
if include_debugger:
if 'setuptools' in sys.modules:
......
......@@ -390,8 +390,8 @@ def combined():
'//IntNode[@value = "4"]',
'//IntNode[@value = "5"]',
'//IntNode[@value = "7"]',
'//BoolBinopNode//PrimaryCmpNode',
'//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//GenericBoolBinopNode//PrimaryCmpNode',
'//GenericBoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]',
'//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]',
)
......@@ -423,11 +423,11 @@ def cascaded_cmp_with_partial_constants(a, b):
'//IntNode[@value = "4"]',
'//IntNode[@value = "5"]',
'//IntNode[@value = "7"]',
'//BoolBinopNode',
'//SingleAssignmentNode//BoolBinopNode',
'//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "a"]',
'//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "b"]',
'//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//GenericBoolBinopNode',
'//SingleAssignmentNode//GenericBoolBinopNode',
'//SingleAssignmentNode//GenericBoolBinopNode//NameNode[@name = "a"]',
'//SingleAssignmentNode//GenericBoolBinopNode//NameNode[@name = "b"]',
'//GenericBoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//BoolNode[@value = False]',
)
@cython.test_fail_if_path_exists(
......
......@@ -83,7 +83,7 @@ def m_tuple(int a):
return result
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//GenericBoolBinopNode", "//PrimaryCmpNode")
def m_set(int a):
"""
>>> m_set(2)
......@@ -97,7 +97,7 @@ def m_set(int a):
cdef bytes bytes_string = b'abcdefg'
@cython.test_assert_path_exists("//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode")
@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode", "//GenericBoolBinopNode")
def m_bytes(char a):
"""
>>> m_bytes(ord('f'))
......@@ -109,7 +109,7 @@ def m_bytes(char a):
return result
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//GenericBoolBinopNode", "//PrimaryCmpNode")
def m_bytes_literal(char a):
"""
>>> m_bytes_literal(ord('f'))
......@@ -127,7 +127,7 @@ cdef unicode klingon_character = u'\uF8D2'
py_klingon_character = klingon_character
@cython.test_assert_path_exists("//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode")
@cython.test_fail_if_path_exists("//SwitchStatNode", "//GenericBoolBinopNode", "//BoolBinopNode")
def m_unicode(Py_UNICODE a, unicode unicode_string):
"""
>>> m_unicode(ord('f'), py_unicode_string)
......@@ -147,7 +147,7 @@ def m_unicode(Py_UNICODE a, unicode unicode_string):
return result
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def m_unicode_literal(Py_UNICODE a):
"""
>>> m_unicode_literal(ord('f'))
......@@ -160,7 +160,7 @@ def m_unicode_literal(Py_UNICODE a):
cdef int result = a not in u'abcdefg\u1234\uF8D2'
return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode")
@cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_in_or_notin(int a):
"""
......@@ -174,7 +174,7 @@ def m_tuple_in_or_notin(int a):
cdef int result = a not in (1,2,3,4) or a in (3,4)
return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode")
@cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_notin_or_notin(int a):
"""
......@@ -189,7 +189,7 @@ def m_tuple_notin_or_notin(int a):
return result
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def m_tuple_notin_and_notin(int a):
"""
>>> m_tuple_notin_and_notin(2)
......@@ -202,7 +202,7 @@ def m_tuple_notin_and_notin(int a):
cdef int result = a not in (1,2,3,4) and a not in (6,7)
return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode")
@cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_notin_and_notin_overlap(int a):
"""
......@@ -217,7 +217,7 @@ def m_tuple_notin_and_notin_overlap(int a):
return result
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def conditional_int(int a):
"""
>>> conditional_int(1)
......@@ -230,7 +230,7 @@ def conditional_int(int a):
return 1 if a not in (1,2,3,4) else 2
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def conditional_object(int a):
"""
>>> conditional_object(1)
......@@ -243,7 +243,7 @@ def conditional_object(int a):
return 1 if a not in (1,2,3,4) else '2'
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def conditional_bytes(char a):
"""
>>> conditional_bytes(ord('a'))
......@@ -256,7 +256,7 @@ def conditional_bytes(char a):
return 1 if a not in b'abc' else '2'
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def conditional_unicode(Py_UNICODE a):
"""
>>> conditional_unicode(ord('a'))
......@@ -269,7 +269,7 @@ def conditional_unicode(Py_UNICODE a):
return 1 if a not in u'abc' else '2'
@cython.test_assert_path_exists("//SwitchStatNode")
@cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode")
@cython.test_fail_if_path_exists("//GenericBoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode")
def conditional_none(int a):
"""
>>> conditional_none(1)
......
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