refactor: module -> module_ with typedef (#2544)

* WIP: module -> module_ without typedef

* refactor: allow py::module to work again
This commit is contained in:
Henry Schreiner 2020-10-03 13:38:03 -04:00 committed by GitHub
parent 560ed3e34f
commit 6bcd220c8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 132 additions and 127 deletions

View File

@ -108,11 +108,11 @@ The two approaches can also be combined:
Importing modules Importing modules
================= =================
Python modules can be imported using `module::import()`: Python modules can be imported using `module_::import()`:
.. code-block:: cpp .. code-block:: cpp
py::module sys = py::module::import("sys"); py::module_ sys = py::module_::import("sys");
py::print(sys.attr("path")); py::print(sys.attr("path"));
For convenience, the current working directory is included in ``sys.path`` when For convenience, the current working directory is included in ``sys.path`` when
@ -128,12 +128,12 @@ embedding the interpreter. This makes it easy to import local Python files:
.. code-block:: cpp .. code-block:: cpp
py::module calc = py::module::import("calc"); py::module_ calc = py::module_::import("calc");
py::object result = calc.attr("add")(1, 2); py::object result = calc.attr("add")(1, 2);
int n = result.cast<int>(); int n = result.cast<int>();
assert(n == 3); assert(n == 3);
Modules can be reloaded using `module::reload()` if the source is modified e.g. Modules can be reloaded using `module_::reload()` if the source is modified e.g.
by an external process. This can be useful in scenarios where the application by an external process. This can be useful in scenarios where the application
imports a user defined data processing script which needs to be updated after imports a user defined data processing script which needs to be updated after
changes by the user. Note that this function does not reload modules recursively. changes by the user. Note that this function does not reload modules recursively.
@ -153,7 +153,7 @@ like any other module.
namespace py = pybind11; namespace py = pybind11;
PYBIND11_EMBEDDED_MODULE(fast_calc, m) { PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
// `m` is a `py::module` which is used to bind functions and classes // `m` is a `py::module_` which is used to bind functions and classes
m.def("add", [](int i, int j) { m.def("add", [](int i, int j) {
return i + j; return i + j;
}); });
@ -162,7 +162,7 @@ like any other module.
int main() { int main() {
py::scoped_interpreter guard{}; py::scoped_interpreter guard{};
auto fast_calc = py::module::import("fast_calc"); auto fast_calc = py::module_::import("fast_calc");
auto result = fast_calc.attr("add")(1, 2).cast<int>(); auto result = fast_calc.attr("add")(1, 2).cast<int>();
assert(result == 3); assert(result == 3);
} }
@ -196,7 +196,7 @@ naturally:
int main() { int main() {
py::scoped_interpreter guard{}; py::scoped_interpreter guard{};
auto py_module = py::module::import("py_module"); auto py_module = py::module_::import("py_module");
auto locals = py::dict("fmt"_a="{} + {} = {}", **py_module.attr("__dict__")); auto locals = py::dict("fmt"_a="{} + {} = {}", **py_module.attr("__dict__"));
assert(locals["a"].cast<int>() == 1); assert(locals["a"].cast<int>() == 1);

View File

@ -182,7 +182,7 @@ For example:
try { try {
// open("missing.txt", "r") // open("missing.txt", "r")
auto file = py::module::import("io").attr("open")("missing.txt", "r"); auto file = py::module_::import("io").attr("open")("missing.txt", "r");
auto text = file.attr("read")(); auto text = file.attr("read")();
file.attr("close")(); file.attr("close")();
} catch (py::error_already_set &e) { } catch (py::error_already_set &e) {

View File

@ -17,7 +17,7 @@ bindings for functions that return a non-trivial type. Just by looking at the
type information, it is not clear whether Python should take charge of the type information, it is not clear whether Python should take charge of the
returned value and eventually free its resources, or if this is handled on the returned value and eventually free its resources, or if this is handled on the
C++ side. For this reason, pybind11 provides a several *return value policy* C++ side. For this reason, pybind11 provides a several *return value policy*
annotations that can be passed to the :func:`module::def` and annotations that can be passed to the :func:`module_::def` and
:func:`class_::def` functions. The default policy is :func:`class_::def` functions. The default policy is
:enum:`return_value_policy::automatic`. :enum:`return_value_policy::automatic`.

View File

@ -132,7 +132,7 @@ However, it can be acquired as follows:
.. code-block:: cpp .. code-block:: cpp
py::object pet = (py::object) py::module::import("basic").attr("Pet"); py::object pet = (py::object) py::module_::import("basic").attr("Pet");
py::class_<Dog>(m, "Dog", pet) py::class_<Dog>(m, "Dog", pet)
.def(py::init<const std::string &>()) .def(py::init<const std::string &>())
@ -146,7 +146,7 @@ has been executed:
.. code-block:: cpp .. code-block:: cpp
py::module::import("basic"); py::module_::import("basic");
py::class_<Dog, Pet>(m, "Dog") py::class_<Dog, Pet>(m, "Dog")
.def(py::init<const std::string &>()) .def(py::init<const std::string &>())
@ -243,7 +243,7 @@ avoids this issue involves weak reference with a cleanup callback:
.. code-block:: cpp .. code-block:: cpp
auto atexit = py::module::import("atexit"); auto atexit = py::module_::import("atexit");
atexit.attr("register")(py::cpp_function([]() { atexit.attr("register")(py::cpp_function([]() {
// perform cleanup here -- this function is called with the GIL held // perform cleanup here -- this function is called with the GIL held
})); }));
@ -284,7 +284,7 @@ work, it is important that all lines are indented consistently, i.e.:
)mydelimiter"); )mydelimiter");
By default, pybind11 automatically generates and prepends a signature to the docstring of a function By default, pybind11 automatically generates and prepends a signature to the docstring of a function
registered with ``module::def()`` and ``class_::def()``. Sometimes this registered with ``module_::def()`` and ``class_::def()``. Sometimes this
behavior is not desirable, because you want to provide your own signature or remove behavior is not desirable, because you want to provide your own signature or remove
the docstring completely to exclude the function from the Sphinx documentation. the docstring completely to exclude the function from the Sphinx documentation.
The class ``options`` allows you to selectively suppress auto-generated signatures: The class ``options`` allows you to selectively suppress auto-generated signatures:

View File

@ -56,12 +56,12 @@ This example obtains a reference to the Python ``Decimal`` class.
.. code-block:: cpp .. code-block:: cpp
// Equivalent to "from decimal import Decimal" // Equivalent to "from decimal import Decimal"
py::object Decimal = py::module::import("decimal").attr("Decimal"); py::object Decimal = py::module_::import("decimal").attr("Decimal");
.. code-block:: cpp .. code-block:: cpp
// Try to import scipy // Try to import scipy
py::object scipy = py::module::import("scipy"); py::object scipy = py::module_::import("scipy");
return scipy.attr("__version__"); return scipy.attr("__version__");
@ -81,7 +81,7 @@ via ``operator()``.
.. code-block:: cpp .. code-block:: cpp
// Use Python to make our directories // Use Python to make our directories
py::object os = py::module::import("os"); py::object os = py::module_::import("os");
py::object makedirs = os.attr("makedirs"); py::object makedirs = os.attr("makedirs");
makedirs("/tmp/path/to/somewhere"); makedirs("/tmp/path/to/somewhere");
@ -196,9 +196,9 @@ C++ functions that require a specific subtype rather than a generic :class:`obje
#include <pybind11/numpy.h> #include <pybind11/numpy.h>
using namespace pybind11::literals; using namespace pybind11::literals;
py::module os = py::module::import("os"); py::module_ os = py::module_::import("os");
py::module path = py::module::import("os.path"); // like 'import os.path as path' py::module_ path = py::module_::import("os.path"); // like 'import os.path as path'
py::module np = py::module::import("numpy"); // like 'import numpy as np' py::module_ np = py::module_::import("numpy"); // like 'import numpy as np'
py::str curdir_abs = path.attr("abspath")(path.attr("curdir")); py::str curdir_abs = path.attr("abspath")(path.attr("curdir"));
py::print(py::str("Current directory: ") + curdir_abs); py::print(py::str("Current directory: ") + curdir_abs);

View File

@ -42,7 +42,7 @@ redirects output to the corresponding Python streams:
m.def("noisy_func", []() { m.def("noisy_func", []() {
py::scoped_ostream_redirect stream( py::scoped_ostream_redirect stream(
std::cout, // std::ostream& std::cout, // std::ostream&
py::module::import("sys").attr("stdout") // Python output py::module_::import("sys").attr("stdout") // Python output
); );
call_noisy_func(); call_noisy_func();
}); });
@ -104,7 +104,7 @@ can be used.
... ...
// Evaluate in scope of main module // Evaluate in scope of main module
py::object scope = py::module::import("__main__").attr("__dict__"); py::object scope = py::module_::import("__main__").attr("__dict__");
// Evaluate an isolated expression // Evaluate an isolated expression
int result = py::eval("my_variable + 10", scope).cast<int>(); int result = py::eval("my_variable + 10", scope).cast<int>();

View File

@ -118,8 +118,8 @@ a file named :file:`example.cpp` with the following contents:
The :func:`PYBIND11_MODULE` macro creates a function that will be called when an The :func:`PYBIND11_MODULE` macro creates a function that will be called when an
``import`` statement is issued from within Python. The module name (``example``) ``import`` statement is issued from within Python. The module name (``example``)
is given as the first macro argument (it should not be in quotes). The second is given as the first macro argument (it should not be in quotes). The second
argument (``m``) defines a variable of type :class:`py::module <module>` which argument (``m``) defines a variable of type :class:`py::module_ <module>` which
is the main interface for creating bindings. The method :func:`module::def` is the main interface for creating bindings. The method :func:`module_::def`
generates binding code that exposes the ``add()`` function to Python. generates binding code that exposes the ``add()`` function to Python.
.. note:: .. note::
@ -181,7 +181,7 @@ names of the arguments ("i" and "j" in this case).
py::arg("i"), py::arg("j")); py::arg("i"), py::arg("j"));
:class:`arg` is one of several special tag classes which can be used to pass :class:`arg` is one of several special tag classes which can be used to pass
metadata into :func:`module::def`. With this modified binding code, we can now metadata into :func:`module_::def`. With this modified binding code, we can now
call the function using keyword arguments, which is a more readable alternative call the function using keyword arguments, which is a more readable alternative
particularly for functions taking many parameters: particularly for functions taking many parameters:

View File

@ -11,9 +11,9 @@ v2.6.0 (IN PROGRESS)
See :ref:`upgrade-guide-2.6` for help upgrading to the new version. See :ref:`upgrade-guide-2.6` for help upgrading to the new version.
* Provide an additional spelling of ``py::module`` - ``py::module_`` (with a * ``py::module`` was renamed ``py::module_`` to avoid issues with C++20 when
trailing underscore), for C++20 compatibility. Only relevant when used used unqualified, but an alias ``py::module`` is provided for backward
unqualified. compatibility.
`#2489 <https://github.com/pybind/pybind11/pull/2489>`_ `#2489 <https://github.com/pybind/pybind11/pull/2489>`_
* ``pybind11_add_module()`` now accepts an optional ``OPT_SIZE`` flag that * ``pybind11_add_module()`` now accepts an optional ``OPT_SIZE`` flag that
@ -529,7 +529,7 @@ v2.2.2 (February 7, 2018)
v2.2.1 (September 14, 2017) v2.2.1 (September 14, 2017)
----------------------------------------------------- -----------------------------------------------------
* Added ``py::module::reload()`` member function for reloading a module. * Added ``py::module_::reload()`` member function for reloading a module.
`#1040 <https://github.com/pybind/pybind11/pull/1040>`_. `#1040 <https://github.com/pybind/pybind11/pull/1040>`_.
* Fixed a reference leak in the number converter. * Fixed a reference leak in the number converter.

View File

@ -100,8 +100,8 @@ following example:
.. code-block:: cpp .. code-block:: cpp
void init_ex1(py::module &); void init_ex1(py::module_ &);
void init_ex2(py::module &); void init_ex2(py::module_ &);
/* ... */ /* ... */
PYBIND11_MODULE(example, m) { PYBIND11_MODULE(example, m) {
@ -114,7 +114,7 @@ following example:
.. code-block:: cpp .. code-block:: cpp
void init_ex1(py::module &m) { void init_ex1(py::module_ &m) {
m.def("add", [](int a, int b) { return a + b; }); m.def("add", [](int a, int b) { return a + b; });
} }
@ -122,7 +122,7 @@ following example:
.. code-block:: cpp .. code-block:: cpp
void init_ex2(py::module &m) { void init_ex2(py::module_ &m) {
m.def("sub", [](int a, int b) { return a - b; }); m.def("sub", [](int a, int b) { return a - b; });
} }

View File

@ -569,17 +569,17 @@ inline PyObject* make_new_python_type(const type_record &rec) {
#endif #endif
} }
object module; object module_;
if (rec.scope) { if (rec.scope) {
if (hasattr(rec.scope, "__module__")) if (hasattr(rec.scope, "__module__"))
module = rec.scope.attr("__module__"); module_ = rec.scope.attr("__module__");
else if (hasattr(rec.scope, "__name__")) else if (hasattr(rec.scope, "__name__"))
module = rec.scope.attr("__name__"); module_ = rec.scope.attr("__name__");
} }
auto full_name = c_str( auto full_name = c_str(
#if !defined(PYPY_VERSION) #if !defined(PYPY_VERSION)
module ? str(module).cast<std::string>() + "." + rec.name : module_ ? str(module_).cast<std::string>() + "." + rec.name :
#endif #endif
rec.name); rec.name);
@ -658,8 +658,8 @@ inline PyObject* make_new_python_type(const type_record &rec) {
else else
Py_INCREF(type); // Keep it alive forever (reference leak) Py_INCREF(type); // Keep it alive forever (reference leak)
if (module) // Needed by pydoc if (module_) // Needed by pydoc
setattr((PyObject *) type, "__module__", module); setattr((PyObject *) type, "__module__", module_);
PYBIND11_SET_OLDPY_QUALNAME(type, qualname); PYBIND11_SET_OLDPY_QUALNAME(type, qualname);

View File

@ -263,13 +263,13 @@ extern "C" {
***Deprecated in favor of PYBIND11_MODULE*** ***Deprecated in favor of PYBIND11_MODULE***
This macro creates the entry point that will be invoked when the Python interpreter This macro creates the entry point that will be invoked when the Python interpreter
imports a plugin library. Please create a `module` in the function body and return imports a plugin library. Please create a `module_` in the function body and return
the pointer to its underlying Python object at the end. the pointer to its underlying Python object at the end.
.. code-block:: cpp .. code-block:: cpp
PYBIND11_PLUGIN(example) { PYBIND11_PLUGIN(example) {
pybind11::module m("example", "pybind11 example plugin"); pybind11::module_ m("example", "pybind11 example plugin");
/// Set up bindings here /// Set up bindings here
return m.ptr(); return m.ptr();
} }
@ -290,7 +290,7 @@ extern "C" {
This macro creates the entry point that will be invoked when the Python interpreter This macro creates the entry point that will be invoked when the Python interpreter
imports an extension module. The module name is given as the fist argument and it imports an extension module. The module name is given as the fist argument and it
should not be in quotes. The second macro argument defines a variable of type should not be in quotes. The second macro argument defines a variable of type
`py::module` which can be used to initialize the module. `py::module_` which can be used to initialize the module.
The entry point is marked as "maybe unused" to aid dead-code detection analysis: The entry point is marked as "maybe unused" to aid dead-code detection analysis:
since the entry point is typically only looked up at runtime and not referenced since the entry point is typically only looked up at runtime and not referenced
@ -317,12 +317,12 @@ extern "C" {
#else #else
#define PYBIND11_DETAIL_MODULE_STATIC_DEF(name) #define PYBIND11_DETAIL_MODULE_STATIC_DEF(name)
#define PYBIND11_DETAIL_MODULE_CREATE(name) \ #define PYBIND11_DETAIL_MODULE_CREATE(name) \
auto m = pybind11::module(PYBIND11_TOSTRING(name)); auto m = pybind11::module_(PYBIND11_TOSTRING(name));
#endif #endif
#define PYBIND11_MODULE(name, variable) \ #define PYBIND11_MODULE(name, variable) \
PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \ PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
PYBIND11_MAYBE_UNUSED \ PYBIND11_MAYBE_UNUSED \
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &); \
PYBIND11_PLUGIN_IMPL(name) { \ PYBIND11_PLUGIN_IMPL(name) { \
PYBIND11_CHECK_PYTHON_VERSION \ PYBIND11_CHECK_PYTHON_VERSION \
PYBIND11_ENSURE_INTERNALS_READY \ PYBIND11_ENSURE_INTERNALS_READY \
@ -332,7 +332,7 @@ extern "C" {
return m.ptr(); \ return m.ptr(); \
} PYBIND11_CATCH_INIT_EXCEPTIONS \ } PYBIND11_CATCH_INIT_EXCEPTIONS \
} \ } \
void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &variable)
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

View File

@ -549,7 +549,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
return false; return false;
auto obj = reinterpret_borrow<object>(src); auto obj = reinterpret_borrow<object>(src);
object sparse_module = module::import("scipy.sparse"); object sparse_module = module_::import("scipy.sparse");
object matrix_type = sparse_module.attr( object matrix_type = sparse_module.attr(
rowMajor ? "csr_matrix" : "csc_matrix"); rowMajor ? "csr_matrix" : "csc_matrix");
@ -580,7 +580,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
const_cast<Type&>(src).makeCompressed(); const_cast<Type&>(src).makeCompressed();
object matrix_type = module::import("scipy.sparse").attr( object matrix_type = module_::import("scipy.sparse").attr(
rowMajor ? "csr_matrix" : "csc_matrix"); rowMajor ? "csr_matrix" : "csc_matrix");
array data(src.nonZeros(), src.valuePtr()); array data(src.nonZeros(), src.valuePtr());

View File

@ -46,9 +46,9 @@
} }
\endrst */ \endrst */
#define PYBIND11_EMBEDDED_MODULE(name, variable) \ #define PYBIND11_EMBEDDED_MODULE(name, variable) \
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &); \
static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ auto m = pybind11::module_(PYBIND11_TOSTRING(name)); \
try { \ try { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \ PYBIND11_CONCAT(pybind11_init_, name)(m); \
return m.ptr(); \ return m.ptr(); \
@ -64,7 +64,7 @@
pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \ pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \
(PYBIND11_TOSTRING(name), \ (PYBIND11_TOSTRING(name), \
PYBIND11_CONCAT(pybind11_init_impl_, name)); \ PYBIND11_CONCAT(pybind11_init_impl_, name)); \
void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &variable)
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
@ -109,7 +109,7 @@ inline void initialize_interpreter(bool init_signal_handlers = true) {
Py_InitializeEx(init_signal_handlers ? 1 : 0); Py_InitializeEx(init_signal_handlers ? 1 : 0);
// Make .py files in the working directory available by default // Make .py files in the working directory available by default
module::import("sys").attr("path").cast<list>().append("."); module_::import("sys").attr("path").cast<list>().append(".");
} }
/** \rst /** \rst

View File

@ -52,7 +52,7 @@ object eval(str expr, object global = globals(), object local = object()) {
template <eval_mode mode = eval_expr, size_t N> template <eval_mode mode = eval_expr, size_t N>
object eval(const char (&s)[N], object global = globals(), object local = object()) { object eval(const char (&s)[N], object global = globals(), object local = object()) {
/* Support raw string literals by removing common leading whitespace */ /* Support raw string literals by removing common leading whitespace */
auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s))
: str(s); : str(s);
return eval<mode>(expr, global, local); return eval<mode>(expr, global, local);
} }

