diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/doc/python.texi | 15 | ||||
-rw-r--r-- | gdb/python/py-color.c | 34 | ||||
-rw-r--r-- | gdb/python/py-unwind.c | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-color.exp | 25 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-unwind.exp | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-unwind.py | 20 |
6 files changed, 81 insertions, 26 deletions
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 45f5f70..cba3a0d 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -7049,13 +7049,13 @@ writable. @cindex colors in python @tindex gdb.Color -You can assign instance of @code{Color} to the @code{value} of +You can assign instance of @code{gdb.Color} to the @code{value} of a @code{Parameter} instance created with @code{PARAM_COLOR}. -@code{Color} may refer to an index from color palette or contain components -of a color from some colorspace. +@code{gdb.Color} may refer to an index from a color palette or contain +components of a color from some color space. -@defun Color.__init__ (@r{[}@var{value} @r{[}, @var{color-space}@r{]}@r{]}) +@defun Color.__init__ (@r{[}value @r{[}, color_space@r{]}@r{]}) @var{value} is @code{None} (meaning the terminal's default color), an integer index of a color in palette, tuple with color components @@ -7065,8 +7065,9 @@ or one of the following color names: @samp{green}, @samp{yellow}, @samp{blue}, @samp{magenta}, @samp{cyan}, or @samp{white}. -@var{color-space} should be one of the @samp{COLORSPACE_} constants. This -argument tells @value{GDBN} which color space @var{value} belongs. +@var{color_space} should be one of the @samp{COLORSPACE_} constants +listed below. This argument tells @value{GDBN} which color space +@var{value} belongs. @end defun @defvar Color.is_none @@ -7094,7 +7095,7 @@ This attribute exist if @code{is_direct} is @code{True}. Its value is tuple with integer components of a color. @end defvar -@defun Color.escape_sequence (@var{self}, @var{is_foreground}) +@defun Color.escape_sequence (is_foreground) Returns string to change terminal's color to this. If @var{is_foreground} is @code{True}, then the returned sequence will change diff --git a/gdb/python/py-color.c b/gdb/python/py-color.c index c48d14e..e208506 100644 --- a/gdb/python/py-color.c +++ b/gdb/python/py-color.c @@ -136,21 +136,21 @@ get_attr (PyObject *obj, PyObject *attr_name) /* Implementation of Color.escape_sequence (self, is_fg) -> str. */ static PyObject * -colorpy_escape_sequence (PyObject *self, PyObject *is_fg_obj) +colorpy_escape_sequence (PyObject *self, PyObject *args, PyObject *kwargs) { - if (!gdbpy_is_color (self)) - { - PyErr_SetString (PyExc_RuntimeError, - _("Object is not gdb.Color.")); - return nullptr; - } + static const char *keywords[] = { "is_foreground", nullptr }; + PyObject *is_fg_obj; - if (!PyBool_Check (is_fg_obj)) - { - PyErr_SetString (PyExc_RuntimeError, - _("A boolean argument is required.")); - return nullptr; - } + /* Parse method arguments. */ + if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O!", keywords, + &PyBool_Type, &is_fg_obj)) + return nullptr; + + /* Python ensures the type of SELF. */ + gdb_assert (gdbpy_is_color (self)); + + /* The argument parsing ensures we have a bool. */ + gdb_assert (PyBool_Check (is_fg_obj)); bool is_fg = is_fg_obj == Py_True; std::string s = gdbpy_get_color (self).to_ansi (is_fg); @@ -176,7 +176,10 @@ colorpy_init (PyObject *self, PyObject *args, PyObject *kwds) PyObject *colorspace_obj = nullptr; color_space colorspace = color_space::MONOCHROME; - if (!PyArg_ParseTuple (args, "|OO", &value_obj, &colorspace_obj)) + static const char *keywords[] = { "value", "color_space", nullptr }; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kwds, "|OO", keywords, + &value_obj, &colorspace_obj)) return -1; try @@ -285,7 +288,8 @@ gdbpy_initialize_color (void) static PyMethodDef color_methods[] = { - { "escape_sequence", colorpy_escape_sequence, METH_O, + { "escape_sequence", (PyCFunction) colorpy_escape_sequence, + METH_VARARGS | METH_KEYWORDS, "escape_sequence (is_foreground) -> str.\n\ Return the ANSI escape sequence for this color.\n\ IS_FOREGROUND indicates whether this is a foreground or background color."}, diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index ab34971..d43d7e9 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -929,9 +929,9 @@ frame_unwind_python::sniff (const frame_info_ptr &this_frame, /* Received UnwindInfo, cache data. */ PyObject *pyo_unwind_info = PyTuple_GET_ITEM (pyo_execute_ret.get (), 0); - if (PyObject_IsInstance (pyo_unwind_info, - (PyObject *) &unwind_info_object_type) <= 0) - error (_("A Unwinder should return gdb.UnwindInfo instance.")); + if (!PyObject_TypeCheck (pyo_unwind_info, &unwind_info_object_type)) + error (_("an Unwinder should return gdb.UnwindInfo, not %s."), + Py_TYPE (pyo_unwind_info)->tp_name); { unwind_info_object *unwind_info = diff --git a/gdb/testsuite/gdb.python/py-color.exp b/gdb/testsuite/gdb.python/py-color.exp index 99b4689..3563d22 100644 --- a/gdb/testsuite/gdb.python/py-color.exp +++ b/gdb/testsuite/gdb.python/py-color.exp @@ -22,7 +22,10 @@ require allow_python_tests # Start with a fresh gdb. clean_restart -gdb_test_no_output "python print_color_attrs = lambda c: print (c, c.colorspace, c.is_none, c.is_indexed, c.is_direct)" \ +gdb_test_no_output "python get_color_attrs = lambda c: \"%s %s %s %s %s\" % (str(c), c.colorspace, c.is_none, c.is_indexed, c.is_direct)" \ + "get_color_attrs helper" + +gdb_test_no_output "python print_color_attrs = lambda c: print (get_color_attrs (c))" \ "print_color_attrs helper" gdb_test_no_output "python c = gdb.Color ()" \ @@ -58,6 +61,15 @@ gdb_test "python print_color_attrs (c)" "green 1 False True False" \ gdb_test "python print (c.index)" "2" \ "print index of a basic color with ansi colorspace" +# Create a color using keyword arguments, and check it matches the +# non-keyword color. +gdb_test_no_output "python c2 = gdb.Color (color_space = gdb.COLORSPACE_ANSI_8COLOR, value = 2)" \ + "create color from basic index and ansi colorspace using keywords" +gdb_test "python print(get_color_attrs (c) == get_color_attrs (c2))" "True" \ + "check attributes match" +gdb_test "python print(c.index == c2.index)" "True" \ + "check index matches" + gdb_test_no_output "python c = gdb.Color (2, gdb.COLORSPACE_XTERM_256COLOR)" \ "create color from basic index and xterm256 colorspace" gdb_test "python print_color_attrs (c)" "2 3 False True False" \ @@ -96,6 +108,12 @@ gdb_test [concat "python print (c_red.escape_sequence (True) + " \ "c_none.escape_sequence (True))"] \ "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ "escape sequences" +gdb_test [concat "python print (c_red.escape_sequence (is_foreground = True) + " \ + "c_green.escape_sequence (is_foreground = False) + 'red on green' + " \ + "c_none.escape_sequence (is_foreground = False) + ' red on default' + " \ + "c_none.escape_sequence (is_foreground = True))"] \ + "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ + "escape sequences using keyword arguments" gdb_test_multiline "Try to sub-class gdb.Color" \ "python" "" \ @@ -130,3 +148,8 @@ gdb_test "python color_param.value = bad_obj" \ "Python Exception <class 'RuntimeError'>: color argument must be a gdb\\.Color object\\." \ "Error occurred in Python: color argument must be a gdb\\.Color object\\."] \ "set color parameter to a non-color type" + +gdb_test "python c_none.escape_sequence(c_red)" \ + [multi_line \ + "Python Exception <class 'TypeError'>: argument 1 must be bool, not gdb.Color" \ + "Error occurred in Python: argument 1 must be bool, not gdb.Color"] diff --git a/gdb/testsuite/gdb.python/py-unwind.exp b/gdb/testsuite/gdb.python/py-unwind.exp index 80eac28..b416c2f 100644 --- a/gdb/testsuite/gdb.python/py-unwind.exp +++ b/gdb/testsuite/gdb.python/py-unwind.exp @@ -245,6 +245,13 @@ with_test_prefix "frame-id 'pc' is invalid" { "Python Exception <class 'ValueError'>: invalid literal for int\\(\\) with base 10: 'xyz'\r\n.*" } +with_test_prefix "bad object unwinder" { + gdb_test_no_output "python obj = bad_object_unwinder(\"bad-object\")" + gdb_test_no_output "python gdb.unwinder.register_unwinder(None, obj, replace=True)" + gdb_test "backtrace" \ + "Python Exception <class 'gdb.error'>: an Unwinder should return gdb.UnwindInfo, not Blah\\.\r\n.*" +} + # Gather information about every frame. gdb_test_no_output "python capture_all_frame_information()" gdb_test_no_output "python gdb.newest_frame().select()" diff --git a/gdb/testsuite/gdb.python/py-unwind.py b/gdb/testsuite/gdb.python/py-unwind.py index 8e65a1a..0faccf2 100644 --- a/gdb/testsuite/gdb.python/py-unwind.py +++ b/gdb/testsuite/gdb.python/py-unwind.py @@ -267,4 +267,24 @@ class validating_unwinder(Unwinder): return None +class bad_object_unwinder(Unwinder): + def __init__(self, name): + super().__init__(name) + + def __call__(self, pending_frame): + + if pending_frame.level() != 1: + return None + + class Blah: + def __init__(self): + pass + + @property + def __class__(self): + raise RuntimeError("error in Blah.__class__") + + return Blah() + + print("Python script imported") |