I love being a Python developer right now! We’ve seen exciting libraries like Pydantic and FastAPI picking up steam, which is fantastic. That said, there are also some smaller utilities that are gems in their own right. Some, like pytest-sugar, can be dropped into a project with minimal fuss. Others, like ptpython, can be used by an individual on a team without impacting the team. Here are four can’t-live-without Python tools that I’ve recently added to my dev utility belt because they make me a faster developer (and they’re doggone fun to use):


4. ptpython

Website: https://github.com/prompt-toolkit/ptpython

Installation: python -m pip install ptpython, Python 3.6+

Ptpython is what the built-in Python REPL ought to be. Just take a look at these features!

Syntax highlighting

Screenshot of the syntax highlighting in ptpython
Syntax highlighting

Autocompletion

Screen capture of autocompleting the capitalize function on a string in ptpython
Autocompletion

Autoindentation

Watch ptpython automatically indent the body of this class; I didn’t have to manually add tabs or spaces!

Screen capture of automatic identation for a class block in ptpython
Autoindentation

Multiline editing

In this example, I forgot to include the age attribute when I initially defined the class. I hit the up arrow once and now I can edit the entire multiline block of that particular class.

Screen capture of hitting the up arrow once to edit an entire class block at once in ptpython
Multiline editing

Syntax errors

Ptpython will catch syntax errors before you execute the line, giving you a chance to go back and fix them before execution. And yes, it works with multiline blocks.

Screen capture of being able to fix a syntax error before executing a line in ptpython
Syntax errors

I haven’t even gotten into Emacs/Vi modes, IPython compatibility, displaying docstrings and function signatures, running shell commands without leaving the REPL, and host of other features. The next two tools are the peanut butter to ptpython’s chocolate, so install it and get ready for even more fun!


3. devtools, rich, and icecream

Website: https://python-devtools.helpmanual.io/

Installation: python -m pip install devtools, Python 3.7+

Website: https://github.com/Textualize/rich

Installation: python -m pip install rich, Python 3.7+

Website: https://github.com/gruns/icecream

Installation: python -m pip install icecream, Python 2, 3

The next tool is a three-fer: devtools, rich, and IceCream are all great libraries and which one I reach for just depends on how I’m feeling at the moment. They all make printing complex data structures so much nicer than Python’s pprint. They also have more tricks up their sleaves than just pretty printing. Let’s dig in…

devtools.debug()

debug is like print after a good night’s sleep and lots of coffee

The devtools Usage page has a colorful-but-apt description of what debug does. It will pretty print as many variables as you can throw at it, along with the file name, line number, and function where debug is being invoked.

Screen capture of printing out both a complex—nested dictionaries and lists—data structure as well as the returned value from a function call using devtools.debug()
debug()

Additionally, debug returns what you pass into it, meaning you can insert it into your code without changing functionality:

Screen capture of devtools.debug() returning the class passed into it, allowing the variable assignment to happen as expected
inlined debug()

devtools.debug.timer()

You can also use the timer function to do basic timings on operations:

Screen capture of devtools.debug.timer() timing a longer-running operation
debug.timer()

devtools.debug.breakpoint()

Finally, you can use debug.breakpoint() to invoke pdb:

Screen capture of devtools.debug.breakpoint() invoking pdb
debug.breakpoint()

rich.print()

Similar to devtools.debug(), rich.print() is a better pretty printer. Unlike devtools.debug(), which is solely focused on debugging, rich.print() supports a slew of formatting options, such as shortcodes (including emojis).

Screen capture of rich.print() formatting shortcodes and emojis
rich.print()

rich.inspect()

rich.inspect() is a nice tool for digging into variables; it shows the type, the contained values, and optionally methods, private, and dunder attributes. Note: if “dunder” is a new term for you, it refers to attributes with double underscores around them, like __init__; “double underscore” gets tiresome to say, so you’ll frequently see that shortened to “dunder” in the Python world.

Screen capture of rich.inspect() showing more details about an object
rich.print()

