From b5889b8b0fca55583acc8da3067ca7867778de7c Mon Sep 17 00:00:00 2001 From: Stefan Zager Date: Wed, 9 Feb 2011 08:59:09 +0000 Subject: [PATCH] Unicode fixes for python3. Added a few more closure types. Guard against operator overloads outside of a class declaration. Incorporate fix for patch #3171793. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/szager-python-builtin@12446 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/python/builtin.swg | 31 ++++++++++++++++++++++ Lib/python/pyhead.swg | 3 ++- Lib/python/pyrun.swg | 41 ++++++++++++++--------------- Source/Modules/allocate.cxx | 2 +- Source/Modules/python.cxx | 52 +++++++++++++++++++++---------------- 5 files changed, 83 insertions(+), 46 deletions(-) diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index bba988dd4..b662acbb7 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -153,6 +153,37 @@ wrapper##_closure (PyObject *a, PyObject *b, PyObject *c) \ return result; \ } +#define PYSWIG_REPRFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject* \ +wrapper##_closure (PyObject *a) \ +{ \ + return wrapper(a, NULL); \ +} + +#define PYSWIG_HASHFUNC_CLOSURE(wrapper) \ +SWIGINTERN long \ +wrapper##_closure (PyObject *a) \ +{ \ + PyObject *pyresult = wrapper(a, NULL); \ + if (!pyresult || !PyLong_Check(pyresult)) \ + return -1; \ + long result = PyLong_AsLong(pyresult); \ + Py_DECREF(pyresult); \ + return result; \ +} + +#define PYSWIG_ITERNEXT_CLOSURE(wrapper) \ +SWIGINTERN PyObject* \ +wrapper##_closure (PyObject *a) \ +{ \ + PyObject *result = wrapper(a, NULL); \ + if (result && result == Py_None) { \ + Py_DECREF(result); \ + result = NULL; \ + } \ + return result; \ +} + SWIGRUNTIME int py_builtin_bad_init (PyObject *self, PyObject *args, PyObject *kwds) { PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name); diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg index c7f897f78..98ffa8d63 100644 --- a/Lib/python/pyhead.swg +++ b/Lib/python/pyhead.swg @@ -5,10 +5,11 @@ #define PyInt_Check(x) PyLong_Check(x) #define PyInt_AsLong(x) PyLong_AsLong(x) #define PyInt_FromLong(x) PyLong_FromLong(x) +#define PyString_Check(name) PyBytes_Check(name) #define PyString_FromString(x) PyUnicode_FromString(x) #define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) +#define PyString_AsString(str) PyBytes_AsString(str) #define PyString_InternFromString(key) PyUnicode_InternFromString(key) -#define PyString_Check(name) PyUnicode_Check(name) #define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE #define PyString_AS_STRING(x) PyUnicode_AS_STRING(x) #define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index f1857fe27..57b3d1780 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -1703,24 +1703,22 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) descrsetfunc f; int res = -1; - if (!PyString_Check(name)) { #ifdef Py_USING_UNICODE - if (PyUnicode_Check(name)) { - name = PyUnicode_AsEncodedString(name, NULL, NULL); - if (name == NULL) - return -1; - } - else + if (PyString_Check(name)) { + name = PyUnicode_Decode(PyString_AsString(name), PyBytes_Size(name), NULL, NULL); + if (name == NULL) + return -1; + } else if (!PyUnicode_Check(name)) { +#else + if (!PyString_Check(name)) { #endif - { - PyErr_Format(PyExc_TypeError, - "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); - return -1; - } - } - else + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return -1; + } else { Py_INCREF(name); + } if (tp->tp_dict == NULL) { if (PyType_Ready(tp) < 0) @@ -1731,21 +1729,22 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) f = NULL; if (descr != NULL) f = descr->ob_type->tp_descr_set; - if (f == NULL) + if (f == NULL) { PyErr_Format(PyExc_AttributeError, -#if PY_VERSION_HEX >= 0x03000000 +#ifdef Py_USING_UNICODE "'%.100s' object has no attribute '%.200U'", #else "'%.100s' object has no attribute '%.200S'", #endif tp->tp_name, name); - else + } else { res = f(descr, obj, value); - -done: + } + + done: Py_DECREF(name); return res; -} + } #ifdef __cplusplus diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 1a62f5d69..110a92939 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -216,7 +216,7 @@ class Allocate:public Dispatcher { if (!most_base_covariant_type) { // Eliminate the derived virtual method. - if (virtual_elimination_mode && !this_wrapping_protected_members) + if (virtual_elimination_mode && !is_member_director(n)) if (both_have_public_access) if (!is_non_public_base(inclass, b)) if (!Swig_symbol_isoverloaded(n)) { diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 16385d798..9eaaa1f9d 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -176,7 +176,6 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "destructor", "PYSWIG_DESTRUCTOR_CLOSURE", "inquiry", "PYSWIG_INQUIRY_CLOSURE", "getiterfunc", "PYSWIG_UNARYFUNC_CLOSURE", - "iternextfunc", "PYSWIG_UNARYFUNC_CLOSURE", "binaryfunc", "PYSWIG_BINARYFUNC_CLOSURE", "ternaryfunc", "PYSWIG_TERNARYFUNC_CLOSURE", "lenfunc", "PYSWIG_LENFUNC_CLOSURE", @@ -185,6 +184,9 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "ssizeobjargproc", "PYSWIG_SSIZEOBJARGPROC_CLOSURE", "ssizessizeobjargproc", "PYSWIG_SSIZESSIZEOBJARGPROC_CLOSURE", "objobjargproc", "PYSWIG_OBJOBJARGPROC_CLOSURE", + "reprfunc", "PYSWIG_REPRFUNC_CLOSURE", + "hashfunc", "PYSWIG_HASHFUNC_CLOSURE", + "iternextfunc", "PYSWIG_ITERNEXT_CLOSURE", NULL }; @@ -193,7 +195,6 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "destructor", "PYSWIG_DESTRUCTOR_CLOSURE", "inquiry", "PYSWIG_INQUIRY_CLOSURE", "getiterfunc", "PYSWIG_UNARYFUNC_CLOSURE", - "iternextfunc", "PYSWIG_UNARYFUNC_CLOSURE", "ternaryfunc", "PYSWIG_TERNARYFUNC_CLOSURE", "lenfunc", "PYSWIG_LENFUNC_CLOSURE", "ssizeargfunc", "PYSWIG_FUNPACK_SSIZEARGFUNC_CLOSURE", @@ -201,6 +202,9 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "ssizeobjargproc", "PYSWIG_SSIZEOBJARGPROC_CLOSURE", "ssizessizeobjargproc", "PYSWIG_SSIZESSIZEOBJARGPROC_CLOSURE", "objobjargproc", "PYSWIG_OBJOBJARGPROC_CLOSURE", + "reprfunc", "PYSWIG_REPRFUNC_CLOSURE", + "hashfunc", "PYSWIG_HASHFUNC_CLOSURE", + "iternextfunc", "PYSWIG_ITERNEXT_CLOSURE", NULL }; @@ -2637,29 +2641,31 @@ public: Delattr(n, "memberset"); } - /* Handle builtin operator overloads */ - String *slot = Getattr(n, "feature:pyslot"); - if (slot) { - String *closure_decl = getClosure(Getattr(n, "feature:pyslot:functype"), wrapper_name, overname ? 0 : funpack); - String *feature_name = NewStringf("feature:%s", slot); - String *closure_name = Copy(wrapper_name); - if (closure_decl) { - if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) - Printv(f_wrappers, closure_decl, "\n\n", NIL); - Append(closure_name, "_closure"); - Delete(closure_decl); + if (in_class && builtin) { + /* Handle operator overloads overloads for builtin types */ + String *slot = Getattr(n, "feature:pyslot"); + if (slot) { + String *closure_decl = getClosure(Getattr(n, "feature:pyslot:functype"), wrapper_name, overname ? 0 : funpack); + String *feature_name = NewStringf("feature:%s", slot); + String *closure_name = Copy(wrapper_name); + if (closure_decl) { + if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) + Printv(f_wrappers, closure_decl, "\n\n", NIL); + Append(closure_name, "_closure"); + Delete(closure_decl); + } + Setattr(parent, feature_name, closure_name); + Delete(feature_name); + Delete(closure_name); } - Setattr(parent, feature_name, closure_name); - Delete(feature_name); - Delete(closure_name); - } - /* Handle comparison operators for builtin types */ - String *compare = Getattr(n, "feature:pycompare"); - if (compare) { - Hash *richcompare = Getattr(parent, "richcompare"); - assert(richcompare); - Setattr(richcompare, compare, wrapper_name); + /* Handle comparison operators for builtin types */ + String *compare = Getattr(n, "feature:pycompare"); + if (compare) { + Hash *richcompare = Getattr(parent, "richcompare"); + assert(richcompare); + Setattr(richcompare, compare, wrapper_name); + } } Delete(self_parse);