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

advanced-features.mddocs/

0

# Advanced Features

1

2

pybind11 provides advanced features for complex binding scenarios including inheritance, virtual methods, operators, enumerations, smart pointer integration, and embedding Python in C++ applications.

3

4

## Capabilities

5

6

### Inheritance and Virtual Methods

7

8

Support for C++ inheritance hierarchies and virtual method overriding from Python.

9

10

```cpp { .api }

11

// Virtual method overriding support

12

#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...) \

13

PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, __VA_ARGS__)

14

15

#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \

16

PYBIND11_OVERRIDE_PURE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, __VA_ARGS__)

17

18

// Trampoline class base for smart holder compatibility

19

class trampoline_self_life_support {

20

// Base class for trampoline classes when using smart_holder

21

};

22

23

// Multiple inheritance support

24

class multiple_inheritance {

25

// Template parameter to enable multiple inheritance

26

};

27

28

// Dynamic attribute support

29

class dynamic_attr {

30

// Template parameter to enable dynamic attribute access

31

};

32

```

33

34

### Operator Binding

35

36

Comprehensive support for C++ operator overloading in Python.

37

38

```cpp { .api }

39

// Arithmetic operators

40

auto operator+(const T& a, const T& b);

41

auto operator-(const T& a, const T& b);

42

auto operator*(const T& a, const T& b);

43

auto operator/(const T& a, const T& b);

44

auto operator%(const T& a, const T& b);

45

46

// Comparison operators

47

auto operator==(const T& a, const T& b);

48

auto operator!=(const T& a, const T& b);

49

auto operator<(const T& a, const T& b);

50

auto operator<=(const T& a, const T& b);

51

auto operator>(const T& a, const T& b);

52

auto operator>=(const T& a, const T& b);

53

54

// Unary operators

55

auto operator-(const T& a); // Negation

56

auto operator+(const T& a); // Unary plus

57

auto operator!(const T& a); // Logical not

58

auto operator~(const T& a); // Bitwise not

59

60

// Compound assignment

61

auto operator+=(T& a, const T& b);

62

auto operator-=(T& a, const T& b);

63

auto operator*=(T& a, const T& b);

64

auto operator/=(T& a, const T& b);

65

66

// Stream operators

67

auto operator<<(std::ostream& os, const T& obj);

68

auto operator>>(std::istream& is, T& obj);

69

70

// Subscript operator

71

auto operator[](T& obj, const Key& key);

72

73

// Call operator

74

auto operator()(T& obj, Args... args);

75

76

// Self operators (using 'self' placeholder)

77

py::self + py::self;

78

py::self - py::self;

79

py::self * py::self;

80

py::self / py::self;

81

py::self == py::self;

82

py::self != py::self;

83

py::self < py::self;

84

```

85

86

### Enumeration Binding

87

88

Support for C++ enumerations with various options.

89

90

```cpp { .api }

91

template<typename Type>

92

class enum_ : public class_<Type> {

93

public:

94

// Constructor

95

enum_(const handle &scope, const char *name);

96

97

// Add enum values

98

enum_ &value(const char *name, Type value, const char *doc = nullptr);

99

100

// Export values to enclosing scope

101

enum_ &export_values();

102

103

// Arithmetic operations on enums (optional)

104

enum_ &def_arithmetic();

105

};

106

107

// Scoped enums (enum class)

108

template<typename Type>

109

enum_<Type> bind_enum(module_ &m, const char *name);

110

```

111

112

### Smart Pointer Integration

113

114

Advanced smart pointer support and lifetime management.

115

116

```cpp { .api }

117

// Smart pointer holders

118

template<typename T>

119

class holder_type<std::unique_ptr<T>>;

120

121

template<typename T>

122

class holder_type<std::shared_ptr<T>>;

123

124

// Smart holder (experimental advanced holder)

125

template<typename T>

126

class smart_holder;

127

128

// Holder type specification in class binding

129

py::class_<MyClass, std::shared_ptr<MyClass>>(m, "MyClass");

130

py::class_<MyClass, std::unique_ptr<MyClass>>(m, "MyClass");

131

132

// Return value policies for smart pointers

133

return_value_policy::take_ownership; // Transfer unique_ptr ownership

134

return_value_policy::copy; // Copy shared_ptr

135

return_value_policy::reference_internal; // Keep parent alive

136

```

