Warning
This project is being split into 3 separate projects:
friendly_traceback
,friendly
, andfriendly_idle
.
The documentation does not reflect this change.
If you are a end-user, just install friendly
until further notice.
Multiple tracebacks¶
Tip
You might want to skip this section if it is the first time you read through this documentation.
In addition to providing additional information about the actual cause
of an exception, compared with a traditional traceback, the traceback
itself is formatted differently than a traditional Python traceback.
You can choose to see three different tracebacks:
friendly_tb
, python_tb
, debug_tb
.
Of these three, python_tb
is designed to reproduce fairly accurately
what would be seen if a program would be run without
friendly. In a few cases, it will have some minor differences
compared with a normal Python traceback.
In this section, I compare these three tracebacks with the normal Python traceback in three different settings:
Running a module from the command line.
Importing a module.
Writing code in the interpreter.
For the first two, the module I will run contains the following:
import string
def is_lowercase(c):
return c in string.lowercase
is_lowercase('a')
Running a module from the command line¶
First, I show the result of running a module containing the code shown above using Python.
Next, I run the same module using friendly
showing the python_tb
case; this is done using --include python_tb
as a command line option.
In this particular case, the only difference with the
normal Python traceback is the addition of an empty line preceding
the traceback, with the goal of increasing readability.
With the friendly_tb
option, you see a “hint” added to the traceback;
in some instances, no such hint can be provided.
Finally, I use the debug_tb
to show the real traceback produced
when running this example using friendly: it includes
code from friendly itself.
Importing a module¶
Let’s compare what happens if I import the same module instead from a console, starting with Python’s own.
When doing the same with friendly, it is the friendly_tb
that is shown by default. It has three differences compared with
the normal Python traceback:
The name of the console is different (
<friendly-console:...>
instead of<stdin>
.)Paths are shortened (more about this below)
As before, any “hint” available is automatically shown.
You can see the simulated Python traceback by entering python_tb()
;
as before, and except for the name of the console,
the only difference with a normal Python traceback is the addition of
an empty line preceding the traceback.
Finally, you can use debug_tb()
to see the complete traceback.
More about the friendly interpreter¶
When using a normal Python interpreter, the traceback generated includes only a list of “files” without including the actual content of the line that was executed.
As before, when doing the same with friendly,
it is the friendly_tb
that is shown by default.
It includes the line of code that was executed for each “file”.
The same is true for the python_tb()
; I could remove this information
to make it more similar to a “true” Python traceback but I feel that
the loss of information would not be helpful.
As before, I can use debug_tb()
to see the complete traceback.
Since paths can be quite long, when showing information about an
exception, friendly will attempt to reduce the length
of the path shown. You’ve seen before an example where FRIENDLY
was substituted for the name of the directory where friendly
is located; this particular example will rarely be seen by an end-user.
However, sometimes HOME_DIR
will be shown instead of the full
path to the user’s home directory.
A much more significant reduction in length occurs when the path
for a module from the Python standard library, as shown below.
Lines suppressed: recursion example¶
Consider the following:
def a():
b()
def b():
a()
a()
Try running this using Python. Not only will you get a
RecursionError
but you’ll get something like 2000 lines included.
This is not exactly user friendly. It is also what
would be shown if I had used debug_tb()
. Let’s skip this, and
only look at the output from the other two tracebacks, starting
with friendly_tb()
which is shown by default.
As a rule, and not only for the RecursionError
cases,
the friendly_tb()
default will only show a few intermediate lines
of code, to avoid filling the screen with too much information.
A similar, but not quite as extensive suppression is also done for
python_tb()
but only for RecursionError
cases.