Unverified Commit 6bcd220c authored by Henry Schreiner's avatar Henry Schreiner Committed by GitHub
Browse files

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

* WIP: module -> module_ without typedef

* refactor: allow py::module to work again
parent 560ed3e3
......@@ -108,11 +108,11 @@ The two approaches can also be combined:
Importing modules
=================
Python modules can be imported using `module::import()`:
Python modules can be imported using `module_::import()`:
.. code-block:: cpp
py::module sys = py::module::import("sys");
py::module_ sys = py::module_::import("sys");
py::print(sys.attr("path"));
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
py::module calc = py::module::import("calc");
py::module_ calc = py::module_::import("calc");
py::object result = calc.attr("add")(1, 2);
int n = result.cast<int>();
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
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.
......@@ -153,7 +153,7 @@ like any other module.
namespace py = pybind11;
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) {
return i + j;
});
......@@ -162,7 +162,7 @@ like any other module.
int main() {
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>();
assert(result == 3);
}
......@@ -196,7 +196,7 @@ naturally:
int main() {
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__"));
assert(locals["a"].cast<int>() == 1);
......
......@@ -182,7 +182,7 @@ For example:
try {
// 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")();
file.attr("close")();
} catch (py::error_already_set &e) {
......
......@@ -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
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*
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
:enum:`return_value_policy::automatic`.
......
......@@ -132,7 +132,7 @@ However, it can be acquired as follows:
.. 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)
.def(py::init<const std::string &>())
......@@ -146,7 +146,7 @@ has been executed:
.. code-block:: cpp
py::module::import("basic");
py::module_::import("basic");
py::class_<Dog, Pet>(m, "Dog")
.def(py::init<const std::string &>())
......@@ -243,7 +243,7 @@ avoids this issue involves weak reference with a cleanup callback:
.. code-block:: cpp
auto atexit = py::module::import("atexit");
auto atexit = py::module_::import("atexit");
atexit.attr("register")(py::cpp_function([]() {
// 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");
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
the docstring completely to exclude the function from the Sphinx documentation.
The class ``options`` allows you to selectively suppress auto-generated signatures:
......
......@@ -56,12 +56,12 @@ This example obtains a reference to the Python ``Decimal`` class.
.. code-block:: cpp
// 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
// Try to import scipy
py::object scipy = py::module::import("scipy");
py::object scipy = py::module_::import("scipy");
return scipy.attr("__version__");
......@@ -81,7 +81,7 @@ via ``operator()``.
.. code-block:: cpp
// 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");
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>
using namespace pybind11::literals;
py::module os = py::module::import("os");
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_ os = py::module_::import("os");
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::str curdir_abs = path.attr("abspath")(path.attr("curdir"));
py::print(py::str("Current directory: ") + curdir_abs);
......
......@@ -42,7 +42,7 @@ redirects output to the corresponding Python streams:
m.def("noisy_func", []() {
py::scoped_ostream_redirect stream(
std::cout, // std::ostream&
py::module::import("sys").attr("stdout") // Python output
py::module_::import("sys").attr("stdout") // Python output
);
call_noisy_func();
});
......@@ -104,7 +104,7 @@ can be used.
...
// 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
int result = py::eval("my_variable + 10", scope).cast<int>();
......
......@@ -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
``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
argument (``m``) defines a variable of type :class:`py::module <module>` which
is the main interface for creating bindings. The method :func:`module::def`
argument (``m``) defines a variable of type :class:`py::module_ <module>` which
is the main interface for creating bindings. The method :func:`module_::def`
generates binding code that exposes the ``add()`` function to Python.
.. note::
......@@ -181,7 +181,7 @@ names of the arguments ("i" and "j" in this case).
py::arg("i"), py::arg("j"));
: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
particularly for functions taking many parameters:
......
......@@ -11,9 +11,9 @@ v2.6.0 (IN PROGRESS)
See :ref:`upgrade-guide-2.6` for help upgrading to the new version.
* Provide an additional spelling of ``py::module`` - ``py::module_`` (with a
trailing underscore), for C++20 compatibility. Only relevant when used
unqualified.
* ``py::module`` was renamed ``py::module_`` to avoid issues with C++20 when
used unqualified, but an alias ``py::module`` is provided for backward
compatibility.
`#2489 <https://github.com/pybind/pybind11/pull/2489>`_
* ``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)
-----------------------------------------------------
* 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>`_.
* Fixed a reference leak in the number converter.
......
......@@ -100,8 +100,8 @@ following example:
.. code-block:: cpp
void init_ex1(py::module &);
void init_ex2(py::module &);
void init_ex1(py::module_ &);
void init_ex2(py::module_ &);
/* ... */
PYBIND11_MODULE(example, m) {
......@@ -114,7 +114,7 @@ following example:
.. 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; });
}
......@@ -122,7 +122,7 @@ following example:
.. 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; });
}
......
......@@ -569,17 +569,17 @@ inline PyObject* make_new_python_type(const type_record &rec) {
#endif
}
object module;
object module_;
if (rec.scope) {
if (hasattr(rec.scope, "__module__"))
module = rec.scope.attr("__module__");
module_ = rec.scope.attr("__module__");
else if (hasattr(rec.scope, "__name__"))
module = rec.scope.attr("__name__");
module_ = rec.scope.attr("__name__");
}
auto full_name = c_str(
#if !defined(PYPY_VERSION)
module ? str(module).cast<std::string>() + "." + rec.name :
module_ ? str(module_).cast<std::string>() + "." + rec.name :
#endif
rec.name);
......@@ -658,8 +658,8 @@ inline PyObject* make_new_python_type(const type_record &rec) {
else
Py_INCREF(type); // Keep it alive forever (reference leak)
if (module) // Needed by pydoc
setattr((PyObject *) type, "__module__", module);
if (module_) // Needed by pydoc
setattr((PyObject *) type, "__module__", module_);
PYBIND11_SET_OLDPY_QUALNAME(type, qualname);
......
......@@ -263,13 +263,13 @@ extern "C" {
***Deprecated in favor of PYBIND11_MODULE***
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.
.. code-block:: cpp
PYBIND11_PLUGIN(example) {
pybind11::module m("example", "pybind11 example plugin");
pybind11::module_ m("example", "pybind11 example plugin");
/// Set up bindings here
return m.ptr();
}
......@@ -290,7 +290,7 @@ extern "C" {
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
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:
since the entry point is typically only looked up at runtime and not referenced
......@@ -317,12 +317,12 @@ extern "C" {
#else
#define PYBIND11_DETAIL_MODULE_STATIC_DEF(name)
#define PYBIND11_DETAIL_MODULE_CREATE(name) \
auto m = pybind11::module(PYBIND11_TOSTRING(name));
auto m = pybind11::module_(PYBIND11_TOSTRING(name));
#endif
#define PYBIND11_MODULE(name, variable) \
PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
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_CHECK_PYTHON_VERSION \
PYBIND11_ENSURE_INTERNALS_READY \
......@@ -332,7 +332,7 @@ extern "C" {
return m.ptr(); \
} 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)
......
......@@ -549,7 +549,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
return false;
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(
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 */) {
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");
array data(src.nonZeros(), src.valuePtr());
......
......@@ -46,9 +46,9 @@
}
\endrst */
#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)() { \
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
auto m = pybind11::module_(PYBIND11_TOSTRING(name)); \
try { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \
return m.ptr(); \
......@@ -64,7 +64,7 @@
pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \
(PYBIND11_TOSTRING(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)
......@@ -109,7 +109,7 @@ inline void initialize_interpreter(bool init_signal_handlers = true) {
Py_InitializeEx(init_signal_handlers ? 1 : 0);
// 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
......
......@@ -52,7 +52,7 @@ object eval(str expr, object global = globals(), object local = object()) {
template <eval_mode mode = eval_expr, size_t N>
object eval(const char (&s)[N], object global = globals(), object local = object()) {
/* 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);
return eval<mode>(expr, global, local);
}
......
......@@ -102,7 +102,7 @@ PYBIND11_NAMESPACE_END(detail)
.. 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!";
}
\endrst */
......@@ -115,7 +115,7 @@ protected:
public:
scoped_ostream_redirect(
std::ostream &costream = std::cout,
object pyostream = module::import("sys").attr("stdout"))
object pyostream = module_::import("sys").attr("stdout"))
: costream(costream), buffer(pyostream) {
old = costream.rdbuf(&buffer);
}
......@@ -146,7 +146,7 @@ class scoped_estream_redirect : public scoped_ostream_redirect {
public:
scoped_estream_redirect(
std::ostream &costream = std::cerr,
object pyostream = module::import("sys").attr("stderr"))
object pyostream = module_::import("sys").attr("stderr"))
: scoped_ostream_redirect(costream,pyostream) {}
};
......@@ -206,7 +206,7 @@ PYBIND11_NAMESPACE_END(detail)
m.noisy_function_with_error_printing()
\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())
.def(init<bool,bool>(), arg("stdout")=true, arg("stderr")=true)
.def("__enter__", &detail::OstreamRedirect::enter)
......
......@@ -222,7 +222,7 @@ private:
};
static npy_api lookup() {
module_ m = module::import("numpy.core.multiarray");
module_ m = module_::import("numpy.core.multiarray");
auto c = m.attr("_ARRAY_API");
#if PY_MAJOR_VERSION >= 3
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
......@@ -505,7 +505,7 @@ public:
private:
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();
return reinterpret_borrow<object>(obj);
}
......
......@@ -904,9 +904,9 @@ public:
.. code-block:: cpp
py::module m("example", "pybind11 example plugin");
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_ m("example", "pybind11 example plugin");
py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'");
py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
\endrst */
module_ def_submodule(const char *name, const char *doc = nullptr) {
std::string full_name = std::string(PyModule_GetName(m_ptr))
......@@ -965,12 +965,15 @@ private:
};
m_ptr = PyModule_Create(def);
if (m_ptr == nullptr)
pybind11_fail("Internal error in module::module()");
pybind11_fail("Internal error in module_::module_()");
inc_ref();
}
#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_;
#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).
inline dict globals() {
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)
......@@ -1973,7 +1976,7 @@ PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) {
file = kwargs["file"].cast<object>();
} else {
try {
file = module::import("sys").attr("stdout");
file = module_::import("sys").attr("stdout");
} catch (const error_already_set &) {
/* If print() is called from code that is executed as
part of garbage collection during interpreter shutdown,
......
......@@ -120,7 +120,7 @@ public:
throw py::error_already_set();
Py_DECREF(result);
#else
py::module::import("gc").attr("collect")();
py::module_::import("gc").attr("collect")();
#endif
}
......
......@@ -26,8 +26,8 @@ productively.
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.
*/
std::list<std::function<void(py::module &)>> &initializers() {
static std::list<std::function<void(py::module &)>> inits;
std::list<std::function<void(py::module_ &)>> &initializers() {
static std::list<std::function<void(py::module_ &)>> inits;
return inits;
}
......@@ -36,13 +36,13 @@ test_initializer::test_initializer(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);
init(m);
});
}
void bind_ConstructorStats(py::module &m) {
void bind_ConstructorStats(py::module_ &m) {
py::class_<ConstructorStats>(m, "ConstructorStats")
.def("alive", &ConstructorStats::alive)
.def("values", &ConstructorStats::values)
......
......@@ -10,7 +10,7 @@ namespace py = pybind11;
using namespace pybind11::literals;
class test_initializer {
using Initializer = void (*)(py::module &);
using Initializer = void (*)(py::module_ &);
public:
test_initializer(Initializer init);
......@@ -18,9 +18,9 @@ public:
};
#define TEST_SUBMODULE(name, variable) \
void test_submodule_##name(py::module &); \
void test_submodule_##name(py::module_ &); \
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment