Warning
Most of the documentation was written prior to version 0.5 and needs to be updated. This work has now started for version 0.7 and we aim to have it completed before version 0.8 is available.
Other details for advanced users¶
Tip
Some additional information might be available from the command line:
friendly -h
python -m friendly_traceback -h
Running another script¶
We have already explained how to run a program using Friendly. What if the separate script has its own command line arguments?
Consider the following program:
# Demonstration of a program that uses command line arguments
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("numbers", nargs="*",
help="List of numbers to add."
)
parser.add_argument("--to_int",
help="Converts the sum to integer",
action="store_true"
)
total = 0
args = parser.parse_args()
for number in args.numbers:
total += float(number)
if int(total) == total and args.to_int:
total = int(total)
print("The sum is", total)
Using Python, we would normally run this program as follows.
python adder.py 1 2 3
The sum is 6
We can do the same using friendly (or friendly_traceback).
friendly adder.py 1 2 3
The sum is 6.0
Note that this works even if you specify command line arguments that are specific to friendly:
friendly --lang fr adder.py 1 2 3
The sum is 6.0
However, what if one wants to run a script that uses optional named arguments
similarly to how friendly can use --lang
and other optional
arguments? In this case, use --
to separate the list of arguments
to be used by the script from those written previously and
intended to be used by friendly:
friendly --lang fr adder.py -- --to_int 1 2 3
The sum is 6
Finally, let’s generate a traceback to see Friendly in action, this time
using friendly_traceback so that no special formatting is applied,
and using the program found in the demos
directory.
Note that we need to have the required dependencies already installed.
python -m friendly_traceback demos/adder.py -- --to_int 1 2 3 a
Traceback (most recent call last):
File "HOME:\github\friendly-traceback\demos\adder.py", line 13, in <module>
total += float(number)
ValueError: could not convert string to float: 'a'
A `ValueError` indicates that a function or an operation
received an argument of the right type, but an inappropriate value.
The string `a` cannot be converted to a `float`
as it does not represent a number.
Exception raised on line `13` of file 'HOME:\github\friendly-traceback\demos\adder.py'.
9| total = 0
10| args = parser.parse_args()
11|
12| for number in args.numbers:
-->13| total += float(number)
^^^^^^^^^^^^^
14|
15| if int(total) == total and args.to_int:
number: 'a'
float: <class float>
Where the output is written?¶
By default, friendly tracebacks are written to sys.stderr
.
However, it is possible to override this choice, as follows:
friendly.set_stream(stream)
Thus, the default amounts to:
friendly.set_stream(sys.stderr)
A special option exists to capture the output as a string:
friendly.set_stream("capture")
Later, this captured output can be retrieved using:
output = friendly.get_output()
# equivalent to
output = friendly.get_output(flush=True)
The value shown for the flush
parameter is the default; this means that
the output will be cleared once it has been retrieved. If this is not the
desired behaviour, simply use flush=False
.
Language used¶
The language used can be explicitly set as follows:
friendly.set_lang("fr") # two-letter code for French
The language currently used can be obtained using:
lang = friendly.get_lang()
If the language requested does not exist, no error is raised nor any warning given, but the choice reverts to the default (English).
As an exception hook¶
When “installing” friendly, one can use various optional parameters:
friendly.install(lang="fr", redirect="capture", include="explain")
This is equivalent to writing:
friendly.install()
friendly.set_lang("fr")
friendly.set_stream("capture")
friendly.set_include("explain")
Using Friendly by default¶
An alterative to installing Friendly in each individual
programs is to use either a sitecustomize.py
or a usercustomize.py
file, as described in the
Python documentation.
For example, you can use the following approach.
Create a
usercustomize.py
file whose content is the following:import friendly friendly.install() # specify other desired options here
Set the
PYTHONPATH
environment variable to that directory. On Windows, this can be done by navigating to that directory and writing:set PYTHONPATH=%CD%
You can now run your script normally: friendly exception handling will be used by default on it.
Catching exception locally¶
As mentioned before, another way to use friendly is to catch exceptions where they are expected to arise, such as:
try:
# Some code
except Exception:
friendly.explain_traceback()
This uses the default of writing to sys.stderr
.
One can also temporarily redirect the output to any stream:
try:
# Some code
except Exception:
friendly.explain_traceback(redirect=stream)
By default, friendly takes its information from sys.exc_info()
.
It may happen that this is not what we want to show.
For example, the showtraceback method in Python’s code.py replaces one of the items prior to
showing the traceback to the user; we currently also do something similar in
friendly’s own console.
Finally, if one wishes to temporarily change some other option mentioned above, it can be done as in the following example:
try:
# Some code
except Exception:
lang = friendly.get_lang()
friendly.set_lang("fr")
friendly.explain_traceback()
friendly.set_lang(lang)
Logging¶
You can use friendly_traceback with the logging module. How to do so is explained on the next page.