22#include " CPyCppyy.h"
33#include " CPPEnum.h"
44#include " PyStrings.h"
5+ #include " TypeManip.h"
56#include " Utility.h"
67
78
@@ -18,9 +19,9 @@ static PyObject* pytype_from_enum_type(const std::string& enum_type)
1819}
1920
2021// ----------------------------------------------------------------------------
21- PyObject* CPyCppyy:: pyval_from_enum (const std::string& enum_type, PyObject* pytype,
22- PyObject* btype, Cppyy::TCppScope_t enum_constant ) {
23- long long llval = Cppyy::GetEnumDataValue (enum_constant );
22+ static PyObject* pyval_from_enum (const std::string& enum_type, PyObject* pytype,
23+ PyObject* btype, Cppyy::TCppEnum_t etype, Cppyy::TCppIndex_t idata ) {
24+ long long llval = Cppyy::GetEnumDataValue (etype, idata );
2425
2526 if (enum_type == " bool" ) {
2627 PyObject* result = (bool )llval ? Py_True : Py_False;
@@ -37,13 +38,11 @@ PyObject* CPyCppyy::pyval_from_enum(const std::string& enum_type, PyObject* pyty
3738 else
3839 bval = PyLong_FromLongLong (llval);
3940
40- if (pytype && btype) {
4141 PyObject* args = PyTuple_New (1 );
4242 PyTuple_SET_ITEM (args, 0 , bval);
43- bval = ((PyTypeObject*)btype)->tp_new ((PyTypeObject*)pytype, args, nullptr );
43+ PyObject* result = ((PyTypeObject*)btype)->tp_new ((PyTypeObject*)pytype, args, nullptr );
4444 Py_DECREF (args);
45- }
46- return bval;
45+ return result;
4746}
4847
4948
@@ -60,8 +59,6 @@ static PyObject* enum_repr(PyObject* self)
6059{
6160 using namespace CPyCppyy ;
6261
63- PyObject* kls_scope = PyObject_GetAttr ((PyObject*)Py_TYPE (self), PyStrings::gThisModule );
64- if (!kls_scope) PyErr_Clear ();
6562 PyObject* kls_cppname = PyObject_GetAttr ((PyObject*)Py_TYPE (self), PyStrings::gCppName );
6663 if (!kls_cppname) PyErr_Clear ();
6764 PyObject* obj_cppname = PyObject_GetAttr (self, PyStrings::gCppName );
@@ -70,7 +67,7 @@ static PyObject* enum_repr(PyObject* self)
7067
7168 PyObject* repr = nullptr ;
7269 if (kls_cppname && obj_cppname && obj_str) {
73- const std::string resolved = Cppyy::ResolveEnum (PyLong_AsVoidPtr (kls_scope ));
70+ const std::string resolved = Cppyy::ResolveEnum (CPyCppyy_PyText_AsString (kls_cppname ));
7471 repr = CPyCppyy_PyText_FromFormat (" (%s::%s) : (%s) %s" ,
7572 CPyCppyy_PyText_AsString (kls_cppname), CPyCppyy_PyText_AsString (obj_cppname),
7673 resolved.c_str (), CPyCppyy_PyText_AsString (obj_str));
@@ -140,12 +137,12 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
140137
141138 CPPEnum* pyenum = nullptr ;
142139
143- Cppyy::TCppScope_t etype = scope;
144- const std::string& ename = Cppyy::GetScopedFinalName (scope);
140+ const std::string& ename = scope == Cppyy:: gGlobalScope ? name : Cppyy::GetScopedFinalName (scope)+ " :: " +name ;
141+ Cppyy::TCppEnum_t etype = Cppyy::GetEnum (scope, name );
145142 if (etype) {
146143 // create new enum type with labeled values in place, with a meta-class
147144 // to make sure the enum values are read-only
148- const std::string& resolved = Cppyy::ResolveEnum (etype );
145+ const std::string& resolved = Cppyy::ResolveEnum (ename );
149146 PyObject* pyside_type = pytype_from_enum_type (resolved);
150147 PyObject* pymetabases = PyTuple_New (1 );
151148 PyObject* btype = (PyObject*)Py_TYPE (pyside_type);
@@ -173,6 +170,14 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
173170 PyDict_SetItem (dct, PyStrings::gUnderlying , pyresolved);
174171 Py_DECREF (pyresolved);
175172
173+ // add the __module__ to allow pickling
174+ std::string modname = TypeManip::extract_namespace (ename);
175+ TypeManip::cppscope_to_pyscope (modname); // :: -> .
176+ if (!modname.empty ()) modname = " ." +modname;
177+ PyObject* pymodname = CPyCppyy_PyText_FromString ((" cppyy.gbl" +modname).c_str ());
178+ PyDict_SetItem (dct, PyStrings::gModule , pymodname);
179+ Py_DECREF (pymodname);
180+
176181 // create the actual enum class
177182 args = Py_BuildValue ((char *)" sOO" , name.c_str (), pybases, dct);
178183 Py_DECREF (pybases);
@@ -186,10 +191,10 @@ CPyCppyy::CPPEnum* CPyCppyy::CPPEnum_New(const std::string& name, Cppyy::TCppSco
186191 ((PyTypeObject*)pyenum)->tp_str = ((PyTypeObject*)pyside_type)->tp_repr ;
187192
188193 // collect the enum values
189- std::vector< Cppyy::TCppScope_t> econstants = Cppyy::GetEnumConstants (etype);
190- for (auto *econstant : econstants ) {
191- PyObject* val = pyval_from_enum (resolved, pyenum, pyside_type, econstant );
192- PyObject* pydname = CPyCppyy_PyText_FromString (Cppyy::GetFinalName (econstant ).c_str ());
194+ Cppyy::TCppIndex_t ndata = Cppyy::GetNumEnumData (etype);
195+ for (Cppyy::TCppIndex_t idata = 0 ; idata < ndata; ++idata ) {
196+ PyObject* val = pyval_from_enum (resolved, pyenum, pyside_type, etype, idata );
197+ PyObject* pydname = CPyCppyy_PyText_FromString (Cppyy::GetEnumDataName (etype, idata ).c_str ());
193198 PyObject_SetAttr (pyenum, pydname, val);
194199 PyObject_SetAttr (val, PyStrings::gCppName , pydname);
195200 Py_DECREF (pydname);
0 commit comments