Repository: microsoft/onnxruntime
File: onnxruntime/python/onnxruntime_pybind_state.cc (C++)

Code before:
            return session_options.release(); }, py::return_value_policy::take_ownership)
      .def_property_readonly("inputs_meta", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetModelInputs();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("outputs_meta", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetModelOutputs();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("overridable_initializers", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetOverridableInitializers();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("model_meta", [](const PyInferenceSession* sess) -> const onnxruntime::ModelMetadata& {
            auto res = sess->GetSessionHandle()->GetModelMetadata();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("inputs_meminfo", [](const PyInferenceSession* sess) -> std::vector<const OrtMemoryInfo*> { 
          Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
          auto inputs_mem_info = session.GetMemoryInfoForInputs();
          std::vector<const OrtMemoryInfo*> result;
          result.reserve(inputs_mem_info.size());
          for (const auto& info : inputs_mem_info) {
            result.push_back(info);
          }
          return result; }, py::return_value_policy::reference_internal)
      .def_property_readonly("outputs_meminfo", [](const PyInferenceSession* sess) -> std::vector<const OrtMemoryInfo*> { 
          Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
          auto outputs_mem_info = session.GetMemoryInfoForOutputs();
          std::vector<const OrtMemoryInfo*> result;
          result.reserve(outputs_mem_info.size());
          for (const auto& info : outputs_mem_info) {
            result.push_back(info);
          }
          return result; }, py::return_value_policy::reference_internal)
      .def_property_readonly("inputs_epdevices", [](const PyInferenceSession* sess) -> std::vector<const OrtEpDevice*> {
         Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
         auto ep_devices = session.GetEpDeviceForInputs();
         std::vector<const OrtEpDevice*> result;
         result.reserve(ep_devices.size());
         for (const auto& device : ep_devices) {
           result.push_back(device);
         }
         return result; }, py::return_value_policy::reference_internal)

      .def("run_with_iobinding", [](PyInferenceSession* sess, SessionIOBinding& io_binding, RunOptions* run_options = nullptr) -> void {

        Status status;

        if (run_options != nullptr && !run_options->active_adapters.empty()) {
          LOGS(*sess->GetSessionHandle()->GetLogger(), WARNING)

Review comment (suggestion):
I don't think `reference_internal` will works as expected because this is returning a `std::vector<>` by value. The [pybind documentation](https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies) states that it will become `return_value_policy::move`:

> If the return value is an lvalue reference or a pointer, the parent object (the implicit this, or self argument of the called method or property) is kept alive for at least the lifespan of the return value. **Otherwise this policy falls back to return_value_policy::move** 



Code after:
            return session_options.release(); }, py::return_value_policy::take_ownership)
      .def_property_readonly("inputs_meta", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetModelInputs();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("outputs_meta", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetModelOutputs();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("overridable_initializers", [](const PyInferenceSession* sess) -> const std::vector<const onnxruntime::NodeArg*>& {
            auto res = sess->GetSessionHandle()->GetOverridableInitializers();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("model_meta", [](const PyInferenceSession* sess) -> const onnxruntime::ModelMetadata& {
            auto res = sess->GetSessionHandle()->GetModelMetadata();
            OrtPybindThrowIfError(res.first);
            return *(res.second); }, py::return_value_policy::reference_internal)
      .def_property_readonly("input_meminfos", [](const PyInferenceSession* sess) -> py::list { 
          Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
          auto inputs_mem_info = session.GetMemoryInfoForInputs();
          py::list result;
          for (const auto& info : inputs_mem_info) {
            const auto* p_info = static_cast<const OrtMemoryInfo*>(info);
            result.append(py::cast(p_info, py::return_value_policy::reference));
          }
          return result; })
      .def_property_readonly("output_meminfos", [](const PyInferenceSession* sess) -> py::list { 
          Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
          auto outputs_mem_info = session.GetMemoryInfoForOutputs();
          py::list result;
          for (const auto& info : outputs_mem_info) {
            const auto* p_info = static_cast<const OrtMemoryInfo*>(info);
            result.append(py::cast(p_info, py::return_value_policy::reference));
          }
          return result; })
      .def_property_readonly("input_epdevices", [](const PyInferenceSession* sess) -> py::list {
         Ort::ConstSession session(reinterpret_cast<const OrtSession*>(sess->GetSessionHandle()));
         auto ep_devices = session.GetEpDeviceForInputs();
         py::list result;
         for (const auto& device : ep_devices) {
           const auto* p_device = static_cast<const OrtEpDevice*>(device);
           result.append(py::cast(p_device, py::return_value_policy::reference));
         }
         return result; })
      .def("run_with_iobinding", [](PyInferenceSession* sess, SessionIOBinding& io_binding, RunOptions* run_options = nullptr) -> void {

        Status status;

        if (run_options != nullptr && !run_options->active_adapters.empty()) {
          LOGS(*sess->GetSessionHandle()->GetLogger(), WARNING)
              << "run_with_iobinding has active adapters specified, but won't have an effect";