MonkeyType
MonkeyType is a Python library that automatically generates type annotations from sampled production types. It uses Python's `sys.setprofile` hook to record the types of function arguments, return values, and yield values at runtime. Based on this collected data, it can generate stub files (`.pyi`) or apply draft type annotations directly to existing Python code. The current stable version is 23.3.0, with a history of regular updates focusing on Python version compatibility and annotation accuracy.
Common errors
-
AttributeError: '__args__' when generating stubs on Python 3.9
cause Incompatibility with internal changes to Python 3.9's `typing` module.fixUpgrade MonkeyType to version 22.2.0 or newer. -
AttributeError: '_SpecialForm' object has no attribute '__name__' in collecting traces with Union types
cause Incompatibility with Python 3.9's handling of `Union` types during call trace collection.fixUpgrade MonkeyType to version 22.2.0 or newer. -
ModuleNotFoundError: No module named 'libcst' or errors applying stubs.
cause `libcst` is a mandatory dependency for applying type stubs and code transformations, and it might be missing or an incompatible version.fixEnsure `libcst` is installed and meets the required version (`libcst>=0.3.5` for MonkeyType 20.5.0+). Running `pip install monkeytype` typically handles this. -
TypeError/ValueError at import time of a custom config and replacing with a generic “invalid value” message
cause Earlier versions of MonkeyType had issues with configuration loading logic that could prematurely catch errors in custom config files.fixUpgrade MonkeyType to version 23.3.0 or newer. Additionally, ensure your `monkeytype_config.py` is free of syntax or runtime errors.
Warnings
- breaking MonkeyType dropped support for Python 3.6 in version 22.2.0. Users on older Python versions must upgrade their environment or use an older MonkeyType version.
- gotcha The annotations generated by MonkeyType are derived from concrete runtime types and may not always reflect the full intended capability of functions (e.g., `List` instead of `Sequence`). They should be treated as a first draft requiring human review and refinement.
- gotcha When using `monkeytype run <script.py>`, traces are *not* recorded for the entry-point script (`<script.py>`) itself, only for modules it imports. To annotate the entry point, a small wrapper script that imports and calls functions from the target script is needed.
- gotcha Running `monkeytype stub` or `monkeytype apply` on a module with import-time side effects will trigger those side effects because MonkeyType must import your code. For 'executable' modules, ensure execution code is protected by `if __name__ == '__main__'` to prevent unintended execution.
Install
-
pip install monkeytype
Imports
- trace
from monkeytype import trace
- Config
from monkeytype.config import Config
Quickstart
import os
# my_module.py
def add(a, b):
return a + b
def concatenate(s1, s2):
return s1 + s2
# To run this module with MonkeyType tracing
if __name__ == "__main__":
# Simulate usage to collect type traces
add(1, 2)
add(1.5, 2.5)
concatenate("hello", "world")
concatenate(["a"], ["b", "c"])
# --- Steps to run from your terminal ---
# 1. Save the above code as 'my_module.py'.
# 2. Run your module under MonkeyType to collect traces:
# $ monkeytype run my_module.py
# 3. Generate a stub file (.pyi) from the collected traces:
# $ monkeytype stub my_module > my_module.pyi
# 4. Or, apply type annotations directly to your source file (modifies in-place):
# $ monkeytype apply my_module
#
# Note: Traces are stored in a SQLite database (monkeytype.sqlite3) by default.