pybind / pybind/pybind11

pybind11 cheatsheet documentation

Open
#1,201 6 comments 85 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

I have found the pybind11 documentation to be not so great for quickly trying to figure out "how the heck do I get from type A to type B". So I wrote my own notes. I'm interesting in getting these back into the official docs, but I am not sure what is the most appropriate form.

Here goes.


The important types:

  • py::handle - equivalent to PyObject* (no automatic refcounting)
  • py::object - does automatic refcounting. Subclass of py::handle.

Conversions

PyObject* ↔ py::handle

This is a trivial conversion. These two types are basically totally equivalent.

PyObject *x;

py::handle h = x; // implicit conversion OK
x = h.ptr(); // no implicit conversion to raw pointer
py::handle (or subclass) → py::object (or subclass)

The syntax here works for both py::object, and any of its subclasses (e.g., py::str, etc)
http://pybind11.readthedocs.io/en/stable/reference.html#_CPPv26object

All of these are unchecked. Do an isinstance check beforehand if necessary. (Note that if you try to do anything with the py::object subclass, pybind11 will probably throw an exception at that point, so you probably aren't completely hosed. But casts to py::foo things are not checked at the point you do the cast!)

Common gotcha: you MUST pass a template argument to py::cast if you're casting from a PyObject*, it will silently do the wrong thing if you don't.

py::handle h;

// Copying
auto o = py::reinterpret_borrow<py::object>(h); // h can be PyObject*
  // or
auto o = x.cast<py::object>();
  // or
auto o = py::cast<py::object>(h); // h can be PyObject*
// equivalent to:
//    Py_INCREF(x);
//    THPObjectPtr o(x);

// Moving
auto o = py::reinterpret_steal<py::object>(h); // h can be PyObject*
// equivalent to:
//    THPObjectPtr o(x);
py::object (or superclass) → py::handle

Stealing is pretty useful if you're trying to invoke a C API function that steals its argument.

py::object o;

// Borrows from o
py::handle h2 = o;
// refcount NOT increased; h2 is only live as long as o is

// Steals from o
py::handle h = o.release();
// o no longer valid

NB: a “copy” from object into handle doesn't make sense, because handle doesn't know how to manage its own memory.

NB2: these conversions are implemented by the implicit copy-constructor on py::handle,static casting the input py::object as a const py::handle& (in case you're like me and tried to find where in the code this conversion was implemented).

py::object → C++
py::handle h; // or py::object
CppType x = h.cast<CppType>(); // may throw cast_error
  // or
CppType x = py::cast<CppType>(h);
// x is a new copy unrelated to h
C++ → py::object
CppType x;

py::object o = py::cast(x);
  // or
py::object o = py::cast(x, return_value_policy::automatic);
// o is a new copy, but with a different policy it could be different

How do I...

// b = isinstance(x, ty)
py::handle x;
py::handle ty;
bool b = py::isinstance(x, ty);

// b = isinstance(x, str)
py::handle x;
bool b = py::isinstance<py::str>(x);

// b = isinstance(x, tuple)
py::handle x;
bool b = py::isinstance<py::tuple>(x);

// s = str(x)
py::handle x;
py::str s(x); // use the constructor

// b = hasattr(x, "something")
py::handle x;
bool b = py::hasattr(x, "something");

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing reference documentation, especially the pytypes.h and cast.h declarations and the advanced/functions return-value policies page linked in the issue. Compare the proposed conversions and examples with the current official docs, then determine an appropriate documentation location and ensure the cheatsheet’s coverage and code examples are accurate.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.