Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Add support for multi-phase module initialization #485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 3 include/boost/python/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@

# include <boost/python/module_init.hpp>
# define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT
# if PY_VERSION_HEX >= 0x03050000
# define BOOST_PYTHON_MODULE_MULTI_PHASE BOOST_PYTHON_MODULE_MULTI_PHASE_INIT
# endif

#endif // MODULE_DWA20011221_HPP
54 changes: 54 additions & 0 deletions 54 include/boost/python/module_init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ namespace boost { namespace python { namespace detail {

BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef&, void(*)());

# if PY_VERSION_HEX >= 0x03050000

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

# endif

#else

BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
Expand Down Expand Up @@ -54,6 +60,46 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
} \
void BOOST_PP_CAT(init_module_, name)()

# if PY_VERSION_HEX >= 0x03050000

# define _BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name) \
int BOOST_PP_CAT(exec_module_,name)(PyObject* module) \
{ \
return boost::python::detail::exec_module( \
module, BOOST_PP_CAT(init_module_, name) ); \
} \
extern "C" BOOST_SYMBOL_EXPORT PyObject* BOOST_PP_CAT(PyInit_, name)() \
{ \
static PyModuleDef_Base initial_m_base = { \
PyObject_HEAD_INIT(NULL) \
0, /* m_init */ \
0, /* m_index */ \
0 /* m_copy */ }; \
static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; \
\
static PyModuleDef_Slot slots[] = { \
{Py_mod_exec, reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(BOOST_PP_CAT(exec_module_, name)))}, \
{0, NULL} \
}; \
\
static struct PyModuleDef moduledef = { \
initial_m_base, \
BOOST_PP_STRINGIZE(name), \
0, /* m_doc */ \
0, /* m_size */ \
initial_methods, \
slots, /* m_slots */ \
0, /* m_traverse */ \
0, /* m_clear */ \
0, /* m_free */ \
}; \
\
return PyModuleDef_Init(&moduledef); \
} \
void BOOST_PP_CAT(init_module_, name)()

# endif

# else

# define _BOOST_PYTHON_MODULE_INIT(name) \
Expand All @@ -70,6 +116,14 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_INIT(name)

# if PY_VERSION_HEX >= 0x03050000

# define BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" BOOST_SYMBOL_EXPORT _BOOST_PYTHON_MODULE_MULTI_PHASE_INIT(name)

# endif

# endif

#endif // MODULE_INIT_DWA20020722_HPP
12 changes: 12 additions & 0 deletions 12 src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef& moduledef, void(*init_funct
init_function);
}

# if PY_VERSION_HEX >= 0x03050000

BOOST_PYTHON_DECL int exec_module(PyObject* module, void(*init_function)())
{
PyObject* retval = init_module_in_scope(
module,
init_function);
return retval ? 0 : -1;
}

# endif

#else

namespace
Expand Down
5 changes: 5 additions & 0 deletions 5 test/fabscript
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,9 @@ for t in ['numpy/dtype',
tests.append(extension_test(t, numpy=True,
condition=set.define.contains('HAS_NUMPY')))

python_version_major, python_version_minor = map(int, python.instance().version.split('.')[:2])

tests.append(extension_test("module_multi_phase",
condition=python_version_major > 3 or (python_version_major == 3 and python_version_minor >= 5)))

default = report('report', tests, fail_on_failures=True)
15 changes: 15 additions & 0 deletions 15 test/module_multi_phase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python/module.hpp>
#include <boost/python/scope.hpp>

using namespace boost::python;

BOOST_PYTHON_MODULE_MULTI_PHASE(module_multi_phase_ext)
{
scope().attr("x") = "x";
}

#include "module_tail.cpp"
23 changes: 23 additions & 0 deletions 23 test/module_multi_phase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"""
>>> import module_multi_phase_ext
>>> module_multi_phase_ext.x
'x'
"""

def run(args = None):
import sys
import doctest

if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))

if __name__ == '__main__':
print("running...")
import sys
status = run()[0]
if (status == 0): print("Done.")
sys.exit(status)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.