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 ...@@ -21,6 +21,13 @@ Features added
is raised only when such a pointer is assigned to a variable and is raised only when such a pointer is assigned to a variable and
would thus exceed the lifetime of the string itself. 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 * Cascaded assignments (a = b = ...) try to minimise the number of
type coercions. type coercions.
......
This diff is collapsed.
...@@ -816,6 +816,8 @@ class SwitchTransform(Visitor.CythonTransform): ...@@ -816,6 +816,8 @@ class SwitchTransform(Visitor.CythonTransform):
if isinstance(cond, (ExprNodes.CoerceToTempNode, if isinstance(cond, (ExprNodes.CoerceToTempNode,
ExprNodes.CoerceToBooleanNode)): ExprNodes.CoerceToBooleanNode)):
cond = cond.arg cond = cond.arg
elif isinstance(cond, ExprNodes.BoolBinopResultNode):
cond = cond.arg.arg
elif isinstance(cond, UtilNodes.EvalWithTempExprNode): elif isinstance(cond, UtilNodes.EvalWithTempExprNode):
# this is what we get from the FlattenInListTransform # this is what we get from the FlattenInListTransform
cond = cond.subexpression cond = cond.subexpression
...@@ -860,7 +862,7 @@ class SwitchTransform(Visitor.CythonTransform): ...@@ -860,7 +862,7 @@ class SwitchTransform(Visitor.CythonTransform):
elif getattr(cond.operand1, 'entry', None) \ elif getattr(cond.operand1, 'entry', None) \
and cond.operand1.entry.is_const: and cond.operand1.entry.is_const:
return not_in, cond.operand2, [cond.operand1] 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'): if cond.operator == 'or' or (allow_not_in and cond.operator == 'and'):
allow_not_in = (cond.operator == 'and') allow_not_in = (cond.operator == 'and')
not_in_1, t1, c1 = self.extract_conditions(cond.operand1, allow_not_in) 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: ...@@ -74,14 +74,15 @@ if 'setuptools' in sys.modules:
setuptools_extra_args['entry_points'] = { setuptools_extra_args['entry_points'] = {
'console_scripts': [ 'console_scripts': [
'cython = Cython.Compiler.Main:setuptools_main', 'cython = Cython.Compiler.Main:setuptools_main',
'cythonize = Cython.Build.Cythonize:main'
] ]
} }
scripts = [] scripts = []
else: else:
if os.name == "posix": if os.name == "posix":
scripts = ["bin/cython"] scripts = ["bin/cython", 'bin/cythonize']
else: else:
scripts = ["cython.py"] scripts = ["cython.py", "cythonize.py"]
if include_debugger: if include_debugger:
if 'setuptools' in sys.modules: if 'setuptools' in sys.modules:
......
...@@ -390,8 +390,8 @@ def combined(): ...@@ -390,8 +390,8 @@ def combined():
'//IntNode[@value = "4"]', '//IntNode[@value = "4"]',
'//IntNode[@value = "5"]', '//IntNode[@value = "5"]',
'//IntNode[@value = "7"]', '//IntNode[@value = "7"]',
'//BoolBinopNode//PrimaryCmpNode', '//GenericBoolBinopNode//PrimaryCmpNode',
'//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', '//GenericBoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]', '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]',
'//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]', '//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]',
) )
...@@ -423,11 +423,11 @@ def cascaded_cmp_with_partial_constants(a, b): ...@@ -423,11 +423,11 @@ def cascaded_cmp_with_partial_constants(a, b):
'//IntNode[@value = "4"]', '//IntNode[@value = "4"]',
'//IntNode[@value = "5"]', '//IntNode[@value = "5"]',
'//IntNode[@value = "7"]', '//IntNode[@value = "7"]',
'//BoolBinopNode', '//GenericBoolBinopNode',
'//SingleAssignmentNode//BoolBinopNode', '//SingleAssignmentNode//GenericBoolBinopNode',
'//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "a"]', '//SingleAssignmentNode//GenericBoolBinopNode//NameNode[@name = "a"]',
'//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "b"]', '//SingleAssignmentNode//GenericBoolBinopNode//NameNode[@name = "b"]',
'//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', '//GenericBoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
'//BoolNode[@value = False]', '//BoolNode[@value = False]',
) )
@cython.test_fail_if_path_exists( @cython.test_fail_if_path_exists(
......
...@@ -83,7 +83,7 @@ def m_tuple(int a): ...@@ -83,7 +83,7 @@ def m_tuple(int a):
return result return result
@cython.test_assert_path_exists("//SwitchStatNode") @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): def m_set(int a):
""" """
>>> m_set(2) >>> m_set(2)
...@@ -97,7 +97,7 @@ def m_set(int a): ...@@ -97,7 +97,7 @@ def m_set(int a):
cdef bytes bytes_string = b'abcdefg' cdef bytes bytes_string = b'abcdefg'
@cython.test_assert_path_exists("//PrimaryCmpNode") @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): def m_bytes(char a):
""" """
>>> m_bytes(ord('f')) >>> m_bytes(ord('f'))
...@@ -109,7 +109,7 @@ def m_bytes(char a): ...@@ -109,7 +109,7 @@ def m_bytes(char a):
return result return result
@cython.test_assert_path_exists("//SwitchStatNode") @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): def m_bytes_literal(char a):
""" """
>>> m_bytes_literal(ord('f')) >>> m_bytes_literal(ord('f'))
...@@ -127,7 +127,7 @@ cdef unicode klingon_character = u'\uF8D2' ...@@ -127,7 +127,7 @@ cdef unicode klingon_character = u'\uF8D2'
py_klingon_character = klingon_character py_klingon_character = klingon_character
@cython.test_assert_path_exists("//PrimaryCmpNode") @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): def m_unicode(Py_UNICODE a, unicode unicode_string):
""" """
>>> m_unicode(ord('f'), py_unicode_string) >>> m_unicode(ord('f'), py_unicode_string)
...@@ -147,7 +147,7 @@ def m_unicode(Py_UNICODE a, unicode unicode_string): ...@@ -147,7 +147,7 @@ def m_unicode(Py_UNICODE a, unicode unicode_string):
return result return result
@cython.test_assert_path_exists("//SwitchStatNode") @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): def m_unicode_literal(Py_UNICODE a):
""" """
>>> m_unicode_literal(ord('f')) >>> m_unicode_literal(ord('f'))
...@@ -160,7 +160,7 @@ def m_unicode_literal(Py_UNICODE a): ...@@ -160,7 +160,7 @@ def m_unicode_literal(Py_UNICODE a):
cdef int result = a not in u'abcdefg\u1234\uF8D2' cdef int result = a not in u'abcdefg\u1234\uF8D2'
return result return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_in_or_notin(int a): def m_tuple_in_or_notin(int a):
""" """
...@@ -174,7 +174,7 @@ 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) cdef int result = a not in (1,2,3,4) or a in (3,4)
return result return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_notin_or_notin(int a): def m_tuple_notin_or_notin(int a):
""" """
...@@ -189,7 +189,7 @@ def m_tuple_notin_or_notin(int a): ...@@ -189,7 +189,7 @@ def m_tuple_notin_or_notin(int a):
return result return result
@cython.test_assert_path_exists("//SwitchStatNode") @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): def m_tuple_notin_and_notin(int a):
""" """
>>> m_tuple_notin_and_notin(2) >>> m_tuple_notin_and_notin(2)
...@@ -202,7 +202,7 @@ def m_tuple_notin_and_notin(int a): ...@@ -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) cdef int result = a not in (1,2,3,4) and a not in (6,7)
return result return result
@cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_assert_path_exists("//SwitchStatNode", "//GenericBoolBinopNode")
@cython.test_fail_if_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode")
def m_tuple_notin_and_notin_overlap(int a): def m_tuple_notin_and_notin_overlap(int a):
""" """
...@@ -217,7 +217,7 @@ def m_tuple_notin_and_notin_overlap(int a): ...@@ -217,7 +217,7 @@ def m_tuple_notin_and_notin_overlap(int a):
return result return result
@cython.test_assert_path_exists("//SwitchStatNode") @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): def conditional_int(int a):
""" """
>>> conditional_int(1) >>> conditional_int(1)
...@@ -230,7 +230,7 @@ def conditional_int(int a): ...@@ -230,7 +230,7 @@ def conditional_int(int a):
return 1 if a not in (1,2,3,4) else 2 return 1 if a not in (1,2,3,4) else 2
@cython.test_assert_path_exists("//SwitchStatNode") @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): def conditional_object(int a):
""" """
>>> conditional_object(1) >>> conditional_object(1)
...@@ -243,7 +243,7 @@ def conditional_object(int a): ...@@ -243,7 +243,7 @@ def conditional_object(int a):
return 1 if a not in (1,2,3,4) else '2' return 1 if a not in (1,2,3,4) else '2'
@cython.test_assert_path_exists("//SwitchStatNode") @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): def conditional_bytes(char a):
""" """
>>> conditional_bytes(ord('a')) >>> conditional_bytes(ord('a'))
...@@ -256,7 +256,7 @@ def conditional_bytes(char a): ...@@ -256,7 +256,7 @@ def conditional_bytes(char a):
return 1 if a not in b'abc' else '2' return 1 if a not in b'abc' else '2'
@cython.test_assert_path_exists("//SwitchStatNode") @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): def conditional_unicode(Py_UNICODE a):
""" """
>>> conditional_unicode(ord('a')) >>> conditional_unicode(ord('a'))
...@@ -269,7 +269,7 @@ def conditional_unicode(Py_UNICODE a): ...@@ -269,7 +269,7 @@ def conditional_unicode(Py_UNICODE a):
return 1 if a not in u'abc' else '2' return 1 if a not in u'abc' else '2'
@cython.test_assert_path_exists("//SwitchStatNode") @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): def conditional_none(int a):
""" """
>>> conditional_none(1) >>> 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