Skip to content

Commit 0c8779f

Browse files
authored
Merge pull request #8 from cdce8p/dev
Release v0.3.0
2 parents 55c78e2 + 8c62e6d commit 0c8779f

17 files changed

+176
-29
lines changed

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "python-typing-update",
9+
"type": "python",
10+
"request": "launch",
11+
"module": "python_typing_update",
12+
"args": [
13+
"${file}",
14+
],
15+
"console": "internalConsole"
16+
}
17+
]
18+
}

README.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Python typing update
22

3-
Small tool to update Python typing syntax.
3+
Tool to update Python typing syntax.
44
It uses token analysis and
55
- [python-reorder-imports][pri]
66
- [pyupgrade][pyu]
@@ -33,7 +33,7 @@ and revert all changes to the file. This can be overwritten by using `--force`.
3333
unused. If not, revert changes with `git restore`.
3434
4. Remove unused imports with [autoflake][autoflake].
3535
5. Run [isort][isort] to try to restore the previous formatting.
36-
6. Optional: Run [black][black]
36+
6. Optional: Run [black][black]. (Requires `black` to be added as `additional_dependency`)
3737
7. Check `git diff` for modified comments.
3838
If one is detected, revert changes and print file name.
3939
Can be overwritten with `--force`.
@@ -74,8 +74,24 @@ Use additional options from [python-reorder-imports][pri] to rewrite
7474
- `--py38-plus` (default): Imports from `mypy_extensions` and `typing_extensions` when possible.
7575
- `--py39-plus`: Rewrite [PEP 585][PEP585] typing imports. Additionally `typing.Hashable` and `typing.Sized` will also be replace by their `collections.abc` equivalents.
7676

77+
**`--keep-updates`**
78+
Keep updates even if no import was removed. Use with caution, might result in more errors.
79+
7780
**`--black`**
78-
Run `black` formatting after updates.
81+
Run `black` formatting after updates.
82+
To use it, add `black` as `additional_dependency` in your `.pre-commit-config.yaml`.
83+
84+
```yaml
85+
additional_dependencies:
86+
- black==<insert current version here!>
87+
```
88+
89+
**`--disable-committed-check`**
90+
Don't abort with uncommitted changes. **Don't use it in production!**
91+
Risk of losing uncommitted changes.
92+
93+
94+
### Different mode options
7995

8096
**`--check`**
8197
Check if files would be modified. Return with exitcode `1` or `0` if not. Useful for CI runs.
@@ -88,11 +104,17 @@ Check `git diff` before committing!
88104
Only update files which are likely to require extra work.
89105
Check `git diff` before committing!
90106

107+
108+
### Python version options
109+
110+
**`--py38-plus`**
111+
Set the minimum Python syntax version to **3.8**. This is the default.
112+
91113
**`--py39-plus`**
92-
Set the minimum Python syntax to **3.9**. (Default: **3.8**)
114+
Set the minimum Python syntax version to **3.9**. (Default: **3.8**)
93115

94116
**`--py310-plus`**
95-
Set the minimum Python syntax to **3.10**. (Default: **3.10**)
117+
Set the minimum Python syntax version to **3.10**. (Default: **3.8**)
96118

97119

98120
## License

python_typing_update/__main__.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ async def async_main(argv: list[str] | None = None) -> int:
2929
description="Tool to update Python typing syntax.",
3030
formatter_class=CustomHelpFormatter,
3131
)
32+
mode_options = parser.add_argument_group("select different mode")
33+
py_version_options = parser.add_argument_group("python version options")
34+
3235
parser.add_argument(
3336
'-v', '--verbose',
3437
action='count', default=0,
@@ -51,45 +54,50 @@ async def async_main(argv: list[str] | None = None) -> int:
5154
action='store_true',
5255
help="Add version_str to 'reorder-python-import' args",
5356
)
57+
parser.add_argument(
58+
'--keep-updates',
59+
action='store_true',
60+
help="Keep updates even if no import was removed",
61+
)
5462
parser.add_argument(
5563
'--black',
5664
action='store_true',
5765
help="Run black formatting after update",
5866
)
5967
parser.add_argument(
6068
'--disable-committed-check',
61-
action='store_true', help=argparse.SUPPRESS,
62-
# Don't abort with uncommited changes
63-
# Use for testing only!
69+
action='store_true',
70+
help="Don't abort with uncommited changes. Don't use it in production!",
6471
)
6572

