MCPcopy Create free account
hub / github.com/pybind/pybind11 / MySingleton

Class MySingleton

tests/mod_per_interpreter_gil_with_singleton.cpp:16–74  ·  view source on GitHub ↗

A singleton class that holds references to certain Python objects This singleton is per-interpreter using gil_safe_call_once_and_store

Source from the content-addressed store, hash-verified

14// A singleton class that holds references to certain Python objects
15// This singleton is per-interpreter using gil_safe_call_once_and_store
16class MySingleton {
17public:
18 MySingleton() = default;
19 ~MySingleton() = default;
20 MySingleton(const MySingleton &) = delete;
21 MySingleton &operator=(const MySingleton &) = delete;
22 MySingleton(MySingleton &&) = default;
23 MySingleton &operator=(MySingleton &&) = default;
24
25 static MySingleton &get_instance() {
26 PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<MySingleton> storage;
27 return storage
28 .call_once_and_store_result([]() -> MySingleton {
29 MySingleton instance{};
30
31 auto emplace = [&instance](const py::handle &obj) -> void {
32 obj.inc_ref(); // Ensure the object is not GC'd while interpreter is alive
33 instance.objects.emplace_back(obj);
34 };
35
36 // Example objects to store in the singleton
37 emplace(py::type::handle_of(py::none())); // static type
38 emplace(py::type::handle_of(py::tuple())); // static type
39 emplace(py::type::handle_of(py::list())); // static type
40 emplace(py::type::handle_of(py::dict())); // static type
41 emplace(py::module_::import("collections").attr("OrderedDict")); // static type
42 emplace(py::module_::import("collections").attr("defaultdict")); // heap type
43 emplace(py::module_::import("collections").attr("deque")); // heap type
44
45 assert(instance.objects.size() == 7);
46 return instance;
47 })
48 .get_stored();
49 }
50
51 std::vector<py::handle> &get_objects() { return objects; }
52
53 static void init() {
54 // Ensure the singleton is created
55 auto &instance = get_instance();
56 (void) instance; // suppress unused variable warning
57 assert(instance.objects.size() == 7);
58 // Register cleanup at interpreter exit
59 py::module_::import("atexit").attr("register")(py::cpp_function(&MySingleton::clear));
60 }
61
62 static void clear() {
63 auto &instance = get_instance();
64 (void) instance; // suppress unused variable warning
65 assert(instance.objects.size() == 7);
66 for (const auto &obj : instance.objects) {
67 obj.dec_ref();
68 }
69 instance.objects.clear();
70 }
71
72private:
73 std::vector<py::handle> objects;

Callers

nothing calls this directly

Calls 9

noneClass · 0.85
tupleClass · 0.85
listClass · 0.85
dictClass · 0.85
importFunction · 0.85
inc_refMethod · 0.80
emplace_backMethod · 0.80
attrMethod · 0.80
sizeMethod · 0.45

Tested by

no test coverage detected