0
# Type System and Conversion
1
2
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.
3
4
## Capabilities
5
6
### Automatic Type Conversion
7
8
Built-in conversions for fundamental C++ and Python types.
9
10
```cpp { .api }
11
// Casting functions
12
template<typename T>
13
T cast(const handle &obj);
14
15
template<typename T>
16
handle cast(T &&value, return_value_policy policy = return_value_policy::automatic);
17
18
template<typename T>
19
object cast(T &&value, return_value_policy policy = return_value_policy::automatic);
20
21
// Casting with explicit policy
22
template<typename T>
23
T cast(const handle &obj, return_value_policy policy);
24
```
25
26
### Python Type Wrappers
27
28
C++ wrapper classes for Python built-in types, providing seamless integration.
29
30
```cpp { .api }
31
class str : public object {
32
public:
33
str(const char *c = "");
34
str(const std::string &s);
35
36
operator std::string() const;
37
const char* c_str() const;
38
};
39
40
class bytes : public object {
41
public:
42
bytes(const char *c);
43
bytes(const std::string &s);
44
45
operator std::string() const;
46
const char* c_str() const;
47
};
48
49
class int_ : public object {
50
public:
51
int_(int value);
52
int_(long value);
53
54
operator int() const;
55
operator long() const;
56
};
57
58
class float_ : public object {
59
public:
60
float_(double value);
61
62
operator double() const;
63
};
64
65
class bool_ : public object {
66
public:
67
bool_(bool value);
68
69
operator bool() const;
70
};
71
```
72
73
### Container Type Wrappers
74
75
Wrapper classes for Python container types.
76
77
```cpp { .api }
78
class list : public object {
79
public:
80
list();
81
list(size_t size);
82
83
size_t size() const;
84
bool empty() const;
85
86
template<typename T>
87
void append(T &&val);
88
89
template<typename T>
90
void insert(size_t index, T &&val);
91
92
object operator[](size_t index) const;
93
void clear();
94
};
95
96
class tuple : public object {
97
public:
98
tuple();
99
tuple(size_t size);
100
101
size_t size() const;
102
object operator[](size_t index) const;
103
};
104
105
class dict : public object {
106
public:
107
dict();
108
109
size_t size() const;
110
bool empty() const;
111
bool contains(const object &key) const;
112
113
object operator[](const object &key) const;
114
void clear();
115
116
list keys() const;
117
list values() const;
118
list items() const;
119
};
120
121
class set : public object {
122
public:
123
set();
124
125
size_t size() const;
126
bool empty() const;
127
bool contains(const object &key) const;
128
129
void add(const object &key);
130
void clear();
131
};
132
133
class slice : public object {
134
public:
135
slice(ssize_t start, ssize_t stop, ssize_t step = 1);
136
137
ssize_t start() const;
138
ssize_t stop() const;
139
ssize_t step() const;
140
};
141
```
142
143
### Return Value Policies
144
145
Control how return values are handled when crossing the C++/Python boundary.
146
147
```cpp { .api }
148
enum class return_value_policy {
149
/** Automatic policy selection (default) */
150
automatic = 0,
151
152
/** Copy the return value */
153
copy,
154
155
/** Move the return value */
156
move,
157
158
/** Return a reference (dangerous if object lifetime not managed) */
159
reference,
160
161
/** Return a reference, keep parent object alive */
162
reference_internal,
163
164
/** Transfer ownership to Python (for pointers) */
165
take_ownership
166
};
167
```
168
169
### Special Argument Types
170
171
Special types for handling function arguments and keyword arguments.
172
173
```cpp { .api }
174
class args : public tuple {
175
// Represents *args in Python function calls
176
public:
177
args(const tuple &tuple);
178
};
179
180
class kwargs : public dict {
181
// Represents **kwargs in Python function calls
182
public:
183
kwargs(const dict &dict);
184
};
185
186
class capsule : public object {
187
// Python capsule for passing opaque C pointers
188
public:
189
capsule(const void *value, const char *name = nullptr);
190
capsule(const void *value, const char *name, void (*destructor)(void *));
191
192
template<typename T>
193
T *get_pointer() const;
194
};
195
```
196
197
### Custom Type Casters
198
199
Framework for defining custom type conversion between C++ and Python types.
200
201
```cpp { .api }
202
// Type caster base template (specialized for custom types)
203
template<typename T>
204
struct type_caster {
205
// Must be specialized for custom types
206
// Provides load() and cast() methods
207
};
208
209
// Macro for simple type casters
210
#define PYBIND11_TYPE_CASTER(type, py_name) \
211
protected: \
212
type value; \
213
public: \
214
static constexpr auto name = py_name; \
215
template<typename T_, enable_if_t<std::is_same_v<type, remove_cv_t<T_>>, int> = 0> \
216
static handle cast(T_ *src, return_value_policy policy, handle parent) { \
217
/* Implementation */ \
218
} \
219
template<typename T_, enable_if_t<std::is_same_v<type, remove_cv_t<T_>>, int> = 0> \
220
static handle cast(T_ &&src, return_value_policy policy, handle parent) { \
221
/* Implementation */ \
222
} \
223
bool load(handle src, bool convert) { \
224
/* Implementation */ \
225
} \
226
operator type*() { return &value; } \
227
operator type&() { return value; }
228
229
// Create type caster instance
230
template<typename T>
231
auto make_caster(T &&value) -> type_caster<T>;
232
```
233
234
### Type Conversion Utilities
235
236
Utility functions for type checking and conversion.
237
238
```cpp { .api }
239
// Type checking
240
template<typename T>
241
bool isinstance(handle obj);
242
243
template<typename T>
244
bool isinstance(handle obj, handle type);
245
246
// Attribute access
247
template<typename T>
248
T getattr(handle obj, const char *name);
249
250
template<typename T>
251
T getattr(handle obj, const char *name, handle default_);
252
253
bool hasattr(handle obj, const char *name);
254
255
template<typename T>
256
void setattr(handle obj, const char *name, T &&value);
257
258
void delattr(handle obj, const char *name);
259
260
// Item access (for containers)
261
template<typename T>
262
T getitem(handle obj, handle key);
263
264
template<typename T>
265
void setitem(handle obj, handle key, T &&value);
266
267
void delitem(handle obj, handle key);
268
```
269
270
### Buffer Protocol Support
271
272
Support for Python's buffer protocol for efficient data exchange.
273
274
```cpp { .api }
275
class buffer_info {
276
public:
277
void *ptr; // Pointer to buffer data
278
ssize_t itemsize; // Size of individual items
279
std::string format; // Buffer format string
280
ssize_t ndim; // Number of dimensions
281
std::vector<ssize_t> shape; // Shape of buffer
282
std::vector<ssize_t> strides; // Strides for each dimension
283
284
buffer_info(void *ptr, ssize_t itemsize, const std::string &format,
285
ssize_t ndim, std::vector<ssize_t> shape,
286
std::vector<ssize_t> strides);
287
};
288
289
// Buffer protocol implementation
290
template<typename T>
291
buffer_info get_buffer_info(T *ptr, ssize_t size);
292
```
293
294
## Usage Examples
295
296
### Basic Type Conversion
297
298
```cpp
299
#include <pybind11/pybind11.h>
300
301
namespace py = pybind11;
302
303
// Automatic conversion
304
std::string process_string(const std::string& input) {
305
return "Processed: " + input;
306
}
307
308
PYBIND11_MODULE(example, m) {
309
// String automatically converted between std::string and Python str
310
m.def("process_string", &process_string);
311
}
312
```
313
314
### Using Python Type Wrappers
315
316
```cpp
317
py::list create_list() {
318
py::list result;
319
result.append("hello");
320
result.append(42);
321
result.append(3.14);
322
return result;
323
}
324
325
py::dict create_dict() {
326
py::dict result;
327
result["name"] = "pybind11";
328
result["version"] = "3.0.1";
329
return result;
330
}
331
332
PYBIND11_MODULE(example, m) {
333
m.def("create_list", &create_list);
334
m.def("create_dict", &create_dict);
335
}
336
```
337
338
### Custom Type Caster
339
340
```cpp
341
// Custom C++ type
342
struct Point {
343
double x, y;
344
};
345
346
namespace pybind11 { namespace detail {
347
template <> struct type_caster<Point> {
348
public:
349
PYBIND11_TYPE_CASTER(Point, _("Point"));
350
351
bool load(handle src, bool) {
352
if (!py::isinstance<py::sequence>(src))
353
return false;
354
auto seq = py::reinterpret_borrow<py::sequence>(src);
355
if (seq.size() != 2)
356
return false;
357
value.x = seq[0].cast<double>();
358
value.y = seq[1].cast<double>();
359
return true;
360
}
361
362
static handle cast(Point src, return_value_policy, handle) {
363
return py::make_tuple(src.x, src.y).release();
364
}
365
};
366
}}
367
368
// Now Point can be used directly in function signatures
369
Point add_points(const Point& a, const Point& b) {
370
return {a.x + b.x, a.y + b.y};
371
}
372
373
PYBIND11_MODULE(example, m) {
374
m.def("add_points", &add_points);
375
}
376
```
377
378
### Return Value Policies
379
380
```cpp
381
class DataHolder {
382
std::vector<double> data;
383
public:
384
const std::vector<double>& get_data() const { return data; }
385
std::vector<double>& get_data_mutable() { return data; }
386
};
387
388
PYBIND11_MODULE(example, m) {
389
py::class_<DataHolder>(m, "DataHolder")
390
// Return reference, keeping parent alive
391
.def("get_data", &DataHolder::get_data,
392
py::return_value_policy::reference_internal)
393
// Return copy (safer but slower)
394
.def("get_data_copy", &DataHolder::get_data,
395
py::return_value_policy::copy);
396
}
397
```
398
399
## Types
400
401
```cpp { .api }
402
namespace pybind11 {
403
// Core casting types
404
template<typename T> struct type_caster;
405
class buffer_info;
406
407
// Return value policies
408
enum class return_value_policy;
409
410
// Python object wrappers
411
class str;
412
class bytes;
413
class int_;
414
class float_;
415
class bool_;
416
class list;
417
class tuple;
418
class dict;
419
class set;
420
class slice;
421
class capsule;
422
423
// Special argument types
424
class args;
425
class kwargs;
426
427
// Type traits and utilities
428
template<typename T> struct handle_type_name;
429
template<typename T> constexpr bool is_pyobject_v;
430
}
431
```