The standard Python interpreter lets you run scripts from files or interactively execute code on the fly in a so-called read-evaluate-print loop (REPL). While this is a powerful tool for exploring the language and discovering its libraries through instant feedback on your code inputs, the default REPL shipped with Python has several limitations. Luckily, alternatives like bpython offer a much more programmer-friendly and convenient experience.
You can use bpython to experiment with your code or quickly test an idea without switching contexts between different programs, just like in an integrated development environment (IDE). In addition, bpython may be a valuable teaching tool in either a virtual or physical classroom.
In this tutorial, you’ll learn how to:
- Install and use bpython as your alternative Python REPL
- Boost your productivity thanks to bpython’s unique features
- Tweak bpython’s configuration and its color theme
- Use common keyboard shortcuts to code more quickly
- Contribute to bpython’s open-source project on GitHub
Before starting this tutorial, make sure you’re already familiar with Python basics and know how to start the standard Python REPL in the command line. In addition, you should be able to install packages with pip, ideally into a virtual environment.
To download the configuration files and sample scripts that you’ll use in this tutorial, click the link below:
Source Code: Click here to download the free source code that you’ll use to harness the power of bpython.
Get Started With bpython
Unlike stand-alone Python distributions, such as CPython, PyPy, or Anaconda, bpython is merely a pure-Python package serving as a lightweight wrapper around a chosen Python interpreter. Therefore, you can use bpython on top of any particular Python distribution, version, or even a virtual environment, which gives you plenty of flexibility.
Note: The letter b in bpython stands for Bob Farrell, who’s the original author and maintainer of the tool.
At the same time, bpython remains a familiar Python REPL with only a few essential features, such as syntax highlighting and auto-completion, borrowed from the full-fledged Python IDEs. This minimalistic approach contrasts with tools like IPython, which is yet another alternative to the standard Python REPL, popular in the data science community. IPython introduces a lot of custom commands and other extras that are unavailable in vanilla Python.
There are a few ways to get bpython on your computer. Package managers like Homebrew or APT offer pre-built versions of bpython for your operating system. However, they’re likely obsolete and hardwired to the system-wide Python interpreter. While you can build the latest bpython version from its source code by hand, it’s better to install it into a virtual environment with pip:
(venv) $ python -m pip install bpython
It’s common to have bpython installed in several copies across many virtual environments, and that’s fine. This allows you to wrap bpython around the specific Python interpreter that you used to create the virtual environment in the first place.
Note: Unfortunately, bpython isn’t natively supported on Windows because it depends on the curses library, which is only available on Unix-like systems, such as macOS and Linux. The official documentation mentions a work-around, which relies on an unofficial binary for Windows, but it seems not to work anymore. If you’re on Windows, then your best bet is to install the Windows Subsystem for Linux (WSL) and use bpython from there.
Once it’s installed, you can start bpython using either of these two commands:
bpythonpython -m bpython
It’s preferable to choose the more explicit second command, which invokes bpython as a runnable Python module. This way, you’ll ensure that you’re running the bpython program installed into the currently active virtual environment.
On the other hand, using the bare bpython command could silently fall back to the program installed globally, if there is one. It could also be aliased to a different executable in your shell, taking precedence over the local bpython module.
Here’s an example illustrating the use of bpython against a few different Python interpreters encapsulated within isolated virtual environments:
(py2.7) $ python -m bpython
bpython version 0.20.1 on top of Python 2.7.18
⮑ /home/realpython/py2.7/bin/python
WARNING: You are using `bpython` on Python 2. Support for Python 2
⮑ has been deprecated in version 0.19 and might disappear
⮑ in a future version.
>>> import platform
>>> platform.python_version()
'2.7.18'
>>> platform.python_implementation()
'CPython'
(py3.11) $ python -m bpython
bpython version 0.23 on top of Python 3.11.0
⮑ /home/realpython/py3.11/bin/python
>>> import platform
>>> platform.python_version()
'3.11.0'
>>> platform.python_implementation()
'CPython'
(pypy) $ python -m bpython
bpython version 0.23 on top of Python 3.9.12
⮑ /home/realpython/pypy/bin/python
>>> import platform
>>>> platform.python_version()
'3.9.12'
>>> platform.python_implementation()
'PyPy'
Notice that you use the same command to run bpython from different virtual environments. Each highlighted line indicates the interpreter version and a path to the Python executable that bpython wraps in the current REPL session. You can confirm the Python version and its implementation through the platform module from the standard library.
Note: The Django web framework can detect bpython if it’s installed in your virtual environment. The framework will automatically run bpython when you execute the shell command to bring up the Python interactive interpreter with your project files on the module search path.
Okay, now that you’ve learned how to install and run bpython as an alternative Python REPL, it’s time to explore its key features. Over the next few sections, you’ll discover several ways that bpython can increase your productivity as a Python programmer, regardless of your skill level.
Spot Typos at a Glance
Compared to bpython, Python’s standard REPL is like an old black-and-white TV set. It does the job of accurately conveying information, but sometimes you wish to see things in color for greater clarity. That’s particularly important during code editing, where every detail matters. Therefore, syntax highlighting and bracket matching are perhaps the most common features found in any decent IDE or code editor.
In bpython, you get both features out of the box, even though it’s only a text-based user interface (TUI) to the Python REPL. Colorful syntax highlighting helps you identify the structure of your code at a glance, while bracket matching makes it easier to keep the opening and closing brackets correctly balanced. Read on to see those features in action.
Syntax Highlighting
As you type code into bpython, your instructions get tokenized into Python keywords, operators, comments, variables, and literal values like strings, numbers, or Booleans. Each token type has an associated color to let you quickly see what kind of language construct you’re working with:
This tokenizing and coloring isn’t done by bpython directly, but by the Pygments library used under the surface. Later, you’ll learn how to customize the color theme in bpython.
Bracket Matching
In addition to providing syntax highlighting, bpython also lets you know if the opening and closing brackets in your code are correctly balanced. When you type a closing bracket, bpython will highlight the corresponding opening bracket and the other way around:
This works with different kinds of brackets in Python, including round brackets (()), square brackets ([]), and curly brackets ({}). You can even nest brackets inside one another, and bpython will highlight the correct pair of brackets when you place your cursor on one of them.
Type More Quickly and Accurately
When using the regular Python REPL, your coding speed is directly limited by how quickly you can type and how well you remember the names of functions, their arguments, and so on. In contrast, bpython provides useful suggestions that you can apply at the hit of a button with auto-completion. Plus, it helps you correctly indent your code and offers contextual history.
All these features can save you a lot of typing and help avoid annoying typos, making you faster and more productive at work.
Code Suggestions
As soon as you start typing something, bpython will look up Python keywords, built-ins, globals, and your current lexical scope according to the LEGB rule to find objects with matching names. It matches names that begin with a specific sequence of characters, so typing more characters will narrow down the results. It’ll then display a list of relevant suggestions in alphabetical order:
In this example, you’re getting suggestions for the pass statement, a few built-in functions like print(), and a user-defined variable called program_variable that was defined earlier in the current global scope.
You can cycle forward through those suggestions with Tab or cycle backward with Shift+Tab if you accidentally overshoot. This can be especially helpful when there’s too much content to fit on your screen.
Code suggestions also work in other places, a handy feature that you may use for type introspection to find out what attributes and methods are available in an object. But that’s not all!
Auto-Completion
Code suggestions go hand in hand with auto-completion, which is another nifty feature in many code editors, and bpython has it too. Essentially, it can write the remaining code for you when there’s no ambiguity about what you’re trying to type:
As you cycle through the available suggestions with Tab or Shift+Tab, bpython goes ahead and inserts the highlighted option into the Python REPL. On the other hand, if there’s only one suggestion left and you haven’t finished typing the whole name, then you can press Tab to have bpython automatically complete the remaining part.
A lesser-known fact about bpython’s auto-completion mechanism is that it understands your file system. In other words, when you start typing a string literal that resembles a file path and you hit Tab, then bpython will list all the files and folders that match the string you’ve typed so far:
It also expands special symbols. For example, the tilde character (~) is a shorthand notation for the current user’s home directory on macOS and Linux, which bpython will expand into an absolute path, saving you even more typing.
Auto-Indentation
When you write long blocks of code in the standard Python REPL, you must correctly indent each line yourself. This can be tedious, error-prone, and unnatural if you’re used to writing code in a full-fledged editor. Fortunately, bpython automatically adds the appropriate amount of indentation to the next line when you press the Enter key:
The default indentation in bpython is four spaces, which complies with the Python style described in a document called PEP 8. However, you can change the corresponding tab-length option in bpython’s configuration if you prefer a different indentation size. To exit the current block of code, you can hit Enter without typing anything on that line. This will reduce the indentation level by one.
Contextual History
The standard Python REPL keeps an unlimited history of the in-line instructions that you typed previously, even those from finished interpreter sessions. You can find your command history in a file named .python_history located in your user’s home directory. Like many other tools, the interactive Python interpreter handles the history through an interface to the GNU Readline library or by emulating it.
On the other hand, your bpython history is stored separately in a file called .pythonhist and is limited to one thousand lines by default, although you can increase that limit in the configuration. Despite these differences, both the standard Python REPL and bpython conceptually support the same basic commands to access the history. That said, bpython also maintains a contextual history, with results depending on where you are in your code.
You can browse the history by repeatedly using the arrow keys on your keyboard. Use the Up arrow to go back in time and the Down arrow to go forward in time, one line of code at a time. You can hit Enter to confirm your choice and reuse one of the old instructions:
Notice how the historical suggestions offered by bpython don’t always follow their chronological order. Instead, bpython filters out suggestions that wouldn’t fit the context on your current indentation level.
Unlike in the vanilla Python REPL, in bpython, history also comes into play when you start typing a line of code that’s already been executed before:
As soon as bpython finds a historical entry that begins with a matching character sequence, it’ll show a grayed-out completion. You can ignore it by typing something else over it, or you can accept the suggestion by pressing the Right arrow on your keyboard to have it auto-completed.
Avoid Context Switching
While computers are made for multitasking, humans aren’t very good at it. Context switching requires your brain to save the current state of each task, then jump to a different task, and continue from where you left off the previous task. This takes time and energy and can lead to mistakes, reducing your productivity. As a programmer, you already have enough complexity to worry about, so your tools should work to minimize context switching.
Integrated development environments, or IDEs, address this problem by consolidating various tools for writing software into a single application. The bpython REPL also provides means to help you maintain focus through the following features:
- Type Introspection: Look into objects at runtime to reveal their members.
- Function Signatures: See the expected parameters of functions and methods.
- Docstrings: Read the user-provided descriptions of types and functions.
- Source Code: View the underlying code of an object at hand.
By having this information right where you need it, you no longer have to open another program to explore unfamiliar code, potentially losing track of what you were doing. You’ll take a closer look at each of these features now.
Runtime Type Introspection
Code suggestions in bpython work in many places. One of them is Python’s dot operator (.) for accessing members of an object. Normally, you need to know the names of attributes and methods defined in a class up front or check the corresponding documentation or source code to avoid an attribute error. Fortunately, bpython allows you to introspect objects and filter their attributes at runtime without ever leaving your terminal.
For example, say that you’re creating a multithreaded application and don’t remember the exact name of a given method or attribute in the threading.Thread class. In this situation, you can use bpython like this:
Note that only public members are displayed by default because, under normal circumstances, you’re not supposed to touch the object’s internal implementation. However, occasionally, you may want to reach for or modify its internals. To reveal such private members in bpython, type one or two underscore characters (_) right after the dot operator.
Many of the suggested members whose names start with a double underscore are, in fact, special methods that allow for operator overloading in Python.
You can also use bpython’s suggestions to explore Python modules and packages before importing them. The REPL knows what modules are importable in the existing session, including the Python standard library, third-party libraries installed with pip, and custom modules located in your project folder. To trigger those suggestions, type import followed by a single space and at least one character, and then hit the Tab key:
Just like with inspecting object attributes, internal modules don’t show up as suggestions in bpython unless you explicitly request them by using the leading underscore or double underscore. Once you import a specific module, you can examine its contents using the familiar dot operator as before.
Function Signatures and Docstrings
When you type an opening parenthesis to call a function or method in bpython, it’ll display the corresponding function signature with its formal parameters and their default values. It’ll also show information on which ones are positional, positional-only, keyword, or keyword-only arguments:
As you provide values for your function call, bpython highlights the current parameter name in the function signature to indicate how many are left. This can be very helpful when the function expects multiple arguments.
Note: Displaying function signatures is an amazing feature of bpython. Unfortunately, this feature doesn’t support type hints, so the types of arguments or the function’s return value aren’t shown at all even if they exist in the source code.
Other than that, you’ll notice that some callable objects, such as complex(), don’t trigger their function signatures in bpython. Those are typically implemented as classes with special methods to make them appear and behave like functions, which bpython can struggle with.
Function signatures already provide plenty of useful information that can help you understand what a function or method does without having to look up its documentation. However, bpython goes the extra mile by displaying a docstring from the function’s body if it can find and extract one from the source code. In the example above, both your sub() function and Python’s built-in max() function have docstrings that bpython shows.
A docstring is usually a multiline string literal that immediately follows the function signature and contains a human-readable description of the function. Sometimes, it may include details about the function arguments or automated doctests to self-test and demonstrate how to use the function. Automatically displaying docstrings is more efficient than using Python’s built-in help() function or accessing the function’s .__doc__ attribute.
If neither the function signature nor the docstring is enough for you, then you can use bpython to reveal the underlying source code.
Source Code Preview
Contemporary code editors let you navigate to the definition of a symbol by clicking on it while holding a designated key on your keyboard. This works equally well for symbols that you’ve defined in your project and ones that are defined in the Python standard library or a third-party package installed with pip. In bpython, you can display a read-only preview of the corresponding source code by pressing F2 after typing a given symbol:
You can type the name of a module, function, or class. Depending on the type of symbol, you’ll only see the source code belonging to that particular scope. Interestingly enough, you can request the source code of the functions and classes that you defined earlier in the same REPL session.
Note: The source code preview opens in your operating system’s default terminal pager program, which is usually the Unix less command. You can use the arrow keys or Page Up and Page Down to scroll up and down, and press Q to quit. Searching is also possible with a forward-slash (/) and then N for the next occurrence or P for the previous one.
Whether you use a code editor or bpython, this feature will only work as long as there’s pure-Python source code available. On the other hand, if the symbol that you’re interested in is a built-in function or was implemented as an extension module in the C programming language, then you won’t be able to get any information about it. Instead, bpython will display a message that no source code was found.
Fix Mistakes More Quickly
Code editing capability is another area where the standard Python REPL is lacking. Oftentimes, you’ll find yourself retyping the same piece of code over and over again because of typos in nested blocks of code that are difficult to fix without starting from scratch.
Even with bpython’s intelligent code suggestions and auto-completion, you’ll occasionally make mistakes or just change your mind about a particular implementation when typing out code. The bpython REPL makes editing and reevaluating your code a breeze, offering many useful features that allow you to:
- Rewind one or more lines
- Edit code in an external editor
- Reload imported modules
In the following sections, you’ll learn how to use these neat features of bpython to quickly fix mistakes and typos or to change the implementation of your code snippets.
Rewind One or More Lines
When you make a typo in the middle of a code block using the vanilla Python REPL, then you have to retype the entire block of code from scratch. In bpython, you can press Ctrl+R to undo only one or just the last few lines and replace them with new ones:
Beware that each time you rewind even a single line of code, bpython runs the entire REPL session from the beginning again, including unedited lines that you’ve already executed. Therefore, you should be extra careful about the potential side effects of mutating an external state—for example, when writing to a file, database, or network connection.
The rewind feature is a great way to fix a mistake that you spotted right after making it, but it’s ill-suited for fixing earlier errors or for making major changes. For this, bpython has something else to offer.
Edit Code in an External Editor
By pressing Ctrl+X on your keyboard, you can add or modify code located at the current line in your bpython REPL using an external code editor:
The line selected for editing may be empty, or it may already contain some Python instruction that bpython will first save to a temporary file for the external editor to load. Note that you’re allowed to add more than one line of code while you’re using the editor—for example, to define a new function or an entire class. Once you’ve finished making modifications, save the file and exit your editor to return to bpython.
The bpython REPL will detect when you close the editor. Then, it’ll inject your new code from the temporary file back into the current session and reevaluate it, just as with the rewind feature before.
Note: The editor configured by default in bpython is the venerable vi, which comes with many Unix-like systems. While vi is a powerful editor, it earned a bad rap for its confusing modes and keyboard shortcuts. Therefore, you may want to choose a different editor that doesn’t require as much learning to master. You’ll find out how to change the code editor in bpython to something more modern, like Visual Studio Code, later on.
In addition to editing a single line or a block of code, you can edit your entire REPL session using an external code editor in bpython. Press F7 to open your current session in an editor:
This time, you’ll see all the contents of your REPL session, including outputs of the previous instructions in the form of comments. They’ll be ignored, as bpython will eventually reevaluate your session when you close the editor.
Note: When you paste a longer piece of code into bpython—for example, through an external editor—it knows where the entire code block ends, as you’d expect. This is an improvement over the regular Python REPL, which isn’t so clever about handling newlines.
For instance, newlines between class method definitions raise an IndentationError when evaluated by the vanilla Python REPL, but not in bpython: