An overview of Python development tooling in 2020

18 Dec 2020

This is a review of what tools are available to Python developers who like to work in minimal and self-built development environments as of late 2020. Language servers, linters, a bit of everything.

This is aimed mostly for people who do not work in an IDE (e.g. PyCharm) or IDE-like (e.g. VS Code) editor. These tools provide a wrapped version of many of these functionalities, but I like to know everything that might pop a little warning or error here and there from under the hood. PyCharm works great, VS Code with the Python extension works kinda well.

Python dev tools ecosystem is nice but a bit messy and it can be hard to understand which tool does what and how to use them, what is deprecated, what is supported or recommended by the Python developers, etc. If you are feeling a bit lost, I hope this post will help you see the bigger picture better.

Let's look at what types of tools are available to you: coding tools, type checkers, linters, formatters and language servers.


"Coding" tools is a bit vague, for the lack of a better term. Those programs are here to assist you during the development process, they provide useful features such as static analysis to jump to definitions and references, refactoring methods and more, that is to say the main features most people expect out of the box from IDEs.

These tools are quite complex and as such I have never found them to be reliable 100% of the time, but it would be a great loss to overlook them. I have limited experience with Rope: on the projects I used it, it tended to perform a bit worse than Jedi. Both are worth at least checking out.


Python is a dynamic, strongly typed language. This is an interesting combination that is sometimes obscured by the fact that types themselves often do not appear in the code. Since Python 3.5, type hints have been maid to provide developers ways to declare types and for tools to optionally use them during static analysis. It is often improved by each minor release so it is expected to stay and grow in usage in the future.

The only specific typing tool that comes to my mind is Mypy, a static type checker that now works using those type hints. Other tools may do some kind of type checking using more or less complex introspection, with or without using type hints: as of today, the majority of Python code produced still does not use type annotations or at least not everywhere (I don't have stats to back this up though, this is just from browsing code bases experience).


Linters are static analysis tools that can produce a variety of different types of diagnotics: syntax errors, missing imports, unused variables, performance issues, code style issues, deprecation warnings, etc. Even though the common premise for most of these tools is that diagnotics are expected to be produced each time a file is saved, an efficient linter can produce this information almost in real-time.

I have a personal preference for Pyflakes for its speed and simplicity while providing useful diagnostics. I also try to respect the PEP 8 (most of the time).


Formatters are also static analysis tools that reformat parts of your code so it complies with a configuration, whether it's a project-shared convention or a public convention. They are often called right when a file is saved to automatically format it, or in your VCS hooks before a commit/push.

I tend to not use formatters as I prefer to act on style diagnostics myself, or only when the modifications are really simple and hard to argue against.

Language servers

Language servers (LS) are what all the cool kids use now. The idea behind it is neat especially for language developers: instead of implementing language support for a plethora of different editors, just implement a single program, the language server, that implements the Language Server Protocol (LSP); now editors just need to implement a generic LSP client and boom, they can operate common development operations for every program when an LS is installed. Depending on the LS, this can include code completion, go to definition, rename symbol, find references and more.

As it originates from an initiative at VS Code to streamline dev tools implementation and integration, some of the most advanced LS available originate from VS Code extensions, but now there are very powerful, perfectly editor-agnostic LS for many major languages.


That's it for now, I hope it has been useful to you. It's hard to track such a complex environment for what has become one of the most popular language worldwide, so if you feel like I missed an important tool or want to point out inaccuracies, please let me know about it.