# infer-types
A CLI tool to automatically add type annotations into Python code.
The main scenario for using the tool is to help you with annotating a big and old codebase. It won't solve the task for you 100% but will definitely help you tremendously, because many of the functions in the real world have quite simple return types that are easy to infer automatically.
Features:
+ 100% automated, get a bunch of type annotations with no effort.
+ 100% static, all types are inferred without running the code.
+ A lot of heuristics and smart inference.
+ Actively uses [typeshed](https://github.com/python/typeshed) to find annotations for unannotated dependencies.
## Example
Let's say, you have the following method:
```python
class Database:
def users_count(self):
return len(self.users)
```
Since `len` always returns `int`, `infer-types` is able to infer the return type of the method. So, after running the tool, the code will look like this:
```python
class Database:
def users_count(self) -> int:
return len(self.users)
```
## Installation
```bash
python3 -m pip install infer-types
```
## Usage
```bash
python3 -m infer_types ./example/
```
The tool will add new import statements that can be duplicated and are located not at the top of the file. To fix it, run [isort](https://github.com/PyCQA/isort):
```bash
python3 -m isort ./example/
```
The infer-types tool uses the new fancy syntax for type annotations introduced in Python 3.10. So, instead of `Optional[str]` it will emit `str | None`. If your code is supposed to run on an older version of Python, add `from __future__ import annotations` at the beginning of each file. It will solve the issue and also make startup of your app faster. You can also do that with isort:
```bash
python3 -m isort --add-import 'from __future__ import annotations' ./example/
```
See [awesome-python-typing](https://github.com/typeddjango/awesome-python-typing) for more tools to help you with annotating your code.
## How it works
+ Most of heuristics live in [astypes](https://github.com/orsinium-labs/astypes) package. Check it out learn more about the main inference logic.
+ If the same method is defined in a base class, copy the type annotations from there.
+ If there are no return statements returning a value, the return type is `None`.
+ If there is a `yield` statement, the return type is `typing.Iterator`.
+ In some cases, the return type can be guessed from the function name. For example, `is_open` function is assumed to return `bool` because it starts with `is_`.
You can run only a specific heuristic using the `--only` flag.
Raw data
{
"_id": null,
"home_page": null,
"name": "infer_types",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "typing,annotations,type annotations,formatter,code formatter",
"author": null,
"author_email": "Gram <git@orsinium.dev>",
"download_url": "https://files.pythonhosted.org/packages/ab/00/bce897ae055f60e805485ccf64a0b74767ed397195a48e9e220c63bfa41f/infer_types-1.0.0.tar.gz",
"platform": null,
"description": "# infer-types\n\nA CLI tool to automatically add type annotations into Python code.\n\nThe main scenario for using the tool is to help you with annotating a big and old codebase. It won't solve the task for you 100% but will definitely help you tremendously, because many of the functions in the real world have quite simple return types that are easy to infer automatically.\n\nFeatures:\n\n+ 100% automated, get a bunch of type annotations with no effort.\n+ 100% static, all types are inferred without running the code.\n+ A lot of heuristics and smart inference.\n+ Actively uses [typeshed](https://github.com/python/typeshed) to find annotations for unannotated dependencies.\n\n## Example\n\nLet's say, you have the following method:\n\n```python\nclass Database:\n def users_count(self):\n return len(self.users)\n```\n\nSince `len` always returns `int`, `infer-types` is able to infer the return type of the method. So, after running the tool, the code will look like this:\n\n```python\nclass Database:\n def users_count(self) -> int:\n return len(self.users)\n```\n\n## Installation\n\n```bash\npython3 -m pip install infer-types\n```\n\n## Usage\n\n```bash\npython3 -m infer_types ./example/\n```\n\nThe tool will add new import statements that can be duplicated and are located not at the top of the file. To fix it, run [isort](https://github.com/PyCQA/isort):\n\n```bash\npython3 -m isort ./example/\n```\n\nThe infer-types tool uses the new fancy syntax for type annotations introduced in Python 3.10. So, instead of `Optional[str]` it will emit `str | None`. If your code is supposed to run on an older version of Python, add `from __future__ import annotations` at the beginning of each file. It will solve the issue and also make startup of your app faster. You can also do that with isort:\n\n```bash\npython3 -m isort --add-import 'from __future__ import annotations' ./example/\n```\n\nSee [awesome-python-typing](https://github.com/typeddjango/awesome-python-typing) for more tools to help you with annotating your code.\n\n## How it works\n\n+ Most of heuristics live in [astypes](https://github.com/orsinium-labs/astypes) package. Check it out learn more about the main inference logic.\n+ If the same method is defined in a base class, copy the type annotations from there.\n+ If there are no return statements returning a value, the return type is `None`.\n+ If there is a `yield` statement, the return type is `typing.Iterator`.\n+ In some cases, the return type can be guessed from the function name. For example, `is_open` function is assumed to return `bool` because it starts with `is_`.\n\nYou can run only a specific heuristic using the `--only` flag.\n",
"bugtrack_url": null,
"license": null,
"summary": "CLI tool to automatically annotate Python code.",
"version": "1.0.0",
"split_keywords": [
"typing",
"annotations",
"type annotations",
"formatter",
"code formatter"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3a299b412805f930bae4dd60babef9be5677a033e00f3c0b3b40e64e6f3224cb",
"md5": "b922fac369377e3d6d555a055ab0f8b0",
"sha256": "98ac8ff060061d56736e13238945b835c5c90eef7fc17f42adf9dded26b94f29"
},
"downloads": -1,
"filename": "infer_types-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b922fac369377e3d6d555a055ab0f8b0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 11154,
"upload_time": "2023-03-17T10:51:23",
"upload_time_iso_8601": "2023-03-17T10:51:23.705187Z",
"url": "https://files.pythonhosted.org/packages/3a/29/9b412805f930bae4dd60babef9be5677a033e00f3c0b3b40e64e6f3224cb/infer_types-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ab00bce897ae055f60e805485ccf64a0b74767ed397195a48e9e220c63bfa41f",
"md5": "c09a9906057d6ea92bc19ad1065b9dff",
"sha256": "a7d09a87431bccf73c30983b7918803bf4fe066df053aecf35ab293aad9a0c2b"
},
"downloads": -1,
"filename": "infer_types-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "c09a9906057d6ea92bc19ad1065b9dff",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14569,
"upload_time": "2023-03-17T10:51:25",
"upload_time_iso_8601": "2023-03-17T10:51:25.940385Z",
"url": "https://files.pythonhosted.org/packages/ab/00/bce897ae055f60e805485ccf64a0b74767ed397195a48e9e220c63bfa41f/infer_types-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-17 10:51:25",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "infer_types"
}