<commit_before># Python static type checker (mypy)

[mypy](http://mypy-lang.org/) is a compile-time static type checker
for Python, allowing optional, gradual typing of Python code. Zulip
was fully annotated with mypy's Python 2 syntax in 2016, before our
migration to Python 3 in late 2017. In 2018 and 2020, we migrated
essentially the entire codebase to the nice PEP 484 (Python 3 only)
and PEP 526 (Python 3.6) syntax for static types:

```python
user_dict: Dict[str, UserProfile] = {}

def get_user(email: str, realm: Realm) -> UserProfile:
    ... # Actual code of the function here
```

You can learn more about it at:

- The
  [mypy cheat sheet for Python 3](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)
  is the best resource for quickly understanding how to write the PEP
  484 type annotations used by mypy correctly. The
  [Python 2 cheat sheet](https://mypy.readthedocs.io/en/latest/cheat_sheet.html)
  is useful for understanding the type comment syntax needed for our
  few modules that need to support both Python 2 and 3.

- The
  [Python type annotation spec in PEP 484](https://www.python.org/dev/peps/pep-0484/).

- Our [blog post on being an early adopter of mypy][mypy-blog-post] from 2016.

- Our [best practices](#best-practices) section below.

The mypy type checker is run automatically as part of Zulip's Travis
CI testing process in the `backend` build.

[mypy-blog-post]: https://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/

## Installing mypy

mypy is installed by default in the Zulip development environment.

## Running mypy on Zulip's code locally

To run mypy on Zulip's python code, you can run the command:

```bash
tools/run-mypy
```

Mypy outputs errors in the same style as a compiler would. For
example, if your code has a type error like this:

```python<commit_msg>docs: Remove the broken link to typing cheat sheet.<commit_after># Python static type checker (mypy)

[mypy](http://mypy-lang.org/) is a compile-time static type checker
for Python, allowing optional, gradual typing of Python code. Zulip
was fully annotated with mypy's Python 2 syntax in 2016, before our
migration to Python 3 in late 2017. In 2018 and 2020, we migrated
essentially the entire codebase to the nice PEP 484 (Python 3 only)
and PEP 526 (Python 3.6) syntax for static types:

```python
user_dict: Dict[str, UserProfile] = {}

def get_user(email: str, realm: Realm) -> UserProfile:
    ... # Actual code of the function here
```

You can learn more about it at:

- The
  [mypy cheat sheet for Python 3](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)
  is the best resource for quickly understanding how to write the PEP
  484 type annotations used by mypy correctly.

- The
  [Python type annotation spec in PEP 484](https://www.python.org/dev/peps/pep-0484/).

- Our [blog post on being an early adopter of mypy][mypy-blog-post] from 2016.

- Our [best practices](#best-practices) section below.

The mypy type checker is run automatically as part of Zulip's Travis
CI testing process in the `backend` build.

[mypy-blog-post]: https://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/

## Installing mypy

mypy is installed by default in the Zulip development environment.

## Running mypy on Zulip's code locally

To run mypy on Zulip's python code, you can run the command:

```bash
tools/run-mypy
```

Mypy outputs errors in the same style as a compiler would. For
example, if your code has a type error like this:

```python
{'fraction_non_alphanumeric': 0.09023415191319246, 'fraction_numerical': 0.02998286693318104, 'mean_word_length': 4.033045977011494, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 7, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '768370', 'n_tokens_mistral': 1241, 'n_tokens_neox': 1077, 'n_words': 472}