Allow a pretty-printer without a to_string method
authorTom Tromey <tom@tromey.com>
Sat, 8 Sep 2018 20:40:38 +0000 (14:40 -0600)
committerTom Tromey <tom@tromey.com>
Sun, 9 Sep 2018 02:49:15 +0000 (20:49 -0600)
PR python/16047 points out that, while the documentation says that the
to_string method is optional for a pretty-printer, the code disagrees
and throws an exception.  This patch fixes the problem.  varobj is
already ok here.

Tested on x86-64 Fedora 26.

gdb/ChangeLog
2018-09-08  Tom Tromey  <tom@tromey.com>

PR python/16047:
* python/py-prettyprint.c (pretty_print_one_value): Check for
to_string method.

gdb/testsuite/ChangeLog
2018-09-08  Tom Tromey  <tom@tromey.com>

PR python/16047:
* gdb.python/py-prettyprint.py (pp_int_typedef3): New class.
(register_pretty_printers): Register new printer.
* gdb.python/py-prettyprint.exp (run_lang_tests): Add int_type3
test.
* gdb.python/py-prettyprint.c (int_type3): New typedef.
(an_int_type3): New global.

gdb/ChangeLog
gdb/python/py-prettyprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-prettyprint.c
gdb/testsuite/gdb.python/py-prettyprint.exp
gdb/testsuite/gdb.python/py-prettyprint.py

index 3247b66f6bb9e3e117d3c057a8a6688d93d859bb..bf5dcbca34aee45afbdbc12799c4238f6eae90f4 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-08  Tom Tromey  <tom@tromey.com>
+
+       PR python/16047:
+       * python/py-prettyprint.c (pretty_print_one_value): Check for
+       to_string method.
+
 2018-09-08  Joel Brobecker  <brobecker@adacore.com>
 
        * ada-lang.c (resolve_subexp): Pass correct OPLEN in call to
index a8a8489930993f0a12467defb53436754501c589..df0266b26139a485d1dcc1615a774de151aefc0a 100644 (file)
@@ -195,18 +195,23 @@ pretty_print_one_value (PyObject *printer, struct value **out_value)
   *out_value = NULL;
   TRY
     {
-      result.reset (PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst,
-                                               NULL));
-      if (result != NULL)
+      if (!PyObject_HasAttr (printer, gdbpy_to_string_cst))
+       result = gdbpy_ref<>::new_reference (Py_None);
+      else
        {
-         if (! gdbpy_is_string (result.get ())
-             && ! gdbpy_is_lazy_string (result.get ())
-             && result != Py_None)
+         result.reset (PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst,
+                                                   NULL));
+         if (result != NULL)
            {
-             *out_value = convert_value_from_python (result.get ());
-             if (PyErr_Occurred ())
-               *out_value = NULL;
-             result = NULL;
+             if (! gdbpy_is_string (result.get ())
+                 && ! gdbpy_is_lazy_string (result.get ())
+                 && result != Py_None)
+               {
+                 *out_value = convert_value_from_python (result.get ());
+                 if (PyErr_Occurred ())
+                   *out_value = NULL;
+                 result = NULL;
+               }
            }
        }
     }
index 02da57f7872bbe3d368ce71ab411dc360b18c448..6403cb8eb69e7f75470b55ea196ee0c447cc2b94 100644 (file)
@@ -1,3 +1,13 @@
+2018-09-08  Tom Tromey  <tom@tromey.com>
+
+       PR python/16047:
+       * gdb.python/py-prettyprint.py (pp_int_typedef3): New class.
+       (register_pretty_printers): Register new printer.
+       * gdb.python/py-prettyprint.exp (run_lang_tests): Add int_type3
+       test.
+       * gdb.python/py-prettyprint.c (int_type3): New typedef.
+       (an_int_type3): New global.
+
 2018-09-08  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.ada/expr_with_funcall: New testcase.
index 35ef5e0756b182c56145bd11961046407f22dede..ef5b0c3c5eade57141c47d99a3e3b18411812b60 100644 (file)
@@ -271,10 +271,12 @@ bug_14741()
    when looking for a printer.  */
 typedef int int_type;
 typedef int_type int_type2;
+typedef int_type int_type3;
 
 int an_int = -1;
 int_type an_int_type = 1;
 int_type2 an_int_type2 = 2;
+int_type3 an_int_type3 = 3;
 
 int
 main ()
index 2671cb8471b8de0dd23cbcf597ff33793b2ca0fd..0508a9718fec7fe09cea7e9b150bbfd330f60cc4 100644 (file)
@@ -127,6 +127,10 @@ proc run_lang_tests {exefile lang} {
     gdb_test "print (int_type) an_int_type2" " = type=int_type, val=2"
     gdb_test "print (int_type2) an_int_type2" " = type=int_type2, val=2"
 
+    # PR python/16047: it is ok for a pretty printer not to have a
+    # to_string method.
+    gdb_test "print (int_type3) an_int_type2" " = {s = 27}"
+
     gdb_continue_to_end
 }
 
index 7357f05cc93e17cac3cc81d2fd841c23402a6761..91592b4ec7933600f4d9152e3bbd09035f4efc4d 100644 (file)
@@ -253,6 +253,15 @@ class pp_int_typedef (object):
     def to_string(self):
         return "type=%s, val=%s" % (self.val.type, int(self.val))
 
+class pp_int_typedef3 (object):
+    "A printer without a to_string method"
+
+    def __init__(self, val):
+        self.val = val
+
+    def children(self):
+        yield 's', 27
+
 def lookup_function (val):
     "Look-up and return a pretty-printer that can print val."
 
@@ -362,6 +371,7 @@ def register_pretty_printers ():
 
     typedefs_pretty_printers_dict[re.compile ('^int_type$')] = pp_int_typedef
     typedefs_pretty_printers_dict[re.compile ('^int_type2$')] = pp_int_typedef
+    typedefs_pretty_printers_dict[re.compile ('^int_type3$')] = pp_int_typedef3
 
 # Dict for struct types with typedefs fully stripped.
 pretty_printers_dict = {}