Skip to content

Commit 881a6ae

Browse files
Expose each python module's registry, allowing lookup of global objects.
1 parent 1f54e2a commit 881a6ae

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

pythonBuffer.h

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,19 @@
3333

3434
namespace classdesc
3535
{
36-
// per compile unit registry
37-
namespace {
38-
RESTProcess_t registry;
36+
// map of registries, one per module
37+
inline std::map<std::string, RESTProcess_t>& registries()
38+
{
39+
static std::map<std::string, RESTProcess_t> registries;
40+
return registries;
3941
}
4042

43+
namespace
44+
{
45+
// reference to per compile unit registry
46+
RESTProcess_t* registry=nullptr;
47+
}
48+
4149
/// @{ utility python object constructors
4250
inline PyObject* newPyObject(const bool& x) {if (x) Py_RETURN_TRUE; Py_RETURN_FALSE;}
4351
template <class T> inline typename enable_if<And<is_integral<T>, Not<is_same<T,bool>>>, PyObject*>::T
@@ -476,7 +484,7 @@ struct CppWrapperType: public PyTypeObject
476484
static Py_ssize_t size(PyObject* self)
477485
{
478486
auto cppWrapper=static_cast<CppWrapper*>(self);
479-
return registry.process(cppWrapper->command+".@size",{}).get_uint64();
487+
return registry->process(cppWrapper->command+".@size",{}).get_uint64();
480488
}
481489

482490
static PyObject* getElem(PyObject* self, PyObject* key)
@@ -537,13 +545,13 @@ struct CppWrapperType: public PyTypeObject
537545
if (!pyObject||command.find('@')!=string::npos) return;
538546
try
539547
{
540-
PyObject_SetAttrString(pyObject, "_signature",newPyObject(registry.process(command+".@signature",{})));
541-
PyObject_SetAttrString(pyObject, "_type", newPyObject(registry.process(command+".@type",{})));
548+
PyObject_SetAttrString(pyObject, "_signature",newPyObject(registry->process(command+".@signature",{})));
549+
PyObject_SetAttrString(pyObject, "_type", newPyObject(registry->process(command+".@type",{})));
542550
}
543551
catch (...) { } // do not log, nor report errors back to python - there are too many
544552
try
545553
{
546-
auto methods=registry.process(command+".@list",{});
554+
auto methods=registry->process(command+".@list",{});
547555
if (methods.type()!=RESTProcessType::array) return;
548556
for (auto& i: methods.array())
549557
{
@@ -577,7 +585,7 @@ struct CppWrapperType: public PyTypeObject
577585
try
578586
{
579587
auto args=arguments.get<json_pack_t>();
580-
const PythonBuffer result(registry.process(command, args));
588+
const PythonBuffer result(registry->process(command, args));
581589

582590
auto pyResult=result.getPyObject();
583591
switch (result.type())
@@ -612,18 +620,19 @@ struct CppWrapperType: public PyTypeObject
612620
void initModule(PyObject* module, const char* objName, T& object)
613621
{
614622
assert(module);
615-
classdesc::RESTProcess(registry,objName,object);
623+
classdesc::RESTProcess(*registry,objName,object);
616624
PyObjectRef pyObject=CppWrapper::create(objName);
617625
LimitRecursion().attachMethods(pyObject,objName);
618626
PyModule_AddObject(module, objName, pyObject.release());
619-
/* enum reflection */
627+
628+
// enum reflection
620629
PyObjectRef enummer=PyDict_New();
621-
auto enumList=registry.process("@enum.@list",{});
630+
auto enumList=registry->process("@enum.@list",{});
622631
for (auto& i: enumList.array())
623632
{
624633
string name=i.get_str();
625634
PyDict_SetItemString(enummer, name.c_str(),
626-
newPyObjectJson(registry.process("@enum."+name,{})));
635+
newPyObjectJson(registry->process("@enum."+name,{})));
627636
}
628637
PyModule_AddObject(module, "enum", enummer.release());
629638
}
@@ -644,24 +653,25 @@ namespace classdesc_access
644653
/// a convenience macro for creating a python module with a single global object
645654
/// @param name module name
646655
/// @param object C++ object to expose to python
647-
#define CLASSDESC_PYTHON_MODULE(name,object) \
648-
PyMODINIT_FUNC PyInit_##name() \
649-
{ \
650-
static PyModuleDef module_##name = { \
651-
PyModuleDef_HEAD_INIT, \
652-
#name, \
653-
"Python interface to C++ code", \
654-
-1, \
655-
NULL, \
656-
NULL, \
657-
NULL, \
658-
NULL, \
659-
NULL \
660-
}; \
661-
\
662-
auto module=PyModule_Create(&module_##name); \
663-
if (module) initModule(module, #object, object); \
664-
return module; \
656+
#define CLASSDESC_PYTHON_MODULE(name,object) \
657+
PyMODINIT_FUNC PyInit_##name() \
658+
{ \
659+
static PyModuleDef module_##name = { \
660+
PyModuleDef_HEAD_INIT, \
661+
#name, \
662+
"Python interface to C++ code", \
663+
-1, \
664+
nullptr, \
665+
nullptr, \
666+
nullptr, \
667+
nullptr, \
668+
nullptr \
669+
}; \
670+
\
671+
auto module=PyModule_Create(&module_##name); \
672+
registry=&registries()[#name]; \
673+
if (module) initModule(module, #object, object); \
674+
return module; \
665675
}
666676

667677

0 commit comments

Comments
 (0)