diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index f477d4a..840c842 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -461,7 +461,7 @@ Return true if this block is valid, false if not." },
   {NULL}  /* Sentinel */
 };
 
-static PyGetSetDef block_object_getset[] = {
+static gdb_PyGetSetDef block_object_getset[] = {
   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
   { "function", blpy_get_function, NULL,
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 724a7ed..34f46fb 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -1048,7 +1048,7 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v)
   return PyObject_GenericSetAttr ((PyObject *)self, name, v);
 }
 
-static PyGetSetDef breakpoint_object_getset[] = {
+static gdb_PyGetSetDef breakpoint_object_getset[] = {
   { "enabled", bppy_get_enabled, bppy_set_enabled,
     "Boolean telling whether the breakpoint is enabled.", NULL },
   { "silent", bppy_get_silent, bppy_set_silent,
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index 127dcc7..dc1d73e 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -114,7 +114,7 @@ evpy_emit_event (PyObject *event,
   return 0;
 }
 
-static PyGetSetDef event_object_getset[] =
+static gdb_PyGetSetDef event_object_getset[] =
 {
   { "__dict__", gdb_py_generic_dict, NULL,
     "The __dict__ for this event.", &event_object_type },
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 106fe34..76189b8 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -426,7 +426,7 @@ gdbpy_initialize_finishbreakpoints (void)
   return 0;
 }
 
-static PyGetSetDef finish_breakpoint_object_getset[] = {
+static gdb_PyGetSetDef finish_breakpoint_object_getset[] = {
   { "return_value", bpfinishpy_get_returnvalue, NULL,
   "gdb.Value object representing the return value, if any. \
 None otherwise.", NULL },
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 46a0aad..77fc543 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -827,7 +827,7 @@ gdbpy_initialize_inferior (void)
 				 &membuf_object_type);
 }
 
-static PyGetSetDef inferior_object_getset[] =
+static gdb_PyGetSetDef inferior_object_getset[] =
 {
   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 5482bf9..626c15c 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -304,7 +304,7 @@ gdbpy_initialize_thread (void)
 				 (PyObject *) &thread_object_type);
 }
 
-static PyGetSetDef thread_object_getset[] =
+static gdb_PyGetSetDef thread_object_getset[] =
 {
   { "name", thpy_get_name, thpy_set_name,
     "The name of the thread, as set by the user or the OS.", NULL },
diff --git a/gdb/python/py-lazy-string.c b/gdb/python/py-lazy-string.c
index ab3f411..1999033 100644
--- a/gdb/python/py-lazy-string.c
+++ b/gdb/python/py-lazy-string.c
@@ -300,7 +300,7 @@ static PyMethodDef lazy_string_object_methods[] = {
 };
 
 
-static PyGetSetDef lazy_string_object_getset[] = {
+static gdb_PyGetSetDef lazy_string_object_getset[] = {
   { "address", stpy_get_address, NULL, "Address of the string.", NULL },
   { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
   { "length", stpy_get_length, NULL, "Length of the string.", NULL },
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index a5e57b0..8d17aab 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -550,7 +550,7 @@ PyTypeObject ltpy_iterator_object_type = {
 };
 
 
-static PyGetSetDef linetable_entry_object_getset[] = {
+static gdb_PyGetSetDef linetable_entry_object_getset[] = {
   { "line", ltpy_entry_get_line, NULL,
     "The line number in the source file.", NULL },
   { "pc", ltpy_entry_get_pc, NULL,
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 105d88a..6a47c17 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -670,7 +670,7 @@ Add FILE_NAME to the list of files containing debug info for the objfile." },
   { NULL }
 };
 
-static PyGetSetDef objfile_getset[] =
+static gdb_PyGetSetDef objfile_getset[] =
 {
   { "__dict__", gdb_py_generic_dict, NULL,
     "The __dict__ for this objfile.", &objfile_object_type },
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index 1e06a75..edabba4 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -378,7 +378,7 @@ gdbpy_initialize_pspace (void)
 
 
 
-static PyGetSetDef pspace_getset[] =
+static gdb_PyGetSetDef pspace_getset[] =
 {
   { "__dict__", gdb_py_generic_dict, NULL,
     "The __dict__ for this progspace.", &pspace_object_type },
diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c
index c816332..6d08121 100644
--- a/gdb/python/py-record-btrace.c
+++ b/gdb/python/py-record-btrace.c
@@ -903,7 +903,7 @@ recpy_bt_goto (PyObject *self, PyObject *args)
 
 /* BtraceInstruction members.  */
 
-struct PyGetSetDef btpy_insn_getset[] =
+struct gdb_PyGetSetDef btpy_insn_getset[] =
 {
   { "number", btpy_number, NULL, "instruction number", NULL},
   { "error", btpy_insn_error, NULL, "error number for gaps", NULL},
@@ -920,7 +920,7 @@ executed speculatively", NULL},
 
 /* BtraceFunctionCall members.  */
 
-static PyGetSetDef btpy_call_getset[] =
+static gdb_PyGetSetDef btpy_call_getset[] =
 {
   { "number", btpy_number, NULL, "function call number", NULL},
   { "level", btpy_call_level, NULL, "call stack level", NULL},
diff --git a/gdb/python/py-record.c b/gdb/python/py-record.c
index 72922a4..60c0a7c 100644
--- a/gdb/python/py-record.c
+++ b/gdb/python/py-record.c
@@ -175,7 +175,7 @@ Rewind to given location."},
 
 /* Record member list.  */
 
-static PyGetSetDef recpy_record_getset[] = {
+static gdb_PyGetSetDef recpy_record_getset[] = {
   { "ptid", recpy_ptid, NULL, "Current thread.", NULL },
   { "method", recpy_method, NULL, "Current recording method.", NULL },
   { "format", recpy_format, NULL, "Current recording format.", NULL },
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index b71cfb4..05b002f 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -560,7 +560,7 @@ gdbpy_initialize_symbols (void)
 
 
 
-static PyGetSetDef symbol_object_getset[] = {
+static gdb_PyGetSetDef symbol_object_getset[] = {
   { "type", sympy_get_type, NULL,
     "Type of the symbol.", NULL },
   { "symtab", sympy_get_symtab, NULL,
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index 09cab22..53b160e 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -544,7 +544,7 @@ gdbpy_initialize_symtabs (void)
 
 
 
-static PyGetSetDef symtab_object_getset[] = {
+static gdb_PyGetSetDef symtab_object_getset[] = {
   { "filename", stpy_get_filename, NULL,
     "The symbol table's source filename.", NULL },
   { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.",
@@ -606,7 +606,7 @@ PyTypeObject symtab_object_type = {
   symtab_object_getset		  /*tp_getset */
 };
 
-static PyGetSetDef sal_object_getset[] = {
+static gdb_PyGetSetDef sal_object_getset[] = {
   { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL },
   { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL },
   { "last", salpy_get_last, NULL,
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index f071006..12b6310 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1413,7 +1413,7 @@ gdbpy_initialize_types (void)
 
 
 
-static PyGetSetDef type_object_getset[] =
+static gdb_PyGetSetDef type_object_getset[] =
 {
   { "code", typy_get_code, NULL,
     "The code for this type.", NULL },
@@ -1587,7 +1587,7 @@ PyTypeObject type_object_type =
   0,				  /* tp_new */
 };
 
-static PyGetSetDef field_object_getset[] =
+static gdb_PyGetSetDef field_object_getset[] =
 {
   { "__dict__", gdb_py_generic_dict, NULL,
     "The __dict__ for this field.", &field_object_type },
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index bb42e8b..9c0470f 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1767,7 +1767,7 @@ gdbpy_initialize_values (void)
 
 
 
-static PyGetSetDef value_object_getset[] = {
+static gdb_PyGetSetDef value_object_getset[] = {
   { "address", valpy_get_address, NULL, "The address of the value.",
     NULL },
   { "is_optimized_out", valpy_get_is_optimized_out, NULL,
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 55efd75..d4ed170 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -286,6 +286,36 @@ gdb_PySys_SetPath (const GDB_PYSYS_SETPATH_CHAR *path)
 
 #define PySys_SetPath gdb_PySys_SetPath
 
+/* Wrap PyGetSetDef to allow convenient construction with string
+   literals.  Unfortunately, PyGetSetDef's 'name' and 'doc' members
+   are 'char *' instead of 'const char *', meaning that in order to
+   list-initialize PyGetSetDef arrays with string literals (and
+   without the wrapping below) would require writing explicit 'char *'
+   casts.  Instead, we extend PyGetSetDef and add constexpr
+   constructors that accept const 'name' and 'doc', hiding the ugly
+   casts here in a single place.  */
+
+struct gdb_PyGetSetDef : PyGetSetDef
+{
+  constexpr gdb_PyGetSetDef (const char *name_, getter get_, setter set_,
+			     const char *doc_, void *closure_)
+    : PyGetSetDef {const_cast<char *> (name_), get_, set_,
+		   const_cast<char *> (doc_), closure_}
+  {}
+
+  /* Alternative constructor that allows omitting the closure in list
+     initialization.  */
+  constexpr gdb_PyGetSetDef (const char *name_, getter get_, setter set_,
+			     const char *doc_)
+    : gdb_PyGetSetDef {name_, get_, set_, doc_, NULL}
+  {}
+
+  /* Constructor for the sentinel entries.  */
+  constexpr gdb_PyGetSetDef (std::nullptr_t)
+    : gdb_PyGetSetDef { NULL, NULL, NULL, NULL, NULL }
+  {}
+};
+
 /* In order to be able to parse symtab_and_line_to_sal_object function
    a real symtab_and_line structure is needed.  */
 #include "symtab.h"
