From e2ef929f044790cb20a0d58f8e09a029fbf7504e Mon Sep 17 00:00:00 2001 From: Paul RASCLE Date: Wed, 3 Jan 2018 22:15:03 +0100 Subject: [PATCH] try fix REFCOUNT_TEMPLATE... --- src/engine_swig/CMakeLists.txt | 3 +- src/engine_swig/IteratorPy3.hxx | 16 ++++---- src/engine_swig/engtypemaps.i | 65 +++++++++++++++++++++++---------- src/engine_swig/pilot.i | 9 +++-- 4 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/engine_swig/CMakeLists.txt b/src/engine_swig/CMakeLists.txt index af9df8b3c..320824aa6 100644 --- a/src/engine_swig/CMakeLists.txt +++ b/src/engine_swig/CMakeLists.txt @@ -106,7 +106,8 @@ ENDFOREACH() SET(SWIGINCLUDES ${ENGINEINCL} "${PROJECT_SOURCE_DIR}/src/bases/yacsconfig.h" - "ExecutorSwig.hxx") + "ExecutorSwig.hxx" + "IteratorPy3.hxx") SET(SWIG_MODULE_pilot_EXTRA_DEPS engtypemaps.i ${SWIGINCLUDES}) SWIG_ADD_MODULE(pilot python pilot.i ExecutorSwig.cxx) diff --git a/src/engine_swig/IteratorPy3.hxx b/src/engine_swig/IteratorPy3.hxx index dd480dfda..dd39f1e89 100644 --- a/src/engine_swig/IteratorPy3.hxx +++ b/src/engine_swig/IteratorPy3.hxx @@ -18,14 +18,16 @@ // // Author: Nicolas GEIMER (EDF) -#ifndef ITERATORPY3_HXX_ -#define ITERATORPY3_HXX_ +#ifndef __ITERATORPY3_HXX__ +#define __ITERATORPY3_HXX__ -template class StopIterator {}; -template class Iterator { +template class StopIteratorPy3 {}; + +template class IteratorPy3 { public: - Iterator( typename std::map::iterator _cur, typename std::map::iterator _end) : cur(_cur), end(_end) {} - Iterator* __iter__() + IteratorPy3( typename std::map::iterator _cur, typename std::map::iterator _end) : cur(_cur), end(_end) {} + ~IteratorPy3() {} + IteratorPy3* __iter__() { return this; } @@ -33,5 +35,5 @@ template class Iterator { typename std::map::iterator end; }; -#endif /* ITERATORPY3_HXX */ +#endif /* __ITERATORPY3_HXX__ */ diff --git a/src/engine_swig/engtypemaps.i b/src/engine_swig/engtypemaps.i index 0d1675b33..0771a1c7e 100644 --- a/src/engine_swig/engtypemaps.i +++ b/src/engine_swig/engtypemaps.i @@ -62,6 +62,7 @@ catch (const CORBA::SystemException& ex) { \ #include "OutputDataStreamPort.hxx" #include "OptimizerLoop.hxx" #include "HomogeneousPoolContainer.hxx" +#include "IteratorPy3.hxx" #include @@ -251,6 +252,8 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons %} +// ---------------------------------------------------------------------------- + #if SWIG_VERSION >= 0x010329 %template() std::list; %template() std::list; @@ -307,6 +310,8 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons #endif #endif +// ---------------------------------------------------------------------------- + #ifdef SWIGPYTHON %typecheck(SWIG_TYPECHECK_POINTER) YACS::ENGINE::Any* @@ -652,6 +657,8 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons #endif +// ---------------------------------------------------------------------------- + /* * Exception section */ @@ -773,6 +780,8 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons * End of Exception section */ +// ---------------------------------------------------------------------------- + /* * Ownership section */ @@ -803,6 +812,8 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons * End of Reference counting section */ +// ---------------------------------------------------------------------------- + /* %wrapper %{ namespace swig { @@ -830,11 +841,18 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons %} */ -%define REFCOUNT_TEMPLATE(tname, T...) +// ---------------------------------------------------------------------------- + +%include "IteratorPy3.hxx" +%include "exception.i" + +%define REFCOUNT_TEMPLATE(tname, T) /* This macro is a special wrapping for map with value type which derives from RefCounter. To overload standard SWIG wrapping we define a full specialization of std::map - with %extend for 4 basic methods : getitem, setitem, delitem and keys. + with %extend for 5 basic methods : getitem, setitem, delitem, keys and iter. + We also provide an iterator and %extend with the __next__ method : required in python 3. + (see https://docs.python.org/3/library/stdtypes.html#iterator-types) Then we complete the interface by deriving the shadow wrapper from the python mixin class (UserDict.DictMixin / collections.MutableMapping with Python 3). Do not forget to declare the new shadow class to SWIG with tname_swigregister(tname). @@ -842,30 +860,34 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons call decrRef (see feature("unref") for RefCounter). */ -%include "exception.i" -%exception Iterator::next { +%exception IteratorPy3::__next__ +{ try { $action // calls %extend function next() below } - catch (StopIterator) + catch (StopIteratorPy3) { PyErr_SetString(PyExc_StopIteration, "End of iterator"); return NULL; } } -%extend Iterator +%extend IteratorPy3 { - std::map& next() +// std::pair& __next__() + std::string __next__() { if ($self->cur != $self->end) { // dereference the iterator and return reference to the object, // after that it increments the iterator - return *$self->cur++; + //return *self->cur++; + std::string key= self->cur->first; + *self->cur++; + return key; } - throw StopIterator(); + throw StopIteratorPy3(); } } @@ -901,28 +923,30 @@ public: void __delitem__(std::string name) { std::map::iterator i = self->find(name); - if (i != self->end()){ + if (i != self->end()) + { i->second->decrRef(); self->erase(i); } else throw std::out_of_range("key not found"); } - PyObject* keys() { + PyObject* keys() + { int pysize = self->size(); PyObject* keyList = PyList_New(pysize); std::map::const_iterator i = self->begin(); - for (int j = 0; j < pysize; ++i, ++j) { + for (int j = 0; j < pysize; ++i, ++j) + { PyList_SET_ITEM(keyList, j, PyUnicode_FromString(i->first.c_str())); } return keyList; } - Iterator __iter__() + IteratorPy3 __iter__() { - // return a constructed Iterator object - return typename Iterator($self->begin(), $self->end()); + // return a constructed IteratorPy3 object + return IteratorPy3($self->begin(), $self->end()); } - int __len__() { int pysize = self->size(); @@ -930,12 +954,13 @@ public: } } }; -%rename(__next__) Iterator::next; %newobject std::map::__getitem__; %newobject std::map::__iter__; -%template() std::pair; -%template(tname) std::map; -%pythoncode{ +%template(tname##it) IteratorPy3; +%template() std::pair; +%template(tname) std::map; +%pythoncode +{ from collections import MutableMapping class tname(tname,MutableMapping):pass tname##_swigregister(tname) diff --git a/src/engine_swig/pilot.i b/src/engine_swig/pilot.i index c79d4909c..dc2f9bb2d 100644 --- a/src/engine_swig/pilot.i +++ b/src/engine_swig/pilot.i @@ -59,7 +59,6 @@ #include "ComponentInstance.hxx" #include "DataNode.hxx" #include "PlayGround.hxx" -#include "IteratorPy3.hxx" using namespace YACS::ENGINE; @@ -107,14 +106,14 @@ using namespace YACS::ENGINE; %template() std::pair; %template() std::pair; %template() std::pair< std::string, int >; -%template() Iterator; +%template(ItPy3TC) IteratorPy3; //%template(TCmap) std::map; REFCOUNT_TEMPLATE(TCmap,YACS::ENGINE::TypeCode) %template(NODEmap) std::map; %template(INODEmap) std::map; %template(SNODEmap) std::map; //%template(CONTAINmap) std::map; -%template() Iterator; +%template(ItPy3Cont) IteratorPy3; REFCOUNT_TEMPLATE(CONTAINmap,YACS::ENGINE::Container) %template(strvec) std::vector; %template(uivec) std::vector; @@ -133,9 +132,11 @@ REFCOUNT_TEMPLATE(CONTAINmap,YACS::ENGINE::Container) %template(compomap) std::map; %template() std::pair; %template(propmap) std::map; -%template() Iterator; +%template(ItPy3Comp) IteratorPy3; REFCOUNT_TEMPLATE(CompoInstmap,YACS::ENGINE::ComponentInstance) +%include "exception.i" + /* * End of Template section */ -- 2.39.2