merged in Vitja's tab removals master
authorStefan Behnel <scoder@users.berlios.de>
Fri, 29 Apr 2011 20:33:58 +0000 (22:33 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Fri, 29 Apr 2011 20:33:58 +0000 (22:33 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Optimize.py
runtests.py
setup.py
tests/bugs.txt
tests/errors/w_cdef_override.pyx
tests/run/generators_py.py
tests/run/ifelseexpr_T267.pyx
tests/run/test_raisefrom.pyx

index a0b0b22592dcea3d82d25bf5378d322b09b3ef79..27f0ccb9e86fd12de97b5718ddf5e3f11b020bde 100755 (executable)
@@ -6672,6 +6672,14 @@ class CmpNode(object):
                     env.use_utility_code(pyunicode_equals_utility_code)
                     self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
                     return True
+                elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
+                    env.use_utility_code(pybytes_equals_utility_code)
+                    self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
+                    return True
+                elif type1 is Builtin.str_type or type2 is Builtin.str_type:
+                    env.use_utility_code(pystr_equals_utility_code)
+                    self.special_bool_cmp_function = "__Pyx_PyString_Equals"
+                    return True
         return False
 
     def generate_operation_code(self, code, result_code,
@@ -6868,8 +6876,6 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int
                 return -1;
             return (equals == Py_EQ) ? (result == 0) : (result != 0);
         }
-    } else if ((s1 == Py_None) & (s2 == Py_None)) {
-        return (equals == Py_EQ);
     } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
         return (equals == Py_NE);
     } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
