@@ -1325,6 +1325,38 @@ inline void *multi_interp_slot(F &&, O &&...o) {
1325
1325
}
1326
1326
#endif
1327
1327
1328
+ // / Must be a POD type, and must hold enough entries for all of the possible slots PLUS ONE for
1329
+ // / the sentinel (0) end slot.
1330
+ using slots_array = std::array<PyModuleDef_Slot, 4 >;
1331
+
1332
+ // / Initialize an array of slots based on the supplied exec slot and options.
1333
+ template <typename ... Options>
1334
+ static slots_array init_slots (int (*exec_fn)(PyObject *), Options &&...options ) noexcept {
1335
+ /* NOTE: slots_array MUST be large enough to hold all possible options. If you add an option
1336
+ here, you MUST also increase the size of slots_array in the type alias above! */
1337
+ slots_array slots;
1338
+ size_t next_slot = 0 ;
1339
+
1340
+ if (exec_fn != nullptr ) {
1341
+ slots[next_slot++] = {Py_mod_exec, reinterpret_cast <void *>(exec_fn)};
1342
+ }
1343
+
1344
+ #ifdef Py_mod_multiple_interpreters
1345
+ slots[next_slot++] = {Py_mod_multiple_interpreters, multi_interp_slot (options...)};
1346
+ #endif
1347
+
1348
+ if (gil_not_used_option (options...)) {
1349
+ #if defined(Py_mod_gil) && defined(Py_GIL_DISABLED)
1350
+ slots[next_slot++] = {Py_mod_gil, Py_MOD_GIL_NOT_USED};
1351
+ #endif
1352
+ }
1353
+
1354
+ // slots must have a zero end sentinel
1355
+ slots[next_slot++] = {0 , nullptr };
1356
+
1357
+ return slots;
1358
+ }
1359
+
1328
1360
PYBIND11_NAMESPACE_END (detail)
1329
1361
1330
1362
// / Wrapper for Python extension modules
@@ -1438,19 +1470,19 @@ class module_ : public object {
1438
1470
PyModule_AddObject (ptr (), name, obj.inc_ref ().ptr () /* steals a reference */ );
1439
1471
}
1440
1472
1441
- using module_def = PyModuleDef; // TODO: Can this be removed (it was needed only for Python 2)?
1473
+ // DEPRECATED (since PR #5688): Use PyModuleDef directly instead.
1474
+ using module_def = PyModuleDef;
1442
1475
1443
1476
/* * \rst
1444
1477
Create a new top-level module that can be used as the main module of a C extension.
1445
1478
1446
- ``def`` should point to a statically allocated module_def .
1479
+ ``def`` should point to a statically allocated PyModuleDef .
1447
1480
\endrst */
1448
1481
static module_ create_extension_module (const char *name,
1449
1482
const char *doc,
1450
- module_def *def,
1483
+ PyModuleDef *def,
1451
1484
mod_gil_not_used gil_not_used
1452
1485
= mod_gil_not_used(false )) {
1453
- // module_def is PyModuleDef
1454
1486
// Placement new (not an allocation).
1455
1487
new (def) PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,
1456
1488
/* m_name */ name,
@@ -1478,74 +1510,6 @@ class module_ : public object {
1478
1510
// For Python 2, reinterpret_borrow was correct.
1479
1511
return reinterpret_borrow<module_>(m);
1480
1512
}
1481
-
1482
- // / Must be a POD type, and must hold enough entries for all of the possible slots PLUS ONE for
1483
- // / the sentinel (0) end slot.
1484
- using slots_array = std::array<PyModuleDef_Slot, 4 >;
1485
-
1486
- /* * \rst
1487
- Initialize a module def for use with multi-phase module initialization.
1488
-
1489
- ``def`` should point to a statically allocated module_def.
1490
- ``slots`` must already contain a Py_mod_exec or Py_mod_create slot and will be filled with
1491
- additional slots from the supplied options (and the empty sentinel slot).
1492
- \endrst */
1493
- template <typename ... Options>
1494
- static object initialize_multiphase_module_def (const char *name,
1495
- const char *doc,
1496
- module_def *def,
1497
- slots_array &slots,
1498
- Options &&...options) {
1499
- size_t next_slot = 0 ;
1500
- size_t term_slot = slots.size () - 1 ;
1501
-
1502
- // find the end of the supplied slots
1503
- while (next_slot < term_slot && slots[next_slot].slot != 0 ) {
1504
- ++next_slot;
1505
- }
1506
-
1507
- #ifdef Py_mod_multiple_interpreters
1508
- if (next_slot >= term_slot) {
1509
- pybind11_fail (" initialize_multiphase_module_def: not enough space in slots" );
1510
- }
1511
- slots[next_slot++] = {Py_mod_multiple_interpreters, detail::multi_interp_slot (options...)};
1512
- #endif
1513
-
1514
- if (detail::gil_not_used_option (options...)) {
1515
- #if defined(Py_mod_gil) && defined(Py_GIL_DISABLED)
1516
- if (next_slot >= term_slot) {
1517
- pybind11_fail (" initialize_multiphase_module_def: not enough space in slots" );
1518
- }
1519
- slots[next_slot++] = {Py_mod_gil, Py_MOD_GIL_NOT_USED};
1520
- #endif
1521
- }
1522
-
1523
- // slots must have a zero end sentinel
1524
- if (next_slot > term_slot) {
1525
- pybind11_fail (" initialize_multiphase_module_def: not enough space in slots" );
1526
- }
1527
- slots[next_slot++] = {0 , nullptr };
1528
-
1529
- // module_def is PyModuleDef
1530
- // Placement new (not an allocation).
1531
- new (def) PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,
1532
- /* m_name */ name,
1533
- /* m_doc */ options::show_user_defined_docstrings () ? doc : nullptr ,
1534
- /* m_size */ 0 ,
1535
- /* m_methods */ nullptr ,
1536
- /* m_slots */ &slots[0 ],
1537
- /* m_traverse */ nullptr ,
1538
- /* m_clear */ nullptr ,
1539
- /* m_free */ nullptr };
1540
- auto *m = PyModuleDef_Init (def);
1541
- if (m == nullptr ) {
1542
- if (PyErr_Occurred ()) {
1543
- throw error_already_set ();
1544
- }
1545
- pybind11_fail (" Internal error in module_::initialize_multiphase_module_def()" );
1546
- }
1547
- return reinterpret_borrow<object>(m);
1548
- }
1549
1513
};
1550
1514
1551
1515
PYBIND11_NAMESPACE_BEGIN (detail)
0 commit comments