[Lldb-commits] [PATCH] D127458: [lldb][bindings] Implement __repr__ instead of __str__

Dave Lee via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 9 16:53:07 PDT 2022


kastiglione created this revision.
kastiglione added reviewers: jingham, JDevlieghere, mib.
Herald added a project: All.
kastiglione requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

When using the `script` Python repl, SB objects are printed in a way that gives
the user no information. The simplest example is:

  (lldb) script lldb.debugger
  <lldb.SBDebugger; proxy of <Swig Object of type 'lldb::SBDebugger *' at 0x1097a5de0> >

This output comes from the Python repl printing the `repr()` of an object.

None of the SB classes implement `__repr__`, and all print like the above.
However, many (most?, all?) SB classes implement `__str__`. Because they
implement `__str__`, a more detailed output can be had by `print`ing the
object, for example:

  (lldb) script print(lldb.debugger)
  Debugger (instance: "debugger_1", id: 1)

For convenience, this change switches all SB classes that implement to
`__str__` to instead implement `__repr__`. The benefit being that when writing
a `script` invocation, you don't need to remember to wrap in `print`. If that
isn't enough motivation, consider the case where your Python expression results
in a list of SB objects, in that case you'd have to `map` or use a list
comprehension like `[str(x) for x in <some expression>]` in order to see the
details of the objects in the list.

For reference, the docs for `repr` say:

> repr(object)
>
>   Return a string containing a printable representation of an object. For
>   many types, this function makes an attempt to return a string that would
>   yield an object with the same value when passed to eval(); otherwise, the
>   representation is a string enclosed in angle brackets that contains the
>   name of the type of the object together with additional information often
>   including the name and address of the object. A class can control what this
>   function returns for its instances by defining a __repr__() method.

and the docs for `__repr__` say:

> object.__repr__(self)
>
>   Called by the repr() built-in function to compute the “official” string
>   representation of an object. If at all possible, this should look like a
>   valid Python expression that could be used to recreate an object with the
>   same value (given an appropriate environment). If this is not possible, a
>   string of the form <...some useful description...> should be returned. The
>   return value must be a string object. If a class defines __repr__() but not
>   __str__(), then __repr__() is also used when an “informal” string
>   representation of instances of that class is required.
>   
>   This is typically used for debugging, so it is important that the
>   representation is information-rich and unambiguous.

Note the point that when implementing only `__repr__` (and not `__str__`), then
`__repr__` is used when `str()` is called.

Even if it were convenient to construct Python expressions for SB classes so
that they could be `eval`'d, I don't current know of a motivating reason for
typical lldb usage. As it stands, the only thing the docs say to do, that this
change doesn't do, is wrap the `repr` string in `<>` angle brackets.

An alternative implementation is to change lldb's python repl to apply `str()`
to the top level result. While this would work well in the case of a single SB
object, it doesn't work for a list of SB objects, since `str([x])` uses `repr`
to convert each list element to a string.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127458

Files:
  lldb/bindings/macros.swig


Index: lldb/bindings/macros.swig
===================================================================
--- lldb/bindings/macros.swig
+++ lldb/bindings/macros.swig
@@ -1,6 +1,6 @@
 %define STRING_EXTENSION_LEVEL(Class, Level)
 %extend {
-  std::string lldb:: ## Class ## ::__str__(){
+  std::string lldb:: ## Class ## ::__repr__(){
     lldb::SBStream stream;
     $self->GetDescription (stream, Level);
     const char *desc = stream.GetData();
@@ -15,7 +15,7 @@
 
 %define STRING_EXTENSION(Class)
 %extend {
-  std::string lldb:: ## Class ## ::__str__(){
+  std::string lldb:: ## Class ## ::__repr__(){
     lldb::SBStream stream;
     $self->GetDescription (stream);
     const char *desc = stream.GetData();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D127458.435735.patch
Type: text/x-patch
Size: 709 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220609/c9e7f887/attachment.bin>


More information about the lldb-commits mailing list