137

138

### Python Embedding

139

140

Embed Python interpreter in C++ applications.

141

142

```cpp { .api }

143

// Python interpreter management

144

class scoped_interpreter {

145

public:

146

scoped_interpreter(bool init_signal_handlers = true,

147

int argc = 0, const char * const *argv = nullptr,

148

bool add_program_dir_to_path = true);

149

~scoped_interpreter();

150

151

// Non-copyable, non-movable

152

scoped_interpreter(const scoped_interpreter&) = delete;

153

scoped_interpreter& operator=(const scoped_interpreter&) = delete;

154

};

155

156

// Manual interpreter control

157

void initialize_interpreter(bool init_signal_handlers = true,

158

int argc = 0, const char * const *argv = nullptr,

159

bool add_program_dir_to_path = true);

160

161

void finalize_interpreter();

162

163

bool is_interpreter_running();

164

165

// Code execution

166

object exec(const str &expr, object global = globals(), object local = object());

167

object exec(const char *expr, object global = globals(), object local = object());

168

169

object eval(const str &expr, object global = globals(), object local = object());

170

object eval(const char *expr, object global = globals(), object local = object());

171

172

template<typename... Args>

173

object eval_file(const str &fname, Args &&...args);

174

```

175

176

### Function Attributes and Policies

177

178

Advanced function binding options and call policies.

179

180

```cpp { .api }

181

// Function naming and documentation

182

auto name(const char *name);

183

auto doc(const char *doc);

184

185

// Argument handling

186

auto arg(const char *name);

187

template<typename T>

188

auto arg_v(const char *name, T &&value, const char *doc = nullptr);

189

190

// Call policies and lifetime management

191

auto keep_alive(size_t nurse, size_t patient);

192

auto keep_alive_impl(size_t nurse, size_t patient);

193

194

// Function relationship

195

auto sibling(handle other_function);

196

auto is_method(handle self);

197

auto is_operator();

198

199

// Advanced function options

200

auto prepend(); // Prepend to overload chain

201

auto scope(handle scope); // Set function scope

202

```

203

204

### Global Variables and Constants

205

206

Binding global variables and constants to Python.

207

208

```cpp { .api }

209

// Module-level attributes

210

template<typename T>

211

module_ &attr(const char *name, T &&value);

212

213

// Read-only attributes

214

template<typename T>

215

module_ &def_readonly(const char *name, const T *value);

216

217

// Read-write attributes

218

template<typename T>

219

module_ &def_readwrite(const char *name, T *value);

220

```

221

222

### Threading and GIL Management

223

224

Advanced Global Interpreter Lock (GIL) management for multi-threading.

225

226

```cpp { .api }

227

// GIL management classes

228

class gil_scoped_acquire {

229

public:

230

gil_scoped_acquire();

231

~gil_scoped_acquire();

232

233

// Non-copyable, non-movable

234

gil_scoped_acquire(const gil_scoped_acquire&) = delete;

235

};

236

237

class gil_scoped_release {

238

public:

239

gil_scoped_release();

240

~gil_scoped_release();

241

242

// Non-copyable, non-movable

243

gil_scoped_release(const gil_scoped_release&) = delete;

244

};

245

246

// GIL-free function marking

247

class gil_not_used {

248

// Mark module as not using GIL

249

};

250

251

// Multiple interpreter support

252

class multiple_interpreters {

253

// Mark module as supporting multiple interpreters

254

};

255

```

256

257

### Custom Metaclasses and Descriptors

258

259

Advanced class customization options.

260

261

```cpp { .api }

262

// Custom metaclass support

263

template<typename T>

264

class metaclass {

265

public:

266

metaclass(handle meta);

267

};

268

269

// Property descriptors with custom behavior

270

template<typename Getter, typename Setter>

271

class custom_property {

272

public:

273

custom_property(Getter getter, Setter setter);

274

};

275

276

// Dynamic attribute access

277

template<typename T>

278

struct dynamic_attr_support {

279

// Enable __setattr__ and __getattr__

280

};

281

```

