Reputation: 3131
I have created a python module that has the following structure (loosely based on this example):
module_name
├── LICENSE
├── README.md
├── module_name
│ ├── __init__.py
│ └── submodule_name
│ ├── __init__.py
│ └── submodule_name.py
├── setup.py
└── src
└── sq.cpp
I can run setup.py
and install this module without a problem. I can also import the pure python modules:
import module_name
import module_name.submodule_name
For sq.cpp
I have the following in setup.py
from pybind11 import get_cmake_dir
from pybind11.setup_helpers import Pybind11Extension, build_ext
ext_modules = [
Pybind11Extension("sq",
["src/sq.cpp"],),
]
sq.cpp
defines the pybind module as
PYBIND11_MODULE(sq, m)
{
m.doc() = "a function";
m.def("sq", &sq, "a function");
}
At this point I'm confused about how to load the module in sq.cpp
. I have tried import sq
, import module_name.sq
, import sq.sq
but all result in a ModuleNotFoundError
. What am I missing? How am I supposed to import the pybind module? Do I have the structure wrong?
Upvotes: 1
Views: 2272
Reputation: 5370
Your build should fail as the names of the module and function are the same. (Look at sq.cpp
)
When you define a module with PYBIND11_MODULE(sq, m)
, the sq
becomes a local variable and &sq
will reffer to another object, but not to the sq
function. So you can rename the name of the function to keep the module name as sq
.
#include <pybind11/pybind11.h>
void _sq() {}
PYBIND11_MODULE(sq, m) {
m.doc() = "a function";
m.def("sq", &_sq, "a function");
}
setup.py
with yoursimport sys
from pybind11 import get_cmake_dir
from pybind11.setup_helpers import Pybind11Extension, build_ext
from setuptools import setup
__version__ = "0.0.1"
ext_modules = [
Pybind11Extension("sq",
["src/sq.cpp"],
define_macros=[('VERSION_INFO', __version__)],
),
]
setup(
name="sq",
version=__version__,
ext_modules=ext_modules,
cmdclass={"build_ext": build_ext},
zip_safe=False,
python_requires=">=3.6",
)
Redirect to the parent directory of the sq
module directory and execute the following command.
python3 -m pip install ./sq
import sq
sq.sq()
I'm a bit confused because I already have a
setup
section withname="module_name"
. How do I embed thesq
module inside the wholemodule_name
module?
You should change the module name by changing
Pybind11Extension("sq", ...)
to Pybind11Extension("module_name", ...)
setup(name="sq", ...)
to setup(name="module_name", ...)
PYBIND11_MODULE(sq, m)
to PYBIND11_MODULE(module_name, m)
After reinstalling the module with the command above, you can use the sq
function in these ways.
import module_name
from module_name import sq
module_name.sq()
sq()
Upvotes: 2