Commit 9e0f30c1 authored by Stefan Behnel's avatar Stefan Behnel

- more versatile utility code setup: use a dedicated class to distinguish...

- 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
parent 497af27e
...@@ -4,6 +4,7 @@ from Cython.Compiler.Nodes import * ...@@ -4,6 +4,7 @@ from Cython.Compiler.Nodes import *
from Cython.Compiler.ExprNodes import * from Cython.Compiler.ExprNodes import *
from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler.Errors import CompileError from Cython.Compiler.Errors import CompileError
from Cython.Utils import UtilityCode
import Interpreter import Interpreter
import PyrexTypes import PyrexTypes
...@@ -431,7 +432,7 @@ def use_empty_bufstruct_code(env, max_ndim): ...@@ -431,7 +432,7 @@ def use_empty_bufstruct_code(env, max_ndim):
Py_ssize_t __Pyx_zeros[] = {%s}; Py_ssize_t __Pyx_zeros[] = {%s};
Py_ssize_t __Pyx_minusones[] = {%s}; Py_ssize_t __Pyx_minusones[] = {%s};
""") % (", ".join(["0"] * max_ndim), ", ".join(["-1"] * max_ndim)) """) % (", ".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): def buf_lookup_full_code(proto, defin, name, nd):
...@@ -656,9 +657,9 @@ def get_getbuffer_code(dtype, code): ...@@ -656,9 +657,9 @@ def get_getbuffer_code(dtype, code):
typestringchecker = get_typestringchecker(code, dtype) typestringchecker = get_typestringchecker(code, dtype)
dtype_name = str(dtype) dtype_name = str(dtype)
dtype_cname = dtype.declaration_code("") 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*/ 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) { static int %(name)s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
const char* ts; const char* ts;
if (obj == Py_None) { if (obj == Py_None) {
...@@ -697,7 +698,7 @@ def get_getbuffer_code(dtype, code): ...@@ -697,7 +698,7 @@ def get_getbuffer_code(dtype, code):
fail:; fail:;
__Pyx_ZeroBuffer(buf); __Pyx_ZeroBuffer(buf);
return -1; return -1;
}""") % locals()] }""") % locals())
code.globalstate.use_utility_code(utilcode, name) code.globalstate.use_utility_code(utilcode, name)
return name return name
...@@ -776,7 +777,8 @@ def use_py2_buffer_functions(env): ...@@ -776,7 +777,8 @@ def use_py2_buffer_functions(env):
#endif #endif
""") """)
env.use_utility_code([dedent("""\ env.use_utility_code(UtilityCode(
proto = dedent("""\
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
static void __Pyx_ReleaseBuffer(Py_buffer *view); static void __Pyx_ReleaseBuffer(Py_buffer *view);
...@@ -784,7 +786,7 @@ def use_py2_buffer_functions(env): ...@@ -784,7 +786,7 @@ def use_py2_buffer_functions(env):
#define __Pyx_GetBuffer PyObject_GetBuffer #define __Pyx_GetBuffer PyObject_GetBuffer
#define __Pyx_ReleaseBuffer PyBuffer_Release #define __Pyx_ReleaseBuffer PyBuffer_Release
#endif #endif
"""), code], codename) """), impl = code), codename)
# #
# Static utility code # Static utility code
...@@ -793,16 +795,17 @@ def use_py2_buffer_functions(env): ...@@ -793,16 +795,17 @@ def use_py2_buffer_functions(env):
# Utility function to set the right exception # Utility function to set the right exception
# The caller should immediately goto_error # The caller should immediately goto_error
raise_indexerror_code = [ raise_indexerror_code = UtilityCode(
"""\ proto = """\
static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/ static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
""","""\ """,
impl = """\
static void __Pyx_RaiseBufferIndexError(int axis) { static void __Pyx_RaiseBufferIndexError(int axis) {
PyErr_Format(PyExc_IndexError, PyErr_Format(PyExc_IndexError,
"Out of bounds on buffer access (axis %d)", axis); "Out of bounds on buffer access (axis %d)", axis);
} }
"""] """)
# #
# Buffer type checking. Utility code for checking that acquired # Buffer type checking. Utility code for checking that acquired
...@@ -810,13 +813,15 @@ static void __Pyx_RaiseBufferIndexError(int axis) { ...@@ -810,13 +813,15 @@ static void __Pyx_RaiseBufferIndexError(int axis) {
# the format string; the access mode/flags is checked by the # the format string; the access mode/flags is checked by the
# exporter. # exporter.
# #
acquire_utility_code = ["""\ acquire_utility_code = UtilityCode(
proto = """\
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/ static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/
static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/ static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/
static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/ static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/
static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/ static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/
""", """ """,
impl = """
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
if (info->buf == NULL) return; if (info->buf == NULL) return;
if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
...@@ -886,12 +891,14 @@ static const char* __Pyx_DescribeTokenInFormatString(const char* ts) { ...@@ -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*/ 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) { static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_count) {
int count; int count;
if (*ts < '0' || *ts > '9') { if (*ts < '0' || *ts > '9') {
...@@ -906,15 +913,16 @@ static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_c ...@@ -906,15 +913,16 @@ static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_c
*out_count = count; *out_count = count;
return ts; return ts;
} }
"""] """)
raise_buffer_fallback_code = [""" raise_buffer_fallback_code = UtilityCode(
proto = """
static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
""",""" """,
impl = """
static void __Pyx_RaiseBufferFallbackError(void) { static void __Pyx_RaiseBufferFallbackError(void) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!");
} }
"""] """)
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
from Symtab import BuiltinScope, StructOrUnionScope from Symtab import BuiltinScope, StructOrUnionScope
from Cython.Utils import UtilityCode
from TypeSlots import Signature from TypeSlots import Signature
import PyrexTypes import PyrexTypes
import __builtin__ import __builtin__
...@@ -134,9 +135,11 @@ builtin_structs_table = [ ...@@ -134,9 +135,11 @@ builtin_structs_table = [
]) ])
] ]
getattr3_utility_code = [""" getattr3_utility_code = UtilityCode(
proto = """
static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/ static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
PyObject *r = PyObject_GetAttr(o, n); PyObject *r = PyObject_GetAttr(o, n);
if (!r) { if (!r) {
...@@ -150,18 +153,24 @@ static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { ...@@ -150,18 +153,24 @@ static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
bad: bad:
return 0; return 0;
} }
"""] """)
intern_utility_code = [""" intern_utility_code = UtilityCode(
proto = """
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
# define __Pyx_InternFromString(s) PyUnicode_InternFromString(s) # define __Pyx_InternFromString(s) PyUnicode_InternFromString(s)
#else #else
# define __Pyx_InternFromString(s) PyString_InternFromString(s) # define __Pyx_InternFromString(s) PyString_InternFromString(s)
#endif #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 #if PY_VERSION_HEX < 0x02050000
#ifndef PyAnySet_CheckExact #ifndef PyAnySet_CheckExact
...@@ -250,8 +259,8 @@ static int py23sets_import(void) { return 0; } ...@@ -250,8 +259,8 @@ static int py23sets_import(void) { return 0; }
#endif /* !Py_SETOBJECT_H */ #endif /* !Py_SETOBJECT_H */
#endif /* < Py2.4 */ #endif /* < Py2.4 */
#endif /* < Py2.5 */ #endif /* < Py2.5 */
""",""" """,
"""] init = put_py23_set_init_utility_code)
builtin_utility_code = { builtin_utility_code = {
'getattr3' : getattr3_utility_code, 'getattr3' : getattr3_utility_code,
......
...@@ -334,7 +334,7 @@ class GlobalState(object): ...@@ -334,7 +334,7 @@ class GlobalState(object):
# Utility code state # 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. Adds the given utility code to the C file if needed.
...@@ -344,11 +344,13 @@ class GlobalState(object): ...@@ -344,11 +344,13 @@ class GlobalState(object):
If name is provided, it is used as an identifier to avoid inserting If name is provided, it is used as an identifier to avoid inserting
code twice. Otherwise, id(codetup) is used as such an identifier. 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): if self.check_utility_code_needed_and_register(name):
proto, _def = codetup if utility_code.proto:
self.utilprotowriter.put(proto) self.utilprotowriter.put(utility_code.proto)
self.utildefwriter.put(_def) 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): def has_code(self, name):
return name in self.used_utility_code return name in self.used_utility_code
......
...@@ -7,6 +7,7 @@ from string import join ...@@ -7,6 +7,7 @@ from string import join
from Errors import error, warning, InternalError from Errors import error, warning, InternalError
from Errors import hold_errors, release_errors, held_errors, report_error from Errors import hold_errors, release_errors, held_errors, report_error
from Cython.Utils import UtilityCode
import StringEncoding import StringEncoding
import Naming import Naming
from Nodes import Node from Nodes import Node
...@@ -4631,10 +4632,11 @@ class PersistentNode(ExprNode): ...@@ -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*/ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result; PyObject *result;
result = PyObject_GetAttr(dict, name); result = PyObject_GetAttr(dict, name);
...@@ -4642,14 +4644,15 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { ...@@ -4642,14 +4644,15 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyErr_SetObject(PyExc_NameError, name); PyErr_SetObject(PyExc_NameError, name);
return result; return result;
} }
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
import_utility_code = [ import_utility_code = UtilityCode(
""" proto = """
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) { static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
PyObject *__import__ = 0; PyObject *__import__ = 0;
PyObject *empty_list = 0; PyObject *empty_list = 0;
...@@ -4685,14 +4688,15 @@ bad: ...@@ -4685,14 +4688,15 @@ bad:
""" % { """ % {
"BUILTINS": Naming.builtins_cname, "BUILTINS": Naming.builtins_cname,
"GLOBALS": Naming.module_cname, "GLOBALS": Naming.module_cname,
}] })
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
get_exception_utility_code = [ get_exception_utility_code = UtilityCode(
""" proto = """
static PyObject *__Pyx_GetExcValue(void); /*proto*/ static PyObject *__Pyx_GetExcValue(void); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_GetExcValue(void) { static PyObject *__Pyx_GetExcValue(void) {
PyObject *type = 0, *value = 0, *tb = 0; PyObject *type = 0, *value = 0, *tb = 0;
PyObject *tmp_type, *tmp_value, *tmp_tb; PyObject *tmp_type, *tmp_value, *tmp_tb;
...@@ -4728,15 +4732,16 @@ bad: ...@@ -4728,15 +4732,16 @@ bad:
Py_XDECREF(tb); Py_XDECREF(tb);
return result; return result;
} }
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
unpacking_utility_code = [ unpacking_utility_code = UtilityCode(
""" proto = """
static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/ static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
static int __Pyx_EndUnpack(PyObject *); /*proto*/ static int __Pyx_EndUnpack(PyObject *); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) { static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
PyObject *item; PyObject *item;
if (!(item = PyIter_Next(iter))) { if (!(item = PyIter_Next(iter))) {
...@@ -4764,14 +4769,15 @@ static int __Pyx_EndUnpack(PyObject *iter) { ...@@ -4764,14 +4769,15 @@ static int __Pyx_EndUnpack(PyObject *iter) {
else else
return -1; return -1;
} }
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
type_test_utility_code = [ type_test_utility_code = UtilityCode(
""" proto = """
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
""",""" """,
impl = """
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (!type) { if (!type) {
PyErr_Format(PyExc_SystemError, "Missing type object"); PyErr_Format(PyExc_SystemError, "Missing type object");
...@@ -4783,14 +4789,15 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { ...@@ -4783,14 +4789,15 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
Py_TYPE(obj)->tp_name, type->tp_name); Py_TYPE(obj)->tp_name, type->tp_name);
return 0; 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*/ static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
""",""" """,
impl = """
static PyObject *__Pyx_CreateClass( static PyObject *__Pyx_CreateClass(
PyObject *bases, PyObject *dict, PyObject *name, char *modname) PyObject *bases, PyObject *dict, PyObject *name, char *modname)
{ {
...@@ -4815,12 +4822,12 @@ bad: ...@@ -4815,12 +4822,12 @@ bad:
Py_XDECREF(py_modname); Py_XDECREF(py_modname);
return result; return result;
} }
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
cpp_exception_utility_code = [ cpp_exception_utility_code = UtilityCode(
""" proto = """
#ifndef __Pyx_CppExn2PyErr #ifndef __Pyx_CppExn2PyErr
static void __Pyx_CppExn2PyErr() { static void __Pyx_CppExn2PyErr() {
try { try {
...@@ -4840,12 +4847,14 @@ static void __Pyx_CppExn2PyErr() { ...@@ -4840,12 +4847,14 @@ static void __Pyx_CppExn2PyErr() {
} }
} }
#endif #endif
""",""] """,
impl = ""
)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
append_utility_code = [ append_utility_code = UtilityCode(
""" proto = """
static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
if (likely(PyList_CheckExact(L))) { if (likely(PyList_CheckExact(L))) {
if (PyList_Append(L, x) < 0) return NULL; if (PyList_Append(L, x) < 0) return NULL;
...@@ -4856,16 +4865,17 @@ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { ...@@ -4856,16 +4865,17 @@ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
return PyObject_CallMethod(L, "append", "(O)", 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 # If the is_unsigned flag is set, we need to do some extra work to make
# sure the index doesn't become negative. # 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) { static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
PyObject *r; PyObject *r;
if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { 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 ...@@ -4888,13 +4898,13 @@ static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsig
return r; 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) { static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int is_unsigned) {
int r; int r;
if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { 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 ...@@ -4915,24 +4925,27 @@ static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int i
return r; return r;
} }
""", """,
""" impl = """
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
raise_noneattr_error_utility_code = [ raise_noneattr_error_utility_code = UtilityCode(
""" proto = """
static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname); static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname);
""", """ """,
impl = """
static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) { static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) {
PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", 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(); static INLINE void __Pyx_RaiseNoneIndexingError();
""", """ """,
impl = """
static INLINE void __Pyx_RaiseNoneIndexingError() { static INLINE void __Pyx_RaiseNoneIndexingError() {
PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable"); PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
} }
"""] """)
...@@ -22,7 +22,7 @@ import Version ...@@ -22,7 +22,7 @@ import Version
from Errors import error, warning from Errors import error, warning
from PyrexTypes import py_object_type 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 from StringEncoding import escape_byte_string, EncodedString
...@@ -182,15 +182,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -182,15 +182,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code.putln("static %s;" % type.declaration_code(entry.cname)) h_code.putln("static %s;" % type.declaration_code(entry.cname))
h_code.putln("") h_code.putln("")
h_code.put_h_guard(Naming.api_func_guard + "import_module") 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("")
h_code.putln("#endif") h_code.putln("#endif")
if api_funcs: if api_funcs:
h_code.putln("") h_code.putln("")
h_code.put(function_import_utility_code[1]) h_code.put(function_import_utility_code.impl)
if public_extension_types: if public_extension_types:
h_code.putln("") 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("")
h_code.putln("static int import_%s(void) {" % name) h_code.putln("static int import_%s(void) {" % name)
h_code.putln("PyObject *module = 0;") h_code.putln("PyObject *module = 0;")
...@@ -457,7 +457,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -457,7 +457,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("") code.putln("")
code.putln("#endif") 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("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define Py_TPFLAGS_CHECKTYPES 0") code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
...@@ -1567,10 +1567,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1567,10 +1567,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Initialize various global constants etc. ---*/") code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos)) 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 ---*/") code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code) self.generate_module_creation_code(env, code)
...@@ -1955,20 +1951,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -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 #if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else #else
#define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif #endif
"""] """)
import_module_utility_code = [ import_module_utility_code = UtilityCode(
""" proto = """
static PyObject *__Pyx_ImportModule(const char *name); /*proto*/ static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
""",""" """,
impl = """
#ifndef __PYX_HAVE_RT_ImportModule #ifndef __PYX_HAVE_RT_ImportModule
#define __PYX_HAVE_RT_ImportModule #define __PYX_HAVE_RT_ImportModule
static PyObject *__Pyx_ImportModule(const char *name) { static PyObject *__Pyx_ImportModule(const char *name) {
...@@ -1990,14 +1986,15 @@ bad: ...@@ -1990,14 +1986,15 @@ bad:
return 0; return 0;
} }
#endif #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*/ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
""",""" """,
impl = """
#ifndef __PYX_HAVE_RT_ImportType #ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
...@@ -2043,14 +2040,15 @@ bad: ...@@ -2043,14 +2040,15 @@ bad:
return 0; return 0;
} }
#endif #endif
"""] """)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
function_export_utility_code = [ function_export_utility_code = UtilityCode(
""" proto = """
static int __Pyx_ExportFunction(char *name, void *f, char *sig); /*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) { static int __Pyx_ExportFunction(char *name, void *f, char *sig) {
PyObject *d = 0; PyObject *d = 0;
PyObject *p = 0; PyObject *p = 0;
...@@ -2076,14 +2074,16 @@ bad: ...@@ -2076,14 +2074,16 @@ bad:
Py_XDECREF(d); Py_XDECREF(d);
return -1; 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*/ static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
""",""" """,
impl = """
#ifndef __PYX_HAVE_RT_ImportFunction #ifndef __PYX_HAVE_RT_ImportFunction
#define __PYX_HAVE_RT_ImportFunction #define __PYX_HAVE_RT_ImportFunction
static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) { static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
...@@ -2118,14 +2118,16 @@ bad: ...@@ -2118,14 +2118,16 @@ bad:
return -1; return -1;
} }
#endif #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 int __Pyx_RegisterCleanup(void); /*proto*/
static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/ static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0}; static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
""",""" """,
impl = """
static int __Pyx_RegisterCleanup(void) { static int __Pyx_RegisterCleanup(void) {
/* Don't use Py_AtExit because that has a 32-call limit /* Don't use Py_AtExit because that has a 32-call limit
* and is called after python finalization. * and is called after python finalization.
...@@ -2163,7 +2165,7 @@ bad: ...@@ -2163,7 +2165,7 @@ bad:
Py_XDECREF(res); Py_XDECREF(res);
return ret; return ret;
} }
"""] """)
import_star_utility_code = """ import_star_utility_code = """
......
This diff is collapsed.
...@@ -88,3 +88,20 @@ def long_literal(value): ...@@ -88,3 +88,20 @@ def long_literal(value):
else: else:
value = int(value) value = int(value)
return not -2**31 <= value < 2**31 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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment