Code Monkey home page Code Monkey logo

fix-future-annotations's Introduction

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
typing.Dict[str, int]
List[str]
dict[str, int]
list[str]

PEP 604 – Allow writing union types as X | Y

OldNew
typing.Union[str, int]
Optional[str]
str | int
str | None

PEP 563 – Postponed Evaluation of Annotations

OldNew
def create() -> "Foo": pass
def create() -> Foo: pass

Import aliases handling

OldNew
import typing as t
from typing import Tuple as MyTuple

def foo() -> MyTuple[str, t.Optional[int]]:
    pass
from __future__ import annotations

import typing as t

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

Full example

OldNew
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]]:
    ...
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

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:

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:

[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 license.

fix-future-annotations's People

Contributors

frostming avatar pierre-sassoulas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fix-future-annotations's Issues

Thanks!

I wish I had seen this one month ago, before doing that with a handful of regular expressions 🤣
And I'll use it right now on another project! So thanks, lots of time spared thanks to this tool 🙂

[0.5.0 misuse] Only exclude 'class .+\(BaseModel\):' is not enough for pydantic proj.

The "bug" reproducting branch:
https://github.com/boholder/puntgun/commits/test-fix-tool

Env( boholder/puntgun@7ba9738 ):

pyproject.toml:

[tool.fix_future_annotations]
exclude_lines = [
    'class .+\(BaseModel\):'
]

Run the tool (with pre-commit) with the configuration above, then revert the data.py file, unit tests can pass as usual.
Ok, I then tried one by one against the changes (made to the data.py file by this tool) and found that only the insert of from __future__ import annotations statement will actually triggered the error.

Without this line (tests pass):
boholder/puntgun@1e85bb9

With this line (tests fail):
boholder/puntgun@005e180

(puntgun-3.10) \code\python\puntgun>pdm test
ImportError while loading conftest 'E:\code\python\puntgun\tests\conftest.py'.
tests\conftest.py:9: in <module>
    from puntgun.rules.config_parser import ConfigParser
puntgun\rules\config_parser.py:93: in <module>
    import_rule_classes()
puntgun\rules\config_parser.py:32: in import_rule_classes
    importlib.import_module(f"{base_module_name}.{module_name}")
puntgun\rules\user\action_rules.py:3: in <module>
    from puntgun.client import NeedClientMixin
puntgun\client.py:15: in <module>
    from puntgun.rules.data import Media, Place, Poll, Tweet, User
puntgun\rules\data.py:217: in <module>
    class Tweet(BaseModel):
puntgun\rules\data.py:228: in Tweet
    author: User | None = User()
pydantic\main.py:342: in pydantic.main.BaseModel.__init__
    ???
E   pydantic.error_wrappers.ValidationError: 1 validation error for User
E   pinned_tweet
E     field required (type=value_error.missing)

I think it would be better to change the logic of exclude class configuration to "exclude the file where the class is located"? Although there is already a configuration to exclude files, but the configuration to exclude special classes is more flexible than to exclude files?

It up to you, dear maintainer, thank you very much for your work and quick response to the needs. ♥

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.