mirror of https://github.com/astral-sh/ruff
[ty] Always infer the submodule literal for submodule attribute-access, even when we emit a diagnostic
This commit is contained in:
parent
a2f9e5a680
commit
a4be2aad04
|
|
@ -2770,9 +2770,9 @@ import foo
|
||||||
import baz
|
import baz
|
||||||
|
|
||||||
# error: [possibly-missing-attribute]
|
# error: [possibly-missing-attribute]
|
||||||
reveal_type(foo.bar) # revealed: Unknown
|
reveal_type(foo.bar) # revealed: <module 'foo.bar'>
|
||||||
# error: [possibly-missing-attribute]
|
# error: [possibly-missing-attribute]
|
||||||
reveal_type(baz.bar) # revealed: Unknown
|
reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||||
```
|
```
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.imported.X) # revealed: int
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
### In Non-Stub
|
### In Non-Stub
|
||||||
|
|
@ -91,7 +91,7 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.imported.X) # revealed: int
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Absolute `from` Import of Direct Submodule in `__init__`
|
## Absolute `from` Import of Direct Submodule in `__init__`
|
||||||
|
|
@ -126,7 +126,7 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.imported.X) # revealed: int
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
### In Non-Stub
|
### In Non-Stub
|
||||||
|
|
@ -156,7 +156,7 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.imported.X) # revealed: int
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Import of Direct Submodule in `__init__`
|
## Import of Direct Submodule in `__init__`
|
||||||
|
|
@ -185,7 +185,7 @@ import mypackage
|
||||||
|
|
||||||
# TODO: this could work and would be nice to have?
|
# TODO: this could work and would be nice to have?
|
||||||
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
||||||
reveal_type(mypackage.imported.X) # revealed: Unknown
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
### In Non-Stub
|
### In Non-Stub
|
||||||
|
|
@ -209,7 +209,7 @@ import mypackage
|
||||||
|
|
||||||
# TODO: this could work and would be nice to have
|
# TODO: this could work and would be nice to have
|
||||||
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
||||||
reveal_type(mypackage.imported.X) # revealed: Unknown
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Relative `from` Import of Nested Submodule in `__init__`
|
## Relative `from` Import of Nested Submodule in `__init__`
|
||||||
|
|
@ -243,9 +243,9 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
# error: [unresolved-attribute] "has no member `nested`"
|
# error: [unresolved-attribute] "has no member `nested`"
|
||||||
reveal_type(mypackage.nested) # revealed: Unknown
|
reveal_type(mypackage.nested) # revealed: Unknown
|
||||||
# error: [unresolved-attribute] "has no member `nested`"
|
# error: [unresolved-attribute] "has no member `nested`"
|
||||||
|
|
@ -281,9 +281,9 @@ import mypackage
|
||||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# TODO: this would be nice to support
|
# TODO: this would be nice to support
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
|
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
reveal_type(mypackage.nested.X) # revealed: int
|
reveal_type(mypackage.nested.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
@ -319,9 +319,9 @@ import mypackage
|
||||||
|
|
||||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
# error: [unresolved-attribute] "has no member `nested`"
|
# error: [unresolved-attribute] "has no member `nested`"
|
||||||
reveal_type(mypackage.nested) # revealed: Unknown
|
reveal_type(mypackage.nested) # revealed: Unknown
|
||||||
# error: [unresolved-attribute] "has no member `nested`"
|
# error: [unresolved-attribute] "has no member `nested`"
|
||||||
|
|
@ -357,9 +357,9 @@ import mypackage
|
||||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# TODO: this would be nice to support
|
# TODO: this would be nice to support
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
|
reveal_type(mypackage.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
reveal_type(mypackage.nested.X) # revealed: int
|
reveal_type(mypackage.nested.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
@ -394,11 +394,13 @@ X: int = 42
|
||||||
import mypackage
|
import mypackage
|
||||||
|
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule) # revealed: Unknown
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
### In Non-Stub
|
### In Non-Stub
|
||||||
|
|
@ -430,11 +432,13 @@ import mypackage
|
||||||
|
|
||||||
# TODO: this would be nice to support
|
# TODO: this would be nice to support
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule) # revealed: Unknown
|
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested) # revealed: Unknown
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
|
reveal_type(mypackage.submodule.nested) # revealed: <module 'mypackage.submodule.nested'>
|
||||||
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `submodule` may not be available"
|
||||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
# error: [possibly-missing-attribute] "Submodule `nested` may not be available"
|
||||||
|
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Relative `from` Import of Direct Submodule in `__init__`, Mismatched Alias
|
## Relative `from` Import of Direct Submodule in `__init__`, Mismatched Alias
|
||||||
|
|
@ -461,7 +465,7 @@ X: int = 42
|
||||||
import mypackage
|
import mypackage
|
||||||
|
|
||||||
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
||||||
reveal_type(mypackage.imported.X) # revealed: Unknown
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
# error: [unresolved-attribute] "has no member `imported_m`"
|
# error: [unresolved-attribute] "has no member `imported_m`"
|
||||||
reveal_type(mypackage.imported_m.X) # revealed: Unknown
|
reveal_type(mypackage.imported_m.X) # revealed: Unknown
|
||||||
```
|
```
|
||||||
|
|
@ -487,7 +491,7 @@ import mypackage
|
||||||
|
|
||||||
# TODO: this would be nice to support, as it works at runtime
|
# TODO: this would be nice to support, as it works at runtime
|
||||||
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `imported` may not be available"
|
||||||
reveal_type(mypackage.imported.X) # revealed: Unknown
|
reveal_type(mypackage.imported.X) # revealed: int
|
||||||
reveal_type(mypackage.imported_m.X) # revealed: int
|
reveal_type(mypackage.imported_m.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -759,7 +763,7 @@ reveal_type(imported.X) # revealed: int
|
||||||
# error: [unresolved-attribute] "has no member `fails`"
|
# error: [unresolved-attribute] "has no member `fails`"
|
||||||
reveal_type(imported.fails.Y) # revealed: Unknown
|
reveal_type(imported.fails.Y) # revealed: Unknown
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
# error: [possibly-missing-attribute] "Submodule `fails` may not be available"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
### In Non-Stub
|
### In Non-Stub
|
||||||
|
|
@ -792,7 +796,7 @@ from mypackage import imported
|
||||||
reveal_type(imported.X) # revealed: int
|
reveal_type(imported.X) # revealed: int
|
||||||
reveal_type(imported.fails.Y) # revealed: int
|
reveal_type(imported.fails.Y) # revealed: int
|
||||||
# error: [possibly-missing-attribute] "Submodule `fails`"
|
# error: [possibly-missing-attribute] "Submodule `fails`"
|
||||||
reveal_type(mypackage.fails.Y) # revealed: Unknown
|
reveal_type(mypackage.fails.Y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Fractal Re-export Nameclash Problems
|
## Fractal Re-export Nameclash Problems
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ from . import foo
|
||||||
import package
|
import package
|
||||||
|
|
||||||
# error: [possibly-missing-attribute]
|
# error: [possibly-missing-attribute]
|
||||||
reveal_type(package.foo.X) # revealed: Unknown
|
reveal_type(package.foo.X) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
## Relative imports at the top of a search path
|
## Relative imports at the top of a search path
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/attributes.md
|
||||||
2 | import baz
|
2 | import baz
|
||||||
3 |
|
3 |
|
||||||
4 | # error: [possibly-missing-attribute]
|
4 | # error: [possibly-missing-attribute]
|
||||||
5 | reveal_type(foo.bar) # revealed: Unknown
|
5 | reveal_type(foo.bar) # revealed: <module 'foo.bar'>
|
||||||
6 | # error: [possibly-missing-attribute]
|
6 | # error: [possibly-missing-attribute]
|
||||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
7 | reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||||
```
|
```
|
||||||
|
|
||||||
# Diagnostics
|
# Diagnostics
|
||||||
|
|
@ -43,10 +43,10 @@ warning[possibly-missing-attribute]: Submodule `bar` may not be available as an
|
||||||
--> src/main.py:5:13
|
--> src/main.py:5:13
|
||||||
|
|
|
|
||||||
4 | # error: [possibly-missing-attribute]
|
4 | # error: [possibly-missing-attribute]
|
||||||
5 | reveal_type(foo.bar) # revealed: Unknown
|
5 | reveal_type(foo.bar) # revealed: <module 'foo.bar'>
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
6 | # error: [possibly-missing-attribute]
|
6 | # error: [possibly-missing-attribute]
|
||||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
7 | reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||||
|
|
|
|
||||||
help: Consider explicitly importing `foo.bar`
|
help: Consider explicitly importing `foo.bar`
|
||||||
info: rule `possibly-missing-attribute` is enabled by default
|
info: rule `possibly-missing-attribute` is enabled by default
|
||||||
|
|
@ -57,9 +57,9 @@ info: rule `possibly-missing-attribute` is enabled by default
|
||||||
warning[possibly-missing-attribute]: Submodule `bar` may not be available as an attribute on module `baz`
|
warning[possibly-missing-attribute]: Submodule `bar` may not be available as an attribute on module `baz`
|
||||||
--> src/main.py:7:13
|
--> src/main.py:7:13
|
||||||
|
|
|
|
||||||
5 | reveal_type(foo.bar) # revealed: Unknown
|
5 | reveal_type(foo.bar) # revealed: <module 'foo.bar'>
|
||||||
6 | # error: [possibly-missing-attribute]
|
6 | # error: [possibly-missing-attribute]
|
||||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
7 | reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
help: Consider explicitly importing `baz.bar`
|
help: Consider explicitly importing `baz.bar`
|
||||||
|
|
|
||||||
|
|
@ -629,7 +629,7 @@ from module2 import imported as other_imported
|
||||||
from ty_extensions import TypeOf, static_assert, is_equivalent_to
|
from ty_extensions import TypeOf, static_assert, is_equivalent_to
|
||||||
|
|
||||||
# error: [possibly-missing-attribute]
|
# error: [possibly-missing-attribute]
|
||||||
reveal_type(imported.abc) # revealed: Unknown
|
reveal_type(imported.abc) # revealed: <module 'imported.abc'>
|
||||||
|
|
||||||
reveal_type(other_imported.abc) # revealed: <module 'imported.abc'>
|
reveal_type(other_imported.abc) # revealed: <module 'imported.abc'>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9148,7 +9148,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
{
|
{
|
||||||
let mut maybe_submodule_name = module_name.clone();
|
let mut maybe_submodule_name = module_name.clone();
|
||||||
maybe_submodule_name.extend(&relative_submodule);
|
maybe_submodule_name.extend(&relative_submodule);
|
||||||
if resolve_module(db, &maybe_submodule_name).is_some() {
|
if let Some(submodule) = resolve_module(db, &maybe_submodule_name) {
|
||||||
if let Some(builder) = self
|
if let Some(builder) = self
|
||||||
.context
|
.context
|
||||||
.report_lint(&POSSIBLY_MISSING_ATTRIBUTE, attribute)
|
.report_lint(&POSSIBLY_MISSING_ATTRIBUTE, attribute)
|
||||||
|
|
@ -9161,7 +9161,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
"Consider explicitly importing `{maybe_submodule_name}`"
|
"Consider explicitly importing `{maybe_submodule_name}`"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return fallback();
|
return TypeAndQualifiers::new(
|
||||||
|
Type::module_literal(db, self.file(), submodule),
|
||||||
|
TypeOrigin::Inferred,
|
||||||
|
TypeQualifiers::empty(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue