Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,66 @@ reveal_type(a) # revealed: Unknown
# Modifications allowed in this case:
a = None
```

## In stub files

In stub files, we have a minor modification to the rules above: we do not union with `Unknown` for
undeclared symbols.

### Undeclared and bound

`mod.pyi`:

```pyi
MyInt = int

class C:
MyStr = str
```

```py
from mod import MyInt, C

reveal_type(MyInt) # revealed: Literal[int]
reveal_type(C.MyStr) # revealed: Literal[str]
```

### Undeclared and possibly unbound

`mod.pyi`:

```pyi
def flag() -> bool:
return True

if flag():
MyInt = int

class C:
MyStr = str
```

```py
# error: [possibly-unbound-import]
# error: [possibly-unbound-import]
from mod import MyInt, C

reveal_type(MyInt) # revealed: Literal[int]
reveal_type(C.MyStr) # revealed: Literal[str]
```

### Undeclared and unbound

`mod.pyi`:

```pyi
if False:
MyInt = int
```

```py
# error: [unresolved-import]
from mod import MyInt

reveal_type(MyInt) # revealed: Unknown
```
8 changes: 0 additions & 8 deletions crates/red_knot_python_semantic/src/semantic_index/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ impl<'db> ScopeId<'db> {
self.node(db).scope_kind().is_function_like()
}

pub(crate) fn is_module_scope(self, db: &'db dyn Db) -> bool {
self.node(db).scope_kind().is_module()
}

pub(crate) fn is_type_parameter(self, db: &'db dyn Db) -> bool {
self.node(db).scope_kind().is_type_parameter()
}
Expand Down Expand Up @@ -267,10 +263,6 @@ impl ScopeKind {
matches!(self, ScopeKind::Class)
}

pub(crate) fn is_module(self) -> bool {
matches!(self, ScopeKind::Module)
}

pub(crate) fn is_type_parameter(self) -> bool {
matches!(self, ScopeKind::Annotation | ScopeKind::TypeAlias)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/red_knot_python_semantic/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ fn symbol_by_id<'db>(
"__slots__" | "TYPE_CHECKING"
);

if scope.is_module_scope(db) && scope.file(db).is_stub(db.upcast()) {
if scope.file(db).is_stub(db.upcast()) {
// We generally trust module-level undeclared symbols in stubs and do not union
// with `Unknown`. If we don't do this, simple aliases like `IOError = OSError` in
// stubs would result in `IOError` being a union of `OSError` and `Unknown`, which
Expand Down
Loading