bpython's keymap is the feature list, and F8 uploads your screen to pastebin
bpython - A fancy curses interface to the Python interactive interpreter
At a glance
- What is it?
- A curses interface to the Python interactive interpreter with highlighting, parameter hints, auto-indentation and completion. Three of its features work by re-running the whole session, and the fourth sends the screen to a paste site. Its dependency lists disagree with each other and macOS has one package route.
- Who is it for?
- Adopt bpython if you want a REPL that colours code as you type, shows function signatures, and can replay the last state of a session after an edit, and if you are on Linux or willing to pip install on macOS. Do not adopt it expecting a maintained modern console: the optional completion path is jedi for experimental multiline completion, the release tags carry no v prefix, and the only macOS package route is MacPorts under the name py-bpython.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 33 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four conveniences, and an explicit refusal to be an IDE
The README is reStructuredText, opening with a row of asterisks and a title that says a fancy interface to the Python interactive interpreter. The repository description calls it a curses interface to the same thing.
The feature list is four items. Syntax highlighting, expected parameter list, auto-indentation and autocompletion. Then a sentence that sets the ceiling: bpython does not aim to be a complete IDE, and the stated focus is implementing a few ideas in a practical, useful and lightweight manner.
The parameter list is the most substantial of the four and has a documented fallback chain. For any function you call, it tries the inspect module first, and pydoc if that fails. Highlighting is not its own parser: it uses Pygments to lex the code as you type, which is why Pygments is a required dependency rather than an optional one.
The intended occasions are equally specific. Testing a solution to somebody's problem on IRC, and trying a method without creating a temporary file. Both are throwaway-interpreter tasks, which is the frame the tool is built for.
A black code style badge sits at the top of the file, and the repository carries a theme/ directory for the curses appearance and a bpdb/ directory for the debugger.
Rewind, F6 and F7 all re-run the whole session
Three of the seven features share one mechanism, and it is the one to understand before typing anything.
Rewind keeps the code you entered in memory; calling it pops the last line and re-evaluates the entire session. The bound key is control-R. The README is unusually candid about the naming, saying it is not called Undo because that would be misleading, and that Rewind is probably as bad.
F7 opens the current session in a text editor, and if you make modifications the session is rerun with those changes. F6 clears `sys.modules` and reruns the session, which is how you test a change to a module you are working on.
So none of the three is incremental. Each one re-executes every line you have entered, not just the edit. For a session that has printed things, mutated a global, written a file or created an object with a side effect, the second run does that work again, and the README does not warn about it. That is the practical constraint on using any of them, and it is a property of the design rather than a bug.
The description of Rewind as a feature of memory keeping is accurate; the description of it as undo is not, for exactly this reason.
F8 uploads the screen to pastebin and returns a URL
The seventh feature is the odd one out. Press F8 and the screen's contents are uploaded to pastebin, with a URL returned.
Every other feature is local. Highlighting lexes locally, the parameter list calls inspect or pydoc locally, rewind re-evaluates locally. The pastebin action is the one feature in the list that sends data off the machine, and it does so from inside an interactive session where a single keystroke triggers it.
The README documents no confirmation prompt, no preview of what would be uploaded, no size limit and no offline substitute. What it does document is the return value: a URL.
The dependency list is consistent with the feature existing, since requests is a required dependency, but nothing else on the page warns about it. If your terminal sessions contain credentials, internal hostnames or customer data, that is the one keystroke to bind away, and the README gives no option to disable the feature.
The other bindings for reference: control-R for rewind, F6 for the module reload, F7 for the editor, F8 for the upload. `exit()` or control-D leaves the interpreter, the same as vanilla Python.
requirements.txt and the README list different dependencies
The README lists nine. Four are required: Pygments, curtsies 0.4.0 or newer, greenlet and pyxdg, plus requests, which makes five. Five are optional: Sphinx 1.5 or newer for the documentation, babel for internationalization, jedi for experimental multiline completion, watchdog for monitoring imported modules for changes, and pyperclip for copying to the clipboard.
The file in the repository root disagrees on both sides:
Pygments
curtsies >=0.4.0
cwcwidth
greenlet
pyxdg
requests
setuptools>=62.4.0`cwcwidth` appears in the file and nowhere in the README's dependency list, so it is a runtime requirement the documentation does not mention. `setuptools>=62.4.0` appears there as well, which is a build requirement sitting in what reads as a runtime requirements file. And the five optional packages are absent from the file entirely, which is consistent with them being extras.
Greenlet is listed without any explanation of what it is for, which is an unusual omission for a dependency with as specific a purpose. The README also documents a second front end, bpython-urwid, which needs the urwid package on top of everything above.
pyproject.toml holds the backend and the formatter, and no metadata
The pyproject.toml is twenty-seven lines and contains two tables. The build system requires setuptools 62.4.0 or newer with the setuptools.build_meta backend. The rest is the formatter:
[tool.black]
line-length = 80
target_version = ["py311"]
include = '\.pyi?$'There is no project table. So the name, version, description and dependencies are not declared there, which leaves setup.py and setup.cfg carrying them, and setup.py is still substantial rather than a stub. It defines a BuildDoc distutils command that runs Sphinx, it checks for babel and sets a translations flag, and it wires both into the build.
One of those checks is wrong in a way that will bite eventually:
import sphinx
# Sphinx 1.5 and newer support Python 3.6
using_sphinx = sphinx.__version__ >= "1.5"That compares version strings rather than parsed versions, so a Sphinx release numbered 1.10 sorts below 1.5 and the check would decide the documentation tooling is too old.
Elsewhere the project is mid-migration rather than confused: stubs/ holds type stubs, and black is told to include `\.pyi?$`, which is what makes that consistent.
macOS gets MacPorts under a different package name, and nothing else
Six package managers are documented, one per platform, and one platform is missing from the list.
$ apt install bpython
$ apt-get install bpython
$ pacman -S bpython
$ dnf install bpython
$ guix install bpython
$ sudo port install py-bpythonThe first two lines are the same instruction at two generations of Debian tooling, with `apt-get install` offered as the fallback for an older system. The last one is macOS, and the README is explicit about the reason: macOS does not include a package manager by default, and if you have installed a third-party one like MacPorts you can install it that way. The package name also changes, from bpython to py-bpython, which is a MacPorts naming convention rather than a typo.
So there is no Homebrew line, and pip is the only other route on macOS. There is no Windows package line either, leaving pip as the documented path there too.
Configuration follows the same pattern. Save it as `~/.config/bpython/config`, which the README spells out as `$XDG_CONFIG_HOME/bpython/config`, or point elsewhere from the command line:
bpython --config /path/to/bpython/configThe sample-config file in the repository is the stated source for the available options.
Bugs go to one inbox, and the release tags carry no v prefix
The Known Bugs section contains no bugs. It points to a known issues and FAQ page hosted on the project site, so the defect list lives outside the repository and outside the changelog.
Contact is equally direct. Bug reports and patch suggestions go to a named individual, Robert, at a personal gmail address, or to the GitHub issues tracker. Any other communication is routed through a community page. The tone is friendly and the routing is unambiguous, which means one person's inbox is the documented escalation path.
The release tags are named `0.26-release`, `0.25-release` and `0.24-release`, with the tag text repeating the name in each case. No v prefix anywhere. The dates are 2025-10-28, 2025-01-17 and 2023-08-05, so the gap between 0.24 and 0.25 ran to seventeen months and the last push to the branch was on 2026-09-02, about eleven months after 0.26 shipped.
Two smaller facts. The project metadata records no licence identifier while a LICENSE file sits at the root, so a scanner reading the metadata gets nothing. And the root carries AUTHORS.rst, CHANGELOG.rst, MANIFEST.in and a .readthedocs.yaml alongside four packaging files, which is a lot of configuration surface for a tool whose stated ambition is to be small.
Editorial conclusion
Adopt bpython if you want a REPL that colours code as you type, shows function signatures, and can replay the last state of a session after an edit, and if you are on Linux or willing to pip install on macOS. Do not adopt it expecting a maintained modern console: the optional completion path is jedi for experimental multiline completion, the release tags carry no v prefix, and the only macOS package route is MacPorts under the name py-bpython. Verify first that F8 is acceptable in your terminal, because it uploads the screen to pastebin and returns a URL, and that re-running your session is safe, since Rewind, F6 and F7 all re-evaluate every line you entered rather than only the last one.
Frequently asked questions
How do you install bpython?
With `pip install bpython`, or through an OS package manager: `apt install bpython` on Ubuntu and Debian, `apt-get install bpython` on older versions, `pacman -S bpython` on Arch, `dnf install bpython` on Fedora, `guix install bpython` on Guix, and `sudo port install py-bpython` on macOS via MacPorts.
What is bpython?
It is a lightweight Python interpreter that adds features common to IDEs: syntax highlighting using Pygments, an expected parameter list resolved through inspect and then pydoc, auto-indentation and autocompletion. The README states explicitly that it does not aim to be a complete IDE.
Where does bpython keep its configuration?
Save it as `~/.config/bpython/config`, which the README gives as `$XDG_CONFIG_HOME/bpython/config`, or point at another path with `bpython --config /path/to/bpython/config`. The README says the sample-config file lists the available options.
What do the function keys do in bpython?
F6 clears sys.modules and reruns the session, F7 opens the session in a text editor and reruns it with your modifications, and F8 uploads the screen's contents to pastebin and returns a URL. Rewind, on control-R, pops the last line and re-evaluates the entire session.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bpython-bpython)