From: Stefan Behnel Date: Fri, 13 Aug 2010 12:19:09 +0000 (+0200) Subject: unpack exception test tuples in 'except' clauses, results in shorter, faster and... X-Git-Tag: 0.13~22 X-Git-Url: http://git.tremily.us/?p=cython.git;a=commitdiff_plain;h=93af9e10a5b55599442df39f5333933c36053ca2 unpack exception test tuples in 'except' clauses, results in shorter, faster and more readable code --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 05ce3c96..1672f0a4 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -4702,7 +4702,7 @@ class TryExceptStatNode(StatNode): class ExceptClauseNode(Node): # Part of try ... except statement. # - # pattern ExprNode + # pattern [ExprNode] # target ExprNode or None # body StatNode # excinfo_target NameNode or None optional target for exception info @@ -4732,8 +4732,10 @@ class ExceptClauseNode(Node): genv = env.global_scope() self.function_name = env.qualified_name if self.pattern: - self.pattern.analyse_expressions(env) - self.pattern = self.pattern.coerce_to_pyobject(env) + # normalise/unpack self.pattern into a list + for i, pattern in enumerate(self.pattern): + pattern.analyse_expressions(env) + self.pattern[i] = pattern.coerce_to_pyobject(env) if self.target: self.exc_value = ExprNodes.ExcValueNode(self.pos, env) @@ -4750,15 +4752,17 @@ class ExceptClauseNode(Node): def generate_handling_code(self, code, end_label): code.mark_pos(self.pos) if self.pattern: - self.pattern.generate_evaluation_code(code) - + exc_tests = [] + for pattern in self.pattern: + pattern.generate_evaluation_code(code) + exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result()) + match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False) code.putln( - "%s = PyErr_ExceptionMatches(%s);" % ( - match_flag, - self.pattern.py_result())) - self.pattern.generate_disposal_code(code) - self.pattern.free_temps(code) + "%s = %s;" % (match_flag, ' || '.join(exc_tests))) + for pattern in self.pattern: + pattern.generate_disposal_code(code) + pattern.free_temps(code) code.putln( "if (%s) {" % match_flag) @@ -4837,7 +4841,8 @@ class ExceptClauseNode(Node): def annotate(self, code): if self.pattern: - self.pattern.annotate(code) + for pattern in self.pattern: + pattern.annotate(code) if self.target: self.target.annotate(code) self.body.annotate(code) diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 0596c93d..6a040a54 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1426,6 +1426,11 @@ def p_except_clause(s): exc_value = None if s.sy != ':': exc_type = p_test(s) + # normalise into list of single exception tests + if isinstance(exc_type, ExprNodes.TupleNode): + exc_type = exc_type.args + else: + exc_type = [exc_type] if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as'): s.next() exc_value = p_test(s)