66-
group1 = parser.add_mutually_exclusive_group()
67-
group1.add_argument(
73+
group_mode = mode_options.add_mutually_exclusive_group()
74+
group_mode.add_argument(
6875
'--check',
6976
action='store_true',
7077
help="Check if files would be updated",
7178
)
72-
group1.add_argument(
79+
group_mode.add_argument(
7380
'--force',
7481
action='store_true',
7582
help="Update all files. Double check changes afterwards!",
7683
)
77-
group1.add_argument(
84+
group_mode.add_argument(
7885
'--only-force',
7986
action='store_true',
8087
help="Only update files which are likely to require extra work",
8188
)
8289

83-
group2 = parser.add_mutually_exclusive_group()
84-
group2.add_argument(
90+
group_py_version = py_version_options.add_mutually_exclusive_group()
91+
group_py_version.add_argument(
8592
'--py38-plus',
8693
action='store_const', dest='min_version', default=(3, 8), const=(3, 8),
94+
help="Default"
8795
)
88-
group2.add_argument(
96+
group_py_version.add_argument(
8997
'--py39-plus',
9098
action='store_const', dest='min_version', const=(3, 9),
9199
)
92-
group2.add_argument(
100+
group_py_version.add_argument(
93101
'--py310-plus',
94102
action='store_const', dest='min_version', const=(3, 10),
95103
)
@@ -101,6 +109,14 @@ async def async_main(argv: list[str] | None = None) -> int:
101109
if args.verbose > 0:
102110
logger.setLevel(logging.DEBUG)
103111

112+
if args.black:
113+
try:
114+
# pylint: disable=unused-import,import-outside-toplevel
115+
import black # noqa: F401
116+
except ImportError:
117+
print("Error! Black is not installed")
118+
return 2
119+
104120
return await async_run(args)
105121

106122

python_typing_update/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from enum import Flag, auto
77
from typing import NamedTuple
88

9-
version = (0, 2, 0)
9+
version = (0, 3, 0)
1010
dev_version = None
1111

1212
version_str = '.'.join(map(str, version))

python_typing_update/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ async def typing_update(
7474
None, autoflake_partial,
7575
[None, '-c', filename],
7676
)
77-
if not args.full_reorder and FileStatus.COMMENT_TYPING not in file_status:
77+
if (
78+
args.keep_updates is False
79+
and args.full_reorder is False
80+
and FileStatus.COMMENT_TYPING not in file_status
81+
):
7882
# -> No unused imports, revert changes
7983
return 2, filename
8084
except SystemExit:

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
aiofiles==0.6.0
22
autoflake==1.4
3-
black==20.8b1
43
isort==5.7.0
54
pyupgrade==2.10.1
65
reorder-python-imports==2.4.0

requirements_black.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
black==20.8b1

setup.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1+
from __future__ import annotations
2+
13
from setuptools import setup
24

35
from python_typing_update.const import version_str
46

5-
with open('requirements.txt') as fp:
6-
requirements = [
7-
line.strip().split(' ', 1)[0] for line in fp.read().splitlines()
8-
if line.strip() != '' and not line.startswith('#')
9-
]
7+
8+
def load_requirements_file(filename: str) -> list[str]:
9+
with open(filename) as fp:
10+
return [
11+
line.strip().split(' ', 1)[0] for line in fp.read().splitlines()
12+
if line.strip() != '' and not line.startswith('#')
13+
]
14+
1015

1116
setup(
1217
version=version_str,
1318
packages=['python_typing_update'],
14-
install_requires=requirements,
1519
python_requires='>=3.8, <3.10',
20+
install_requires=load_requirements_file('requirements.txt'),
21+
extras_require={
22+
'black': load_requirements_file('requirements_black.txt'),
23+
},
1624
entry_points={
1725
'console_scripts': [
1826
'python-typing-update = python_typing_update.__main__:main',
1927
],
20-
}
28+
},
2129
)

tests/fixtures/changed.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
"""Update typing syntax for Python 3.8+"""
22
from typing import Any, Container, Hashable, List, Union
33

4+
from typing_extensions import TypeGuard, TypedDict
5+
46
var1: List[str]
57
var2: Any
68
var3: Union[int, str]
79
var4: Hashable
810
var5: Container
11+
var6: TypedDict
12+
var7: TypeGuard[int]

tests/fixtures/changed_fixed.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33

44
from typing import Any, Container, Hashable
55

6+
from typing_extensions import TypedDict, TypeGuard
7+
68
var1: list[str]
79
var2: Any
810
var3: int | str
911
var4: Hashable
1012
var5: Container
13+
var6: TypedDict
14+
var7: TypeGuard[int]

0 commit comments

Comments
 (0)