View File

@ -102,7 +102,7 @@ PYBIND11_NAMESPACE_END(detail)
.. code-block:: cpp .. code-block:: cpp
{ {
py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; py::scoped_ostream_redirect output{std::cerr, py::module_::import("sys").attr("stderr")};
std::cerr << "Hello, World!"; std::cerr << "Hello, World!";
} }
\endrst */ \endrst */
@ -115,7 +115,7 @@ protected:
public: public:
scoped_ostream_redirect( scoped_ostream_redirect(
std::ostream &costream = std::cout, std::ostream &costream = std::cout,
object pyostream = module::import("sys").attr("stdout")) object pyostream = module_::import("sys").attr("stdout"))
: costream(costream), buffer(pyostream) { : costream(costream), buffer(pyostream) {
old = costream.rdbuf(&buffer); old = costream.rdbuf(&buffer);
} }
@ -146,7 +146,7 @@ class scoped_estream_redirect : public scoped_ostream_redirect {
public: public:
scoped_estream_redirect( scoped_estream_redirect(
std::ostream &costream = std::cerr, std::ostream &costream = std::cerr,
object pyostream = module::import("sys").attr("stderr")) object pyostream = module_::import("sys").attr("stderr"))
: scoped_ostream_redirect(costream,pyostream) {} : scoped_ostream_redirect(costream,pyostream) {}
}; };
@ -206,7 +206,7 @@ PYBIND11_NAMESPACE_END(detail)
m.noisy_function_with_error_printing() m.noisy_function_with_error_printing()
\endrst */ \endrst */
inline class_<detail::OstreamRedirect> add_ostream_redirect(module m, std::string name = "ostream_redirect") { inline class_<detail::OstreamRedirect> add_ostream_redirect(module_ m, std::string name = "ostream_redirect") {
return class_<detail::OstreamRedirect>(m, name.c_str(), module_local()) return class_<detail::OstreamRedirect>(m, name.c_str(), module_local())
.def(init<bool,bool>(), arg("stdout")=true, arg("stderr")=true) .def(init<bool,bool>(), arg("stdout")=true, arg("stderr")=true)
.def("__enter__", &detail::OstreamRedirect::enter) .def("__enter__", &detail::OstreamRedirect::enter)

View File

@ -222,7 +222,7 @@ private:
}; };
static npy_api lookup() { static npy_api lookup() {
module_ m = module::import("numpy.core.multiarray"); module_ m = module_::import("numpy.core.multiarray");
auto c = m.attr("_ARRAY_API"); auto c = m.attr("_ARRAY_API");
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL); void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
@ -505,7 +505,7 @@ public:
private: private:
static object _dtype_from_pep3118() { static object _dtype_from_pep3118() {
static PyObject *obj = module::import("numpy.core._internal") static PyObject *obj = module_::import("numpy.core._internal")
.attr("_dtype_from_pep3118").cast<object>().release().ptr(); .attr("_dtype_from_pep3118").cast<object>().release().ptr();
return reinterpret_borrow<object>(obj); return reinterpret_borrow<object>(obj);
} }

View File

@ -904,9 +904,9 @@ public:
.. code-block:: cpp .. code-block:: cpp
py::module m("example", "pybind11 example plugin"); py::module_ m("example", "pybind11 example plugin");
py::module m2 = m.def_submodule("sub", "A submodule of 'example'"); py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'");
py::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
\endrst */ \endrst */
module_ def_submodule(const char *name, const char *doc = nullptr) { module_ def_submodule(const char *name, const char *doc = nullptr) {
std::string full_name = std::string(PyModule_GetName(m_ptr)) std::string full_name = std::string(PyModule_GetName(m_ptr))
@ -965,12 +965,15 @@ private:
}; };
m_ptr = PyModule_Create(def); m_ptr = PyModule_Create(def);
if (m_ptr == nullptr) if (m_ptr == nullptr)
pybind11_fail("Internal error in module::module()"); pybind11_fail("Internal error in module_::module_()");
inc_ref(); inc_ref();
} }
#endif #endif
}; };
// When inside a namespace (or anywhere as long as it's not the first item on a line),
// C++20 allows "module" to be used. This is provided for backward compatibility, and for
// simplicity, if someone wants to use py::module for example, that is perfectly safe.
using module = module_; using module = module_;
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
@ -986,7 +989,7 @@ PYBIND11_NAMESPACE_END(detail)
/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded). /// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded).
inline dict globals() { inline dict globals() {
PyObject *p = PyEval_GetGlobals(); PyObject *p = PyEval_GetGlobals();
return reinterpret_borrow<dict>(p ? p : module::import("__main__").attr("__dict__").ptr()); return reinterpret_borrow<dict>(p ? p : module_::import("__main__").attr("__dict__").ptr());
} }
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
@ -1973,7 +1976,7 @@ PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) {
file = kwargs["file"].cast<object>(); file = kwargs["file"].cast<object>();
} else { } else {
try { try {
file = module::import("sys").attr("stdout"); file = module_::import("sys").attr("stdout");
} catch (const error_already_set &) { } catch (const error_already_set &) {
/* If print() is called from code that is executed as /* If print() is called from code that is executed as
part of garbage collection during interpreter shutdown, part of garbage collection during interpreter shutdown,

View File

@ -120,7 +120,7 @@ public:
throw py::error_already_set(); throw py::error_already_set();
Py_DECREF(result); Py_DECREF(result);
#else #else
py::module::import("gc").attr("collect")(); py::module_::import("gc").attr("collect")();
#endif #endif
} }

View File

@ -26,8 +26,8 @@ productively.
Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions" Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions"
section of the documentation for good practice on splitting binding code over multiple files. section of the documentation for good practice on splitting binding code over multiple files.
*/ */
std::list<std::function<void(py::module &)>> &initializers() { std::list<std::function<void(py::module_ &)>> &initializers() {
static std::list<std::function<void(py::module &)>> inits; static std::list<std::function<void(py::module_ &)>> inits;
return inits; return inits;
} }
@ -36,13 +36,13 @@ test_initializer::test_initializer(Initializer init) {
} }
test_initializer::test_initializer(const char *submodule_name, Initializer init) { test_initializer::test_initializer(const char *submodule_name, Initializer init) {
initializers().emplace_back([=](py::module &parent) { initializers().emplace_back([=](py::module_ &parent) {
auto m = parent.def_submodule(submodule_name); auto m = parent.def_submodule(submodule_name);
init(m); init(m);
}); });
} }
void bind_ConstructorStats(py::module &m) { void bind_ConstructorStats(py::module_ &m) {
py::class_<ConstructorStats>(m, "ConstructorStats") py::class_<ConstructorStats>(m, "ConstructorStats")
.def("alive", &ConstructorStats::alive) .def("alive", &ConstructorStats::alive)
.def("values", &ConstructorStats::values) .def("values", &ConstructorStats::values)

View File

@ -10,7 +10,7 @@ namespace py = pybind11;
using namespace pybind11::literals; using namespace pybind11::literals;
class test_initializer { class test_initializer {
using Initializer = void (*)(py::module &); using Initializer = void (*)(py::module_ &);
public: public:
test_initializer(Initializer init); test_initializer(Initializer init);
@ -18,9 +18,9 @@ public:
}; };
#define TEST_SUBMODULE(name, variable) \ #define TEST_SUBMODULE(name, variable) \
void test_submodule_##name(py::module &); \ void test_submodule_##name(py::module_ &); \
test_initializer name(#name, test_submodule_##name); \ test_initializer name(#name, test_submodule_##name); \
void test_submodule_##name(py::module &variable) void test_submodule_##name(py::module_ &variable)
/// Dummy type which is not exported anywhere -- something to trigger a conversion error /// Dummy type which is not exported anywhere -- something to trigger a conversion error

View File

@ -18,7 +18,7 @@ TEST_SUBMODULE(async_module, m) {
.def(py::init<>()) .def(py::init<>())
.def("__await__", [](const SupportsAsync& self) -> py::object { .def("__await__", [](const SupportsAsync& self) -> py::object {
static_cast<void>(self); static_cast<void>(self);
py::object loop = py::module::import("asyncio.events").attr("get_event_loop")(); py::object loop = py::module_::import("asyncio.events").attr("get_event_loop")();
py::object f = loop.attr("create_future")(); py::object f = loop.attr("create_future")();
f.attr("set_result")(5); f.attr("set_result")(5);
return f.attr("__await__")(); return f.attr("__await__")();

View File

@ -172,12 +172,12 @@ TEST_SUBMODULE(class_, m) {
struct MismatchDerived2 : MismatchBase2 { }; struct MismatchDerived2 : MismatchBase2 { };
m.def("mismatched_holder_1", []() { m.def("mismatched_holder_1", []() {
auto mod = py::module::import("__main__"); auto mod = py::module_::import("__main__");
py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1"); py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1"); py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1");
}); });
m.def("mismatched_holder_2", []() { m.def("mismatched_holder_2", []() {
auto mod = py::module::import("__main__"); auto mod = py::module_::import("__main__");
py::class_<MismatchBase2>(mod, "MismatchBase2"); py::class_<MismatchBase2>(mod, "MismatchBase2");
py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>,
MismatchBase2>(mod, "MismatchDerived2"); MismatchBase2>(mod, "MismatchDerived2");

View File

@ -12,10 +12,10 @@ int main(int argc, char *argv[]) {
py::scoped_interpreter guard{}; py::scoped_interpreter guard{};
auto m = py::module::import("test_cmake_build"); auto m = py::module_::import("test_cmake_build");
if (m.attr("add")(1, 2).cast<int>() != 3) if (m.attr("add")(1, 2).cast<int>() != 3)
throw std::runtime_error("embed.cpp failed"); throw std::runtime_error("embed.cpp failed");
py::module::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp"); py::module_::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp");
py::eval_file(test_py_file, py::globals()); py::eval_file(test_py_file, py::globals());
} }

View File

@ -317,11 +317,11 @@ TEST_SUBMODULE(eigen, m) {
// a new array (np.ones(10)) increases the chances that the temp array will be garbage // a new array (np.ones(10)) increases the chances that the temp array will be garbage
// collected and/or that its memory will be overridden with different values. // collected and/or that its memory will be overridden with different values.
m.def("get_elem_direct", [](Eigen::Ref<const Eigen::VectorXd> v) { m.def("get_elem_direct", [](Eigen::Ref<const Eigen::VectorXd> v) {
py::module::import("numpy").attr("ones")(10); py::module_::import("numpy").attr("ones")(10);
return v(5); return v(5);
}); });
m.def("get_elem_indirect", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) { m.def("get_elem_indirect", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) {
py::module::import("numpy").attr("ones")(10); py::module_::import("numpy").attr("ones")(10);
return v[0](5); return v[0](5);
}); });
} }

View File

@ -51,17 +51,17 @@ PYBIND11_EMBEDDED_MODULE(throw_error_already_set, ) {
} }
TEST_CASE("Pass classes and data between modules defined in C++ and Python") { TEST_CASE("Pass classes and data between modules defined in C++ and Python") {
auto module = py::module::import("test_interpreter"); auto module_ = py::module_::import("test_interpreter");
REQUIRE(py::hasattr(module, "DerivedWidget")); REQUIRE(py::hasattr(module_, "DerivedWidget"));
auto locals = py::dict("hello"_a="Hello, World!", "x"_a=5, **module.attr("__dict__")); auto locals = py::dict("hello"_a="Hello, World!", "x"_a=5, **module_.attr("__dict__"));
py::exec(R"( py::exec(R"(
widget = DerivedWidget("{} - {}".format(hello, x)) widget = DerivedWidget("{} - {}".format(hello, x))
message = widget.the_message message = widget.the_message
)", py::globals(), locals); )", py::globals(), locals);
REQUIRE(locals["message"].cast<std::string>() == "Hello, World! - 5"); REQUIRE(locals["message"].cast<std::string>() == "Hello, World! - 5");
auto py_widget = module.attr("DerivedWidget")("The question"); auto py_widget = module_.attr("DerivedWidget")("The question");
auto message = py_widget.attr("the_message"); auto message = py_widget.attr("the_message");
REQUIRE(message.cast<std::string>() == "The question"); REQUIRE(message.cast<std::string>() == "The question");
@ -70,10 +70,10 @@ TEST_CASE("Pass classes and data between modules defined in C++ and Python") {
} }
TEST_CASE("Import error handling") { TEST_CASE("Import error handling") {
REQUIRE_NOTHROW(py::module::import("widget_module")); REQUIRE_NOTHROW(py::module_::import("widget_module"));
REQUIRE_THROWS_WITH(py::module::import("throw_exception"), REQUIRE_THROWS_WITH(py::module_::import("throw_exception"),
"ImportError: C++ Error"); "ImportError: C++ Error");
REQUIRE_THROWS_WITH(py::module::import("throw_error_already_set"), REQUIRE_THROWS_WITH(py::module_::import("throw_error_already_set"),
Catch::Contains("ImportError: KeyError")); Catch::Contains("ImportError: KeyError"));
} }
@ -107,14 +107,14 @@ bool has_pybind11_internals_static() {
TEST_CASE("Restart the interpreter") { TEST_CASE("Restart the interpreter") {
// Verify pre-restart state. // Verify pre-restart state.
REQUIRE(py::module::import("widget_module").attr("add")(1, 2).cast<int>() == 3); REQUIRE(py::module_::import("widget_module").attr("add")(1, 2).cast<int>() == 3);
REQUIRE(has_pybind11_internals_builtin()); REQUIRE(has_pybind11_internals_builtin());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
REQUIRE(py::module::import("external_module").attr("A")(123).attr("value").cast<int>() == 123); REQUIRE(py::module_::import("external_module").attr("A")(123).attr("value").cast<int>() == 123);
// local and foreign module internals should point to the same internals: // local and foreign module internals should point to the same internals:
REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) == REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) ==
py::module::import("external_module").attr("internals_at")().cast<uintptr_t>()); py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
// Restart the interpreter. // Restart the interpreter.
py::finalize_interpreter(); py::finalize_interpreter();
@ -130,14 +130,14 @@ TEST_CASE("Restart the interpreter") {
REQUIRE(has_pybind11_internals_builtin()); REQUIRE(has_pybind11_internals_builtin());
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) == REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) ==
py::module::import("external_module").attr("internals_at")().cast<uintptr_t>()); py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
// Make sure that an interpreter with no get_internals() created until finalize still gets the // Make sure that an interpreter with no get_internals() created until finalize still gets the
// internals destroyed // internals destroyed
py::finalize_interpreter(); py::finalize_interpreter();
py::initialize_interpreter(); py::initialize_interpreter();
bool ran = false; bool ran = false;
py::module::import("__main__").attr("internals_destroy_test") = py::module_::import("__main__").attr("internals_destroy_test") =
py::capsule(&ran, [](void *ran) { py::detail::get_internals(); *static_cast<bool *>(ran) = true; }); py::capsule(&ran, [](void *ran) { py::detail::get_internals(); *static_cast<bool *>(ran) = true; });
REQUIRE_FALSE(has_pybind11_internals_builtin()); REQUIRE_FALSE(has_pybind11_internals_builtin());
REQUIRE_FALSE(has_pybind11_internals_static()); REQUIRE_FALSE(has_pybind11_internals_static());
@ -149,20 +149,20 @@ TEST_CASE("Restart the interpreter") {
REQUIRE_FALSE(has_pybind11_internals_static()); REQUIRE_FALSE(has_pybind11_internals_static());
// C++ modules can be reloaded. // C++ modules can be reloaded.
auto cpp_module = py::module::import("widget_module"); auto cpp_module = py::module_::import("widget_module");
REQUIRE(cpp_module.attr("add")(1, 2).cast<int>() == 3); REQUIRE(cpp_module.attr("add")(1, 2).cast<int>() == 3);
// C++ type information is reloaded and can be used in python modules. // C++ type information is reloaded and can be used in python modules.
auto py_module = py::module::import("test_interpreter"); auto py_module = py::module_::import("test_interpreter");
auto py_widget = py_module.attr("DerivedWidget")("Hello after restart"); auto py_widget = py_module.attr("DerivedWidget")("Hello after restart");
REQUIRE(py_widget.attr("the_message").cast<std::string>() == "Hello after restart"); REQUIRE(py_widget.attr("the_message").cast<std::string>() == "Hello after restart");
} }
TEST_CASE("Subinterpreter") { TEST_CASE("Subinterpreter") {
// Add tags to the modules in the main interpreter and test the basics. // Add tags to the modules in the main interpreter and test the basics.
py::module::import("__main__").attr("main_tag") = "main interpreter"; py::module_::import("__main__").attr("main_tag") = "main interpreter";
{ {
auto m = py::module::import("widget_module"); auto m = py::module_::import("widget_module");
m.attr("extension_module_tag") = "added to module in main interpreter"; m.attr("extension_module_tag") = "added to module in main interpreter";
REQUIRE(m.attr("add")(1, 2).cast<int>() == 3); REQUIRE(m.attr("add")(1, 2).cast<int>() == 3);
@ -181,9 +181,9 @@ TEST_CASE("Subinterpreter") {
REQUIRE(has_pybind11_internals_static()); REQUIRE(has_pybind11_internals_static());
// Modules tags should be gone. // Modules tags should be gone.
REQUIRE_FALSE(py::hasattr(py::module::import("__main__"), "tag")); REQUIRE_FALSE(py::hasattr(py::module_::import("__main__"), "tag"));
{ {
auto m = py::module::import("widget_module"); auto m = py::module_::import("widget_module");
REQUIRE_FALSE(py::hasattr(m, "extension_module_tag")); REQUIRE_FALSE(py::hasattr(m, "extension_module_tag"));
// Function bindings should still work. // Function bindings should still work.
@ -194,8 +194,8 @@ TEST_CASE("Subinterpreter") {
Py_EndInterpreter(sub_tstate); Py_EndInterpreter(sub_tstate);
PyThreadState_Swap(main_tstate); PyThreadState_Swap(main_tstate);
REQUIRE(py::hasattr(py::module::import("__main__"), "main_tag")); REQUIRE(py::hasattr(py::module_::import("__main__"), "main_tag"));
REQUIRE(py::hasattr(py::module::import("widget_module"), "extension_module_tag")); REQUIRE(py::hasattr(py::module_::import("widget_module"), "extension_module_tag"));
} }
TEST_CASE("Execution frame") { TEST_CASE("Execution frame") {
@ -245,7 +245,7 @@ TEST_CASE("Reload module from file") {
// Disable generation of cached bytecode (.pyc files) for this test, otherwise // Disable generation of cached bytecode (.pyc files) for this test, otherwise
// Python might pick up an old version from the cache instead of the new versions // Python might pick up an old version from the cache instead of the new versions
// of the .py files generated below // of the .py files generated below
auto sys = py::module::import("sys"); auto sys = py::module_::import("sys");
bool dont_write_bytecode = sys.attr("dont_write_bytecode").cast<bool>(); bool dont_write_bytecode = sys.attr("dont_write_bytecode").cast<bool>();
sys.attr("dont_write_bytecode") = true; sys.attr("dont_write_bytecode") = true;
// Reset the value at scope exit // Reset the value at scope exit
@ -267,8 +267,8 @@ TEST_CASE("Reload module from file") {
}); });
// Import the module from file // Import the module from file
auto module = py::module::import(module_name.c_str()); auto module_ = py::module_::import(module_name.c_str());
int result = module.attr("test")().cast<int>(); int result = module_.attr("test")().cast<int>();
REQUIRE(result == 1); REQUIRE(result == 1);
// Update the module .py file with a small change // Update the module .py file with a small change
@ -278,7 +278,7 @@ TEST_CASE("Reload module from file") {
test_module.close(); test_module.close();
// Reload the module // Reload the module
module.reload(); module_.reload();
result = module.attr("test")().cast<int>(); result = module_.attr("test")().cast<int>();
REQUIRE(result == 2); REQUIRE(result == 2);
} }

View File

@ -14,7 +14,7 @@
TEST_SUBMODULE(eval_, m) { TEST_SUBMODULE(eval_, m) {
// test_evals // test_evals
auto global = py::dict(py::module::import("__main__").attr("__dict__")); auto global = py::dict(py::module_::import("__main__").attr("__dict__"));
m.def("test_eval_statements", [global]() { m.def("test_eval_statements", [global]() {
auto local = py::dict(); auto local = py::dict();

View File

@ -163,7 +163,7 @@ TEST_SUBMODULE(exceptions, m) {
m.def("modulenotfound_exception_matches_base", []() { m.def("modulenotfound_exception_matches_base", []() {
try { try {
// On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError // On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError
py::module::import("nonexistent"); py::module_::import("nonexistent");
} }
catch (py::error_already_set &ex) { catch (py::error_already_set &ex) {
if (!ex.matches(PyExc_ImportError)) throw; if (!ex.matches(PyExc_ImportError)) throw;

View File

@ -142,7 +142,7 @@ public:
TEST_SUBMODULE(factory_constructors, m) { TEST_SUBMODULE(factory_constructors, m) {
// Define various trivial types to allow simpler overload resolution: // Define various trivial types to allow simpler overload resolution:
py::module m_tag = m.def_submodule("tag"); py::module_ m_tag = m.def_submodule("tag");
#define MAKE_TAG_TYPE(Name) \ #define MAKE_TAG_TYPE(Name) \
struct Name##_tag {}; \ struct Name##_tag {}; \
py::class_<Name##_tag>(m_tag, #Name "_tag").def(py::init<>()); \ py::class_<Name##_tag>(m_tag, #Name "_tag").def(py::init<>()); \

View File

@ -45,7 +45,7 @@ TEST_SUBMODULE(gil_scoped, m) {
[](VirtClass &virt) { virt.pure_virtual_func(); }); [](VirtClass &virt) { virt.pure_virtual_func(); });
m.def("test_cross_module_gil", m.def("test_cross_module_gil",
[]() { []() {
auto cm = py::module::import("cross_module_gil_utils"); auto cm = py::module_::import("cross_module_gil_utils");
auto gil_acquire = reinterpret_cast<void (*)()>( auto gil_acquire = reinterpret_cast<void (*)()>(
PyLong_AsVoidPtr(cm.attr("gil_acquire_funcaddr").ptr())); PyLong_AsVoidPtr(cm.attr("gil_acquire_funcaddr").ptr()));
py::gil_scoped_release gil_release; py::gil_scoped_release gil_release;

View File

@ -37,7 +37,7 @@ TEST_SUBMODULE(iostream, m) {
}); });
m.def("captured_output", [](std::string msg) { m.def("captured_output", [](std::string msg) {
py::scoped_ostream_redirect redir(std::cout, py::module::import("sys").attr("stdout")); py::scoped_ostream_redirect redir(std::cout, py::module_::import("sys").attr("stdout"));
std::cout << msg << std::flush; std::cout << msg << std::flush;
}); });
@ -46,7 +46,7 @@ TEST_SUBMODULE(iostream, m) {
py::arg("msg"), py::arg("flush")=true); py::arg("msg"), py::arg("flush")=true);
m.def("captured_err", [](std::string msg) { m.def("captured_err", [](std::string msg) {
py::scoped_ostream_redirect redir(std::cerr, py::module::import("sys").attr("stderr")); py::scoped_ostream_redirect redir(std::cerr, py::module_::import("sys").attr("stderr"));
std::cerr << msg << std::flush; std::cerr << msg << std::flush;
}); });
@ -65,8 +65,8 @@ TEST_SUBMODULE(iostream, m) {
}); });
m.def("captured_dual", [](std::string msg, std::string emsg) { m.def("captured_dual", [](std::string msg, std::string emsg) {
py::scoped_ostream_redirect redirout(std::cout, py::module::import("sys").attr("stdout")); py::scoped_ostream_redirect redirout(std::cout, py::module_::import("sys").attr("stdout"));
py::scoped_ostream_redirect redirerr(std::cerr, py::module::import("sys").attr("stderr")); py::scoped_ostream_redirect redirerr(std::cerr, py::module_::import("sys").attr("stderr"));
std::cout << msg << std::flush; std::cout << msg << std::flush;
std::cerr << emsg << std::flush; std::cerr << emsg << std::flush;
}); });

View File

@ -107,7 +107,7 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
return py::make_tuple(i, j, k, kwargs); }, return py::make_tuple(i, j, k, kwargs); },
py::arg() /* positional */, py::arg("j") = -1 /* both */, py::kw_only(), py::arg("k") /* kw-only */); py::arg() /* positional */, py::arg("j") = -1 /* both */, py::kw_only(), py::arg("k") /* kw-only */);
m.def("register_invalid_kw_only", [](py::module m) { m.def("register_invalid_kw_only", [](py::module_ m) {
m.def("bad_kw_only", [](int i, int j) { return py::make_tuple(i, j); }, m.def("bad_kw_only", [](int i, int j) { return py::make_tuple(i, j); },
py::kw_only(), py::arg() /* invalid unnamed argument */, "j"_a); py::kw_only(), py::arg() /* invalid unnamed argument */, "j"_a);
}); });
@ -138,5 +138,5 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
// Make sure a class (not an instance) can be used as a default argument. // Make sure a class (not an instance) can be used as a default argument.
// The return value doesn't matter, only that the module is importable. // The return value doesn't matter, only that the module is importable.
m.def("class_default_argument", [](py::object a) { return py::repr(a); }, m.def("class_default_argument", [](py::object a) { return py::repr(a); },
"a"_a = py::module::import("decimal").attr("Decimal")); "a"_a = py::module_::import("decimal").attr("Decimal"));
} }

View File

@ -41,7 +41,7 @@ TEST_SUBMODULE(local_bindings, m) {
// should raise a runtime error from the duplicate definition attempt. If test_class isn't // should raise a runtime error from the duplicate definition attempt. If test_class isn't
// available it *also* throws a runtime error (with "test_class not enabled" as value). // available it *also* throws a runtime error (with "test_class not enabled" as value).
m.def("register_local_external", [m]() { m.def("register_local_external", [m]() {
auto main = py::module::import("pybind11_tests"); auto main = py::module_::import("pybind11_tests");
if (py::hasattr(main, "class_")) { if (py::hasattr(main, "class_")) {
bind_local<LocalExternal, 7>(m, "LocalExternal", py::module_local()); bind_local<LocalExternal, 7>(m, "LocalExternal", py::module_local());
} }

View File

@ -207,12 +207,12 @@ TEST_SUBMODULE(methods_and_attributes, m) {
// test_no_mixed_overloads // test_no_mixed_overloads
// Raise error if trying to mix static/non-static overloads on the same name: // Raise error if trying to mix static/non-static overloads on the same name:
.def_static("add_mixed_overloads1", []() { .def_static("add_mixed_overloads1", []() {
auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA")); auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module_::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
emna.def ("overload_mixed1", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded)) emna.def ("overload_mixed1", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded))
.def_static("overload_mixed1", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded)); .def_static("overload_mixed1", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded));
}) })
.def_static("add_mixed_overloads2", []() { .def_static("add_mixed_overloads2", []() {
auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA")); auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module_::import("pybind11_tests.methods_and_attributes").attr("ExampleMandA"));
emna.def_static("overload_mixed2", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded)) emna.def_static("overload_mixed2", static_cast<py::str ( *)(float )>(&ExampleMandA::overloaded))
.def ("overload_mixed2", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded)); .def ("overload_mixed2", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded));
}) })
@ -308,11 +308,11 @@ TEST_SUBMODULE(methods_and_attributes, m) {
m.attr("debug_enabled") = false; m.attr("debug_enabled") = false;
#endif #endif
m.def("bad_arg_def_named", []{ m.def("bad_arg_def_named", []{
auto m = py::module::import("pybind11_tests"); auto m = py::module_::import("pybind11_tests");
m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg("a") = UnregisteredType()); m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg("a") = UnregisteredType());
}); });
m.def("bad_arg_def_unnamed", []{ m.def("bad_arg_def_unnamed", []{
auto m = py::module::import("pybind11_tests"); auto m = py::module_::import("pybind11_tests");
m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg() = UnregisteredType()); m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg() = UnregisteredType());
}); });

View File

@ -13,6 +13,7 @@
TEST_SUBMODULE(modules, m) { TEST_SUBMODULE(modules, m) {
// test_nested_modules // test_nested_modules
// This is intentionally "py::module" to verify it still can be used in place of "py::module_"
py::module m_sub = m.def_submodule("subsubmodule"); py::module m_sub = m.def_submodule("subsubmodule");
m_sub.def("submodule_func", []() { return "submodule_func()"; }); m_sub.def("submodule_func", []() { return "submodule_func()"; });
@ -50,6 +51,7 @@ TEST_SUBMODULE(modules, m) {
.def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default
.def_readwrite("a2", &B::a2); .def_readwrite("a2", &B::a2);
// This is intentionally "py::module" to verify it still can be used in place of "py::module_"
m.attr("OD") = py::module::import("collections").attr("OrderedDict"); m.attr("OD") = py::module::import("collections").attr("OrderedDict");
// test_duplicate_registration // test_duplicate_registration
@ -60,7 +62,7 @@ TEST_SUBMODULE(modules, m) {
class Dupe3 { }; class Dupe3 { };
class DupeException { }; class DupeException { };
auto dm = py::module("dummy"); auto dm = py::module_("dummy");
auto failures = py::list(); auto failures = py::list();
py::class_<Dupe1>(dm, "Dupe1"); py::class_<Dupe1>(dm, "Dupe1");

View File

@ -22,7 +22,7 @@ struct DtypeCheck {
template <typename T> template <typename T>
DtypeCheck get_dtype_check(const char* name) { DtypeCheck get_dtype_check(const char* name) {
py::module np = py::module::import("numpy"); py::module_ np = py::module_::import("numpy");
DtypeCheck check{}; DtypeCheck check{};
check.numpy = np.attr("dtype")(np.attr(name)); check.numpy = np.attr("dtype")(np.attr(name));
check.pybind11 = py::dtype::of<T>(); check.pybind11 = py::dtype::of<T>();
@ -133,7 +133,7 @@ template <typename T, typename T2> py::handle auxiliaries(T &&r, T2 &&r2) {
static int data_i = 42; static int data_i = 42;
TEST_SUBMODULE(numpy_array, sm) { TEST_SUBMODULE(numpy_array, sm) {
try { py::module::import("numpy"); } try { py::module_::import("numpy"); }
catch (...) { return; } catch (...) { return; }
// test_dtypes // test_dtypes

View File

@ -255,7 +255,7 @@ struct A {};
struct B {}; struct B {};
TEST_SUBMODULE(numpy_dtypes, m) { TEST_SUBMODULE(numpy_dtypes, m) {
try { py::module::import("numpy"); } try { py::module_::import("numpy"); }
catch (...) { return; } catch (...) { return; }
// typeinfo may be registered before the dtype descriptor for scalar casts to work... // typeinfo may be registered before the dtype descriptor for scalar casts to work...

View File

@ -17,7 +17,7 @@ double my_func(int x, float y, double z) {
} }
TEST_SUBMODULE(numpy_vectorize, m) { TEST_SUBMODULE(numpy_vectorize, m) {
try { py::module::import("numpy"); } try { py::module_::import("numpy"); }
catch (...) { return; } catch (...) { return; }
// test_vectorize, test_docs, test_array_collapse // test_vectorize, test_docs, test_array_collapse

View File

@ -289,7 +289,7 @@ TEST_SUBMODULE(pytypes, m) {
py::print("no new line here", "end"_a=" -- "); py::print("no new line here", "end"_a=" -- ");
py::print("next print"); py::print("next print");
auto py_stderr = py::module::import("sys").attr("stderr"); auto py_stderr = py::module_::import("sys").attr("stderr");
py::print("this goes to stderr", "file"_a=py_stderr); py::print("this goes to stderr", "file"_a=py_stderr);
py::print("flush", "flush"_a=true); py::print("flush", "flush"_a=true);

View File

@ -117,7 +117,7 @@ TEST_SUBMODULE(stl_binders, m) {
}); });
// The rest depends on numpy: // The rest depends on numpy:
try { py::module::import("numpy"); } try { py::module_::import("numpy"); }
catch (...) { return; } catch (...) { return; }
// test_vector_buffer_numpy // test_vector_buffer_numpy

View File

@ -187,7 +187,7 @@ static void test_gil_from_thread() {
// Forward declaration (so that we can put the main tests here; the inherited virtual approaches are // Forward declaration (so that we can put the main tests here; the inherited virtual approaches are
// rather long). // rather long).
void initialize_inherited_virtuals(py::module &m); void initialize_inherited_virtuals(py::module_ &m);
TEST_SUBMODULE(virtual_functions, m) { TEST_SUBMODULE(virtual_functions, m) {
// test_override // test_override
@ -459,7 +459,7 @@ public:
}; };
*/ */
void initialize_inherited_virtuals(py::module &m) { void initialize_inherited_virtuals(py::module_ &m) {
// test_inherited_virtuals // test_inherited_virtuals
// Method 1: repeat // Method 1: repeat