CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pybind11

Seamless operability between C++11 and Python for creating Python bindings of existing C++ code

Pending
Overview
Eval results
Files

type-system.mddocs/

Type System and Conversion

The pybind11 type system provides automatic conversion between C++ and Python types, with support for custom type casters and various casting policies. This system handles the complex task of marshalling data between the two languages transparently.

Capabilities

Automatic Type Conversion

Built-in conversions for fundamental C++ and Python types.

// Casting functions
template<typename T>
T cast(const handle &obj);

template<typename T>
handle cast(T &&value, return_value_policy policy = return_value_policy::automatic);

template<typename T>
object cast(T &&value, return_value_policy policy = return_value_policy::automatic);

// Casting with explicit policy
template<typename T>
T cast(const handle &obj, return_value_policy policy);

Python Type Wrappers

C++ wrapper classes for Python built-in types, providing seamless integration.

class str : public object {
public:
    str(const char *c = "");
    str(const std::string &s);
    
    operator std::string() const;
    const char* c_str() const;
};

class bytes : public object {
public:
    bytes(const char *c);
    bytes(const std::string &s);
    
    operator std::string() const;
    const char* c_str() const;
};

class int_ : public object {
public:
    int_(int value);
    int_(long value);
    
    operator int() const;
    operator long() const;
};

class float_ : public object {
public:
    float_(double value);
    
    operator double() const;
};

class bool_ : public object {
public:
    bool_(bool value);
    
    operator bool() const;
};

Container Type Wrappers

Wrapper classes for Python container types.

class list : public object {
public:
    list();
    list(size_t size);
    
    size_t size() const;
    bool empty() const;
    
    template<typename T>
    void append(T &&val);
    
    template<typename T>
    void insert(size_t index, T &&val);
    
    object operator[](size_t index) const;
    void clear();
};

class tuple : public object {
public:
    tuple();
    tuple(size_t size);
    
    size_t size() const;
    object operator[](size_t index) const;
};

class dict : public object {
public:
    dict();
    
    size_t size() const;
    bool empty() const;
    bool contains(const object &key) const;
    
    object operator[](const object &key) const;
    void clear();
    
    list keys() const;
    list values() const;
    list items() const;
};

class set : public object {
public:
    set();
    
    size_t size() const;
    bool empty() const;
    bool contains(const object &key) const;
    
    void add(const object &key);
    void clear();
};

class slice : public object {
public:
    slice(ssize_t start, ssize_t stop, ssize_t step = 1);
    
    ssize_t start() const;
    ssize_t stop() const;
    ssize_t step() const;
};

Return Value Policies

Control how return values are handled when crossing the C++/Python boundary.

enum class return_value_policy {
    /** Automatic policy selection (default) */
    automatic = 0,
    
    /** Copy the return value */
    copy,
    
    /** Move the return value */
    move,
    
    /** Return a reference (dangerous if object lifetime not managed) */
    reference,
    
    /** Return a reference, keep parent object alive */
    reference_internal,
    
    /** Transfer ownership to Python (for pointers) */
    take_ownership
};

Special Argument Types

Special types for handling function arguments and keyword arguments.

class args : public tuple {
    // Represents *args in Python function calls
public:
    args(const tuple &tuple);
};

class kwargs : public dict {
    // Represents **kwargs in Python function calls  
public:
    kwargs(const dict &dict);
};

class capsule : public object {
    // Python capsule for passing opaque C pointers
public:
    capsule(const void *value, const char *name = nullptr);
    capsule(const void *value, const char *name, void (*destructor)(void *));
    
    template<typename T>
    T *get_pointer() const;
};

Custom Type Casters

Framework for defining custom type conversion between C++ and Python types.

// Type caster base template (specialized for custom types)
template<typename T>
struct type_caster {
    // Must be specialized for custom types
    // Provides load() and cast() methods
};

// Macro for simple type casters
#define PYBIND11_TYPE_CASTER(type, py_name) \
    protected: \
        type value; \
    public: \
        static constexpr auto name = py_name; \
        template<typename T_, enable_if_t<std::is_same_v<type, remove_cv_t<T_>>, int> = 0> \
        static handle cast(T_ *src, return_value_policy policy, handle parent) { \
            /* Implementation */ \
        } \
        template<typename T_, enable_if_t<std::is_same_v<type, remove_cv_t<T_>>, int> = 0> \
        static handle cast(T_ &&src, return_value_policy policy, handle parent) { \
            /* Implementation */ \
        } \
        bool load(handle src, bool convert) { \
            /* Implementation */ \
        } \
        operator type*() { return &value; } \
        operator type&() { return value; }

