Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite pep 585 imports with --py39-plus #151

Merged
merged 1 commit into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ all older versions.
- `--py3-plus`: `division`, `absolute_import`, `print_function`,
`unicode_literals`
- `--py37-plus`: `generator_stop`
- `--py310-plus`: `annotations`

## Removing / rewriting obsolete `six` imports

Expand Down Expand Up @@ -277,10 +278,21 @@ With `--py3-plus`, `reorder-python-imports` will also rewrite various `mock` imp
## Rewriting `mypy_extensions` and `typing_extension` imports

With `--py36-plus` and higher, `reorder-python-imports` will also rewrite
`mypy_extensions` and `typing_extensions` imports ported to `typing`. Each option
implies all older versions.
`mypy_extensions` and `typing_extensions` imports ported to `typing`.

```diff
-from mypy_extensions import TypedDict
+from typing import TypedDict
```

## Rewriting pep 585 typing imports

With `--py39-plus` and higher, `reorder-python-imports` will replace imports
which were moved out of the typing module in [pep 585].

```diff
-from typing import Sequence
+from collections.abc import Sequence
```

[pep 585]: https://www.python.org/dev/peps/pep-0585/
36 changes: 36 additions & 0 deletions reorder_python_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,42 @@ def _report_diff(contents: str, new_contents: str, filename: str) -> None:
))
# END GENERATED

# GENERATED VIA generate-typing-pep585-rewrites
REPLACES[(3, 9)].update((
'typing=collections.abc:AsyncGenerator',
'typing=collections.abc:AsyncIterable',
'typing=collections.abc:AsyncIterator',
'typing=collections.abc:Awaitable',
'typing=collections.abc:ByteString',
'typing=collections.abc:Callable',
'typing=collections.abc:Collection',
'typing=collections.abc:Container',
'typing=collections.abc:Coroutine',
'typing=collections.abc:Generator',
'typing=collections.abc:Hashable',
'typing=collections.abc:ItemsView',
'typing=collections.abc:Iterable',
'typing=collections.abc:Iterator',
'typing=collections.abc:KeysView',
'typing=collections.abc:Mapping',
'typing=collections.abc:MappingView',
'typing=collections.abc:MutableMapping',
'typing=collections.abc:MutableSequence',
'typing=collections.abc:MutableSet',
'typing=collections.abc:Reversible',
'typing=collections.abc:Sequence',
'typing=collections.abc:Sized',
'typing=collections.abc:ValuesView',
'typing=collections:ChainMap',
'typing=collections:Counter',
'typing=collections:OrderedDict',
'typing=re:Match',
'typing=re:Pattern',
'typing.re=re:Match',
'typing.re=re:Pattern',
))
# END GENERATED

# GENERATED VIA generate-python-future-info
# Using future==0.18.2
REMOVALS[(3,)].update((
Expand Down
35 changes: 35 additions & 0 deletions testing/generate-typing-pep585-rewrites
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
import os.path
import sys
import typing.re


def main() -> int:
assert sys.version_info[:2] == (3, 9), sys.version_info

renames = [
f'typing={value.__origin__.__module__}:{name}'
for name, value in vars(typing).items()
if hasattr(value, '__origin__')
# TODO: still can't support symbol renaming
if value.__origin__.__name__ == name
] + [
f'typing.re={value.__origin__.__module__}:{name}'
for name, value in vars(typing.re).items()
if hasattr(value, '__origin__')
# TODO: still can't support symbol renaming
if value.__origin__.__name__ == name
]

print(f'# GENERATED VIA {os.path.basename(sys.argv[0])}')
print('REPLACES[(3, 9)].update((')
for rename in sorted(renames, key=lambda s: s.split('=')):
print(f' {rename!r},')
print('))')
print('# END GENERATED')

return 0


if __name__ == '__main__':
exit(main())
7 changes: 7 additions & 0 deletions tests/reorder_python_imports_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,13 @@ def test_py38_plus_rewrites_mypy_extensions_import(tmpdir):
assert f.read() == 'from typing import TypedDict\n'


def test_py39_plus_rewrites_pep585_imports(tmpdir):
f = tmpdir.join('f.py')
f.write('from typing import Sequence\n')
assert main((str(f), '--py39-plus'))
assert f.read() == 'from collections.abc import Sequence\n'


@pytest.mark.parametrize('opt', ('--add-import', '--remove-import'))
@pytest.mark.parametrize('s', ('syntax error', '"import os"'))
def test_invalid_add_remove_syntaxes(tmpdir, capsys, opt, s):
Expand Down