diff --git a/Examples/test-suite/python/struct_value_runme.py b/Examples/test-suite/python/struct_value_runme.py index 727996f53..a20e83439 100644 --- a/Examples/test-suite/python/struct_value_runme.py +++ b/Examples/test-suite/python/struct_value_runme.py @@ -7,3 +7,24 @@ if b.a.x != 3: raise RuntimeError b.b.x = 3 if b.b.x != 3: raise RuntimeError + + +# Test dynamically added attributes - Github pull request #320 +b.added = 123 + +if b.added != 123: + raise RuntimeError("Wrong attribute value") + +if not b.__dict__.has_key("added"): + raise RuntimeError("Missing added attribute in __dict__") + +class PyBar(struct_value.Bar): + def __init__(self): + self.extra = "hi" + struct_value.Bar.__init__(self) + +pybar = PyBar() +if not pybar.__dict__.has_key("extra"): + raise RuntimeError("Missing extra attribute in __dict__") +if pybar.extra != "hi": + raise RuntimeError("Incorrect attribute value for extra") diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 28c557a21..1d892375c 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -9,6 +9,7 @@ SWIGINTERN void \ wrapper##_closure(PyObject *a) { \ SwigPyObject *sobj; \ sobj = (SwigPyObject *)a; \ + Py_XDECREF(sobj->dict); \ if (sobj->own) { \ PyObject *o = wrapper(a, NULL); \ Py_XDECREF(o); \ diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index a713486d1..7ef8d5e39 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -381,6 +381,23 @@ typedef struct { #endif } SwigPyObject; + +#ifdef SWIGPYTHON_BUILTIN + +SWIGRUNTIME PyObject * +SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) +{ + SwigPyObject *sobj = (SwigPyObject *)v; + + if (!sobj->dict) + sobj->dict = PyDict_New(); + + Py_INCREF(sobj->dict); + return sobj->dict; +} + +#endif + SWIGRUNTIME PyObject * SwigPyObject_long(SwigPyObject *v) { @@ -1420,18 +1437,21 @@ SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int f newobj = (SwigPyObject *) newobj->next; newobj->next = next_self; newobj = (SwigPyObject *)next_self; +#ifdef SWIGPYTHON_BUILTIN + newobj->dict = 0; +#endif } } else { newobj = PyObject_New(SwigPyObject, clientdata->pytype); +#ifdef SWIGPYTHON_BUILTIN + newobj->dict = 0; +#endif } if (newobj) { newobj->ptr = ptr; newobj->ty = type; newobj->own = own; newobj->next = 0; -#ifdef SWIGPYTHON_BUILTIN - newobj->dict = 0; -#endif return (PyObject*) newobj; } return SWIG_Py_Void(); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 0e4a40229..bc31c4264 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -3058,6 +3058,17 @@ public: } /* If this is a builtin type, create a PyGetSetDef entry for this member variable. */ + if (builtin) { + const char *memname = "__dict__"; + Hash *h = Getattr(builtin_getset, memname); + if (!h) { + h = NewHash(); + Setattr(builtin_getset, memname, h); + Delete(h); + } + Setattr(h, "getter", "SwigPyObject_get___dict__"); + } + if (builtin_getter) { String *memname = Getattr(n, "membervariableHandler:sym:name"); if (!memname)