282

283

## Usage Examples

284

285

### Inheritance and Virtual Methods

286

287

```cpp

288

#include <pybind11/pybind11.h>

289

290

namespace py = pybind11;

291

292

// Base class with virtual methods

293

class Animal {

294

public:

295

virtual ~Animal() = default;

296

virtual std::string speak() const = 0;

297

virtual std::string type() const { return "Animal"; }

298

};

299

300

// Trampoline class for Python inheritance

301

class PyAnimal : public Animal {

302

public:

303

using Animal::Animal;

304

305

std::string speak() const override {

306

PYBIND11_OVERRIDE_PURE(std::string, Animal, speak);

307

}

308

309

std::string type() const override {

310

PYBIND11_OVERRIDE(std::string, Animal, type);

311

}

312

};

313

314

// Derived class

315

class Dog : public Animal {

316

public:

317

std::string speak() const override { return "Woof!"; }

318

std::string type() const override { return "Dog"; }

319

};

320

321

PYBIND11_MODULE(example, m) {

322

py::class_<Animal, PyAnimal>(m, "Animal")

323

.def(py::init<>())

324

.def("speak", &Animal::speak)

325

.def("type", &Animal::type);

326

327

py::class_<Dog>(m, "Dog", py::base<Animal>())

328

.def(py::init<>());

329

}

330

331

// Python usage:

332

// class Cat(Animal):

333

// def speak(self):

334

// return "Meow!"

335

//

336

// cat = Cat()

337

// print(cat.speak()) # "Meow!"

338

```

339

340

### Operator Overloading

341

342

```cpp

343

#include <pybind11/pybind11.h>

344

#include <pybind11/operators.h>

345

346

namespace py = pybind11;

347

348

class Vector2D {

349

public:

350

double x, y;

351

352

Vector2D(double x = 0, double y = 0) : x(x), y(y) {}

353

354

Vector2D operator+(const Vector2D& other) const {

355

return Vector2D(x + other.x, y + other.y);

356

}

357

358

Vector2D operator-(const Vector2D& other) const {

359

return Vector2D(x - other.x, y - other.y);

360

}

361

362

Vector2D operator*(double scalar) const {

363

return Vector2D(x * scalar, y * scalar);

364

}

365

366

bool operator==(const Vector2D& other) const {

367

return x == other.x && y == other.y;

368

}

369

370

double length() const {

371

return std::sqrt(x * x + y * y);

372

}

373

};

374

375

PYBIND11_MODULE(example, m) {

376

py::class_<Vector2D>(m, "Vector2D")

377

.def(py::init<double, double>())

378

.def_readwrite("x", &Vector2D::x)

379

.def_readwrite("y", &Vector2D::y)

380

.def("length", &Vector2D::length)

381

// Bind operators

382

.def(py::self + py::self)

383

.def(py::self - py::self)

384

.def(py::self * double())

385

.def(double() * py::self)

386

.def(py::self == py::self)

387

.def("__repr__", [](const Vector2D& v) {

388

return "Vector2D(" + std::to_string(v.x) + ", " + std::to_string(v.y) + ")";

389

});

390

}

391

```

392

393

### Enumeration Binding

394

395

```cpp

396

#include <pybind11/pybind11.h>

397

398

namespace py = pybind11;

399

400

enum class Color { Red, Green, Blue };

401

402

enum LogLevel {

403

DEBUG = 0,

404

INFO = 1,

405

WARNING = 2,

406

ERROR = 3

407

};

408

409

PYBIND11_MODULE(example, m) {

410

// Scoped enum (enum class)

411

py::enum_<Color>(m, "Color")

412

.value("Red", Color::Red)

413

.value("Green", Color::Green)

414

.value("Blue", Color::Blue)

415

.export_values(); // Optional: export to module scope

416

417

// Traditional enum with arithmetic operations

418

py::enum_<LogLevel>(m, "LogLevel")

419

.value("DEBUG", DEBUG)

420

.value("INFO", INFO)

421

.value("WARNING", WARNING)

422

.value("ERROR", ERROR)

423

.def_arithmetic(); // Enable arithmetic operations

424

}

425

426

// Python usage:

427

// print(Color.Red) # Color.Red

428

// print(LogLevel.INFO + 1) # 2 (if arithmetic enabled)

429

```