icecream.ic()

ic() is pretty similar to the other two libraries but with the added advantage that it’s even faster to type!

Screen capture of icecream.ic() printing out basic data
icecream.ic()

It will print both the variable name and its value, with syntax highlighting.

Screen capture of icecream.ic() printing out a complex dictionary
icecream.ic()

Like devtools.debug() it’ll return what you passed in, so you can inline it in your code.

Screen capture of icecream.ic() printing out a class; the instance is also passed to a variable, which is then passed to another ic() call to print the name attribute
icecream.ic()

One additional neat trick is that you can scatter it throughout your code like debugging breadcrumbs and it’ll inspect itself, leaving you with a trail of exactly which lines in the code were triggered:

Screen capture of icecream.ic() printing out a trail through multiple functions and conditionals
icecream.ic()

2. pytest-sugar

Website: https://github.com/Teemu/pytest-sugar

Installation: python -m pip install pytest-sugar, Python 3.8+, pytest 6.2+

pytest-sugar is a drop-in (automatically activated) plugin for pytest. It does several things to make your tests look and work better:

  • Errors are reported immediately; no waiting to see what broke
  • A progress bar visualizes how far you’ve progressed through the suite
  • Colored summary report

Here’s a test suite without pytest-sugar:

Screen capture of a test suite, with some failures, using default pytest formatting
Without pytest-sugar

And the same test suite with pytest-sugar:

Screen capture of a test suite, with some failures, using pytest-sugar's formatting
With pytest-sugar

1. Ruff

Website: https://docs.astral.sh/ruff/

Installation: python -m pip install pytest-sugar, Python 3.7+

Ruff is an extremely fast Python linter. In addition to its speed, I also appreciate its sensible default settings and large ruleset.

Linting in Python is worth its own blog post, so I’ll try to summarize here. The question, “what linter should I use for Python?” always felt fraught with uncertainty and complications. I’ve seen many projects end up with autopep8, flake8, pylint, bandit, and isort and nobody knows which are still used … or even what they’re used for.

Ruff replaces them all.

It’s hard to understate just how little work we’ve had to do to switch to Ruff at my current client: we just swapped the dependencies out, deleted all the non-Ruff configuration, and were good to go. We started migrating to Ruff when we upgraded to SQLAlchemy 2.0 and ran into a bug that caused our pylint runs to be unbearably slow. The bug is now fixed as of pylint 3; however, our switch to Ruff was so easy that we didn’t need to wait around for that fix to land.

As Ruff matures, we continue to replace tools. The most recent swap was pulling bandit for Ruff’s flake8-bandit ruleset. We’re keeping an eye on the Ruff Formatter, and it seems likely that we’ll be replacing Black soon. (Black is another tool I love, and it would be on this list if it weren’t for Ruff moving towards feature parity.)


BONUS: VS Code Extensions

Because you made it this far, I’ll throw in two recently-discovered, favorite VS Code extensions:

indent-rainbow

Makes your indent levels both pretty and easy to read!

Screenshot of indent-rainbow shading different indent levels different colors in a JSON document
indent-rainbow

gitmoji

Spice up your commit messages with gitmojis, because every commit log should be as beautiful as FastAPI’s.

Screenshot of FastAPI's commit log with gitmoji commit messages
gitmoji

It feels like—after three decades—the Python world is experiencing a renaissance, both in tooling and in libraries. Over the last several years I’ve seen a number of new libraries and tools pop up that disrupt the staid and sometimes-musty old guard (and I don’t use “disrupt” lightly given how it’s overused in our industry). It’s an exciting time to be a Python developer, and I hope this list has given you some new toys to try out. Have fun exploring!

Want to continue the conversation about Python tooling? Join our N.E.A.T. community or if you’re already registered, head on over to the forum to talk Python tool tips!

Kyle Adams

Person An icon of a human figure Status
Double Agent
Hash An icon of a hash sign Code Name
Agent 0033
Location An icon of a map marker Location
Indianapolis, IN