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
|
||||
|
||||
# error: [possibly-missing-attribute]
|
||||
reveal_type(foo.bar) # revealed: Unknown
|
||||
reveal_type(foo.bar) # revealed: <module 'foo.bar'>
|
||||
# error: [possibly-missing-attribute]
|
||||
reveal_type(baz.bar) # revealed: Unknown
|
||||
reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||
```
|
||||
|
||||
## References
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.imported.X) # revealed: int
|
||||
# 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
|
||||
|
|
@ -91,7 +91,7 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.imported.X) # revealed: int
|
||||
# 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__`
|
||||
|
|
@ -126,7 +126,7 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.imported.X) # revealed: int
|
||||
# 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
|
||||
|
|
@ -156,7 +156,7 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.imported.X) # revealed: int
|
||||
# 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__`
|
||||
|
|
@ -185,7 +185,7 @@ import mypackage
|
|||
|
||||
# TODO: this could work and would be nice to have?
|
||||
# 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
|
||||
|
|
@ -209,7 +209,7 @@ import mypackage
|
|||
|
||||
# TODO: this could work and would be nice to have
|
||||
# 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__`
|
||||
|
|
@ -243,9 +243,9 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||
# 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"
|
||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
||||
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||
# error: [unresolved-attribute] "has no member `nested`"
|
||||
reveal_type(mypackage.nested) # revealed: Unknown
|
||||
# error: [unresolved-attribute] "has no member `nested`"
|
||||
|
|
@ -281,9 +281,9 @@ import mypackage
|
|||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||
# TODO: this would be nice to support
|
||||
# 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"
|
||||
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.X) # revealed: int
|
||||
```
|
||||
|
|
@ -319,9 +319,9 @@ import mypackage
|
|||
|
||||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||
# 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"
|
||||
reveal_type(mypackage.submodule.nested.X) # revealed: Unknown
|
||||
reveal_type(mypackage.submodule.nested.X) # revealed: int
|
||||
# error: [unresolved-attribute] "has no member `nested`"
|
||||
reveal_type(mypackage.nested) # revealed: Unknown
|
||||
# error: [unresolved-attribute] "has no member `nested`"
|
||||
|
|
@ -357,9 +357,9 @@ import mypackage
|
|||
reveal_type(mypackage.submodule) # revealed: <module 'mypackage.submodule'>
|
||||
# TODO: this would be nice to support
|
||||
# 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"
|
||||
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.X) # revealed: int
|
||||
```
|
||||
|
|
@ -394,11 +394,13 @@ X: int = 42
|
|||
import mypackage
|
||||
|
||||
# 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"
|
||||
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"
|
||||
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
|
||||
|
|
@ -430,11 +432,13 @@ import mypackage
|
|||
|
||||
# TODO: this would be nice to support
|
||||
# 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"
|
||||
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"
|
||||
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
|
||||
|
|
@ -461,7 +465,7 @@ X: int = 42
|
|||
import mypackage
|
||||
|
||||
# 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`"
|
||||
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
|
||||
# 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
|
||||
```
|
||||
|
||||
|
|
@ -759,7 +763,7 @@ reveal_type(imported.X) # revealed: int
|
|||
# error: [unresolved-attribute] "has no member `fails`"
|
||||
reveal_type(imported.fails.Y) # revealed: Unknown
|
||||
# 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
|
||||
|
|
@ -792,7 +796,7 @@ from mypackage import imported
|
|||
reveal_type(imported.X) # revealed: int
|
||||
reveal_type(imported.fails.Y) # revealed: int
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ from . import foo
|
|||
import package
|
||||
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ mdtest path: crates/ty_python_semantic/resources/mdtest/attributes.md
|
|||
2 | import baz
|
||||
3 |
|
||||
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]
|
||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
||||
7 | reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||
```
|
||||
|
||||
# Diagnostics
|
||||
|
|
@ -43,10 +43,10 @@ warning[possibly-missing-attribute]: Submodule `bar` may not be available as an
|
|||
--> src/main.py:5:13
|
||||
|
|
||||
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]
|
||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
||||
7 | reveal_type(baz.bar) # revealed: <module 'baz.bar'>
|
||||
|
|
||||
help: Consider explicitly importing `foo.bar`
|
||||
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`
|
||||
--> 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]
|
||||
7 | reveal_type(baz.bar) # revealed: Unknown
|
||||
7 | reveal_type(baz.bar) # revealed: <module '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
|
||||
|
||||
# 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'>
|
||||
|
||||
|
|
|
|||
|
|
@ -9148,7 +9148,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
{
|
||||
let mut maybe_submodule_name = module_name.clone();
|
||||
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
|
||||
.context
|
||||
.report_lint(&POSSIBLY_MISSING_ATTRIBUTE, attribute)
|
||||
|
|
@ -9161,7 +9161,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
"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