# Python typing update
[![PyPI](https://img.shields.io/pypi/v/python-typing-update?color=blue)](https://pypi.org/project/python-typing-update/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-typing-update)](https://github.com/cdce8p/python-typing-update)
[![GitHub](https://img.shields.io/github/license/cdce8p/python-typing-update)](https://github.com/cdce8p/python-typing-update/blob/main/LICENSE)
[![image](https://static.pepy.tech/badge/python-typing-update)](https://pepy.tech/project/python-typing-update)
Tool to update Python typing syntax.
It uses token analysis and
- [python-reorder-imports][pri]
- [pyupgrade][pyu]
- [isort][isort]
- [autoflake][autoflake]
- [black][black]
- [ruff][ruff]
- git
to try and update the typing syntax the best it can.
**Important**
Every project uses a different formatting style,
so always check `git diff` before comitting any changes!
Since this tool uses [pyupgrade][pyu], it's best used for
projects that use it already.
## Limitations
Due to the way the tool works, it will reorder the imports multiple times.
By default the tool tries to detect if a comment was moved
and revert all changes to the file. This can be overwritten by using `--force`.
Currently, it's not possible to update aliases with a different name.
In particular, these need to be updated manually:
| Old typing name | New |
| --------------- | --- |
| `Deque` | `collections.deque` |
| `DefaultDict` | `collections.defaultdict` |
| `AbstractSet` | `collections.abc.Set` |
| `ContextManager` | `contextlib.AbstractContextManager` |
| `AsyncContextMananger` | `contextlib.AbstractAsyncContextManager` |
## How it works
1. Run [python-reorder-import][pri] to add
`from __future__ import annotations` to each file.
2. Run [pyupgrade][pyu] to use generic aliases ([PEP 585][PEP585])
and alternative union syntax ([PEP 604][PEP604]) where possible.
3. Run [autoflake][autoflake] to check if any typing import is now
unused. If not, revert changes with `git restore`.
4. Remove unused imports with [autoflake][autoflake].
5. Run [isort][isort] to try to restore the previous formatting.
6. Optional: Run [black][black]. (Requires `black` to be added as `additional_dependency`)
OR: Run [ruff][ruff]. (Requires `ruff` to be added as `additional_dependency`)
7. Check `git diff` for modified comments.
If one is detected, revert changes and print file name.
Can be overwritten with `--force`.
## Setup pre-commit
Add this to the `.pre-commit-config.yaml` file
```yaml
repos:
- repo: https://github.com/cdce8p/python-typing-update
rev: <insert current tag here!>
hooks:
- id: python-typing-update
stages: [manual]
```
Run with
```bash
pre-commit run --hook-stage manual python-typing-update --all-files
```
## Configuration
**`--verbose`**
Always print verbose logging.
**`--limit`**
Max number of files that should be changed. No performance improvements,
since the limit is only applied **after** all files have been processed.
**`--concurrent-files`**
Number of files to process concurrently during initial load.
**`--full-reorder`**
Use additional options from [python-reorder-imports][pri] to rewrite
- `--py38-plus` (default): Imports from `mypy_extensions` and `typing_extensions` when possible.
- `--py39-plus`: Rewrite [PEP 585][PEP585] typing imports. Additionally `typing.Hashable` and `typing.Sized` will also be replaced by their `collections.abc` equivalents.
**`--keep-updates`**
Keep updates even if no import was removed. Use with caution, might result in more errors.
**`--black`**
Run `black` formatting after updates.
To use it, add `black` as `additional_dependency` in your `.pre-commit-config.yaml`.
```yaml
additional_dependencies:
- black==<insert current version here!>
```
**`--ruff`**
Run `ruff check --fix` and `ruff format` after updates.
To use it, add `ruff` as `additional_dependency` in your `.pre-commit-config.yaml`.
```yaml
additional_dependencies:
- ruff==<insert current version here!>
```
**`--disable-committed-check`**
Don't abort with uncommitted changes. **Don't use it in production!**
Risk of losing uncommitted changes.
### Different mode options
**`--check`**
Check if files would be modified. Return with exitcode `1` or `0` if not. Useful for CI runs.
**`--force`**
Don't revert changes if a modified comment is detected.
Check `git diff` before committing!
**`--only-force`**
Only update files which are likely to require extra work.
Check `git diff` before committing!
### Python version options
**`--py37-plus`**
Set the minimum Python syntax version to **3.7**. (Default: **3.9**)
**`--py38-plus`**
Set the minimum Python syntax version to **3.8**. (Default: **3.9**)
**`--py39-plus`**
Set the minimum Python syntax version to **3.9**. This is the default.
**`--py310-plus`**
Set the minimum Python syntax version to **3.10**. (Default: **3.9**)
**`--py311-plus`**
Set the minimum Python syntax version to **3.11**. (Default: **3.9**)
**`--py312-plus`**
Set the minimum Python syntax version to **3.12**. (Default: **3.9**)
**`--py313-plus`**
Set the minimum Python syntax version to **3.13**. (Default: **3.9**)
## License
This Project is licensed under the MIT license.
See [LICENSE][LICENSE_FILE] for the full license text.
[pri]: https://github.com/asottile/reorder_python_imports
[pyu]: https://github.com/asottile/pyupgrade
[isort]: https://github.com/PyCQA/isort
[autoflake]: https://github.com/PyCQA/autoflake
[black]: https://github.com/psf/black
[ruff]: https://github.com/astral-sh/ruff
[PEP585]: https://www.python.org/dev/peps/pep-0585/
[PEP604]: https://www.python.org/dev/peps/pep-0604/
[LICENSE_FILE]: https://github.com/cdce8p/python-typing-update/blob/main/LICENSE
Raw data
{
"_id": null,
"home_page": null,
"name": "python-typing-update",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "typing, pep585, pep604",
"author": "Marc Mueller",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/93/1d/83cddeb65c202d2c237753d0f61b06087ef19261e5f98acd82234dfa03d9/python_typing_update-0.7.0.tar.gz",
"platform": null,
"description": "# Python typing update\n\n[![PyPI](https://img.shields.io/pypi/v/python-typing-update?color=blue)](https://pypi.org/project/python-typing-update/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-typing-update)](https://github.com/cdce8p/python-typing-update)\n[![GitHub](https://img.shields.io/github/license/cdce8p/python-typing-update)](https://github.com/cdce8p/python-typing-update/blob/main/LICENSE)\n[![image](https://static.pepy.tech/badge/python-typing-update)](https://pepy.tech/project/python-typing-update)\n\nTool to update Python typing syntax.\nIt uses token analysis and\n- [python-reorder-imports][pri]\n- [pyupgrade][pyu]\n- [isort][isort]\n- [autoflake][autoflake]\n- [black][black]\n- [ruff][ruff]\n- git\n\nto try and update the typing syntax the best it can.\n\n**Important** \nEvery project uses a different formatting style,\nso always check `git diff` before comitting any changes!\nSince this tool uses [pyupgrade][pyu], it's best used for\nprojects that use it already.\n\n\n## Limitations\nDue to the way the tool works, it will reorder the imports multiple times.\nBy default the tool tries to detect if a comment was moved\nand revert all changes to the file. This can be overwritten by using `--force`.\n\nCurrently, it's not possible to update aliases with a different name.\nIn particular, these need to be updated manually:\n| Old typing name | New |\n| --------------- | --- |\n| `Deque` | `collections.deque` |\n| `DefaultDict` | `collections.defaultdict` |\n| `AbstractSet` | `collections.abc.Set` |\n| `ContextManager` | `contextlib.AbstractContextManager` |\n| `AsyncContextMananger` | `contextlib.AbstractAsyncContextManager` |\n\n\n## How it works\n1. Run [python-reorder-import][pri] to add\n `from __future__ import annotations` to each file.\n2. Run [pyupgrade][pyu] to use generic aliases ([PEP 585][PEP585])\n and alternative union syntax ([PEP 604][PEP604]) where possible.\n3. Run [autoflake][autoflake] to check if any typing import is now\n unused. If not, revert changes with `git restore`.\n4. Remove unused imports with [autoflake][autoflake].\n5. Run [isort][isort] to try to restore the previous formatting.\n6. Optional: Run [black][black]. (Requires `black` to be added as `additional_dependency`) \n OR: Run [ruff][ruff]. (Requires `ruff` to be added as `additional_dependency`)\n7. Check `git diff` for modified comments.\n If one is detected, revert changes and print file name.\n Can be overwritten with `--force`.\n\n\n## Setup pre-commit\n\nAdd this to the `.pre-commit-config.yaml` file\n\n```yaml\nrepos:\n - repo: https://github.com/cdce8p/python-typing-update\n rev: <insert current tag here!>\n hooks:\n - id: python-typing-update\n stages: [manual]\n```\n\nRun with\n```bash\npre-commit run --hook-stage manual python-typing-update --all-files\n```\n\n## Configuration\n\n**`--verbose`** \nAlways print verbose logging.\n\n**`--limit`** \nMax number of files that should be changed. No performance improvements,\nsince the limit is only applied **after** all files have been processed.\n\n**`--concurrent-files`** \nNumber of files to process concurrently during initial load.\n\n**`--full-reorder`** \nUse additional options from [python-reorder-imports][pri] to rewrite\n- `--py38-plus` (default): Imports from `mypy_extensions` and `typing_extensions` when possible.\n- `--py39-plus`: Rewrite [PEP 585][PEP585] typing imports. Additionally `typing.Hashable` and `typing.Sized` will also be replaced by their `collections.abc` equivalents.\n\n**`--keep-updates`** \nKeep updates even if no import was removed. Use with caution, might result in more errors.\n\n**`--black`** \nRun `black` formatting after updates. \nTo use it, add `black` as `additional_dependency` in your `.pre-commit-config.yaml`.\n\n```yaml\n additional_dependencies:\n - black==<insert current version here!>\n```\n\n**`--ruff`** \nRun `ruff check --fix` and `ruff format` after updates. \nTo use it, add `ruff` as `additional_dependency` in your `.pre-commit-config.yaml`.\n\n```yaml\n additional_dependencies:\n - ruff==<insert current version here!>\n```\n\n**`--disable-committed-check`** \nDon't abort with uncommitted changes. **Don't use it in production!**\nRisk of losing uncommitted changes.\n\n\n### Different mode options\n\n**`--check`** \nCheck if files would be modified. Return with exitcode `1` or `0` if not. Useful for CI runs.\n\n**`--force`** \nDon't revert changes if a modified comment is detected.\nCheck `git diff` before committing!\n\n**`--only-force`** \nOnly update files which are likely to require extra work.\nCheck `git diff` before committing!\n\n\n### Python version options\n\n**`--py37-plus`**\nSet the minimum Python syntax version to **3.7**. (Default: **3.9**)\n\n**`--py38-plus`** \nSet the minimum Python syntax version to **3.8**. (Default: **3.9**)\n\n**`--py39-plus`** \nSet the minimum Python syntax version to **3.9**. This is the default.\n\n**`--py310-plus`** \nSet the minimum Python syntax version to **3.10**. (Default: **3.9**)\n\n**`--py311-plus`** \nSet the minimum Python syntax version to **3.11**. (Default: **3.9**)\n\n**`--py312-plus`** \nSet the minimum Python syntax version to **3.12**. (Default: **3.9**)\n\n**`--py313-plus`**\nSet the minimum Python syntax version to **3.13**. (Default: **3.9**)\n\n\n## License\nThis Project is licensed under the MIT license.\nSee [LICENSE][LICENSE_FILE] for the full license text.\n\n\n[pri]: https://github.com/asottile/reorder_python_imports\n[pyu]: https://github.com/asottile/pyupgrade\n[isort]: https://github.com/PyCQA/isort\n[autoflake]: https://github.com/PyCQA/autoflake\n[black]: https://github.com/psf/black\n[ruff]: https://github.com/astral-sh/ruff\n[PEP585]: https://www.python.org/dev/peps/pep-0585/\n[PEP604]: https://www.python.org/dev/peps/pep-0604/\n\n[LICENSE_FILE]: https://github.com/cdce8p/python-typing-update/blob/main/LICENSE\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Update Python typing syntax",
"version": "0.7.0",
"project_urls": {
"Source Code": "https://github.com/cdce8p/python-typing-update"
},
"split_keywords": [
"typing",
" pep585",
" pep604"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "707866439840c75a39e5547831fff4e7f2ae3475bfb29c23f45379abe0cc82b6",
"md5": "0445458b02a803edc1cc86ae57188336",
"sha256": "9b7bb7453a098756581944b089e510b1e12ab48aa178a71c1dcd90b529c0c899"
},
"downloads": -1,
"filename": "python_typing_update-0.7.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0445458b02a803edc1cc86ae57188336",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 11735,
"upload_time": "2024-10-12T20:42:16",
"upload_time_iso_8601": "2024-10-12T20:42:16.962409Z",
"url": "https://files.pythonhosted.org/packages/70/78/66439840c75a39e5547831fff4e7f2ae3475bfb29c23f45379abe0cc82b6/python_typing_update-0.7.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "931d83cddeb65c202d2c237753d0f61b06087ef19261e5f98acd82234dfa03d9",
"md5": "9fc463059de31f9e55e852b427116e1a",
"sha256": "c65ca0905fdc5802b4c0d1853b76aaf94a0165fb9dcc8774e264707863810fd6"
},
"downloads": -1,
"filename": "python_typing_update-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "9fc463059de31f9e55e852b427116e1a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 14833,
"upload_time": "2024-10-12T20:42:18",
"upload_time_iso_8601": "2024-10-12T20:42:18.449383Z",
"url": "https://files.pythonhosted.org/packages/93/1d/83cddeb65c202d2c237753d0f61b06087ef19261e5f98acd82234dfa03d9/python_typing_update-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-12 20:42:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cdce8p",
"github_project": "python-typing-update",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "python-typing-update"
}