fix: add life support to handles cast to string_view (#6092)

* Fix handling of string_view to prevent GC'ing strings before they are used.

* style: pre-commit fixes

* Update cast.h

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index b7a4c2b..32e730f 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -526,6 +526,9 @@
                 return false;
             }
             value = StringType(buffer, static_cast<size_t>(size));
+            if (IsView) {
+                loader_life_support::add_patient(src);
+            }
             return true;
         }
 
@@ -603,6 +606,9 @@
                 pybind11_fail("Unexpected PYBIND11_BYTES_AS_STRING() failure.");
             }
             value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr()));
+            if (IsView) {
+                loader_life_support::add_patient(src);
+            }
             return true;
         }
         if (PyByteArray_Check(src.ptr())) {
@@ -613,6 +619,9 @@
                 pybind11_fail("Unexpected PyByteArray_AsString() failure.");
             }
             value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr()));
+            if (IsView) {
+                loader_life_support::add_patient(src);
+            }
             return true;
         }
 
diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp
index 8bddbb1..526c764 100644
--- a/tests/test_stl.cpp
+++ b/tests/test_stl.cpp
@@ -582,6 +582,16 @@
           [](const std::list<std::string> &) { return 2; });
     m.def("func_with_string_or_vector_string_arg_overload", [](const std::string &) { return 3; });
 
+#ifdef PYBIND11_HAS_STRING_VIEW
+    m.def("func_with_string_views", [](const std::vector<std::string_view> &svs) {
+        py::list l;
+        for (std::string_view sv : svs) {
+            l.append(sv);
+        }
+        return l;
+    });
+#endif
+
     class Placeholder {
     public:
         Placeholder() { print_created(this); }
diff --git a/tests/test_stl.py b/tests/test_stl.py
index b04f55c..8b97c76 100644
--- a/tests/test_stl.py
+++ b/tests/test_stl.py
@@ -28,6 +28,18 @@
     # Test regression caused by 936: pointers to stl containers weren't castable
     assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
 
+    if hasattr(m, "func_with_string_views"):
+
+        def gen():
+            return ("a" + str(x) for x in range(10000, 10010))
+
+        expected = list(gen())
+        assert m.func_with_string_views(gen()) == expected
+        assert m.func_with_string_views(x.encode() for x in gen()) == expected
+        assert (
+            m.func_with_string_views(bytearray(x.encode()) for x in gen()) == expected
+        )
+
 
 def test_deque():
     """std::deque <-> list"""