@@ -6886,6 +6892,53 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int
 }
 """)
 
+pybytes_equals_utility_code = UtilityCode(
+proto="""
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
+""",
+impl="""
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+    if (s1 == s2) {   /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
+        return (equals == Py_EQ);
+    } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+        if (PyBytes_GET_SIZE(s1) != PyBytes_GET_SIZE(s2)) {
+            return (equals == Py_NE);
+        } else if (PyBytes_GET_SIZE(s1) == 1) {
+            if (equals == Py_EQ)
+                return (PyBytes_AS_STRING(s1)[0] == PyBytes_AS_STRING(s2)[0]);
+            else
+                return (PyBytes_AS_STRING(s1)[0] != PyBytes_AS_STRING(s2)[0]);
+        } else {
+            int result = memcmp(PyBytes_AS_STRING(s1), PyBytes_AS_STRING(s2), PyBytes_GET_SIZE(s1));
+            return (equals == Py_EQ) ? (result == 0) : (result != 0);
+        }
+    } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+        return (equals == Py_NE);
+    } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+        return (equals == Py_NE);
+    } else {
+        int result;
+        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+        if (!py_result)
+            return -1;
+        result = __Pyx_PyObject_IsTrue(py_result);
+        Py_DECREF(py_result);
+        return result;
+    }
+}
+""",
+requires=[Builtin.include_string_h_utility_code])
+
+pystr_equals_utility_code = UtilityCode(
+proto="""
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+""",
+requires=[pybytes_equals_utility_code, pyunicode_equals_utility_code])
+
 
 class PrimaryCmpNode(ExprNode, CmpNode):
     #  Non-cascaded comparison or first comparison of
index 53824cf238c3bb6ebda3d4e147302b6dd7e5b7e1..804824d476e8db1682b51275be76f936500b4eb6 100644 (file)
@@ -3138,6 +3138,15 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
         return ExprNodes.BoolNode(node.pos, value=bool_result,
                                   constant_result=bool_result)
 
+    def visit_CondExprNode(self, node):
+        self._calculate_const(node)
+        if node.test.constant_result is ExprNodes.not_a_constant:
+            return node
+        if node.test.constant_result:
+            return node.true_val
+        else:
+            return node.false_val
+
     def visit_IfStatNode(self, node):
         self.visitchildren(node)
         # eliminate dead code based on constant condition results
index e9d09f1562f12ea5d12ce986601e06812ffa9f19..d565aed1c9497128c3df274b2fedc183b8cb3a21 100644 (file)
@@ -69,20 +69,18 @@ if sys.platform == 'win32':
     distutils_distro.parse_config_files(cfgfiles)
 
 EXT_DEP_MODULES = {
-    'numpy' : 'tag:numpy',
-    'pstats' : 'tag:pstats',
-    'posix' : 'tag:posix',
+    'tag:numpy' : 'numpy',
+    'tag:pstats': 'pstats',
+    'tag:posix' : 'posix',
 }
 
-def get_numpy_include_dirs():
+def update_numpy_extension(ext):
     import numpy
-    return [numpy.get_include()]
+    ext.include_dirs.append(numpy.get_include())
 
-# TODO: use tags
-EXT_DEP_INCLUDES = [
-    # test name matcher , callable returning list
-    (re.compile('numpy_.*').match, get_numpy_include_dirs),
-]
+EXT_EXTRAS = {
+    'tag:numpy' : update_numpy_extension,
+}
 
 # TODO: use tags
 VER_DEP_MODULES = {
@@ -159,6 +157,8 @@ def parse_tags(filepath):
 
 parse_tags = memoize(parse_tags)
 
+list_unchanging_dir = memoize(lambda x: os.listdir(x))
+
 
 class build_ext(_build_ext):
     def build_extension(self, ext):
@@ -245,7 +245,7 @@ class TestBuilder(object):
             os.makedirs(workdir)
 
         suite = unittest.TestSuite()
-        filenames = os.listdir(path)
+        filenames = list_unchanging_dir(path)
         filenames.sort()
         for filename in filenames:
             filepath = os.path.join(path, filename)
@@ -297,7 +297,7 @@ class TestBuilder(object):
         return suite
 
     def build_tests(self, test_class, path, workdir, module, expect_errors, tags):
-        if 'werror' in tags['tags']:
+        if 'werror' in tags['tag']:
             warning_errors = True
         else:
             warning_errors = False
@@ -414,19 +414,21 @@ class CythonCompileTestCase(unittest.TestCase):
     def build_target_filename(self, module_name):
         target = '%s.%s' % (module_name, self.language)
         return target
-
-    def copy_related_files(self, test_directory, target_directory, module_name):
+    
+    def related_files(self, test_directory, module_name):
         is_related = re.compile('%s_.*[.].*' % module_name).match
-        for filename in os.listdir(test_directory):
-            if is_related(filename):
-                shutil.copy(os.path.join(test_directory, filename),
-                            target_directory)
+        return [filename for filename in list_unchanging_dir(test_directory)
+            if is_related(filename)]
+
+    def copy_files(self, test_directory, target_directory, file_list):
+        for filename in file_list:
+            shutil.copy(os.path.join(test_directory, filename),
+                        target_directory)
 
-    def find_source_files(self, workdir, module_name):
-        is_related = re.compile('%s_.*[.]%s' % (module_name, self.language)).match
-        return [self.build_target_filename(module_name)] + [
-            filename for filename in os.listdir(workdir)
-            if is_related(filename) and os.path.isfile(os.path.join(workdir, filename)) ]
+    def source_files(self, workdir, module_name, file_list):
+        return ([self.build_target_filename(module_name)] +
+            [filename for filename in file_list
+                if not os.path.isfile(os.path.join(workdir, filename))])
 
     def split_source_and_output(self, test_directory, module, workdir):
         source_file = self.find_module_source_file(os.path.join(test_directory, module) + '.pyx')
@@ -487,6 +489,12 @@ class CythonCompileTestCase(unittest.TestCase):
 
     def run_distutils(self, test_directory, module, workdir, incdir,
                       extra_extension_args=None):
+        original_source = self.find_module_source_file(
+            os.path.join(test_directory, module + '.pyx'))
+        try:
+            tags = parse_tags(original_source)
+        except IOError:
+            tags = {}
         cwd = os.getcwd()
         os.chdir(workdir)
         try:
@@ -497,24 +505,27 @@ class CythonCompileTestCase(unittest.TestCase):
             build_extension.finalize_options()
             if COMPILER:
                 build_extension.compiler = COMPILER
-            ext_include_dirs = []
-            for match, get_additional_include_dirs in EXT_DEP_INCLUDES:
-                if match(module):
-                    ext_include_dirs += get_additional_include_dirs()
             ext_compile_flags = CFLAGS[:]
             if  build_extension.compiler == 'mingw32':
                 ext_compile_flags.append('-Wno-format')
             if extra_extension_args is None:
                 extra_extension_args = {}
 
-            self.copy_related_files(test_directory, workdir, module)
+            related_files = self.related_files(test_directory, module)
+            self.copy_files(test_directory, workdir, related_files)
             extension = Extension(
                 module,
-                sources = self.find_source_files(workdir, module),
-                include_dirs = ext_include_dirs,
+                sources = self.source_files(workdir, module, related_files),
                 extra_compile_args = ext_compile_flags,
                 **extra_extension_args
                 )
+            for matcher, fixer in EXT_EXTRAS.items():
+                if isinstance(matcher, str):
+                    del EXT_EXTRAS[matcher]
+                    matcher = string_selector(matcher)
+                    EXT_EXTRAS[matcher] = fixer
+                if matcher(module, tags):
+                    extension = fixer(extension) or extension
             if self.language == 'cpp':
                 extension.language = 'c++'
             build_extension.extensions = [extension]
@@ -1000,9 +1011,9 @@ class EmbedTest(unittest.TestCase):
 
 class MissingDependencyExcluder:
     def __init__(self, deps):
-        # deps: { module name : matcher func }
+        # deps: { matcher func : module name }
         self.exclude_matchers = []
-        for mod, matcher in deps.items():
+        for matcher, mod in deps.items():
             try:
                 __import__(mod)
             except ImportError:
@@ -1189,6 +1200,9 @@ def main():
     parser.add_option("--coverage-xml", dest="coverage_xml",
                       action="store_true", default=False,
                       help="collect source coverage data for the Compiler in XML format")
+    parser.add_option("--coverage-html", dest="coverage_html",
+                      action="store_true", default=False,
+                      help="collect source coverage data for the Compiler in HTML format")
     parser.add_option("-A", "--annotate", dest="annotate_source",
                       action="store_true", default=True,
                       help="generate annotated HTML versions of the test source files")
@@ -1244,9 +1258,9 @@ def main():
 
     WITH_CYTHON = options.with_cython
 
-    if options.coverage or options.coverage_xml:
+    if options.coverage or options.coverage_xml or options.coverage_html:
         if not WITH_CYTHON:
-            options.coverage = options.coverage_xml = False
+            options.coverage = options.coverage_xml = options.coverage_html = False
         else:
             from coverage import coverage as _coverage
             coverage = _coverage(branch=True)
@@ -1379,7 +1393,7 @@ def main():
 
     result = test_runner.run(test_suite)
 
-    if options.coverage or options.coverage_xml:
+    if options.coverage or options.coverage_xml or options.coverage_html:
         coverage.stop()
         ignored_modules = ('Options', 'Version', 'DebugFlags', 'CmdLine')
         modules = [ module for name, module in sys.modules.items()
@@ -1390,6 +1404,8 @@ def main():
             coverage.report(modules, show_missing=0)
         if options.coverage_xml:
             coverage.xml_report(modules, outfile="coverage-report.xml")
+        if options.coverage_html:
+            coverage.html_report(modules, directory="coverage-report-html")
 
     if missing_dep_excluder.tests_missing_deps:
         sys.stderr.write("Following tests excluded because of missing dependencies on your system:\n")
index cb4f996dd241e9fb0d60e1f2702a9e105a82ec4e..782dea25edf0bd376c7809fceb1e68fe6b30dec1 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -249,7 +249,11 @@ except ValueError:
 
 try:
     sys.argv.remove("--no-cython-compile")
+    compile_cython_itself = False
 except ValueError:
+    compile_cython_itself = True
+
+if compile_cython_itself:
     compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny)
 
 setup_args.update(setuptools_extra_args)
index c586868ee99e8a6b4609ac2e72a50519b282391b..5eca55f001d051dd4027afaf92aa71961b457aa5 100644 (file)
@@ -30,3 +30,11 @@ pyregr.test_pep3131
 # CPython regression tests that don't make sense
 pyregr.test_gdb
 pyregr.test_support
+
+# Inlined generators
+all
+any
+builtin_sorted
+dictcomp
+inlined_generator_expressions
+setcomp
index e3e5156969a3331ec2c245ab17b193a6d00f51a7..c3da55fa4df0b053f230447fdd40fe4b0e6f494d 100644 (file)
@@ -1,5 +1,5 @@
 # mode: error
-# tags: werror
+# tag: werror
 
 cdef foo():
     pass
index 57a11d0a9cccf553e310d176a933690a54c0a09c..b43962cd17c0d60c946b405547143de4ad34c78d 100644 (file)
@@ -167,6 +167,40 @@ def check_yield_in_except():
     except ValueError:
         yield
 
+def yield_in_except_throw_exc_type():
+    """
+    >>> import sys
+    >>> g = yield_in_except_throw_exc_type()
+    >>> next(g)
+    >>> g.throw(TypeError)
+    Traceback (most recent call last):
+    TypeError
+    >>> next(g)
+    Traceback (most recent call last):
+    StopIteration
+    """
+    try:
+        raise ValueError
+    except ValueError:
+        yield
+
+def yield_in_except_throw_instance():
+    """
+    >>> import sys
+    >>> g = yield_in_except_throw_instance()
+    >>> next(g)
+    >>> g.throw(TypeError())
+    Traceback (most recent call last):
+    TypeError
+    >>> next(g)
+    Traceback (most recent call last):
+    StopIteration
+    """
+    try:
+        raise ValueError
+    except ValueError:
+        yield
+
 def test_swap_assignment():
     """
     >>> gen = test_swap_assignment()
