|
|
Subscribe / Log in / New account

An introduction to pytype

By Jake Edge
June 8, 2016

Python Language Summit

Google's pytype tool, which uses the PEP 484 type hints for static analysis, was the subject of a presentation by one of its developers, Matthias Kramm, at the 2016 Python Language Summit. In it, he compared several different tools and their reaction to various kinds of type errors in the code. He also described pytype's static type-inference capabilities.

There are several different tools using type hints at this point (mypy, PyCharm, and, soon, Pylint). Kramm showed a short example program with a type error:

    def f(x: int):
        return x
    f("foo")
He then showed the results of running mypy, pytype, and PyCharm on the program. As expected, each complained that the type of the argument in the [Matthias Kramm] call to f() was wrong, though they each had their own way of indicating that.

He then moved on to some examples where mypy and pytype differ on whether there is a type error or not. For example, an argument annotated as an Iterable[float] (i.e. an iterable object, like a list, of floats) that was passed as a list of strings ([ "1", "2" ]) would cause pytype to emit an error, but not mypy. On the other hand, mypy looks at what is done with the argument inside the function:

    def f(x: List[str]):
        x.append(42)
That will cause a complaint from mypy, but not pytype, because pytype interprets the annotation as only applying to what is passed in. There were a few other examples where the two tools "disagree on what PEP 484 means" and how the type annotations should be interpreted. For the most part, though, the two tools are in sync, Kramm said.

After that, he turned to a pytype feature that is not present in the other tools: static type inference. Pytype can analyze Python source files to infer the types of arguments and functions return values. It outputs the type annotations into a stub (.pyi) file. There is a merge_pyi tool that can then be used to put the annotations from the stub back into the Python source file.

He gave a number of examples of the type inferences that pytype can make. For example:

    def get_label(self):
        return self.name.capitalize()
That method would be annotated with a str return type based on the type returned by capitalize(). A more complicated example:
    def dict_subset(d):
        return {key: d[key] for key in d.keys()
                if key.startswith(PREFIX)}
In this case, pytype would infer that both the argument d and the return type are of type Dict[str, Any] (i.e. a dictionary with a string key and any type for a value).

The tool will typically infer more types than might be expected. Types such as slice objects or complex objects may be overlooked by the function's author, but pytype will still take them into account.

For the future, there are plans to add support for duck typing, which might require changes to the existing type hints. There are also ideas about handling dependency graphs, so that large, existing projects can be processed. Right now, any imported modules need to have their types annotated before type inference can be done on a given file. Even for straightforward dependency graphs, that can be somewhat painful. For large projects (he showed rather complicated dependency graphs for several), it will require a tool to sort things out.

At the end of the talk, there was a short, fast-paced discussion among attendees about what kinds of annotations might be needed in the future and whether PEP 484 needs some additions.


Index entries for this article
ConferencePython Language Summit/2016


to post comments


Copyright © 2016, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds