Commit c786d3c0 authored by Stefan Behnel's avatar Stefan Behnel

original Py3 code generation patch by Lisandro Dalcin

parent 75e2cc0d
......@@ -4066,7 +4066,7 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (obj == Py_None || PyObject_TypeCheck(obj, type))
return 1;
PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
obj->ob_type->tp_name, type->tp_name);
Py_TYPE(obj)->tp_name, type->tp_name);
return 0;
}
"""]
......@@ -4088,7 +4088,11 @@ static PyObject *__Pyx_CreateClass(
goto bad;
if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
goto bad;
#if PY_MAJOR_VERSION < 3
result = PyClass_New(bases, dict, name);
#else
result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
#endif
bad:
Py_XDECREF(py_modname);
return result;
......
......@@ -367,6 +367,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#ifndef PY_LONG_LONG")
code.putln(" #define PY_LONG_LONG LONG_LONG")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(" #define METH_COEXIST 0")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02050000")
code.putln(" typedef int Py_ssize_t;")
code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
......@@ -376,9 +380,41 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(" #define METH_COEXIST 0")
code.putln("#if PY_VERSION_HEX < 0x02060000")
code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
code.putln(" #define Py_SIZE(ob) ((PyVarObject*)(ob))->ob_size)")
code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
code.putln(" PyObject_HEAD_INIT(type) size,")
code.putln("#endif")
code.put(builtin_module_name_utility_code[0])
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
code.putln(" #define PyInt_FromString PyLong_FromString")
code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
code.putln(" #define PyInt_FromLong PyLong_FromLong")
code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
code.putln(" #define PyInt_AsLong PyLong_AsLong")
code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyMethod_New(func, self, klass) (func!=NULL?(Py_INCREF(func),func):NULL)")
code.putln("#endif")
code.putln("#ifndef __stdcall")
code.putln(" #define __stdcall")
code.putln("#endif")
......@@ -787,7 +823,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"%s(o);" % tp_dealloc)
else:
code.putln(
"(*o->ob_type->tp_free)(o);")
"(*Py_TYPE(o)->tp_free)(o);")
code.putln(
"}")
......@@ -801,14 +837,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyErr_Fetch(&etype, &eval, &etb);")
code.putln(
"++o->ob_refcnt;")
"++Py_REFCNT(o);")
code.putln(
"%s(o);" %
entry.func_cname)
code.putln(
"if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
code.putln(
"--o->ob_refcnt;")
"--Py_REFCNT(o);")
code.putln(
"PyErr_Restore(etype, eval, etb);")
code.putln(
......@@ -906,7 +942,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
code.putln(
"r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
"r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
code.putln(
"Py_DECREF(x);")
code.putln(
......@@ -937,7 +973,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "Subscript assignment not supported by %s", o->ob_type->tp_name);')
' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
code.putln(
"return -1;")
code.putln(
......@@ -954,7 +990,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "Subscript deletion not supported by %s", o->ob_type->tp_name);')
' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
code.putln(
"return -1;")
code.putln(
......@@ -1004,7 +1040,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
code.putln(
"return -1;")
code.putln(
......@@ -1021,7 +1057,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
code.putln(
"return -1;")
code.putln(
......@@ -1242,9 +1278,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#code.putln(header % scope.parent_type.typeobj_cname)
code.putln(header % type.typeobj_cname)
code.putln(
"PyObject_HEAD_INIT(0)")
code.putln(
"0, /*ob_size*/")
"PyVarObject_HEAD_INIT(0, 0)")
code.putln(
'"%s.%s", /*tp_name*/' % (
self.full_module_name, scope.class_name))
......@@ -1477,7 +1511,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.module_cname,
code.error_goto(self.pos)));
code.putln(
'%s = PyImport_AddModule("__builtin__");' %
'%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME);' %
Naming.builtins_cname)
code.putln(
"if (!%s) %s;" % (
......@@ -1643,9 +1677,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); %s' % (
module_name = type.module_name
if module_name not in ('__builtin__', 'builtins'):
module_name = '"%s"' % module_name
else:
module_name = '__Pyx_BUILTIN_MODULE_NAME'
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
type.typeptr_cname,
type.module_name,
module_name,
type.name,
objstruct,
error_code))
......@@ -1740,6 +1779,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#
#------------------------------------------------------------------------------------
builtin_module_name_utility_code = [
"""\
#if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
"""]
import_module_utility_code = [
"""
static PyObject *__Pyx_ImportModule(char *name); /*proto*/
......@@ -1750,7 +1799,11 @@ static PyObject *__Pyx_ImportModule(char *name) {
PyObject *py_name = 0;
PyObject *py_module = 0;
#if PY_MAJOR_VERSION < 3
py_name = PyString_FromString(name);
#else
py_name = PyUnicode_FromString(name);
#endif
if (!py_name)
goto bad;
py_module = PyImport_Import(py_name);
......@@ -1778,7 +1831,11 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
PyObject *result = 0;
PyObject *py_name = 0;
#if PY_MAJOR_VERSION < 3
py_name = PyString_FromString(module_name);
#else
py_name = PyUnicode_FromString(module_name);
#endif
if (!py_name)
goto bad;
......
......@@ -1923,7 +1923,7 @@ class OverrideCheckNode(StatNode):
if self.py_func.is_module_scope:
code.putln("else {")
else:
code.putln("else if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg)
code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
err = code.error_goto_if_null(self_arg, self.pos)
# need to get attribute manually--scope would return cdef method
if Options.intern_names:
......@@ -1931,7 +1931,7 @@ class OverrideCheckNode(StatNode):
else:
code.putln('%s = PyObject_GetAttrString(%s, "%s"); %s' % (self.func_node.result_code, self_arg, self.py_func.entry.name, err))
# It appears that this type is not anywhere exposed in the Python/C API
is_builtin_function_or_method = '(strcmp(%s->ob_type->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code
is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code
is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result_code, self.py_func.entry.func_cname)
code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
self.body.generate_execution_code(code)
......@@ -3872,7 +3872,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
goto raise_error;
}
#else
type = (PyObject*) type->ob_type;
type = (PyObject*) Py_TYPE(type);
Py_INCREF(type);
if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
PyErr_SetString(PyExc_TypeError,
......@@ -3922,14 +3922,14 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
}
if (none_allowed && obj == Py_None) return 1;
else if (exact) {
if (obj->ob_type == type) return 1;
if (Py_TYPE(obj) == type) return 1;
}
else {
if (PyObject_TypeCheck(obj, type)) return 1;
}
PyErr_Format(PyExc_TypeError,
"Argument '%s' has incorrect type (expected %s, got %s)",
name, type->tp_name, obj->ob_type->tp_name);
name, type->tp_name, Py_TYPE(obj)->tp_name);
return 0;
}
"""]
......@@ -4067,7 +4067,11 @@ static int __Pyx_SplitKeywords(
if (!*kwds2)
goto bad;
for (i = 0, p = kwd_list; *p; i++, p++) {
#if PY_MAJOR_VERSION < 3
s = PyString_FromString(*p);
#else
s = PyUnicode_FromString(*p);
#endif
x = PyDict_GetItem(*kwds, s);
if (x) {
if (PyDict_SetItem(kwds1, s, x) < 0)
......@@ -4147,7 +4151,11 @@ static void __Pyx_WriteUnraisable(char *name) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
PyErr_Fetch(&old_exc, &old_val, &old_tb);
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name);
#else
ctx = PyUnicode_FromString(name);
#endif
PyErr_Restore(old_exc, old_val, old_tb);
if (!ctx)
ctx = Py_None;
......@@ -4173,13 +4181,25 @@ static void __Pyx_AddTraceback(char *funcname) {
PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0;
#if PY_MAJOR_VERSION < 3
py_srcfile = PyString_FromString(%(FILENAME)s);
#else
py_srcfile = PyUnicode_FromString(%(FILENAME)s);
#endif
if (!py_srcfile) goto bad;
if (%(CLINENO)s) {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromFormat( "%%s (%%s:%%u)", funcname, %(CFILENAME)s, %(CLINENO)s);
#else
py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%u)", funcname, %(CFILENAME)s, %(CLINENO)s);
#endif
}
else {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromString(funcname);
#else
py_funcname = PyUnicode_FromString(funcname);
#endif
}
if (!py_funcname) goto bad;
py_globals = PyModule_GetDict(%(GLOBALS)s);
......@@ -4188,6 +4208,9 @@ static void __Pyx_AddTraceback(char *funcname) {
if (!empty_string) goto bad;
py_code = PyCode_New(
0, /*int argcount,*/
#if PY_MAJOR_VERSION >= 3
0, /*int kwonlyargcount,*/
#endif
0, /*int nlocals,*/
0, /*int stacksize,*/
0, /*int flags,*/
......@@ -4289,7 +4312,11 @@ static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
""","""
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
while (t->p) {
#if PY_MAJOR_VERSION < 3
*t->p = PyString_InternFromString(t->s);
#else
*t->p = PyUnicode_InternFromString(t->s);
#endif
if (!*t->p)
return -1;
++t;
......@@ -4309,7 +4336,11 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
if (t->is_unicode) {
*t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
} else {
#if PY_MAJOR_VERSION < 3
*t->p = PyString_FromStringAndSize(t->s, t->n - 1);
#else
*t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
#endif
}
if (!*t->p)
return -1;
......
......@@ -249,7 +249,7 @@ class BuiltinObjectType(PyObjectType):
return type.is_pyobject and self.assignable_from(type)
def type_test_code(self, arg):
return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", %s->ob_type->tp_name), 0)' % (self.name[0].upper() + self.name[1:], arg, arg, self.name, arg)
return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (self.name[0].upper() + self.name[1:], arg, arg, self.name, arg)
class PyExtensionType(PyObjectType):
......
......@@ -1401,7 +1401,7 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
/* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
/* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */
if (strcmp(method->ob_type->tp_name, "method_descriptor") == 0) { /* cdef classes */
if (strcmp(Py_TYPE(method)->tp_name, "method_descriptor") == 0) { /* cdef classes */
PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
}
......
......@@ -121,11 +121,13 @@ class SlotDescriptor:
# slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot
# py3k Indicates presence of slot in Python 3
def __init__(self, slot_name, dynamic = 0, flag = None):
def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True):
self.slot_name = slot_name
self.is_initialised_dynamically = dynamic
self.flag = flag
self.py3k = py3k
def generate(self, scope, code):
if self.is_initialised_dynamically:
......@@ -133,9 +135,14 @@ class SlotDescriptor:
else:
value = self.slot_code(scope)
flag = self.flag
py3k = self.py3k
if not py3k:
code.putln("#if PY_MAJOR_VERSION < 3")
if flag:
code.putln("#if Py_TPFLAGS_DEFAULT & %s" % flag)
code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
code.putln("%s, /*%s*/" % (value, self.slot_name))
if not py3k:
code.putln("#endif")
if flag:
code.putln("#endif")
......@@ -183,8 +190,8 @@ class MethodSlot(SlotDescriptor):
# method_name string The __xxx__ name of the method
# default string or None Default value of the slot
def __init__(self, signature, slot_name, method_name, default = None, flag = None):
SlotDescriptor.__init__(self, slot_name, flag = flag)
def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True):
SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k)
self.signature = signature
self.slot_name = slot_name
self.method_name = method_name
......@@ -515,7 +522,7 @@ PyNumberMethods = (
MethodSlot(binaryfunc, "nb_add", "__add__"),
MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
MethodSlot(binaryfunc, "nb_divide", "__div__"),
MethodSlot(binaryfunc, "nb_divide", "__div__", py3k = False),
MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
MethodSlot(ternaryfunc, "nb_power", "__pow__"),
......@@ -540,7 +547,7 @@ PyNumberMethods = (
MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__"),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", py3k = False),
MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
......@@ -580,10 +587,10 @@ PyMappingMethods = (
)
PyBufferProcs = (
MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__"),
MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__"),
MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__"),
MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__"),
MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3k = False),
MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3k = False),
MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3k = False),
MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3k = False),
)
#------------------------------------------------------------------------------------------
......
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