* feat!: drop support for Python 3.8 The minimum supported version is now Python 3.9. pybind11 v3.0 was the last release that supports Python 3.8. The deprecation note said that support goes away in 3.1. Remove the code paths that this makes dead: - the `_PyObject_Vectorcall` fallback in `cast.h` - the `frame->f_code` and `frame->f_back` fallbacks in `pytypes.h` - the `PyFrame_FastToLocals` path in `get_type_override` - the conditional `Py_VISIT(Py_TYPE(self))` in `tp_traverse` - `PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX`, the pre-PyConfig interpreter init, and the `widen_chars` helpers in `embed.h` Assisted-by: ClaudeCode:claude-opus-5 * ci(appveyor): use Python 3.9 The AppVeyor job set `PYTHON: 38`, which makes the path `C:\Python38`. The image gives Python 3.9.13 as `C:\Python39`. Assisted-by: ClaudeCode:claude-opus-5 * feat!: require MSVC 2019 or newer Python 3.9 is the new minimum, so MSVC 2017 is no longer needed. Raise the compile-time floor to _MSC_VER 1920 and remove the workarounds that only applied below it: std::launder, fold expressions, weak_from_this, aligned new/delete, the C4100 warning helper, and the func_handle syntax error. AppVeyor now builds with Visual Studio 2019. Assisted-by: ClaudeCode:claude-opus-5 * fix(appveyor): build against the Python that has the test packages CMake 4 has no FindPythonLibs, so pybind11 uses FindPython. FindPython reads the registry before PATH and selected `C:\Python314-x64`, but the test packages go into the Python on PATH. Pass `Python_ROOT_DIR` to name the correct one. Also set `CMAKE_ARCH`. It was never set, so the architecture came from the generator. Visual Studio 2017 defaults to Win32, but Visual Studio 2019 defaults to x64, which made this x86 job build 64-bit code. Assisted-by: ClaudeCode:claude-opus-5 * fix(appveyor): give the linker Python's libs directory The build compiled but failed to link with LNK1104 on a bare `python39.lib`. That name comes from the `#pragma comment(lib, ...)` in pyconfig.h, so the linker needs the directory. CMake 4 has no FindPythonLibs, and FindPython does not add it for this Debug x86 build. Put it on LIB instead. The directory listing is temporary, to confirm the library is present. Assisted-by: ClaudeCode:claude-opus-5 * fix(appveyor): link the release Python library in Debug The image ships python39_d.lib next to python39.lib, so FindPython picks the debug import library for a Debug build. pybind11 undefines _DEBUG around Python.h, so pyconfig.h asks for python39.lib instead and the link failed with LNK1104. Name the release library for the debug slot. Setting LIB does not work, because MSBuild replaces it from the toolset, and it would link both import libraries. Assisted-by: ClaudeCode:claude-opus-5 * chore(appveyor): print link settings to debug LNK1104 Revert the two attempted fixes. Neither changed the failure: setting LIB does not survive MSBuild, and naming the release library for Python_LIBRARY_DEBUG had no effect. Print the Python cache entries and the link settings of a generated project file instead, to see what the linker really gets. Temporary. Assisted-by: ClaudeCode:claude-opus-5 * fix(appveyor): take the release Python library in Debug The generated project file linked C:\Python39\libs\python39_d.lib in the Debug configuration, because the image ships debug binaries next to the release ones. pybind11 undefines _DEBUG around Python.h, so pyconfig.h asks for python39.lib in a #pragma comment(lib), which nothing on the link line satisfies and no library directory holds. Map Debug to the release artifacts. Assisted-by: ClaudeCode:claude-opus-5 * chore(appveyor): drop the temporary link diagnostic Assisted-by: ClaudeCode:claude-opus-5 * fix(tests): guard the unraisable warning filter for pytest < 6 The distro pytest in the Clang and GCC Docker jobs has no PytestUnraisableExceptionWarning, so an unconditional filterwarnings mark makes pytest fail with an INTERNALERROR after the tests pass. Assisted-by: ClaudeCode:claude-opus-5 Claude-Session: https://claude.ai/code/session_01Aimf6HuSz1vLRwBnbxmCTc * docs: address review items on version hints, embed docs, and a PyPy xfail Extend Python_ADDITIONAL_VERSIONS through 3.15, describe the PyConfig behavior of initialize_interpreter, and drop the stale Python 3.8 wording from the PyPy xfail reason. Assisted-by: ClaudeCode:claude-opus-5 * Update README.rst Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com> --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
316 lines
9.2 KiB
ReStructuredText
316 lines
9.2 KiB
ReStructuredText
.. _basics:
|
|
|
|
First steps
|
|
###########
|
|
|
|
This sections demonstrates the basic features of pybind11. Before getting
|
|
started, make sure that development environment is set up to compile the
|
|
included set of test cases.
|
|
|
|
|
|
Compiling the test cases
|
|
========================
|
|
|
|
Linux/macOS
|
|
-----------
|
|
|
|
On Linux you'll need to install the **python-dev** or **python3-dev** packages as
|
|
well as **cmake**. On macOS, the included python version works out of the box,
|
|
but **cmake** must still be installed.
|
|
|
|
After installing the prerequisites, run
|
|
|
|
.. code-block:: bash
|
|
|
|
mkdir build
|
|
cd build
|
|
cmake ..
|
|
make check -j 4
|
|
|
|
The last line will both compile and run the tests.
|
|
|
|
Windows
|
|
-------
|
|
|
|
On Windows, only **Visual Studio 2019** and newer are supported.
|
|
|
|
.. Note::
|
|
|
|
The ``/permissive-`` flag `to enforce standard conformance`_ is not necessary, but it is
|
|
still advised.
|
|
|
|
.. _`to enforce standard conformance`: https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance
|
|
|
|
To compile and run the tests:
|
|
|
|
.. code-block:: batch
|
|
|
|
mkdir build
|
|
cd build
|
|
cmake ..
|
|
cmake --build . --config Release --target check
|
|
|
|
This will create a Visual Studio project, compile and run the target, all from the
|
|
command line.
|
|
|
|
.. Note::
|
|
|
|
If all tests fail, make sure that the Python binary and the testcases are compiled
|
|
for the same processor type and bitness (i.e. either **i386** or **x86_64**). You
|
|
can specify **x86_64** as the target architecture for the generated Visual Studio
|
|
project using ``cmake -A x64 ..``.
|
|
|
|
.. seealso::
|
|
|
|
Advanced users who are already familiar with Boost.Python may want to skip
|
|
the tutorial and look at the test cases in the :file:`tests` directory,
|
|
which exercise all features of pybind11.
|
|
|
|
Header and namespace conventions
|
|
================================
|
|
|
|
For brevity, all code examples assume that the following two lines are present:
|
|
|
|
.. code-block:: cpp
|
|
|
|
#include <pybind11/pybind11.h>
|
|
|
|
namespace py = pybind11;
|
|
|
|
.. note::
|
|
|
|
``pybind11/pybind11.h`` includes ``Python.h``, as such it must be the first file
|
|
included in any source file or header for `the same reasons as Python.h`_.
|
|
|
|
.. _`the same reasons as Python.h`: https://docs.python.org/3/extending/extending.html#a-simple-example
|
|
|
|
Some features may require additional headers, but those will be specified as needed.
|
|
|
|
.. _simple_example:
|
|
|
|
Creating bindings for a simple function
|
|
=======================================
|
|
|
|
Let's start by creating Python bindings for an extremely simple function, which
|
|
adds two numbers and returns their result:
|
|
|
|
.. code-block:: cpp
|
|
|
|
int add(int i, int j) {
|
|
return i + j;
|
|
}
|
|
|
|
For simplicity [#f1]_, we'll put both this function and the binding code into
|
|
a file named :file:`example.cpp` with the following contents:
|
|
|
|
.. code-block:: cpp
|
|
|
|
#include <pybind11/pybind11.h>
|
|
|
|
namespace py = pybind11;
|
|
|
|
int add(int i, int j) {
|
|
return i + j;
|
|
}
|
|
|
|
PYBIND11_MODULE(example, m, py::mod_gil_not_used()) {
|
|
m.doc() = "pybind11 example plugin"; // optional module docstring
|
|
|
|
m.def("add", &add, "A function that adds two numbers");
|
|
}
|
|
|
|
.. [#f1] In practice, implementation and binding code will generally be located
|
|
in separate files.
|
|
|
|
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`
|
|
generates binding code that exposes the ``add()`` function to Python.
|
|
|
|
.. note::
|
|
|
|
Notice how little code was needed to expose our function to Python: all
|
|
details regarding the function's parameters and return value were
|
|
automatically inferred using template metaprogramming. This overall
|
|
approach and the used syntax are borrowed from Boost.Python, though the
|
|
underlying implementation is very different.
|
|
|
|
pybind11 is a header-only library, hence it is not necessary to link against
|
|
any special libraries and there are no intermediate (magic) translation steps.
|
|
On Linux, the above example can be compiled using the following command:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3 -m pybind11 --extension-suffix)
|
|
|
|
.. note::
|
|
|
|
If you used :ref:`include_as_a_submodule` to get the pybind11 source, then
|
|
use ``$(python3-config --includes) -Iextern/pybind11/include`` instead of
|
|
``$(python3 -m pybind11 --includes)`` in the above compilation, as
|
|
explained in :ref:`building_manually`.
|
|
|
|
For more details on the required compiler flags on Linux and macOS, see
|
|
:ref:`building_manually`. For complete cross-platform compilation instructions,
|
|
refer to the :ref:`compiling` page.
|
|
|
|
The `python_example`_ and `cmake_example`_ repositories are also a good place
|
|
to start. They are both complete project examples with cross-platform build
|
|
systems. The only difference between the two is that `python_example`_ uses
|
|
Python's ``setuptools`` to build the module, while `cmake_example`_ uses CMake
|
|
(which may be preferable for existing C++ projects).
|
|
|
|
.. _python_example: https://github.com/pybind/python_example
|
|
.. _cmake_example: https://github.com/pybind/cmake_example
|
|
|
|
Building the above C++ code will produce a binary module file that can be
|
|
imported to Python. Assuming that the compiled module is located in the
|
|
current directory, the following interactive Python session shows how to
|
|
load and execute the example:
|
|
|
|
.. code-block:: pycon
|
|
|
|
$ python
|
|
Python 3.9.10 (main, Jan 15 2022, 11:48:04)
|
|
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
|
|
Type "help", "copyright", "credits" or "license" for more information.
|
|
>>> import example
|
|
>>> example.add(1, 2)
|
|
3
|
|
>>>
|
|
|
|
.. _keyword_args:
|
|
|
|
Keyword arguments
|
|
=================
|
|
|
|
With a simple code modification, it is possible to inform Python about the
|
|
names of the arguments ("i" and "j" in this case).
|
|
|
|
.. code-block:: cpp
|
|
|
|
m.def("add", &add, "A function which adds two numbers",
|
|
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
|
|
call the function using keyword arguments, which is a more readable alternative
|
|
particularly for functions taking many parameters:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> import example
|
|
>>> example.add(i=1, j=2)
|
|
3L
|
|
|
|
The keyword names also appear in the function signatures within the documentation.
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> help(example)
|
|
|
|
....
|
|
|
|
FUNCTIONS
|
|
add(...)
|
|
Signature : (i: int, j: int) -> int
|
|
|
|
A function which adds two numbers
|
|
|
|
A shorter notation for named arguments is also available:
|
|
|
|
.. code-block:: cpp
|
|
|
|
// regular notation
|
|
m.def("add1", &add, py::arg("i"), py::arg("j"));
|
|
// shorthand
|
|
using namespace pybind11::literals;
|
|
m.def("add2", &add, "i"_a, "j"_a);
|
|
|
|
The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`.
|
|
Note that the literal operator must first be made visible with the directive
|
|
``using namespace pybind11::literals``. This does not bring in anything else
|
|
from the ``pybind11`` namespace except for literals.
|
|
|
|
.. _default_args:
|
|
|
|
Default arguments
|
|
=================
|
|
|
|
Suppose now that the function to be bound has default arguments, e.g.:
|
|
|
|
.. code-block:: cpp
|
|
|
|
int add(int i = 1, int j = 2) {
|
|
return i + j;
|
|
}
|
|
|
|
Unfortunately, pybind11 cannot automatically extract these parameters, since they
|
|
are not part of the function's type information. However, they are simple to specify
|
|
using an extension of :class:`arg`:
|
|
|
|
.. code-block:: cpp
|
|
|
|
m.def("add", &add, "A function which adds two numbers",
|
|
py::arg("i") = 1, py::arg("j") = 2);
|
|
|
|
The default values also appear within the documentation.
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> help(example)
|
|
|
|
....
|
|
|
|
FUNCTIONS
|
|
add(...)
|
|
Signature : (i: int = 1, j: int = 2) -> int
|
|
|
|
A function which adds two numbers
|
|
|
|
The shorthand notation is also available for default arguments:
|
|
|
|
.. code-block:: cpp
|
|
|
|
// regular notation
|
|
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
|
|
// shorthand
|
|
m.def("add2", &add, "i"_a=1, "j"_a=2);
|
|
|
|
Exporting variables
|
|
===================
|
|
|
|
To expose a value from C++, use the ``attr`` function to register it in a
|
|
module as shown below. Built-in types and general objects (more on that later)
|
|
are automatically converted when assigned as attributes, and can be explicitly
|
|
converted using the function ``py::cast``.
|
|
|
|
.. code-block:: cpp
|
|
|
|
PYBIND11_MODULE(example, m, py::mod_gil_not_used()) {
|
|
m.attr("the_answer") = 42;
|
|
py::object world = py::cast("World");
|
|
m.attr("what") = world;
|
|
}
|
|
|
|
These are then accessible from Python:
|
|
|
|
.. code-block:: pycon
|
|
|
|
>>> import example
|
|
>>> example.the_answer
|
|
42
|
|
>>> example.what
|
|
'World'
|
|
|
|
.. _supported_types:
|
|
|
|
Supported data types
|
|
====================
|
|
|
|
A large number of data types are supported out of the box and can be used
|
|
seamlessly as functions arguments, return values or with ``py::cast`` in general.
|
|
For a full overview, see the :doc:`advanced/cast/index` section.
|