Skip to content

Commit 87025cc

Browse files
committed
Provide 'state' accessor in module definition
1 parent 5c5a996 commit 87025cc

2 files changed

Lines changed: 44 additions & 7 deletions

File tree

‎include/boost/python/module_init.hpp‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef&, void(*)(), bool gil_not_us
5656

5757
BOOST_PYTHON_DECL int exec_module(PyObject*, void(*)());
5858

59+
BOOST_PYTHON_DECL int exec_module_with_state(PyObject*, void(*)(void*));
60+
5961
# endif // PY_VERSION_HEX >= 0x03050000
6062

6163
# else // PY_VERSION_HEX >= 0x03000000
@@ -169,7 +171,7 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
169171
int BOOST_PP_CAT(exec_module_,name)(PyObject* mod) \
170172
{ \
171173
return boost::python::detail::exec_module( \
172-
mod, BOOST_PP_CAT(init_module_, name) ); \
174+
mod, reinterpret_cast<void(*)(void*)>(BOOST_PP_CAT(init_module_, name)) ); \
173175
} \
174176
extern "C" BOOST_SYMBOL_EXPORT PyObject* BOOST_PP_CAT(PyInit_, name)() \
175177
{ \
@@ -202,7 +204,7 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
202204
\
203205
return PyModuleDef_Init(&moduledef); \
204206
} \
205-
void BOOST_PP_CAT(init_module_, name)()
207+
void BOOST_PP_CAT(init_module_, name)(StateType* state)
206208
# else // ! HAS_CXX11 && Python 3.13+
207209
# define _BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name) \
208210
int BOOST_PP_CAT(exec_module_,name)(PyObject* mod) \
@@ -243,7 +245,7 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
243245
int BOOST_PP_CAT(exec_module_,name)(PyObject* mod) \
244246
{ \
245247
return boost::python::detail::exec_module( \
246-
mod, BOOST_PP_CAT(init_module_, name) ); \
248+
mod, reinterpret_cast<void(*)(void*)>(BOOST_PP_CAT(init_module_, name)) ); \
247249
} \
248250
extern "C" BOOST_SYMBOL_EXPORT PyObject* BOOST_PP_CAT(PyInit_, name)() \
249251
{ \
@@ -275,7 +277,7 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
275277
\
276278
return PyModuleDef_Init(&moduledef); \
277279
} \
278-
void BOOST_PP_CAT(init_module_, name)()
280+
void BOOST_PP_CAT(init_module_, name)(StateType* state)
279281
# endif // HAS_CXX11 && Python 3.13+
280282

281283
# endif // PY_VERSION_HEX >= 0x03050000
@@ -308,15 +310,15 @@ extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_INIT(name)
308310
void BOOST_PP_CAT(init_module_,name)(); \
309311
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name, __VA_ARGS__)
310312
# define BOOST_PYTHON_MODULE_WITH_STATE_INIT(name, StateType, ...) \
311-
void BOOST_PP_CAT(init_module_,name)(); \
313+
void BOOST_PP_CAT(init_module_,name)(StateType* state); \
312314
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_WITH_STATE_INIT(name, StateType, __VA_ARGS__)
313315
# else
314316
# define BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name) \
315317
void BOOST_PP_CAT(init_module_,name)(); \
316318
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name)
317319
# define BOOST_PYTHON_MODULE_WITH_STATE_INIT(name, StateType) \
318-
void BOOST_PP_CAT(init_module_,name)(); \
319-
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_WITH_STATE_INIT(name)
320+
void BOOST_PP_CAT(init_module_,name)(StateType* state); \
321+
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_WITH_STATE_INIT(name, StateType)
320322
# endif // HAS_CXX11 && Python 3.13+
321323
# endif // PY_VERSION_HEX >= 0x03050000
322324

‎src/module.cpp‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,33 @@ namespace
2626

2727
return m;
2828
}
29+
30+
class init_function_with_state {
31+
public:
32+
init_function_with_state(void(*init_function)(void*), void* state)
33+
: init_function_(init_function), state_(state) {}
34+
35+
void operator()() const { init_function_(state_); }
36+
private:
37+
void(*const init_function_)(void*);
38+
void* const state_;
39+
};
40+
41+
PyObject* init_module_in_scope_with_state(PyObject* m, void(*init_function)(void*))
42+
{
43+
if (m != 0)
44+
{
45+
// Create the current module scope
46+
object m_obj(((borrowed_reference_t*)m));
47+
scope current_module(m_obj);
48+
49+
void* state = PyModule_GetState(m);
50+
51+
if (handle_exception(init_function_with_state(init_function, state))) return NULL;
52+
}
53+
54+
return m;
55+
}
2956
}
3057

3158
BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc)
@@ -62,6 +89,14 @@ BOOST_PYTHON_DECL int exec_module(PyObject* mod, void(*init_function)())
6289
return retval ? 0 : -1;
6390
}
6491

92+
BOOST_PYTHON_DECL int exec_module_with_state(PyObject* mod, void(*init_function)(void*))
93+
{
94+
PyObject* retval = init_module_in_scope_with_state(
95+
mod,
96+
init_function);
97+
return retval ? 0 : -1;
98+
}
99+
65100
# endif
66101

67102
#else

0 commit comments

Comments
 (0)