binutils-gdb/gdb/python
Andrew Burgess 2988a36005 gdb/python: Use tp_init instead of tp_new to setup gdb.Value
The documentation suggests that we implement gdb.Value.__init__,
however, this is not currently true, we really implement
gdb.Value.__new__.  This will cause confusion if a user tries to
sub-class gdb.Value.  They might write:

  class MyVal (gdb.Value):
      def __init__ (self, val):
          gdb.Value.__init__(self, val)

  obj = MyVal(123)
  print ("Got: %s" % obj)

But, when they source this code they'll see:

  (gdb) source ~/tmp/value-test.py
  Traceback (most recent call last):
    File "/home/andrew/tmp/value-test.py", line 7, in <module>
      obj = MyVal(123)
    File "/home/andrew/tmp/value-test.py", line 5, in __init__
      gdb.Value.__init__(self, val)
  TypeError: object.__init__() takes exactly one argument (the instance to initialize)
  (gdb)

The reason for this is that, as we don't implement __init__ for
gdb.Value, Python ends up calling object.__init__ instead, which
doesn't expect any arguments.

The Python docs suggest that the reason why we might take this
approach is because we want gdb.Value to be immutable:

   https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_new

But I don't see any reason why we should require gdb.Value to be
immutable when other types defined in GDB are not.  This current
immutability can be seen in this code:

  obj = gdb.Value(1234)
  print("Got: %s" % obj)
  obj.__init__ (5678)
  print("Got: %s" % obj)

Which currently runs without error, but prints:

  Got: 1234
  Got: 1234

In this commit I propose that we switch to using __init__ to
initialize gdb.Value objects.

This does introduce some additional complexity, during the __init__
call a gdb.Value might already be associated with a gdb value object,
in which case we need to cleanly break that association before
installing the new gdb value object.  However, the cost of doing this
is not great, and the benefit - being able to easily sub-class
gdb.Value seems worth it.

After this commit the first example above works without error, while
the second example now prints:

  Got: 1234
  Got: 5678

In order to make it easier to override the gdb.Value.__init__ method,
I have tweaked the definition of gdb.Value.__init__.  The second,
optional argument to __init__ is a gdb.Type, if this argument is not
present then GDB figures out a suitable type.

However, if we want to override the __init__ method in a sub-class,
and still support the default argument, it is easier to write:

  class MyVal (gdb.Value):
      def __init__ (self, val, type=None):
          gdb.Value.__init__(self, val, type)

Currently, passing None for the Type will result in an error:

  TypeError: type argument must be a gdb.Type.

After this commit I now allow the type argument to be None, in which
case GDB figures out a suitable type just as if the type had not been
passed at all.

Unless a user is trying to reinitialize a value, or create sub-classes
of gdb.Value, there should be no user visible changes after this
commit.
2021-12-08 13:38:11 +00:00
..
lib/gdb gdb/python: fix a few flake8 warnings 2021-10-02 08:33:28 -04:00
py-all-events.def gdb/python: introduce gdb.TargetConnection object type 2021-11-30 12:10:33 +00:00
py-arch.c gdb/python: don't use the 'p' format for parsing args 2021-11-30 15:46:09 +00:00
py-auto-load.c gdb: remove unnecessary lookup_cmd when deprecating commands 2021-05-27 14:00:07 -04:00
py-block.c gdb/python: remove all uses of Py_TPFLAGS_HAVE_ITER 2021-09-09 09:50:38 +01:00
py-bpevent.c
py-breakpoint.c gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptr 2021-11-16 17:45:45 +00:00
py-cmd.c gdb: remove cmd_list_element::function::sfunc 2021-07-23 15:38:54 -04:00
py-connection.c gdb/python: add gdb.RemoteTargetConnection.send_packet 2021-11-30 12:10:40 +00:00
py-continueevent.c
py-event-types.def gdb/python: introduce gdb.TargetConnection object type 2021-11-30 12:10:33 +00:00
py-event.c
py-event.h
py-events.h
py-evtregistry.c
py-evts.c
py-exitedevent.c
py-finishbreakpoint.c gdb: remove bpstat typedef, rename bpstats to bpstat 2021-11-08 16:39:14 -05:00
py-frame.c gdb/python: add PendingFrame.level and Frame.level methods 2021-06-21 16:20:08 +01:00
py-framefilter.c Remove uses of fprintf_symbol_filtered 2021-08-02 10:48:29 -06:00
py-function.c
py-gdb-readline.c
py-inferior.c gdb/python: introduce gdb.TargetConnection object type 2021-11-30 12:10:33 +00:00
py-infevents.c
py-infthread.c gdb: change thread_info::name to unique_xmalloc_ptr, add helper function 2021-09-24 17:25:55 -04:00
py-instruction.c
py-instruction.h
py-lazy-string.c
py-linetable.c gdb/python: remove all uses of Py_TPFLAGS_HAVE_ITER 2021-09-09 09:50:38 +01:00
py-membuf.c gdb/python: move gdb.Membuf support into a new file 2021-10-22 13:43:42 +01:00
py-newobjfileevent.c
py-objfile.c
py-param.c gdb: make string-like set show commands use std::string variable 2021-10-03 17:53:16 +01:00
py-prettyprint.c gdb: fix some indentation issues 2021-05-27 15:01:28 -04:00
py-progspace.c
py-record-btrace.c
py-record-btrace.h
py-record-full.c
py-record-full.h
py-record.c
py-record.h
py-ref.h
py-registers.c gdb/python: remove all uses of Py_TPFLAGS_HAVE_ITER 2021-09-09 09:50:38 +01:00
py-signalevent.c
py-stopevent.c gdb: remove bpstat typedef, rename bpstats to bpstat 2021-11-08 16:39:14 -05:00
py-stopevent.h gdb: remove bpstat typedef, rename bpstats to bpstat 2021-11-08 16:39:14 -05:00
py-symbol.c Restore gdb.SYMBOL_LABEL_DOMAIN constant 2021-06-03 14:56:55 +02:00
py-symtab.c
py-threadevent.c
py-tui.c Forward mouse click to python TUI window 2021-06-04 16:18:10 +02:00
py-type.c gdb: remove TYPE_FIELD_ENUMVAL 2021-10-29 16:44:45 -04:00
py-unwind.c gdb: change functions returning value contents to use gdb::array_view 2021-10-25 14:51:44 -04:00
py-utils.c
py-value.c gdb/python: Use tp_init instead of tp_new to setup gdb.Value 2021-12-08 13:38:11 +00:00
py-varobj.c
py-xmethods.c
python-config.py
python-internal.h gdb/python: introduce gdb.TargetConnection object type 2021-11-30 12:10:33 +00:00
python.c gdb/python: introduce gdb.TargetConnection object type 2021-11-30 12:10:33 +00:00
python.h