snok / pep585-upgrade Goto Github PK
View Code? Open in Web Editor NEWPre-commit hook for upgrading type hints
License: BSD 3-Clause "New" or "Revised" License
Pre-commit hook for upgrading type hints
License: BSD 3-Clause "New" or "Revised" License
Minimal working example:
Input:
from typing import Any, Type, TypeVar
t: Type
Output:
from typing import AnyVar
t: type
I have a fix for this already. Please wait for a PR with a fix and tests.
Check for existing futures imports before adding one
This project is ๐ฅ, I'm going to use it as soon as I don't have to support python 3.6 and 3.7 anymore !
Cheers,
I observe the same issue as #22, using v1.0.1.
Starting with the file
from __future__ import annotations
from typing import Any, Callable, Mapping
MessageCallback = Callable[[Mapping[str, Any], Any], None]
def func(x: Mapping[str, Any], y: Any) -> None:
return None
callback: MessageCallback
callback = func
This originally runs without errors, but not after running pep585-upgrade has run:
$ python -V
Python 3.8.6
$ python test.py
$ pre-commit run
Upgrade type hints.......................................................Failed
- hook id: upgrade-type-hints
- exit code: 1
- files were modified by this hook
Fixing src/workflows/test.py
isort....................................................................Failed
- hook id: isort
- files were modified by this hook
$ git diff
index 72539fc..56bc282 100644
--- a/test.py
+++ b/test.py
@@ -1,6 +1,7 @@
from __future__ import annotations
-from typing import Any, Callable, Mapping
+from collections.abc import Mapping
+from typing import Any, Callable
MessageCallback = Callable[[Mapping[str, Any], Any], None]
$ python test.py
Traceback (most recent call last):
File "test.py", line 6, in <module>
MessageCallback = Callable[[Mapping[str, Any], Any], None]
TypeError: 'ABCMeta' object is not subscriptable
Adding hook via:
- repo: https://github.com/sondrelg/pep585-upgrade
rev: ''
hooks:
- id: upgrade-type-hints
args: [ '--futures=true' ]
When running in a python 3.9 virtualenv everything works, but switching to python 3.7 causes this error:
Upgrade type hints.......................................................Failed
- hook id: upgrade-type-hints
- exit code: 1
Traceback (most recent call last):
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/bin/upgrade-type-hints-script", line 8, in <module>
sys.exit(main())
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/main.py", line 33, in main
annotation_list, imports, futures_import_found = find_annotations_and_imports_in_file(filename)
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/checker.py", line 128, in find_annotations_and_imports_in_file
imports, futures_import_found = map_imports(tree)
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/checker.py", line 113, in map_imports
imports[item.lineno]['end_lineno'] = item.end_lineno
AttributeError: 'Import' object has no attribute 'end_lineno'
Traceback (most recent call last):
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/bin/upgrade-type-hints-script", line 8, in <module>
sys.exit(main())
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/main.py", line 33, in main
annotation_list, imports, futures_import_found = find_annotations_and_imports_in_file(filename)
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/checker.py", line 128, in find_annotations_and_imports_in_file
imports, futures_import_found = map_imports(tree)
File "/home/some_name/.cache/pre-commit/repoh9mucjmj/py_env-python3.7/lib/python3.7/site-packages/src/upgrade_type_hints/checker.py", line 113, in map_imports
imports[item.lineno]['end_lineno'] = item.end_lineno
AttributeError: 'Import' object has no attribute 'end_lineno'
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class C:
mu: ClassVar[float] = 2.0
The code-base I'm modernizing has the following code:
project_acl_list = cast(Optional[List[str]], project.acl)
Unfortunately, this is not transformed.
I'm willing to fix that, but I don't know yet how...
Could we discuss how to implement the transformation for this code?
Running pre-commit autoupdate
leads to the following result:
Updating https://github.com/sondrelg/pep585-upgrade ... updating v1.0.1 -> v1.
Running pre-commit autoupdate
again will result in the following warning:
[WARNING] The 'rev' field of repo 'https://github.com/sondrelg/pep585-upgrade' appears to be a mutable reference (moving tag / branch).
Mutable references are never updated after first install and are not supported.
See https://pre-commit.com/#using-the-latest-version-for-a-repository for more details.
Hint: `pre-commit autoupdate` often fixes this.
It would be cool if pre-commit autoupdate
would work on this hook as expected. I suspect that the problem is that all 3 tags point to the same commit.
The typing
package supports generics, whereas collections.abc
does not. Hence, when this tool replaces typing
types that are used as generics with their equivalent types in collections.abc
, it breaks the build. I found it helpful to run this tool as a one-off and then manually undo these cases though, so thank you!
Hi guys,
Thanks a lot for this great package, it makes the code much more pythonic!
I have one favor: could you create/push a tag for the package? Else I have this annoying warning:
[WARNING] The 'rev' field of repo 'https://github.com/snok/pep585-upgrade' appears to be a mutable reference (moving tag / branch). Mutable references are never updated after first install and are not supported. See https://pre-commit.com/#using-the-latest-version-for-a-repository for more details.
For an input file like this:
from collections.abc import Callable
from typing import Collection
def a(a: Callable, b: Collection):
pass
when applying pep585 hook I get:
from collections.abc import Collection
from collections.abc import Callable
def a(a: Callable, b: Collection):
pass
while I expect:
from collections.abc import Callable, Collection
def a(a: Callable, b: Collection):
pass
It could be argued this is the job of e.g. isort
, however - pep585-upgrade
already tries to be nice in terms of imports - e.g. in a larger import set - this new import line gets added nearby other import from same package and not at the end (which would be simplest I guess)
Input:
#!/usr/bin/env python3
from typing import AbstractSet
s: AbstractSet
Output:
from collections.abc import Set
#!/usr/bin/env python3
s: Set
I didn't prepare the fix yet, but I think that the best solution would be to save the first occurrence of non-comment, non-docstring expressions while scanning AST and put the imports before that. What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.