An open API service indexing awesome lists of open source software.

https://github.com/frostming/fix-future-annotations

A CLI and pre-commit hook to fix future annotations
https://github.com/frostming/fix-future-annotations

pre-commit pre-commit-hook python typing

Last synced: 10 months ago
JSON representation

A CLI and pre-commit hook to fix future annotations

Awesome Lists containing this project

README

          

# fix-future-annotations

A CLI and pre-commit hook to upgrade the typing annotations syntax to PEP 585 and PEP 604.

## Upgrade Details

### [PEP 585] – Type Hinting Generics In Standard Collections

OldNew

```python
typing.Dict[str, int]
List[str]
```

```python
dict[str, int]
list[str]
```

### [PEP 604] – Allow writing union types as `X | Y`

OldNew

```python
typing.Union[str, int]
Optional[str]
```

```python
str | int
str | None
```

### [PEP 563] – Postponed Evaluation of Annotations

OldNew

```python
def create() -> "Foo": pass
```

```python
def create() -> Foo: pass
```

### Import aliases handling

OldNew

```python
import typing as t
from typing import Tuple as MyTuple

def foo() -> MyTuple[str, t.Optional[int]]:
pass
```

```python
from __future__ import annotations

import typing as t

def foo() -> tuple[str, int | None]:
pass
```

### Full example

OldNew

```python
from typing import Union, Dict, Optional, Tuple

# non-annotation usage will be preserved
MyType = Union[str, int]

def foo() -> Tuple[Dict[str, int], Optional[str]]:
...
```

```python
from __future__ import annotations

from typing import Union

# non-annotation usage will be preserved
MyType = Union[str, int]

def foo() -> tuple[dict[str, int], str | None]:
...
```

Unused import names will be removed, and if `from __future__ import annotations` is not found in the script, it will be automatically added if the new syntax is being used.

## Use as a command line tool

```bash
python3 -m pip install -U fix-future-annotations

fix-future-annotations my_script.py
```

## Use as pre-commit hook

Add the following to your `.pre-commit-config.yaml`:

```yaml
repos:
- repo: https://github.com/frostming/fix-future-annotations
rev: 0.5.0 # a released version tag
hooks:
- id: fix-future-annotations
```

## Configurations

`fix-future-annotations` can be configured via `pyproject.toml`. Here is an example:

```toml
[tool.fix_future_annotations]
exclude_files = [ # regex patterns to exclude files
'tests/.*',
'docs/.*',
]

exclude_lines = [ # regex patterns to exclude lines
'# ffa: ignore', # if a line ends with this comment, the whole *block* will be excluded
'class .+\(BaseModel\):' # classes that inherit from `BaseModel` will be excluded
]
```

## License

This work is distributed under [MIT](https://github.com/frostming/fix-future-annotations/blob/main/README.md) license.

[PEP 563]: https://peps.python.org/pep-0563/
[PEP 585]: https://peps.python.org/pep-0585/
[PEP 604]: https://peps.python.org/pep-0604/