Slide 1

Slide 1 text

Static types in Python Greg Price Dropbox Recurse Center 2016-05-09

Slide 2

Slide 2 text

Good news Python has optional static types (in beta). You can use them in your programs. This talk: why and how.

Slide 3

Slide 3 text

Joint work Tech is not all or mainly my own work! Core Mypy team: Jukka Lehtosalo, Guido vR, me, David Fisher, Reid Barton All supported by Dropbox

Slide 4

Slide 4 text

Why static types? Lots of things static types can do … even lots of things “static types” can mean

Slide 5

Slide 5 text

Understanding code Understanding what some code does Humans: 40% of eng time (Dropbox survey, 2015) Computers too (navigate, refactor, find bugs)

Slide 6

Slide 6 text

Understanding code What does this code do? for entry in entries: entry.data.validate()

Slide 7

Slide 7 text

Understanding code What does this code do? for entry in entries: entry.data.validate() Want to read what validate does.

Slide 8

Slide 8 text

Understanding code for entry in entries: entry.data.validate() Want to read what validate does. git grep “def validate” -> 45 results

Slide 9

Slide 9 text

Understanding code: types for entry in entries: entry.data.validate() git grep def\ validate -> 45 results; which? Have to know the type.

Slide 10

Slide 10 text

Understanding code: types for entry in entries: entry.data.validate() What's the type of entry.data? Can find out: – entries a parameter? Grep for call sites – … a return value? Find that method

Slide 11

Slide 11 text

Understanding code: types for entry in entries: entry.data.validate() What's the type of entry.data? Can find out, but a lot of work

Slide 12

Slide 12 text

Understanding code: types What's the type of (some expression)? Can find out, but a lot of work … and maybe the type varies! Subclasses, duck typing, generic containers … and undecidable in general!

Slide 13

Slide 13 text

Understanding code: types What's the type of (some expression)? Lots of excuses, but: The author had some kind of answer. “int”; “list of basestring”; “T and list of T, for any T” That would be enough.

Slide 14

Slide 14 text

Understanding code: static types What's the type of (some expression)? The author had some kind of answer. static type, n.: the expectation the author had of the (runtime) type of an expression's value (usage note: many competing definitions in academia)

Slide 15

Slide 15 text

Static types: writing them down static type, n.: the expectation the author had of the (runtime) type of an expression's value Explicit is better than implicit.

Slide 16

Slide 16 text

Static types: writing them down Explicit is better than implicit. def something(self, entries): '''entries: a list of LogEntry''' for entry in entries: entry.data.validate()

Slide 17

Slide 17 text

Static types: writing them down Explicit is better than implicit. Checked is better than unchecked. If we carry out those principles, we can better understand our code.

Slide 18

Slide 18 text

Static types: writing them down Explicit is better than implicit. → Standard type notation: PEP 484 (Python 2 and Python 3 compatible!) Checked is better than unchecked. → Type-checker: Mypy (no runtime effect)

Slide 19

Slide 19 text

Questions on why? Next up: how – PEP 484 type notation – Type system – Mypy type-checker, workflow

Slide 20

Slide 20 text

Notation Python 3: function annotations (PEP 3107) def gcd(a: int, b: int) -> int: … Python 2 and 3: # type: comments def gcd(a, b): # type: (int, int) -> int ...

Slide 21

Slide 21 text

Notation Python 3: function annotations (PEP 3107) def gcd(a: int, b: int) -> int: ... Annotations are Python expressions Design constraint affected notation

Slide 22

Slide 22 text

Parametric polymorphism Key example: generic containers from typing import List, Dict, Set, Iterable def sum(a): # type: (List[int]) -> int ... def toposort(data): # type: (Dict[str, Set[str]]) -> Iterable[Set[str]] ...

Slide 23

Slide 23 text

Parametric polymorphism from typing import TypeVar, Generic T = TypeVar('T') class MyList(Generic[T]): def append(self, item): # type: (T) -> None ...

Slide 24

Slide 24 text

Gradual typing Typed code coexists with untyped code Still want to type-check the typed code At the boundary: type Any

Slide 25

Slide 25 text

Notation: other people's code The libraries you use may lack written types Solution: write them down, in separate files “stub files”, extension .pyi Collaborative “typeshed” repo has stdlib, more

Slide 26

Slide 26 text

Type system: much more! See PEP 484 for details https://www.python.org/dev/peps/pep-0484/

Slide 27

Slide 27 text

Tools Checked is better than unchecked Type-checker: Mypy http://github.com/python/mypy $ mypy *.py Run at test time / linter time

Slide 28

Slide 28 text

Tools Designed for gradual adoption Run on just the files you've given types to: $ mypy --silent-imports file.py dir/ Other modules become all Any

Slide 29

Slide 29 text

Status at Dropbox ● ~15 eager early adopters ● 50kLOC now has explicit types ● People love it: survey – 100% agree “easier to read and understand” – 100% agree “I am more productive” – 45% “adding to existing code is a lot of work” … but 90% glad to have done it

Slide 30

Slide 30 text

Dropbox: people love having types “Refactors are already so much easier with the typing that's been added. Game changing for the sync engine!” “This makes it sooo much easier for me to read code and figure out what parameters are supposed to be!” “It has addressed my personal biggest pain point with python. It’s really increased the scope of things I’m excited to consider python as great for.”

Slide 31

Slide 31 text

Try it! ● Annotate your favorite Python codebase – Maybe Zulip? http://zulip.readthedocs.io/en/latest/mypy.html ● Report any issues on GitHub – We respond fast and love hearing things ● Patches and code reviews also welcome

Slide 32

Slide 32 text

End Questions?