430

431

### Smart Pointer Integration

432

433

```cpp

434

#include <pybind11/pybind11.h>

435

#include <memory>

436

437

namespace py = pybind11;

438

439

class Resource {

440

public:

441

Resource(const std::string& name) : name_(name) {}

442

const std::string& name() const { return name_; }

443

444

private:

445

std::string name_;

446

};

447

448

// Factory function returning unique_ptr

449

std::unique_ptr<Resource> create_resource(const std::string& name) {

450

return std::make_unique<Resource>(name);

451

}

452

453

// Factory function returning shared_ptr

454

std::shared_ptr<Resource> create_shared_resource(const std::string& name) {

455

return std::make_shared<Resource>(name);

456

}

457

458

PYBIND11_MODULE(example, m) {

459

// Bind class with shared_ptr holder

460

py::class_<Resource, std::shared_ptr<Resource>>(m, "Resource")

461

.def(py::init<const std::string&>())

462

.def("name", &Resource::name);

463

464

m.def("create_resource", &create_resource);

465

m.def("create_shared_resource", &create_shared_resource);

466

}

467

```

468

469

### Python Embedding

470

471

```cpp

472

#include <pybind11/pybind11.h>

473

#include <pybind11/embed.h>

474

475

namespace py = pybind11;

476

477

int main() {

478

// Start Python interpreter

479

py::scoped_interpreter guard{};

480

481

// Execute Python code

482

py::exec("print('Hello from embedded Python!')");

483

484

// Execute Python expressions and get results

485

py::object result = py::eval("2 + 3");

486

std::cout << "2 + 3 = " << result.cast<int>() << std::endl;

487

488

// Import and use Python modules

489

py::object math = py::module_::import("math");

490

py::object pi = math.attr("pi");

491

std::cout << "Pi = " << pi.cast<double>() << std::endl;

492

493

// Execute Python file

494

py::eval_file("script.py");

495

496

// Create Python functions from C++

497

py::exec(R"(

498

def fibonacci(n):

499

if n <= 1:

500

return n

501

return fibonacci(n-1) + fibonacci(n-2)

502

)");

503

504

py::object fib = py::globals()["fibonacci"];

505

py::object result_fib = fib(10);

506

std::cout << "Fibonacci(10) = " << result_fib.cast<int>() << std::endl;

507

508

return 0;

509

}

510

```

511

512

### Advanced GIL Management

513

514

```cpp

515

#include <pybind11/pybind11.h>

516

#include <thread>

517

518

namespace py = pybind11;

519

520

void cpu_intensive_work() {

521

// Release GIL for CPU-intensive work

522

py::gil_scoped_release release;

523

524

// Perform CPU-intensive computation

525

for (int i = 0; i < 1000000; ++i) {

526

// Some computation

527

}

528

529

// GIL automatically reacquired when 'release' goes out of scope

530

}

531

532

void call_python_from_thread(py::function callback) {

533

std::thread worker([callback]() {

534

// Acquire GIL in thread

535

py::gil_scoped_acquire acquire;

536

537

try {

538

callback("Hello from thread!");

539

}

540

catch (py::error_already_set& e) {

541

std::cerr << "Python exception in thread: " << e.what() << std::endl;

542

}

543

});

544

545

worker.join();

546

}

547

548

PYBIND11_MODULE(example, m) {

549

m.def("cpu_intensive_work", &cpu_intensive_work);

550

m.def("call_python_from_thread", &call_python_from_thread);

551

}

552

```

553

554

### Dynamic Attributes

555

556

