add the capsule name to the py::capsule constructor

This allows named capsules to be constructed with `py::capsule`.
diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h
index c8a5014..a5aff66 100644
--- a/include/pybind11/pytypes.h
+++ b/include/pybind11/pytypes.h
@@ -1016,8 +1016,8 @@
     PYBIND11_DEPRECATED("Use reinterpret_borrow<capsule>() or reinterpret_steal<capsule>()")
     capsule(PyObject *ptr, bool is_borrowed) : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) { }
 
-    explicit capsule(const void *value)
-        : object(PyCapsule_New(const_cast<void *>(value), nullptr, nullptr), stolen_t{}) {
+    explicit capsule(const void *value, const char *name = nullptr, void (*destructor)(PyObject *) = nullptr)
+        : object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
         if (!m_ptr)
             pybind11_fail("Could not allocate capsule object!");
     }
@@ -1054,10 +1054,13 @@
     }
 
     template <typename T> operator T *() const {
-        T * result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, nullptr));
+        auto name = this->name();
+        T * result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
         if (!result) pybind11_fail("Unable to extract capsule contents!");
         return result;
     }
+
+    const char *name() const { return PyCapsule_GetName(m_ptr); }
 };
 
 class tuple : public object {
diff --git a/tests/test_python_types.cpp b/tests/test_python_types.cpp
index 0d7ea50..a3ed289 100644
--- a/tests/test_python_types.cpp
+++ b/tests/test_python_types.cpp
@@ -573,6 +573,22 @@
         }
     );
 
+    m.def("return_capsule_with_name_and_destructor_3",
+        []() {
+            py::print("creating capsule");
+            auto capsule=py::capsule((void *) 1234, "pointer type description",
+                [](PyObject *ptr) {
+                 if (ptr) {
+                    py::print("destructing capsule");
+                 }
+            });
+            auto name = capsule.name();
+            void *contents = capsule;
+            py::print("created capsule with name --{}-- and contents {}"_s.format(name,(size_t) contents));
+            return capsule;
+        }
+    );
+
     m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
     m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
 
diff --git a/tests/test_python_types.py b/tests/test_python_types.py
index 08bb3ab..ecd317e 100644
--- a/tests/test_python_types.py
+++ b/tests/test_python_types.py
@@ -603,10 +603,19 @@
         destructing capsule: 1234
     """
 
+    with capture:
+        a = m.return_capsule_with_name_and_destructor_3()
+        del a
+        pytest.gc_collect()
+    assert capture.unordered == """
+        created capsule with name --pointer type description-- and contents 1234
+        creating capsule
+        destructing capsule
+    """
+
 
 def test_void_caster():
     import pybind11_tests as m
-
     assert m.load_nullptr_t(None) is None
     assert m.cast_nullptr_t() is None