index 5f32628b2c1930c40f825681796da023d400e040..270d7f33d0e11b18ef24c73e6d05c32b46398359 100644 (file)
@@ -1,30 +1,53 @@
+# mode: run
+# tag: condexpr
 # ticket: 267
 
-"""
->>> constants(4)
-1
->>> constants(5)
-10
->>> temps(4)
-1
->>> temps(5)
-10
->>> nested(1)
-1
->>> nested(2)
-2
->>> nested(3)
-3
-"""
+cimport cython
 
 def ident(x): return x
 
 def constants(x):
+    """
+    >>> constants(4)
+    1
+    >>> constants(5)
+    10
+    """
     a = 1 if x < 5 else 10
     return a
 
 def temps(x):
+    """
+    >>> temps(4)
+    1
+    >>> temps(5)
+    10
+    """
     return ident(1) if ident(x) < ident(5) else ident(10)
 
 def nested(x):
+    """
+    >>> nested(1)
+    1
+    >>> nested(2)
+    2
+    >>> nested(3)
+    3
+    """
     return 1 if x == 1 else (2 if x == 2 else 3)
+
+@cython.test_fail_if_path_exists('//CondExprNode')
+def const_true(a,b):
+    """
+    >>> const_true(1,2)
+    1
+    """
+    return a if 1 == 1 else b
+
+@cython.test_fail_if_path_exists('//CondExprNode')
+def const_false(a,b):
+    """
+    >>> const_false(1,2)
+    2
+    """
+    return a if 1 != 1 else b
index 3a6110f3c192706dc509666e41721a0e7e742fd9..24ad529da89464cfda17c906928ea9e744abd80e 100644 (file)
@@ -5,7 +5,7 @@ class TestCause(unittest.TestCase):
         try:
             raise IndexError from 5
         except TypeError as e:
-            self.assertIn("exception cause", str(e))
+            self.assertTrue("exception cause" in str(e))
         else:
             self.fail("No exception raised")
 
@@ -13,7 +13,7 @@ class TestCause(unittest.TestCase):
         try:
             raise IndexError from KeyError
         except IndexError as e:
-            self.assertIsInstance(e.__cause__, KeyError)
+            self.assertTrue(isinstance(e.__cause__, KeyError))
         else:
             self.fail("No exception raised")