--- a/src/bindings/python/simgrid_python.cpp
+++ b/src/bindings/python/simgrid_python.cpp
@@ -721,15 +721,19 @@ PYBIND11_MODULE(simgrid, m)
            "Non-blocking read data from disk")
       .def("write_async", &simgrid::s4u::Disk::write_async, py::call_guard<py::gil_scoped_release>(),
            "Non-blocking write data in disk")
-      .def_property("read_bandwidth", &simgrid::s4u::Disk::get_read_bandwidth, &simgrid::s4u::Disk::set_read_bandwidth,
-                    py::call_guard<py::gil_scoped_release>(),
+      .def_property("read_bandwidth",
+                    py::cpp_function{&simgrid::s4u::Disk::get_read_bandwidth, py::call_guard<py::gil_scoped_release>()},
+                    py::cpp_function{&simgrid::s4u::Disk::set_read_bandwidth, py::call_guard<py::gil_scoped_release>()},
                     "The read bandwidth of this disk is the max speed at which read operations progress")
-      .def_property("write_bandwidth", &simgrid::s4u::Disk::get_write_bandwidth,
-                    &simgrid::s4u::Disk::set_write_bandwidth, py::call_guard<py::gil_scoped_release>(),
-                    "The write bandwidth of this disk is the max speed at which write operations progress")
       .def_property(
-          "concurrency_limit", &simgrid::s4u::Disk::get_concurrency_limit, &simgrid::s4u::Disk::set_concurrency_limit,
-          py::call_guard<py::gil_scoped_release>(),
+          "write_bandwidth",
+          py::cpp_function{&simgrid::s4u::Disk::get_write_bandwidth, py::call_guard<py::gil_scoped_release>()},
+          py::cpp_function{&simgrid::s4u::Disk::set_write_bandwidth, py::call_guard<py::gil_scoped_release>()},
+          "The write bandwidth of this disk is the max speed at which write operations progress")
+      .def_property(
+          "concurrency_limit",
+          py::cpp_function{&simgrid::s4u::Disk::get_concurrency_limit, py::call_guard<py::gil_scoped_release>()},
+          py::cpp_function{&simgrid::s4u::Disk::set_concurrency_limit, py::call_guard<py::gil_scoped_release>()},
           "The concurrency limit of this disk is the max amound of concurrent accesses (extra ones are queued)")
       .def("set_sharing_policy", &simgrid::s4u::Disk::set_sharing_policy, py::call_guard<py::gil_scoped_release>(),
            "Set sharing policy for this disk", py::arg("op"), py::arg("policy"),
@@ -738,7 +742,8 @@ PYBIND11_MODULE(simgrid, m)
       .def("turn_on", &Disk::turn_on, py::call_guard<py::gil_scoped_release>(), "Turns the disk on.")
       .def("turn_off", &Disk::turn_off, py::call_guard<py::gil_scoped_release>(), "Turns the disk off.")
       .def_property_readonly("name", &simgrid::s4u::Disk::get_name, "The name of this disk (read-only property).")
-      .def_property_readonly("host", &simgrid::s4u::Disk::get_host, "The Host to which this disk is attached (read-only property)")
+      .def_property_readonly("host", &simgrid::s4u::Disk::get_host,
+                             "The Host to which this disk is attached (read-only property)")
       .def(
           "__repr__", [](const Disk* d) { return "Disk(" + d->get_name() + ")"; },
           "Textual representation of the Disk");
@@ -940,20 +945,26 @@ PYBIND11_MODULE(simgrid, m)
 
   /* Class Comm */
   py::class_<Comm, CommPtr, Activity>(m, "Comm", "Communication. See the C++ documentation for details.")
-      .def_property_readonly("dst_data_size", &Comm::get_dst_data_size, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("dst_data_size",
+                             py::cpp_function{&Comm::get_dst_data_size, py::call_guard<py::gil_scoped_release>()},
                              "Retrieve the size of the received data.")
-      .def_property_readonly("mailbox", &Comm::get_mailbox, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("mailbox", py::cpp_function{&Comm::get_mailbox, py::call_guard<py::gil_scoped_release>()},
                              "Retrieve the mailbox on which this comm acts.")
-      .def_property_readonly("sender", &Comm::get_sender, py::call_guard<py::gil_scoped_release>())
-      .def_property_readonly("state_str", &Comm::get_state_str, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("sender", py::cpp_function{&Comm::get_sender, py::call_guard<py::gil_scoped_release>()})
+      .def_property_readonly("state_str",
+                             py::cpp_function{&Comm::get_state_str, py::call_guard<py::gil_scoped_release>()},
                              "Retrieve the Comm state as string")
-      .def_property_readonly("remaining", &Comm::get_remaining, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("remaining",
+                             py::cpp_function{&Comm::get_remaining, py::call_guard<py::gil_scoped_release>()},
                              "Remaining amount of work that this Comm entails")
-      .def_property_readonly("start_time", &Comm::get_start_time, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("start_time",
+                             py::cpp_function{&Comm::get_start_time, py::call_guard<py::gil_scoped_release>()},
                              "Time at which this Comm started")
-      .def_property_readonly("finish_time", &Comm::get_finish_time, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("finish_time",
+                             py::cpp_function{&Comm::get_finish_time, py::call_guard<py::gil_scoped_release>()},
                              "Time at which this Comm finished")
-      .def_property_readonly("is_suspended", &Comm::is_suspended, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("is_suspended",
+                             py::cpp_function{&Comm::is_suspended, py::call_guard<py::gil_scoped_release>()},
                              "Whether this Comm is suspended")
       .def("set_tracing_category", &Comm::set_tracing_category, py::call_guard<py::gil_scoped_release>(),
            py::arg("category"), "Set a user-defined tracing category.")
@@ -1010,17 +1021,20 @@ PYBIND11_MODULE(simgrid, m)
   /* Class Exec */
   py::class_<simgrid::s4u::Exec, simgrid::s4u::ExecPtr, Activity>(m, "Exec",
                                                                   "Execution. See the C++ documentation for details.")
-      .def_property_readonly("remaining", &simgrid::s4u::Exec::get_remaining, py::call_guard<py::gil_scoped_release>(),
-                             "Amount of flops that remain to be computed until completion (read-only property).")
-      .def_property_readonly("remaining_ratio", &simgrid::s4u::Exec::get_remaining_ratio,
-                             py::call_guard<py::gil_scoped_release>(),
-                             "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done "
-                             "yet) (read-only property).")
+      .def_property_readonly(
+          "remaining", py::cpp_function{&simgrid::s4u::Exec::get_remaining, py::call_guard<py::gil_scoped_release>()},
+          "Amount of flops that remain to be computed until completion (read-only property).")
+      .def_property_readonly(
+          "remaining_ratio",
+          py::cpp_function{&simgrid::s4u::Exec::get_remaining_ratio, py::call_guard<py::gil_scoped_release>()},
+          "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done "
+          "yet) (read-only property).")
       .def_property("host", &simgrid::s4u::Exec::get_host, &simgrid::s4u::Exec::set_host,
                     "Host on which this execution runs. Only the first host is returned for parallel executions. "
                     "Changing this value migrates the execution.")
-      .def_property_readonly("is_suspended", &simgrid::s4u::Exec::is_suspended,
-                             py::call_guard<py::gil_scoped_release>(), "Whether this Exec is suspended")
+      .def_property_readonly(
+          "is_suspended", py::cpp_function{&simgrid::s4u::Exec::is_suspended, py::call_guard<py::gil_scoped_release>()},
+          "Whether this Exec is suspended")
       .def("set_tracing_category", &simgrid::s4u::Exec::set_tracing_category, py::call_guard<py::gil_scoped_release>(),
            py::arg("category"), "Set a user-defined tracing category.")
       .def("test", &simgrid::s4u::Exec::test, py::call_guard<py::gil_scoped_release>(),
@@ -1046,9 +1060,11 @@ PYBIND11_MODULE(simgrid, m)
            "Acquire on the semaphore object with no timeout. Blocks until the semaphore is acquired or return "
            "true if it has not been acquired after the specified timeout.")
       .def("release", &Semaphore::release, py::call_guard<py::gil_scoped_release>(), "Release the semaphore.")
-      .def_property_readonly("capacity", &Semaphore::get_capacity, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("capacity",
+                             py::cpp_function{&Semaphore::get_capacity, py::call_guard<py::gil_scoped_release>()},
                              "Get the semaphore capacity.")
-      .def_property_readonly("would_block", &Semaphore::would_block, py::call_guard<py::gil_scoped_release>(),
+      .def_property_readonly("would_block",
+                             py::cpp_function{&Semaphore::would_block, py::call_guard<py::gil_scoped_release>()},
                              "Check whether trying to acquire the semaphore would block (in other word, checks whether "
                              "this semaphore has capacity).")
       // Allow semaphores to be automatically acquired/released with a context manager: `with semaphore: ...`