// Create type caster instance
template<typename T>
auto make_caster(T &&value) -> type_caster<T>;

Type Conversion Utilities

Utility functions for type checking and conversion.

// Type checking
template<typename T>
bool isinstance(handle obj);

template<typename T>
bool isinstance(handle obj, handle type);

// Attribute access
template<typename T>
T getattr(handle obj, const char *name);

template<typename T>
T getattr(handle obj, const char *name, handle default_);

bool hasattr(handle obj, const char *name);

template<typename T>
void setattr(handle obj, const char *name, T &&value);

void delattr(handle obj, const char *name);

// Item access (for containers)
template<typename T>
T getitem(handle obj, handle key);

template<typename T>
void setitem(handle obj, handle key, T &&value);

void delitem(handle obj, handle key);

Buffer Protocol Support

Support for Python's buffer protocol for efficient data exchange.

class buffer_info {
public:
    void *ptr;           // Pointer to buffer data
    ssize_t itemsize;    // Size of individual items
    std::string format;  // Buffer format string
    ssize_t ndim;        // Number of dimensions
    std::vector<ssize_t> shape;    // Shape of buffer
    std::vector<ssize_t> strides;  // Strides for each dimension
    
    buffer_info(void *ptr, ssize_t itemsize, const std::string &format,
                ssize_t ndim, std::vector<ssize_t> shape,
                std::vector<ssize_t> strides);
};

// Buffer protocol implementation
template<typename T>
buffer_info get_buffer_info(T *ptr, ssize_t size);

Usage Examples

Basic Type Conversion

#include <pybind11/pybind11.h>

namespace py = pybind11;

// Automatic conversion
std::string process_string(const std::string& input) {
    return "Processed: " + input;
}

PYBIND11_MODULE(example, m) {
    // String automatically converted between std::string and Python str
    m.def("process_string", &process_string);
}

Using Python Type Wrappers

py::list create_list() {
    py::list result;
    result.append("hello");
    result.append(42);
    result.append(3.14);
    return result;
}

py::dict create_dict() {
    py::dict result;
    result["name"] = "pybind11";
    result["version"] = "3.0.1";
    return result;
}

PYBIND11_MODULE(example, m) {
    m.def("create_list", &create_list);
    m.def("create_dict", &create_dict);
}

Custom Type Caster

// Custom C++ type
struct Point {
    double x, y;
};

namespace pybind11 { namespace detail {
    template <> struct type_caster<Point> {
    public:
        PYBIND11_TYPE_CASTER(Point, _("Point"));
        
        bool load(handle src, bool) {
            if (!py::isinstance<py::sequence>(src))
                return false;
            auto seq = py::reinterpret_borrow<py::sequence>(src);
            if (seq.size() != 2)
                return false;
            value.x = seq[0].cast<double>();
            value.y = seq[1].cast<double>();
            return true;
        }
        
        static handle cast(Point src, return_value_policy, handle) {
            return py::make_tuple(src.x, src.y).release();
        }
    };
}}

// Now Point can be used directly in function signatures
Point add_points(const Point& a, const Point& b) {
    return {a.x + b.x, a.y + b.y};
}

PYBIND11_MODULE(example, m) {
    m.def("add_points", &add_points);
}

Return Value Policies

class DataHolder {
    std::vector<double> data;
public:
    const std::vector<double>& get_data() const { return data; }
    std::vector<double>& get_data_mutable() { return data; }
};

PYBIND11_MODULE(example, m) {
    py::class_<DataHolder>(m, "DataHolder")
        // Return reference, keeping parent alive
        .def("get_data", &DataHolder::get_data, 
             py::return_value_policy::reference_internal)
        // Return copy (safer but slower)
        .def("get_data_copy", &DataHolder::get_data,
             py::return_value_policy::copy);
}

Types

namespace pybind11 {
    // Core casting types
    template<typename T> struct type_caster;
    class buffer_info;
    
    // Return value policies
    enum class return_value_policy;
    
    // Python object wrappers
    class str;
    class bytes; 
    class int_;
    class float_;
    class bool_;
    class list;
    class tuple;
    class dict;
    class set;
    class slice;
    class capsule;
    
    // Special argument types
    class args;
    class kwargs;
    
    // Type traits and utilities
    template<typename T> struct handle_type_name;
    template<typename T> constexpr bool is_pyobject_v;
}

Install with Tessl CLI

npx tessl i tessl/pypi-pybind11

docs

advanced-features.md

core-binding.md

exception-handling.md

index.md

numpy-integration.md

python-package.md

stl-integration.md

type-system.md

tile.json