Skip to content

Commit

Permalink
Ignore from ... import * imports in stub files (#153)
Browse files Browse the repository at this point in the history
* Ignore `from ... import *` imports in stub files

* avoiding unnecessary  calls.

* Testing star imports with stub file-path.

* Run prettier over docs/README.md via pre-commit.

Co-authored-by: Hadi Alqattan <alqattanhadizaki@gmail.com>
  • Loading branch information
AlexWaygood and hadialqattan committed Jul 13, 2022
1 parent 1a03fde commit 7e85688
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Expand Up @@ -10,6 +10,10 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Added

- [Pycln skips `from foo import *` imports in compliance with PEP 484 in stub files (`.pyi`) by @AlexWaygood](https://github.com/hadialqattan/pycln/pull/153)

### Changed

- [Bump typer from 0.4.1 to 0.5.0 by @dependabot[bot]](https://github.com/hadialqattan/pycln/pull/151)
Expand Down
10 changes: 9 additions & 1 deletion docs/README.md
Expand Up @@ -1093,7 +1093,9 @@ both the developers and QA tools.

> Pycln skips redundant alias imports in compliance with
> [PEP 484](https://peps.python.org/pep-0484/#stub-files) for the purposes of exporting
> modules and symbols for static type checking.
> modules and symbols for static type checking. Additionally, all symbols imported using
> `from foo import *` imports are considered publicly exported in a stub file, so these
> import statements are also ignored for `.pyi` extensions.

- case a:

Expand All @@ -1102,10 +1104,16 @@ both the developers and QA tools.
```

- case b:

```python
from X import Y as Y # marked as used.
```

- case c:
```python
from socket import * # marked as used.
```

# Unsupported Cases

## Specific
Expand Down
10 changes: 9 additions & 1 deletion pycln/utils/refactor.py
Expand Up @@ -393,6 +393,14 @@ def _expand_import_star(
is_star = False
if node.names[0].name == "*":

#: [for `.pyi` files] PEP 484 - Star Imports rule:
#:
#: >>> from X import * # exported (should be treated as used)
#:
#: More info: https://peps.python.org/pep-0484/#stub-files
if self._path.is_stub:
return node, None

if node.module:
if node.module.split(".")[0] in self.configs.skip_imports:
return node, None
Expand Down Expand Up @@ -433,7 +441,7 @@ def _should_remove(
real_name = node.module if isinstance(node, ImportFrom) else alias.name
used_name = alias.asname if alias.asname else alias.name

#: (for `.pyi`) PEP 484 - Redundant Module/Symbol Aliases rule:
#: [for `.pyi` files] PEP 484 - Redundant Module/Symbol Aliases rule:
#:
#: >>> import X as X # exported (should be treated as used)
#:
Expand Down
11 changes: 8 additions & 3 deletions tests/test_refactor.py
Expand Up @@ -837,16 +837,18 @@ def test_transform(
assert fixed_lines == updated_lines

@pytest.mark.parametrize(
"expand_import_star_raise, name, expec_is_star",
"expand_import_star_raise, name, is_stub, expec_is_star",
[
pytest.param(None, "*", True, id="star"),
pytest.param(None, "!*", False, id="not-star"),
pytest.param(None, "*", False, True, id="star"),
pytest.param(None, "!*", False, False, id="not-star"),
pytest.param(
UnexpandableImportStar(Path(""), NodeLocation((1, 0), 1), ""),
"*",
False,
None,
id="not-star",
),
pytest.param(None, "*", True, None, id="star-stub(pyi)"),
],
)
@mock.patch(MOCK % "scan.expand_import_star")
Expand All @@ -855,11 +857,14 @@ def test_expand_import_star(
expand_import_star,
expand_import_star_raise,
name,
is_stub,
expec_is_star,
):
node = ImportFrom(NodeLocation((1, 0), 1), [ast.alias(name=name)], "xxx", 0)
expand_import_star.return_value = node
expand_import_star.side_effect = expand_import_star_raise
if is_stub:
self.session_maker._path = refactor.PyPath("stub.pyi")
enode, is_star = self.session_maker._expand_import_star(node)
assert (enode, is_star) == (node, expec_is_star)

Expand Down

0 comments on commit 7e85688

Please sign in to comment.