Skip to main content

A tool for autoadding simple type annotations.

Project description

When I refactor code I often find myself tediously adding type annotations that are obvious from context: functions that don't return anything, boolean flags, etcetera. That's where autotyping comes in: it automatically adds those types and inserts the right annotations.

Usage

Autotyping can be called directly from the CLI, be used as a pre-commit hook or run via the libcst interface as a codemod. Here's how to use it from the CLI:

  • pip install autotyping
  • python -m autotyping /path/to/my/code

By default it does nothing; you have to add flags to make it do more transformations. The following are supported:

  • Annotating return types:
    • --none-return: add a -> None return type to functions without any return, yield, or raise in their body
    • --scalar-return: add a return annotation to functions that only return literal bool, str, bytes, int, or float objects.
  • Annotating parameter types:
    • --bool-param: add a : bool annotation to any function parameter with a default of True or False
    • --int-param, --float-param, --str-param, --bytes-param: add an annotation to any parameter for which the default is a literal int, float, str, or bytes object
    • --annotate-optional foo:bar.Baz: for any parameter of the form foo=None, add Baz, imported from bar, as the type. For example, use --annotate-optional uid:my_types.Uid to annotate any uid in your codebase with a None default as Optional[my_types.Uid].
    • --annotate-named-param foo:bar.Baz: annotate any parameter with no default that is named foo with bar.Baz. For example, use --annotate-named-param uid:my_types.Uid to annotate any uid parameter in your codebase with no default as my_types.Uid.
    • --guess-common-names: infer certain parameter types from their names based on common patterns in open-source Python code. For example, infer that a verbose parameter is of type bool.
  • Annotating magical methods:
    • --annotate-magics: add type annotation to certain magic methods. Currently this does the following:
      • __str__ returns str
      • __repr__ returns str
      • __len__ returns int
      • __length_hint__ returns int
      • __init__ returns None
      • __del__ returns None
      • __bool__ returns bool
      • __bytes__ returns bytes
      • __format__ returns str
      • __contains__ returns bool
      • __complex__ returns complex
      • __int__ returns int
      • __float__ returns float
      • __index__ returns int
      • __exit__: the three parameters are Optional[Type[BaseException]], Optional[BaseException], and Optional[TracebackType]
      • __aexit__: same as __exit__
    • --annotate-imprecise-magics: add imprecise type annotations for some additional magic methods. Currently this adds typing.Iterator return annotations to __iter__, __await__, and __reversed__. These annotations should have a generic parameter to indicate what you're iterating over, but that's too hard for autotyping to figure out.
  • External integrations
    • --pyanalyze-report: takes types suggested by pyanalyze's suggested_parameter_type and suggested_return_type codes and applies them. You can generate these with a command like: pyanalyze --json-output failures.json -e suggested_return_type -e suggested_parameter_type -v .
    • --only-without-imports: only apply pyanalyze suggestions that do not require new imports. This is useful because suggestions that require imports may need more manual work.

There are two shortcut flags to enable multiple transformations at once:

  • --safe enables changes that should always be safe. This includes --none-return, --scalar-return, and --annotate-magics.
  • --aggressive enables riskier changes that are more likely to produce new type checker errors. It includes all of --safe as well as --bool-param, --int-param, --float-param, --str-param, --bytes-param, and --annotate-imprecise-magics.

LibCST

Autotyping is built as a LibCST codemod; see the LibCST documentation for more information on how to use codemods.

If you wish to run things through the libcst.tool interface, you can do this like so:

  • Make sure you have a .libcst.codemod.yaml with 'autotyping' in the modules list. For an example, see the .libcst.codemod.yaml in this repo.
  • Run python -m libcst.tool codemod autotyping.AutotypeCommand /path/to/my/code

pre-commit hook

Pre-commit hooks are scripts that runs automatically before a commit is made, which makes them really handy for checking and enforcing code-formatting (or in this case, typing)

  1. To add autotyping as a pre-commit hook, you will first need to install pre-commit if you haven't already:
pip install pre-commit
  1. After that, create or update the .pre-commit-config.yaml file at the root of your repository and add in:
- repos:
  - repo: https://github.com/JelleZijlstra/autotyping
    rev: 24.9.0
    hooks:
      - id: autotyping
        stages: [commit]
        types: [python]
        args: [--safe] # or alternatively, --aggressive, or any of the other flags mentioned above 
  1. Finally, run the following command to install the pre-commit hook in your repository:
pre-commit install

Now whenever you commit changes, autotyping will automatically add type annotations to your code!

Limitations

Autotyping is intended to be a simple tool that uses heuristics to find annotations that would be tedious to add by hand. The heuristics may fail, and after you run autotyping you should run a type checker to verify that the types it added are correct.

Known limitations:

  • autotyping does not model code flow through a function, so it may miss implicit None returns

Changelog

24.9.0 (September 23, 2024)

  • Add pre-commit support. (Thanks to Akshit Tyagi and Matthew Akram.)
  • Add missing dependency. (Thanks to Stefane Fermigier.)

24.3.0 (March 25, 2024)

  • Add simpler ways to invoke autotyping. Now, it is possible to simply use python3 -m autotyping to invoke the tool. (Thanks to Shantanu Jain.)
  • Drop support for Python 3.7; add support for Python 3.12. (Thanks to Hugo van Kemenade.)
  • Infer return types for some more magic methods. (Thanks to Dhruv Manilawala.)

23.3.0 (March 3, 2023)

  • Fix crash on certain argument names like iterables (contributed by Marco Gorelli)

23.2.0 (February 3, 2023)

  • Add --guess-common-names (contributed by John Litborn)
  • Fix the --safe and --aggressive flags so they don't take ignored arguments
  • --length-hint should return int (contributed by Nikita Sobolev)
  • Fix bug in import adding (contributed by Shantanu)

22.9.0 (September 5, 2022)

  • Add --safe and --aggressive
  • Add --pyanalyze-report
  • Do not add None return types to methods marked with @abstractmethod and to methods in stub files
  • Improve type inference:
    • "string" % ... is always str
    • b"bytes" % ... is always bytes
    • An and or or operator where left and right sides are of the same type returns that type
    • is, is not, in, and not in always return bool

21.12.0 (December 21, 2021)

  • Initial PyPI release

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

autotyping-24.9.0.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

autotyping-24.9.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file autotyping-24.9.0.tar.gz.

File metadata

  • Download URL: autotyping-24.9.0.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.6

File hashes

Hashes for autotyping-24.9.0.tar.gz
Algorithm Hash digest
SHA256 d7e9787aca0f69b089431581f703c53210d2cf39e792e2106759d04034c1251b
MD5 7e454cf2a0288e62c1f7369e1f89ec19
BLAKE2b-256 1ed6da57f5c54009f3a2436e25aab1f156a241e61d96be6456050be11d5350a8

See more details on using hashes here.

File details

Details for the file autotyping-24.9.0-py3-none-any.whl.

File metadata

  • Download URL: autotyping-24.9.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.6

File hashes

Hashes for autotyping-24.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c16b0bcab310a2dfe5228bb01c4d1dd5499e7bf67fc6b7915c35267c665b498
MD5 85ea732b3a6e6e991afa060291441620
BLAKE2b-256 baf27d40e2913c27634ebf4a3e8a77061a3ed1432ccd0b8590787985e4da8e46

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