or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcore-binding.mdexception-handling.mdindex.mdnumpy-integration.mdpython-package.mdstl-integration.mdtype-system.md

type-system.mddocs/

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

```