Menu
4 Python type checkers to keep code clean

4 Python type checkers to keep code clean

Mypy, Pytype, Pyright, and Pyre can help you keep your type-hinted Python code bug-free. Let’s see what each of these useful tools has to offer

Credit: Sebastian Spindler

In the beginning, Python had no type decorations. That fit with the overall goal of making the language fast and easy to work with, with flexible object types that accommodate the twists and turns of writing code and help developers keep their code concise.

Over the last few years, though, Python has added support for type annotations, inspiring a whole culture of software devoted to type checking Python during development. Python doesn’t check types at runtime — at least, not yet.

But by taking advantage of a good type checker, riding shotgun with you in your IDE of choice, you can use Python’s type annotations to screen out many common mistakes before they hit production.

In this article we’ll delve into four of the major type checking add-ons for Python. All follow roughly the same pattern, scanning Python code with type annotations and providing feedback. But each one offers its own useful additions to the basic concept.

Mypy

Mypy was arguably the first static type checking system for Python, as work on it began in 2012, and it’s still under active development. It is essentially the prototype for how third-party type checking libraries work in Python, even if many others have come along since and expanded on its features.

Mypy can run standalone, or from the command line, or it can work as part of an editor or IDE’s linter integration. Many editors and IDEs integrate Mypy; Visual Studio Code’s Python extension can work with it directly. When run, Mypy generates reports about your code’s consistency based on the type information it provides.

If your code doesn’t include type annotations, Mypy will not perform the vast majority of its code checks. However, you can use Mypy to flag unannotated code. This can be done with varying degrees of strictness depending on one’s needs.

If you’re starting from scratch with a codebase and you want a preemptively aggressive linting strategy, you can use the --strict option to prevent any untyped code.

On the other hand, if you’re working with a legacy codebase that doesn’t have many type definitions, you can use more relaxed options such as preventing only untyped function definitions with --disallow-untyped-defs while allowing other untyped code. And you can always use inline comments like # type: ignore to keep individual lines from being flagged.

Mypy can make use of PEP 484 stub files when you want to use type hints for a module’s public interfaces. On top of this, Mypy offers stubgen, a tool that automatically generates stub files from existing code. For untyped code the stub files use generic types, which you can then mark up as needed.

Pytype

Pytype, created by Google, differs from the likes of Mypy in using inference instead of just type descriptors. In other words, Pytype attempts to determine types by analysing code flow, rather than relying strictly on type annotations.

Pytype errs on the side of leniency whenever it makes sense to do so. If you have an operation that works at runtime and doesn’t contradict any annotations, Pytype won’t squawk about it. However, this means that some problems that should be flagged (e.g., declaring a variable with a type at one point and then redefining it in the same context) pass by unannounced. The documentation states such things will be disallowed at some point in the future.

If you choose to add type annotations to your code, then Pytype’s reveal_type function comes in especially handy. If you insert a statement in your code that reads reveal_type(expr), Pytype evaluates expr and emits an alert that describes its type.

Note that certain Pytype behaviours are controlled by adding attributes to the code itself. For instance, if you want to stop Pytype from complaining about missing attributes or module members that are set dynamically, you have to add the attribute _HAS_DYNAMIC_ATTRIBUTES = True to the class or module in question, as opposed to setting some kind of Pytype configuration metadata.

Pyright / Pylance

Pyright is Microsoft’s Python type checker, included as part of the Pylance extension for Visual Studio Code. If you’re already a VS Code user, the Pylance extension is the most convenient way to work with Pyright; just install it and go. Pyright provides a good all-in-one type checking and code linting experience, with many of the same conveniences and advances as previous Python analysis tools.

Like Pytype, Pyright can work with codebases that don’t have any type information. In those cases, Pyright will do its best to infer what types are in play. Thus you can still get good results with Pytype on older codebases with no type declarations. But you’ll get better results over time as you progressively add type annotations to your code.