```cpp

557

#include <pybind11/pybind11.h>

558

559

namespace py = pybind11;

560

561

class DynamicClass {

562

public:

563

DynamicClass() = default;

564

565

// Optional: custom attribute access

566

py::object get_attr(const std::string& name) {

567

auto it = attrs_.find(name);

568

if (it != attrs_.end()) {

569

return it->second;

570

}

571

throw py::attribute_error("Attribute '" + name + "' not found");

572

}

573

574

void set_attr(const std::string& name, py::object value) {

575

attrs_[name] = value;

576

}

577

578

private:

579

std::map<std::string, py::object> attrs_;

580

};

581

582

PYBIND11_MODULE(example, m) {

583

py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())

584

.def(py::init<>())

585

.def("get_attr", &DynamicClass::get_attr)

586

.def("set_attr", &DynamicClass::set_attr);

587

}

588

589

// Python usage:

590

// obj = DynamicClass()

591

// obj.new_attribute = "Hello" # Dynamic attribute assignment

592

// print(obj.new_attribute) # "Hello"

593

```

594

595

### Chrono and DateTime Integration

596

597

Automatic conversion between C++ chrono types and Python datetime objects.

598

599

```cpp { .api }

600

// Include pybind11/chrono.h for automatic conversions:

601

// std::chrono::duration<Rep, Period> <-> datetime.timedelta

602

// std::chrono::time_point<Clock, Duration> <-> datetime.datetime

603

604

// Supported chrono types

605

using std::chrono::system_clock;

606

using std::chrono::steady_clock;

607

using std::chrono::high_resolution_clock;

608

using std::chrono::duration;

609

using std::chrono::time_point;

610

611

// Common duration types automatically supported

612

using std::chrono::nanoseconds;

613

using std::chrono::microseconds;

614

using std::chrono::milliseconds;

615

using std::chrono::seconds;

616

using std::chrono::minutes;

617

using std::chrono::hours;

618

```

619

620

### Code Evaluation and Execution

621

622

Execute Python code and evaluate expressions from C++.

623

624

```cpp { .api }

625

// Evaluation modes

626

enum eval_mode {

627

eval_expr, // Evaluate expression, return result

628

eval_single_statement, // Execute single statement, return none

629

eval_statements // Execute multiple statements, return none

630

};

631

632

// Evaluation functions

633

template<eval_mode mode = eval_expr>

634

object eval(const str &expr, object global = globals(), object local = object());

635

636

template<eval_mode mode = eval_expr>

637

object eval(const char *expr, object global = globals(), object local = object());

638

639

// File execution

640

template<eval_mode mode = eval_statements, typename... Args>

641

object eval_file(const str &fname, Args &&...args);

642

```

643

644

### Complex Number Support

645

646

Automatic conversion for C++ complex numbers to Python complex.

647

648

```cpp { .api }

649

// Include pybind11/complex.h for automatic conversions:

650

// std::complex<float> <-> Python complex

651

// std::complex<double> <-> Python complex

652

```

653

654

### Functional Programming Utilities

655

656

Higher-order function support and functional programming patterns.

657

658

```cpp { .api }

659

// Include pybind11/functional.h for:

660

// std::function<T> automatic conversion support

661

// Lambda and function object binding utilities

662

```

663

664

## Types

665

666

```cpp { .api }

667

namespace pybind11 {

668

// Advanced class options

669

class multiple_inheritance;

670

class dynamic_attr;

671

template<typename T> class base;

672

class trampoline_self_life_support;

673

674

// Enumeration support

675

template<typename Type> class enum_;

676

677

// Smart pointer holders

678

template<typename T> class holder_type;

679

template<typename T> class smart_holder;

680

681

// Python embedding

682

class scoped_interpreter;

683

684

// Code evaluation

685

enum eval_mode;

686

687

// Chrono support (automatically available with pybind11/chrono.h)

688

template<typename T> struct type_caster<std::chrono::duration<T>>;

689

template<typename T> struct type_caster<std::chrono::time_point<T>>;

690

691

// GIL management

692

class gil_scoped_acquire;

693

class gil_scoped_release;

694

class gil_not_used;

695

class multiple_interpreters;

696

697

// Advanced function options

698

template<size_t nurse, size_t patient> auto keep_alive;

699

auto prepend();

700

auto scope(handle);

701

702

// Operator support

703

struct self_t {};

704

constexpr self_t self{};

705

}

706

```