From: Stefan Behnel Date: Fri, 29 Apr 2011 20:33:58 +0000 (+0200) Subject: merged in Vitja's tab removals X-Git-Url: http://git.tremily.us/?p=cython.git;a=commitdiff_plain;h=87a227a16dc5453f8ff1ac6c8f1d9f05d4846420;hp=097ca9cb6210e6e82c2fcff4a2f525b7565b506a merged in Vitja's tab removals --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index a0b0b225..27f0ccb9 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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 diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 53824cf2..804824d4 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -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 diff --git a/runtests.py b/runtests.py index e9d09f15..d565aed1 100644 --- a/runtests.py +++ b/runtests.py @@ -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") diff --git a/setup.py b/setup.py index cb4f996d..782dea25 100644 --- 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) diff --git a/tests/bugs.txt b/tests/bugs.txt index c586868e..5eca55f0 100644 --- a/tests/bugs.txt +++ b/tests/bugs.txt @@ -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 diff --git a/tests/errors/w_cdef_override.pyx b/tests/errors/w_cdef_override.pyx index e3e51569..c3da55fa 100644 --- a/tests/errors/w_cdef_override.pyx +++ b/tests/errors/w_cdef_override.pyx @@ -1,5 +1,5 @@ # mode: error -# tags: werror +# tag: werror cdef foo(): pass diff --git a/tests/run/generators_py.py b/tests/run/generators_py.py index 57a11d0a..b43962cd 100644 --- a/tests/run/generators_py.py +++ b/tests/run/generators_py.py @@ -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() diff --git a/tests/run/ifelseexpr_T267.pyx b/tests/run/ifelseexpr_T267.pyx index 5f32628b..270d7f33 100644 --- a/tests/run/ifelseexpr_T267.pyx +++ b/tests/run/ifelseexpr_T267.pyx @@ -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 diff --git a/tests/run/test_raisefrom.pyx b/tests/run/test_raisefrom.pyx index 3a6110f3..24ad529d 100644 --- a/tests/run/test_raisefrom.pyx +++ b/tests/run/test_raisefrom.pyx @@ -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")