Pyright is highly flexible in ways that complement the designs of real-world Python projects. As with other type checkers, Pyright can be configured on a per-project basis with a JSON-formatted configuration file in the project’s directory. Individual paths can be excluded (never checked) or ignored (errors and warnings suppressed) in the config file, and the options are highly granular.

In VS Code, workspaces with multiple roots can each have their own Pyright config, in case different parts of the project need different linting configurations. In the same vein, you can define multiple “execution environments” within a project, each with its own venv or import paths.

Pyre

Created by developers at Facebook and Instagram, Pyre is actually two tools in one: a type checker (Pyre) and a static code analysis tool (Pysa). The two are designed to work hand-in-hand to provide a higher level of checking and analysis than other tools, although the user needs to do a little heavy lifting to take full advantage of them.

Pyre takes an approach similar to Pytype and Mypy. Untyped code is handled more leniently than typed code, so you can begin with an untyped Python codebase and add annotations function by function and module by module.

Toggle on “strict mode” in a module, and Pyre will flag any missing annotations. Or you could make strict mode the default and opt out at the module level. Pyre will also work with .pyi-format stub files.

Pyre has a powerful feature for migrating codebases to a typed format. The infer command-line option ingests a file or directory, makes educated guesses about the types used, and applies the annotations to the files. You’ll want to make backups of your code first, though! (If you want to obtain type information from a running Python program, you can do that with another Facebook/Instagram project, MonkeyType.)

While Pyre’s features echo those of the other packages detailed here, Pysa is unique. Pysa performs “taint analysis” on code to identify potential security issues, relying on a library of flow analyses for certain software components and flagging code that appears to be vulnerable.

Anything touched by that code will also be flagged as tainted, though you can specify components that sanitise data and remove that data from the taint graph.

One drawback is that Pysa’s library of third-party component taint analyses is still small, so you might need to devise your own model. But many of the taint analyses are for software that is widely used, such as the Django web framework, the SQL Alchemy ORM, and the Pandas data science library, not to mention analyses for common filesystem issues.


Follow Us

Join the newsletter!

Or

Sign up to gain exclusive access to email subscriptions, event invitations, competitions, giveaways, and much more.

Membership is free, and your security and privacy remain protected. View our privacy policy before signing up.

Error: Please check your email address.

Tags python

Featured

Slideshows

Meet the Reseller News 30 Under 30 Tech Awards 2020 winners

Meet the Reseller News 30 Under 30 Tech Awards 2020 winners

This year’s Reseller News 30 Under 30 Tech Awards were held as an integral part of the first entirely virtual Emerging Leaders​ forum, an annual event dedicated to identifying, educating and showcasing the New Zealand technology market’s rising stars. The 30 Under 30 Tech Awards 2020 recognised the outstanding achievements and business excellence of 30 talented individuals​, across both young leaders and those just starting out. In this slideshow, Reseller News honours this year's winners and captures their thoughts about how their ideas of leadership have changed over time.​

Meet the Reseller News 30 Under 30 Tech Awards 2020 winners
Reseller News Exchange Auckland: Beyond the myths — how partners can master cloud security

Reseller News Exchange Auckland: Beyond the myths — how partners can master cloud security

This exclusive Reseller News Exchange event in Auckland explored the challenges facing the partner community on the cloud security frontier, as well as market trends, customer priorities and how the channel can capitalise on the opportunities available. In association with Arrow, Bitdefender, Exclusive Networks, Fortinet and Palo Alto Networks. Photos by Gino Demeer.

Reseller News Exchange Auckland: Beyond the myths — how partners can master cloud security
Reseller News welcomes industry figures at 2020 Hall of Fame lunch

Reseller News welcomes industry figures at 2020 Hall of Fame lunch

Reseller News welcomed 2019 inductees - Leanne Buer, Ross Jenkins and Terry Dunn - to the fourth running of the Reseller News Hall of Fame lunch, held at the French Cafe in Auckland. The inductees discussed the changing face of the IT channel ecosystem in New Zealand and what it means to be a Reseller News Hall of Fame inductee. Photos by Gino Demeer.

Reseller News welcomes industry figures at 2020 Hall of Fame lunch
Show Comments