Skip to main content

Generating type annotations from sampled production types

Project description

MonkeyType

MonkeyType collects runtime types of function arguments and return values, and can automatically generate stub files or even add draft type annotations directly to your Python code based on the types collected at runtime.

Example

Say some/module.py originally contains:

def add(a, b):
    return a + b

And myscript.py contains:

from some.module import add

add(1, 2)

Now we want to infer the type annotation of add in some/module.py by running myscript.py with MonkeyType. One way is to run:

$ monkeytype run myscript.py

By default, this will dump call traces into a SQLite database in the file monkeytype.sqlite3 in the current working directory. You can then use the monkeytype command to generate a stub file for a module, or apply the type annotations directly to your code.

Running monkeytype stub some.module will output a stub:

def add(a: int, b: int) -> int: ...

Running monkeytype apply some.module will modify some/module.py to:

def add(a: int, b: int) -> int:
    return a + b

This example demonstrates both the value and the limitations of MonkeyType. With MonkeyType, it’s very easy to add annotations that reflect the concrete types you use at runtime, but those annotations may not always match the full intended capability of the functions. For instance, add is capable of handling many more types than just integers. Similarly, MonkeyType may generate a concrete List annotation where an abstract Sequence or Iterable would be more appropriate. MonkeyType’s annotations are an informative first draft, to be checked and corrected by a developer.

Motivation

Readability and static analysis are the primary motivations for adding type annotations to code. It’s already common in many Python style guides to document the argument and return types for a function in its docstring; annotations are a standardized way to provide this documentation, which also permits static analysis by a typechecker such as mypy.

For more on the motivation and design of Python type annotations, see PEP 483 and PEP 484.

Requirements

MonkeyType requires Python 3.6+ and the retype library (for applying type stubs to code files). It generates only Python 3 type annotations (no type comments).

Installing

Install MonkeyType with pip:

pip install MonkeyType

How MonkeyType works

MonkeyType uses the sys.setprofile hook provided by Python to interpose on function calls, function returns, and generator yields, and record the types of arguments / return values / yield values.

It generates stub files based on that data, and can use retype to apply those stub files directly to your code.

See the full documentation for details.

Troubleshooting

Check if your issue is mentioned in the frequently asked questions list.

LICENSE

MonkeyType is BSD licensed.

Changelog

19.5.0

  • Mark monkeytype package as typed per PEP 561. Thanks Vasily Zakharov for the report.

  • Add -v option; don’t display individual traces that fail to decode unless it is given.

19.1.1

  • Pass --incremental to retype when applying stubs, so it doesn’t choke on partial stubs (which can result from e.g. failures to decode some traces).

19.1.0

  • Add --omit-existing-annotations option, implied by apply. Merge of #129. Fixes #11 and #81.

  • Render ... for all parameter defaults in stubs. Remove the --include-unparsable-defaults and --exclude-unparsable-defaults CLI options, as well as the include_unparsable_defaults() config method. Merge of #128, fixes #123.

  • Render forward references (from existing annotations) correctly. Merge of #127.

  • Rewrite Generator[…, None, None] to Iterator[None] by default. Merge of #110, fixes #4. Thanks iyanuashiri.

18.8.0

  • Support Python 3.7. Merge of #107, fixes #78.

  • Print useful error message when filename is passed to stub/apply. Merge of #88, fixes #65. Thanks rajathagasthya.

  • Fix crash in list_modules when there are no traces. Merge of #106, fixes #90. Thanks tyrinwu.

  • Enable python -m monkeytype {run,stub,apply} .... Merge of #100, fixes #99. Thanks retornam.

18.5.1

  • Add MONKEYTYPE_TRACE_MODULES env var for easier tracing of code in site-packages. Merge of #83, fixes #82. Thanks Bo Peng.

  • Fix passing additional arguments to scripts run via monkeytype run. Merge of #85. Thanks Danny Qiu.

  • Fix handling of spaces in filenames passed to retype. Merge of #79, fixes #77.

  • Never render NoneType in stubs, substitute None. Merge of #75, fixes #5. Thanks John Arnold.

