From 925eb5f863a26508681c845f3542030e982a0910 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Wed, 19 Jan 2011 16:14:32 +0100 Subject: [PATCH] implement ticket #650: substitute PyErr_NoMemory() for 'raise MemoryError()' --- Cython/Compiler/Nodes.py | 17 ++++++++++++++++- tests/run/raise_memory_error_T650.pyx | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/run/raise_memory_error_T650.pyx diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index af94c788..9ecbf1a6 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -3935,12 +3935,26 @@ class RaiseStatNode(StatNode): if self.exc_tb: self.exc_tb.analyse_types(env) self.exc_tb = self.exc_tb.coerce_to_pyobject(env) - env.use_utility_code(raise_utility_code) + # special cases for builtin exceptions + self.builtin_exc_name = None + if self.exc_type and not self.exc_value and not self.exc_tb: + exc = self.exc_type + import ExprNodes + if isinstance(exc, ExprNodes.SimpleCallNode) and not exc.args: + exc = exc.function # extract the exception type + if exc.is_name and exc.entry.is_builtin: + self.builtin_exc_name = exc.name + if self.builtin_exc_name == 'MemoryError': + self.exc_type = None # has a separate implementation nogil_check = Node.gil_error gil_message = "Raising exception" def generate_execution_code(self, code): + if self.builtin_exc_name == 'MemoryError': + code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos)) + return + if self.exc_type: self.exc_type.generate_evaluation_code(code) type_code = self.exc_type.py_result() @@ -3956,6 +3970,7 @@ class RaiseStatNode(StatNode): tb_code = self.exc_tb.py_result() else: tb_code = "0" + code.globalstate.use_utility_code(raise_utility_code) code.putln( "__Pyx_Raise(%s, %s, %s);" % ( type_code, diff --git a/tests/run/raise_memory_error_T650.pyx b/tests/run/raise_memory_error_T650.pyx new file mode 100644 index 00000000..da149488 --- /dev/null +++ b/tests/run/raise_memory_error_T650.pyx @@ -0,0 +1,24 @@ + +cimport cython + +@cython.test_assert_path_exists( + '//RaiseStatNode', + '//RaiseStatNode[@builtin_exc_name = "MemoryError"]') +def raise_me_type(): + """ + >>> try: raise_me_type() + ... except MemoryError: pass + ... else: print('NOT RAISED!') + """ + raise MemoryError + +@cython.test_assert_path_exists( + '//RaiseStatNode', + '//RaiseStatNode[@builtin_exc_name = "MemoryError"]') +def raise_me_instance(): + """ + >>> try: raise_me_instance() + ... except MemoryError: pass + ... else: print('NOT RAISED!') + """ + raise MemoryError() -- 2.26.2