Skip to content

[lldb] Implement python __repr__ #5351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 22, 2022

Conversation

kastiglione
Copy link

@kastiglione kastiglione commented Sep 22, 2022

Cherry pick D127458 (c7a56af) to define __repr__ instead of __str__.

Additionally updates the static copy of the bindings.

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 result is that `str()` and
`repr()` will produce the same output**. This is because `str` calls `__repr__`
for classes that have  no `__str__` method.

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 <expr>]`
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.

Even if it were convenient to construct Python expressions for SB classes so
that they could be `eval`'d, however for typical lldb usage, I can't think of a
motivating reason to do so. As it stands, the only action 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.

Differential Revision: https://reviews.llvm.org/D127458

(cherry picked from commit c7a56af)
@kastiglione kastiglione changed the base branch from next to stable/20220421 September 22, 2022 17:15
@kastiglione
Copy link
Author

@swift-ci test

@kastiglione kastiglione merged commit 28ba57e into stable/20220421 Sep 22, 2022
@kastiglione kastiglione deleted the dl/python-use-repr-over-str branch September 22, 2022 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant