Skip to content

[red-knot] Add some knowledge of __all__ to *-import machinery #17373

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

Merged
merged 1 commit into from
Apr 15, 2025
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
119 changes: 108 additions & 11 deletions crates/red_knot_python_semantic/resources/mdtest/import/star.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,30 @@ reveal_type(X) # revealed: Unknown
reveal_type(Y) # revealed: bool
```

### An implicit import in a `.pyi` file later overridden by another assignment

`a.pyi`:

```pyi
X: bool = True
```

`b.pyi`:

```pyi
from a import X

X: bool = False
```

`c.py`:

```py
from b import *

reveal_type(X) # revealed: bool
```

## Visibility constraints

If an `importer` module contains a `from exporter import *` statement in its global namespace, the
Expand Down Expand Up @@ -865,15 +889,10 @@ from exporter import *

reveal_type(X) # revealed: bool

# TODO none of these should error, should all reveal `bool`
# error: [unresolved-reference]
reveal_type(_private) # revealed: Unknown
# error: [unresolved-reference]
reveal_type(__protected) # revealed: Unknown
# error: [unresolved-reference]
reveal_type(__dunder__) # revealed: Unknown
# error: [unresolved-reference]
reveal_type(___thunder___) # revealed: Unknown
reveal_type(_private) # revealed: bool
reveal_type(__protected) # revealed: bool
reveal_type(__dunder__) # revealed: bool
reveal_type(___thunder___) # revealed: bool

# TODO: should emit [unresolved-reference] diagnostic & reveal `Unknown`
reveal_type(Y) # revealed: bool
Expand Down Expand Up @@ -1072,6 +1091,44 @@ reveal_type(Y) # revealed: bool
reveal_type(Z) # revealed: Unknown
```

### `__all__` conditionally defined in a statically known branch (2)

The same example again, but with a different `python-version` set:

```toml
[environment]
python-version = "3.10"
```

`exporter.py`:

```py
import sys

X: bool = True

if sys.version_info >= (3, 11):
__all__ = ["X", "Y"]
Y: bool = True
else:
__all__ = ("Z",)
Z: bool = True
```

`importer.py`:

```py
from exporter import *

# TODO: should reveal `Unknown` and emit `[unresolved-reference]`
reveal_type(X) # revealed: bool

# error: [unresolved-reference]
reveal_type(Y) # revealed: Unknown

reveal_type(Z) # revealed: bool
```

### `__all__` conditionally mutated in a statically known branch

```toml
Expand All @@ -1084,11 +1141,11 @@ python-version = "3.11"
```py
import sys

__all__ = ["X"]
__all__ = []
X: bool = True

if sys.version_info >= (3, 11):
__all__.append("Y")
__all__.extend(["X", "Y"])
Y: bool = True
else:
__all__.append("Z")
Expand All @@ -1107,6 +1164,45 @@ reveal_type(Y) # revealed: bool
reveal_type(Z) # revealed: Unknown
```

### `__all__` conditionally mutated in a statically known branch (2)

The same example again, but with a different `python-version` set:

```toml
[environment]
python-version = "3.10"
```

`exporter.py`:

```py
import sys

__all__ = []
X: bool = True

if sys.version_info >= (3, 11):
__all__.extend(["X", "Y"])
Y: bool = True
else:
__all__.append("Z")
Z: bool = True
```

`importer.py`:

```py
from exporter import *

# TODO: should reveal `Unknown` & emit `[unresolved-reference]
reveal_type(X) # revealed: bool

# error: [unresolved-reference]
reveal_type(Y) # revealed: Unknown

reveal_type(Z) # revealed: bool
```

### Empty `__all__`

An empty `__all__` is valid, but a `*` import from a module with an empty `__all__` results in 0
Expand Down Expand Up @@ -1166,6 +1262,7 @@ from b import *

# TODO: should not error, should reveal `bool`
# (`X` is re-exported from `b.pyi` due to presence in `__all__`)
# See https://github.com/astral-sh/ruff/issues/16159
#
# error: [unresolved-reference]
reveal_type(X) # revealed: Unknown
Expand Down
Loading
Loading