18.2.0

  • Move filtering of __main__ module into CallTraceStoreLogger instead of core tracing code, so it can be overridden by special use cases like IPython tracing. Merge of #72, fixes #68. Thanks Tony Fast.

  • Generate stubs for modules where the module file is like module/__init__.py. Print retype stdout/stderr. Merge of #69, Fixes #66. Thanks John Arnold.

18.1.13

  • Improve error messages in case of “no traces found” and/or file path given instead of module name. Merge of #37, partial fix for #65. Thanks Aarni Koskela.

  • Add monkeytype list_modules sub-command to list all modules present in trace db. Merge of #61, fixes #60. Thanks Alex Miasoiedov.

  • Add --diff option to monkeytype stub. Merge of #59, fixes #58. Thanks Tai-Lin!

  • Add --ignore-existing-annotations option to monkeytype stub. Merge of #55, fixes #15. Thanks Tai-Lin!

18.1.11

  • Fix crash in RewriteEmptyContainers rewriter if a parameter has only empty container types in traces (and more than one). Fixes #53.

18.1.10

  • Display retype errors when stub application fails. Merge of #52, fixes #49.

  • Add --sample-count option to show the number of traces a given stub is based on. Merge of #50, fixes #7. Thanks Tai-Lin.

  • Add monkeytype run -m for running a module as a script. Merge of #41. Thanks Simon Gomizelj.

  • Add support for Django’s cached_property decorator. Merge of #46, fixes #9. Thanks Christopher J Wang.

  • Catch and log serialization exceptions instead of crashing. Fixes #38, merge of #39.

  • Fix bug in default code filter when Python lib paths are symlinked. Merge of #40. Thanks Simon Gomizelj.

17.12.3

  • Rewrite imports from _io module to io. (#1, merge of #32). Thanks Radhans Jadhao.

  • Add Config.cli_context() as a hook for custom CLI initialization and cleanup logic (#28; merge of #29). Thanks Rodney Folz.

17.12.2

  • Exclude “frozen importlib” functions in default code filter.

  • Fix passing args to script run with monkeytype run (#18; merge of #21). Thanks Rodney Folz.

  • Fix generated annotations for NewType types (#22; merge of #23). Thanks Rodney Folz.

17.12.1

  • Fix using MonkeyType outside a virtualenv (#16). Thanks Guido van Rossum for the report.

17.12.0

  • Initial public version.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

MonkeyType-19.5.0.tar.gz (28.0 kB view details)

Uploaded Source

Built Distribution

MonkeyType-19.5.0-py3-none-any.whl (35.3 kB view details)

Uploaded Python 3

File details

Details for the file MonkeyType-19.5.0.tar.gz.

File metadata

  • Download URL: MonkeyType-19.5.0.tar.gz
  • Upload date:
  • Size: 28.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.19.1 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.26.0 CPython/3.6.4

File hashes

Hashes for MonkeyType-19.5.0.tar.gz
Algorithm Hash digest
SHA256 67c8a5694fbc78b3c763eccca834bcbc0a7964969fa467f78e43a4141d650787
MD5 2ceb43a0fdf84a3a2c6de6a21c2ce0d5
BLAKE2b-256 e82e1c7d3e9541569b7a06dd74512895f606a7898d1fc98bdc107f0d2b578b5f

See more details on using hashes here.

File details

Details for the file MonkeyType-19.5.0-py3-none-any.whl.

File metadata

  • Download URL: MonkeyType-19.5.0-py3-none-any.whl
  • Upload date:
  • Size: 35.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.19.1 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.26.0 CPython/3.6.4

File hashes

Hashes for MonkeyType-19.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 adb86d4dd4760e80e9670179ab09b09b4e3765115e31f9f2840c1ef3ebc91167
MD5 57ac21a5f80407939e2cea407e11e239
BLAKE2b-256 6cf51a7888a160900309a57f115b6954e952e19912ec1e9048d500e1ca706e05

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page