LCOV - code coverage report
Current view: top level - python - py_object.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 27 74.1 %
Date: 2024-11-17 01:47:58 Functions: 4 6 66.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #include "py_object.h"
       6             : 
       7             : namespace py = pybind11;
       8             : 
       9             : namespace scipp::python {
      10             : 
      11       40047 : PyObject::~PyObject() {
      12       40047 :   py::gil_scoped_acquire acquire;
      13       40047 :   m_object = py::object();
      14       40047 : }
      15             : 
      16         116 : PyObject::PyObject(const py::object &object) {
      17         116 :   py::gil_scoped_acquire acquire;
      18         116 :   m_object = object; // NOLINT(cppcoreguidelines-prefer-member-initializer)
      19         116 : }
      20             : 
      21          23 : bool PyObject::operator==(const PyObject &other) const {
      22             :   // Similar to above, re-acquiring GIL here due to segfault in Python C API
      23             :   // (PyObject_RichCompare).
      24          23 :   py::gil_scoped_acquire acquire;
      25          46 :   return to_pybind().equal(other.to_pybind());
      26          23 : }
      27             : 
      28          25 : PyObject copy(const PyObject &obj) {
      29          25 :   const auto &object = obj.to_pybind();
      30          25 :   if (object) {
      31             :     // It is essential to acquire the GIL here. Calling Python code otherwise
      32             :     // causes a segfault if the GIL has been released previously. Since this
      33             :     // copy operation is called by anything that copies variables, this includes
      34             :     // almost every C++ function with Python bindings because we typically do
      35             :     // release the GIL everywhere.
      36          25 :     py::gil_scoped_acquire acquire;
      37          25 :     py::module copy = py::module::import("copy");
      38          25 :     py::object deepcopy = copy.attr("deepcopy");
      39          50 :     return {deepcopy(object)};
      40          25 :   } else {
      41           0 :     return {object};
      42             :   }
      43             : }
      44             : 
      45           0 : std::ostream &operator<<(std::ostream &os, const PyObject &obj) {
      46           0 :   return os << to_string(obj);
      47             : }
      48             : 
      49           0 : std::string to_string(const PyObject &obj) {
      50           0 :   py::gil_scoped_acquire gil_{};
      51           0 :   return py::str(obj.to_pybind());
      52           0 : }
      53             : 
      54             : } // namespace scipp::python

Generated by: LCOV version 1.14