From 9e0f30c112de2bfe9f5e400f8f269bbb76b3a028 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 25 Oct 2008 14:34:28 +0200 Subject: [PATCH] - more versatile utility code setup: use a dedicated class to distinguish proto/impl/init/cleanup code - fix set initialisation by making it use the new setup --- Cython/Compiler/Buffer.py | 48 ++++++----- Cython/Compiler/Builtin.py | 27 ++++-- Cython/Compiler/Code.py | 12 +-- Cython/Compiler/ExprNodes.py | 107 ++++++++++++----------- Cython/Compiler/ModuleNode.py | 68 +++++++-------- Cython/Compiler/Nodes.py | 155 +++++++++++++++++++--------------- Cython/Utils.py | 17 ++++ 7 files changed, 251 insertions(+), 183 deletions(-) diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py index e8f092e0..8283cfe1 100644 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@ -4,6 +4,7 @@ from Cython.Compiler.Nodes import * from Cython.Compiler.ExprNodes import * from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.Errors import CompileError +from Cython.Utils import UtilityCode import Interpreter import PyrexTypes @@ -431,7 +432,7 @@ def use_empty_bufstruct_code(env, max_ndim): Py_ssize_t __Pyx_zeros[] = {%s}; Py_ssize_t __Pyx_minusones[] = {%s}; """) % (", ".join(["0"] * max_ndim), ", ".join(["-1"] * max_ndim)) - env.use_utility_code([code, ""], "empty_bufstruct_code") + env.use_utility_code(UtilityCode(proto=code), "empty_bufstruct_code") def buf_lookup_full_code(proto, defin, name, nd): @@ -656,9 +657,9 @@ def get_getbuffer_code(dtype, code): typestringchecker = get_typestringchecker(code, dtype) dtype_name = str(dtype) dtype_cname = dtype.declaration_code("") - utilcode = [dedent(""" + utilcode = UtilityCode(proto = dedent(""" static int %s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/ - """) % name, dedent(""" + """) % name, impl = dedent(""" static int %(name)s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) { const char* ts; if (obj == Py_None) { @@ -697,7 +698,7 @@ def get_getbuffer_code(dtype, code): fail:; __Pyx_ZeroBuffer(buf); return -1; - }""") % locals()] + }""") % locals()) code.globalstate.use_utility_code(utilcode, name) return name @@ -776,7 +777,8 @@ def use_py2_buffer_functions(env): #endif """) - env.use_utility_code([dedent("""\ + env.use_utility_code(UtilityCode( + proto = dedent("""\ #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); static void __Pyx_ReleaseBuffer(Py_buffer *view); @@ -784,7 +786,7 @@ def use_py2_buffer_functions(env): #define __Pyx_GetBuffer PyObject_GetBuffer #define __Pyx_ReleaseBuffer PyBuffer_Release #endif - """), code], codename) + """), impl = code), codename) # # Static utility code @@ -793,16 +795,17 @@ def use_py2_buffer_functions(env): # Utility function to set the right exception # The caller should immediately goto_error -raise_indexerror_code = [ -"""\ +raise_indexerror_code = UtilityCode( +proto = """\ static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/ -""","""\ +""", +impl = """\ static void __Pyx_RaiseBufferIndexError(int axis) { PyErr_Format(PyExc_IndexError, "Out of bounds on buffer access (axis %d)", axis); } -"""] +""") # # Buffer type checking. Utility code for checking that acquired @@ -810,13 +813,15 @@ static void __Pyx_RaiseBufferIndexError(int axis) { # the format string; the access mode/flags is checked by the # exporter. # -acquire_utility_code = ["""\ +acquire_utility_code = UtilityCode( +proto = """\ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/ static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/ static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/ static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/ -""", """ +""", +impl = """ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { if (info->buf == NULL) return; if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; @@ -886,12 +891,14 @@ static const char* __Pyx_DescribeTokenInFormatString(const char* ts) { } } -"""] +""") -parse_typestring_repeat_code = [""" +parse_typestring_repeat_code = UtilityCode( +proto = """ static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_count); /*proto*/ -""",""" +""", +impl = """ static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_count) { int count; if (*ts < '0' || *ts > '9') { @@ -906,15 +913,16 @@ static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_c *out_count = count; return ts; } -"""] +""") -raise_buffer_fallback_code = [""" +raise_buffer_fallback_code = UtilityCode( +proto = """ static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ -""",""" +""", +impl = """ static void __Pyx_RaiseBufferFallbackError(void) { PyErr_Format(PyExc_ValueError, "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); } -"""] - +""") diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index 02b9f0a2..2cf37373 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -3,6 +3,7 @@ # from Symtab import BuiltinScope, StructOrUnionScope +from Cython.Utils import UtilityCode from TypeSlots import Signature import PyrexTypes import __builtin__ @@ -134,9 +135,11 @@ builtin_structs_table = [ ]) ] -getattr3_utility_code = [""" +getattr3_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { PyObject *r = PyObject_GetAttr(o, n); if (!r) { @@ -150,18 +153,24 @@ static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { bad: return 0; } -"""] +""") -intern_utility_code = [""" +intern_utility_code = UtilityCode( +proto = """ #if PY_MAJOR_VERSION >= 3 # define __Pyx_InternFromString(s) PyUnicode_InternFromString(s) #else # define __Pyx_InternFromString(s) PyString_InternFromString(s) #endif -""",""" -"""] +""") -py23_set_utility_code = [""" +def put_py23_set_init_utility_code(code, pos): + code.putln("#if PY_VERSION_HEX < 0x02040000") + code.putln(code.error_goto_if_neg("__Pyx_Py23SetsImport()", pos)) + code.putln("#endif") + +py23_set_utility_code = UtilityCode( +proto = """ #if PY_VERSION_HEX < 0x02050000 #ifndef PyAnySet_CheckExact @@ -250,8 +259,8 @@ static int py23sets_import(void) { return 0; } #endif /* !Py_SETOBJECT_H */ #endif /* < Py2.4 */ #endif /* < Py2.5 */ -""",""" -"""] +""", +init = put_py23_set_init_utility_code) builtin_utility_code = { 'getattr3' : getattr3_utility_code, diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index b88f43b9..9adcdb9b 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -334,7 +334,7 @@ class GlobalState(object): # Utility code state # - def use_utility_code(self, codetup, name=None): + def use_utility_code(self, utility_code, name=None): """ Adds the given utility code to the C file if needed. @@ -344,11 +344,13 @@ class GlobalState(object): If name is provided, it is used as an identifier to avoid inserting code twice. Otherwise, id(codetup) is used as such an identifier. """ - if name is None: name = id(codetup) + if name is None: name = id(utility_code) if self.check_utility_code_needed_and_register(name): - proto, _def = codetup - self.utilprotowriter.put(proto) - self.utildefwriter.put(_def) + if utility_code.proto: + self.utilprotowriter.put(utility_code.proto) + if utility_code.impl: + self.utildefwriter.put(utility_code.impl) + utility_code.write_init_code(self.initwriter, self.module_pos) def has_code(self, name): return name in self.used_utility_code diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 02b9c55b..8bf34fa4 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -7,6 +7,7 @@ from string import join from Errors import error, warning, InternalError from Errors import hold_errors, release_errors, held_errors, report_error +from Cython.Utils import UtilityCode import StringEncoding import Naming from Nodes import Node @@ -4631,10 +4632,11 @@ class PersistentNode(ExprNode): # #------------------------------------------------------------------------------------ -get_name_interned_utility_code = [ -""" +get_name_interned_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { PyObject *result; result = PyObject_GetAttr(dict, name); @@ -4642,14 +4644,15 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { PyErr_SetObject(PyExc_NameError, name); return result; } -"""] +""") #------------------------------------------------------------------------------------ -import_utility_code = [ -""" +import_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) { PyObject *__import__ = 0; PyObject *empty_list = 0; @@ -4685,14 +4688,15 @@ bad: """ % { "BUILTINS": Naming.builtins_cname, "GLOBALS": Naming.module_cname, -}] +}) #------------------------------------------------------------------------------------ -get_exception_utility_code = [ -""" +get_exception_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_GetExcValue(void); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_GetExcValue(void) { PyObject *type = 0, *value = 0, *tb = 0; PyObject *tmp_type, *tmp_value, *tmp_tb; @@ -4728,15 +4732,16 @@ bad: Py_XDECREF(tb); return result; } -"""] +""") #------------------------------------------------------------------------------------ -unpacking_utility_code = [ -""" +unpacking_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/ static int __Pyx_EndUnpack(PyObject *); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) { PyObject *item; if (!(item = PyIter_Next(iter))) { @@ -4764,14 +4769,15 @@ static int __Pyx_EndUnpack(PyObject *iter) { else return -1; } -"""] +""") #------------------------------------------------------------------------------------ -type_test_utility_code = [ -""" +type_test_utility_code = UtilityCode( +proto = """ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { if (!type) { PyErr_Format(PyExc_SystemError, "Missing type object"); @@ -4783,14 +4789,15 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { Py_TYPE(obj)->tp_name, type->tp_name); return 0; } -"""] +""") #------------------------------------------------------------------------------------ -create_class_utility_code = [ -""" +create_class_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/ -""",""" +""", +impl = """ static PyObject *__Pyx_CreateClass( PyObject *bases, PyObject *dict, PyObject *name, char *modname) { @@ -4815,12 +4822,12 @@ bad: Py_XDECREF(py_modname); return result; } -"""] +""") #------------------------------------------------------------------------------------ -cpp_exception_utility_code = [ -""" +cpp_exception_utility_code = UtilityCode( +proto = """ #ifndef __Pyx_CppExn2PyErr static void __Pyx_CppExn2PyErr() { try { @@ -4840,12 +4847,14 @@ static void __Pyx_CppExn2PyErr() { } } #endif -""",""] +""", +impl = "" +) #------------------------------------------------------------------------------------ -append_utility_code = [ -""" +append_utility_code = UtilityCode( +proto = """ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { if (likely(PyList_CheckExact(L))) { if (PyList_Append(L, x) < 0) return NULL; @@ -4856,16 +4865,17 @@ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { return PyObject_CallMethod(L, "append", "(O)", x); } } -""","" -] +""", +impl = "" +) #------------------------------------------------------------------------------------ # If the is_unsigned flag is set, we need to do some extra work to make # sure the index doesn't become negative. -getitem_int_utility_code = [ -""" +getitem_int_utility_code = UtilityCode( +proto = """ static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { PyObject *r; if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { @@ -4888,13 +4898,13 @@ static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsig return r; } """, -""" -"""] +impl = """ +""") #------------------------------------------------------------------------------------ -setitem_int_utility_code = [ -""" +setitem_int_utility_code = UtilityCode( +proto = """ static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int is_unsigned) { int r; if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { @@ -4915,24 +4925,27 @@ static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int i return r; } """, -""" -"""] +impl = """ +""") + #------------------------------------------------------------------------------------ -raise_noneattr_error_utility_code = [ -""" +raise_noneattr_error_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname); -""", """ +""", +impl = """ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname); } -"""] +""") -raise_noneindex_error_utility_code = [ -""" +raise_noneindex_error_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_RaiseNoneIndexingError(); -""", """ +""", +impl = """ static INLINE void __Pyx_RaiseNoneIndexingError() { PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable"); } -"""] +""") diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index f094fab1..e6de94e9 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -22,7 +22,7 @@ import Version from Errors import error, warning from PyrexTypes import py_object_type -from Cython.Utils import open_new_file, replace_suffix +from Cython.Utils import open_new_file, replace_suffix, UtilityCode from StringEncoding import escape_byte_string, EncodedString @@ -182,15 +182,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code.putln("static %s;" % type.declaration_code(entry.cname)) h_code.putln("") h_code.put_h_guard(Naming.api_func_guard + "import_module") - h_code.put(import_module_utility_code[1]) + h_code.put(import_module_utility_code.impl) h_code.putln("") h_code.putln("#endif") if api_funcs: h_code.putln("") - h_code.put(function_import_utility_code[1]) + h_code.put(function_import_utility_code.impl) if public_extension_types: h_code.putln("") - h_code.put(type_import_utility_code[1]) + h_code.put(type_import_utility_code.impl) h_code.putln("") h_code.putln("static int import_%s(void) {" % name) h_code.putln("PyObject *module = 0;") @@ -457,7 +457,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("") code.putln("#endif") - code.put(builtin_module_name_utility_code[0]) + code.put(builtin_module_name_utility_code.proto) code.putln("#if PY_MAJOR_VERSION >= 3") code.putln(" #define Py_TPFLAGS_CHECKTYPES 0") @@ -1567,10 +1567,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("/*--- Initialize various global constants etc. ---*/") code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos)) - code.putln("#if PY_VERSION_HEX < 0x02040000") - code.putln(code.error_goto_if_neg("__Pyx_Py23SetsImport()", self.pos)) - code.putln("#endif") - code.putln("/*--- Module creation code ---*/") self.generate_module_creation_code(env, code) @@ -1955,20 +1951,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): # #------------------------------------------------------------------------------------ -builtin_module_name_utility_code = [ -"""\ +builtin_module_name_utility_code = UtilityCode( +proto = """\ #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #endif -"""] - +""") -import_module_utility_code = [ -""" +import_module_utility_code = UtilityCode( +proto = """ static PyObject *__Pyx_ImportModule(const char *name); /*proto*/ -""",""" +""", +impl = """ #ifndef __PYX_HAVE_RT_ImportModule #define __PYX_HAVE_RT_ImportModule static PyObject *__Pyx_ImportModule(const char *name) { @@ -1990,14 +1986,15 @@ bad: return 0; } #endif -"""] +""") #------------------------------------------------------------------------------------ -type_import_utility_code = [ -""" +type_import_utility_code = UtilityCode( +proto = """ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/ -""",""" +""", +impl = """ #ifndef __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, @@ -2043,14 +2040,15 @@ bad: return 0; } #endif -"""] +""") #------------------------------------------------------------------------------------ -function_export_utility_code = [ -""" +function_export_utility_code = UtilityCode( +proto = """ static int __Pyx_ExportFunction(char *name, void *f, char *sig); /*proto*/ -""",r""" +""", +impl = r""" static int __Pyx_ExportFunction(char *name, void *f, char *sig) { PyObject *d = 0; PyObject *p = 0; @@ -2076,14 +2074,16 @@ bad: Py_XDECREF(d); return -1; } -""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}] +""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name} +) #------------------------------------------------------------------------------------ -function_import_utility_code = [ -""" +function_import_utility_code = UtilityCode( +proto = """ static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/ -""",""" +""", +impl = """ #ifndef __PYX_HAVE_RT_ImportFunction #define __PYX_HAVE_RT_ImportFunction static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) { @@ -2118,14 +2118,16 @@ bad: return -1; } #endif -""" % dict(API = Naming.api_name)] +""" % dict(API = Naming.api_name) +) -register_cleanup_utility_code = [ -""" +register_cleanup_utility_code = UtilityCode( +proto = """ static int __Pyx_RegisterCleanup(void); /*proto*/ static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/ static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0}; -""",""" +""", +impl = """ static int __Pyx_RegisterCleanup(void) { /* Don't use Py_AtExit because that has a 32-call limit * and is called after python finalization. @@ -2163,7 +2165,7 @@ bad: Py_XDECREF(res); return ret; } -"""] +""") import_star_utility_code = """ diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 1083548e..f9e96f33 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -12,7 +12,7 @@ import TypeSlots from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \ StructOrUnionScope, PyClassScope, CClassScope -from Cython.Utils import open_new_file, replace_suffix +from Cython.Utils import open_new_file, replace_suffix, UtilityCode from StringEncoding import EncodedString, escape_byte_string, split_docstring import Options import ControlFlow @@ -4465,14 +4465,15 @@ else: #------------------------------------------------------------------------------------ -printing_utility_code = [ -""" +printing_utility_code = UtilityCode( +proto = """ static int __Pyx_Print(PyObject *, int); /*proto*/ #if PY_MAJOR_VERSION >= 3 static PyObject* %s = 0; static PyObject* %s = 0; #endif -""" % (Naming.print_function, Naming.print_function_kwargs), r""" +""" % (Naming.print_function, Naming.print_function_kwargs), +impl = r""" #if PY_MAJOR_VERSION < 3 static PyObject *__Pyx_GetStdout(void) { PyObject *f = PySys_GetObject("stdout"); @@ -4550,16 +4551,17 @@ static int __Pyx_Print(PyObject *arg_tuple, int newline) { """ % {'BUILTINS' : Naming.builtins_cname, 'PRINT_FUNCTION' : Naming.print_function, 'PRINT_KWARGS' : Naming.print_function_kwargs} -] +) #------------------------------------------------------------------------------------ # The following function is based on do_raise() from ceval.c. -raise_utility_code = [ -""" +raise_utility_code = UtilityCode( +proto = """ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ -""",""" +""", +impl = """ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { Py_XINCREF(type); Py_XINCREF(value); @@ -4623,14 +4625,15 @@ raise_error: Py_XDECREF(tb); return; } -"""] +""") #------------------------------------------------------------------------------------ -reraise_utility_code = [ -""" +reraise_utility_code = UtilityCode( +proto = """ static void __Pyx_ReRaise(void); /*proto*/ -""",""" +""", +impl = """ static void __Pyx_ReRaise(void) { PyThreadState *tstate = PyThreadState_Get(); PyObject *type = tstate->exc_type; @@ -4641,15 +4644,16 @@ static void __Pyx_ReRaise(void) { Py_XINCREF(tb); __Pyx_ErrRestore(type, value, tb); } -"""] +""") #------------------------------------------------------------------------------------ -arg_type_test_utility_code = [ -""" +arg_type_test_utility_code = UtilityCode( +proto = """ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact) { @@ -4669,7 +4673,7 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed name, type->tp_name, Py_TYPE(obj)->tp_name); return 0; } -"""] +""") #------------------------------------------------------------------------------------ # @@ -4677,11 +4681,12 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed # many or too few positional arguments were found. This handles # Py_ssize_t formatting correctly. -raise_argtuple_invalid_utility_code = [ -""" +raise_argtuple_invalid_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/ -""",""" +""", +impl = """ static INLINE void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, @@ -4711,12 +4716,13 @@ static INLINE void __Pyx_RaiseArgtupleInvalid( #endif func_name, more_or_less, num_expected, number, num_found); } -"""] +""") -raise_keyword_required_utility_code = [ -""" +raise_keyword_required_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/ -""",""" +""", +impl = """ static INLINE void __Pyx_RaiseKeywordRequired( const char* func_name, PyObject* kw_name) @@ -4729,13 +4735,14 @@ static INLINE void __Pyx_RaiseKeywordRequired( PyString_AS_STRING(kw_name)); #endif } -"""] +""") -raise_double_keywords_utility_code = [ -""" +raise_double_keywords_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name); /*proto*/ -""",""" +""", +impl = """ static INLINE void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) @@ -4748,7 +4755,7 @@ static INLINE void __Pyx_RaiseDoubleKeywordsError( PyString_AS_STRING(kw_name)); #endif } -"""] +""") #------------------------------------------------------------------------------------ # @@ -4756,11 +4763,12 @@ static INLINE void __Pyx_RaiseDoubleKeywordsError( # were passed to a function, or if any keywords were passed to a # function that does not accept them. -keyword_string_check_utility_code = [ -""" +keyword_string_check_utility_code = UtilityCode( +proto = """ static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/ -""",""" +""", +impl = """ static INLINE int __Pyx_CheckKeywordStrings( PyObject *kwdict, const char* function_name, @@ -4794,7 +4802,7 @@ invalid_keyword: #endif return 0; } -"""] +""") #------------------------------------------------------------------------------------ # @@ -4812,11 +4820,12 @@ invalid_keyword: # This method does not check for required keyword arguments. # -split_keywords_utility_code = [ -""" +split_keywords_utility_code = UtilityCode( +proto = """ static int __Pyx_SplitKeywords(PyObject *kwds, PyObject **argnames[], \ PyObject *kwds2, Py_ssize_t num_pos_args, const char* function_name); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_SplitKeywords( PyObject *kwds, PyObject **argnames[], @@ -4881,14 +4890,15 @@ invalid_keyword: bad: return -1; } -"""] +""") #------------------------------------------------------------------------------------ -unraisable_exception_utility_code = [ -""" +unraisable_exception_utility_code = UtilityCode( +proto = """ static void __Pyx_WriteUnraisable(const char *name); /*proto*/ -""",""" +""", +impl = """ static void __Pyx_WriteUnraisable(const char *name) { PyObject *old_exc, *old_val, *old_tb; PyObject *ctx; @@ -4906,14 +4916,15 @@ static void __Pyx_WriteUnraisable(const char *name) { Py_DECREF(ctx); } } -"""] +""") #------------------------------------------------------------------------------------ -traceback_utility_code = [ -""" +traceback_utility_code = UtilityCode( +proto = """ static void __Pyx_AddTraceback(const char *funcname); /*proto*/ -""",""" +""", +impl = """ #include "compile.h" #include "frameobject.h" #include "traceback.h" @@ -4998,13 +5009,14 @@ bad: 'CLINENO': Naming.clineno_cname, 'GLOBALS': Naming.module_cname, 'EMPTY_TUPLE' : Naming.empty_tuple, -}] +}) -restore_exception_utility_code = [ -""" +restore_exception_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ -""",""" +""", +impl = """ static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); @@ -5031,14 +5043,15 @@ static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject ** tstate->curexc_traceback = 0; } -"""] +""") #------------------------------------------------------------------------------------ -set_vtable_utility_code = [ -""" +set_vtable_utility_code = UtilityCode( +proto = """ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_SetVtable(PyObject *dict, void *vtable) { PyObject *pycobj = 0; int result; @@ -5057,14 +5070,15 @@ done: Py_XDECREF(pycobj); return result; } -"""] +""") #------------------------------------------------------------------------------------ -get_vtable_utility_code = [ -""" +get_vtable_utility_code = UtilityCode( +proto = """ static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/ -""",r""" +""", +impl = r""" static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) { int result; PyObject *pycobj; @@ -5084,14 +5098,15 @@ done: Py_XDECREF(pycobj); return result; } -"""] +""") #------------------------------------------------------------------------------------ -init_string_tab_utility_code = [ -""" +init_string_tab_utility_code = UtilityCode( +proto = """ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 @@ -5117,14 +5132,15 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { } return 0; } -"""] +""") #------------------------------------------------------------------------------------ -get_exception_utility_code = [ -""" +get_exception_utility_code = UtilityCode( +proto = """ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ -""",""" +""", +impl = """ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); @@ -5154,15 +5170,16 @@ bad: return -1; } -"""] +""") #------------------------------------------------------------------------------------ -reset_exception_utility_code = [ -""" +reset_exception_utility_code = UtilityCode( +proto = """ static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ -""",""" +""", +impl = """ static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) { PyThreadState *tstate = PyThreadState_GET(); *type = tstate->exc_type; @@ -5186,6 +5203,6 @@ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); } -"""] +""") #------------------------------------------------------------------------------------ diff --git a/Cython/Utils.py b/Cython/Utils.py index c1027681..7d3e0896 100644 --- a/Cython/Utils.py +++ b/Cython/Utils.py @@ -88,3 +88,20 @@ def long_literal(value): else: value = int(value) return not -2**31 <= value < 2**31 + +# a simple class that simplifies the usage of utility code + +class UtilityCode(object): + def __init__(self, proto=None, impl=None, init=None, cleanup=None): + self.proto = proto + self.impl = impl + self.init = init + self.cleanup = cleanup + + def write_init_code(self, writer, pos): + if not self.init: + return + if callable(self.init): + self.init(writer, pos) + else: + writer.put(self.init) -- 2.26.2