This package is no longer maintained.
When I wrote this, there were no other alternatives for upgrading type syntax, but pyupgrade has since added support for this. If you are looking for a way to lint your code continuously I would recommend using pyupgrade instead.
This is a pre-commit hook configured to automatically upgrade your type hints to the new native types implemented in PEP 585.
This will work for Python 3.8
and above, though if you're using 3.8
specifically you will need to run the hook with futures-imports=true
.
A complete type list is shown below.
See the complete list
Used to be | Will be upgraded to |
---|---|
typing.Tuple | tuple |
typing.List | list |
typing.Dict | dict |
typing.Set | set |
typing.FrozenSet | frozenset |
typing.Type | type |
typing.Deque | collections.deque |
typing.DefaultDict | collections.defaultdict |
typing.OrderedDict | collections.OrderedDict |
typing.Counter | collections.Counter |
typing.ChainMap | collections.ChainMap |
typing.Awaitable | collections.abc.Awaitable |
typing.Coroutine | collections.abc.Coroutine |
typing.AsyncIterable | collections.abc.AsyncIterable |
typing.AsyncIterator | collections.abc.AsyncIterator |
typing.AsyncGenerator | collections.abc.AsyncGenerator |
typing.Iterable | collections.abc.Iterable |
typing.Iterator | collections.abc.Iterator |
typing.Generator | collections.abc.Generator |
typing.Reversible | collections.abc.Reversible |
typing.Container | collections.abc.Container |
typing.Collection | collections.abc.Collection |
typing.Callable | collections.abc.Callable |
typing.AbstractSet | collections.abc.Set |
typing.MutableSet | collections.abc.MutableSet |
typing.Mapping | collections.abc.Mapping |
typing.MutableMapping | collections.abc.MutableMapping |
typing.Sequence | collections.abc.Sequence |
typing.MutableSequence | collections.abc.MutableSequence |
typing.ByteString | collections.abc.ByteString |
typing.MappingView | collections.abc.MappingView |
typing.KeysView | collections.abc.KeysView |
typing.ItemsView | collections.abc.ItemsView |
typing.ValuesView | collections.abc.ValuesView |
typing.ContextManager | contextlib.AbstractContextManager |
typing.AsyncContextManager | contextlib.AbstractAsyncContextManager |
typing.re.Pattern | re.Pattern |
typing.re.Match | re.Match |
In a nutshell, this code
from typing import List, Tuple, Dict, Set, FrozenSet
def do_thing(x: List[Tuple[str, ...]], y: Dict[str, Set[str]]) -> FrozenSet:
becomes this
def do_thing(x: list[tuple[str, ...]], y: dict[str, set[str]]) -> frozenset:
or this, if you're running python < 3.9 or enable the futures option
from __future__ import annotations
def do_thing(x: list[tuple[str, ...]], y: dict[str, set[str]]) -> frozenset:
- Performs in-line substitution for new types
- Adds new imports for upgrade types which need them
- Adds
__futures__
imports if the futures flag is enabled - Removes no longer needed typing imports
Note: even though we remove and add imports reasonably well, I would
recommend running this in tandem with hooks like isort
to aggregate
and sort your imports, and flake8 to discover any unused imports neither were able to remove.
Otherwise you risk needing to do some manual cleanup
from time to time (though it should be pretty rare).
To use this with pre-commit, simply add this to your config file:
- repo: https://github.com/sondrelg/pep585-upgrade
rev: '' # Use the sha / tag you want to point at
hooks:
- id: upgrade-type-hints
and while futures imports are added automatically if you're running Python older than 3.9
,
you can also enable them explicitly, by adding a --futures
arg.
This is required, e.g., when maintaining code that needs to support older Python versions.
- repo: https://github.com/sondrelg/pep585-upgrade
rev: '' # Use the sha / tag you want to point at
hooks:
- id: upgrade-type-hints
args: [ '--futures=true' ]
For more information about available arguments, see the function definitions.
If you wish to run this once on your codebase, that's not easy to do without pre-commit, as it piggybacks on that process quite a bit.
However, installing pre-commit and configuring the hook to run will take you less than a minute. These are the steps:
- Run
pip install pre-commit
- Run
touch .pre-commit-config.yaml
- Copy the configuration shown above into the file
- Run
pre-commit run --all-files
To run the upgrade on a single file, you can clone the repo
and run python -m upgrade_type_hints <filename>
from the src folder, or
something equivalent.
-
We have a hard time removing common
import typing
imports, since we don't have a full inventory of all possible placestyping
could be used. Seeing something like this, you might think this is easy to handleimport typing x: typing.List
but extending this example to a thousand-line file, the way we've structured the logic, there is no way to know whether there is a valid
typing.Optional
somewhere in the file. -
We might remove typing imports in a file where you needed them for more than just type annotations. An example of this is custom type declarations:
from typing import List x: List # this will be upgraded and the import will be removed y = List[str] # this will be left without its required import
The reason for this is that custom type declarations are not a part of the
ast
objects we look at.
Both points are resolved by running flake8.
Please leave a ✭ if this project helped you 👏 and contributions are always welcome!