mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[red-knot] Fix false positives on types.UnionType
instances in type expressions (#17297)
This commit is contained in:
parent
484a8ed36d
commit
781b653511
3 changed files with 30 additions and 1 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## Annotation
|
## Annotation
|
||||||
|
|
||||||
`typing.Union` can be used to construct union types same as `|` operator.
|
`typing.Union` can be used to construct union types in the same way as the `|` operator.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
@ -69,3 +69,20 @@ from typing import Union
|
||||||
def f(x: Union) -> None:
|
def f(x: Union) -> None:
|
||||||
reveal_type(x) # revealed: Unknown
|
reveal_type(x) # revealed: Unknown
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Implicit type aliases using new-style unions
|
||||||
|
|
||||||
|
We don't recognise these as type aliases yet, but we also don't emit false-positive diagnostics if
|
||||||
|
you use them in type expressions:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[environment]
|
||||||
|
python-version = "3.10"
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
X = int | str
|
||||||
|
|
||||||
|
def f(y: X):
|
||||||
|
reveal_type(y) # revealed: @Todo(Support for `types.UnionType` instances in type expressions)
|
||||||
|
```
|
||||||
|
|
|
@ -4035,6 +4035,9 @@ impl<'db> Type<'db> {
|
||||||
Some(KnownClass::GenericAlias) => Ok(todo_type!(
|
Some(KnownClass::GenericAlias) => Ok(todo_type!(
|
||||||
"Support for `typing.GenericAlias` instances in type expressions"
|
"Support for `typing.GenericAlias` instances in type expressions"
|
||||||
)),
|
)),
|
||||||
|
Some(KnownClass::UnionType) => Ok(todo_type!(
|
||||||
|
"Support for `types.UnionType` instances in type expressions"
|
||||||
|
)),
|
||||||
_ => Err(InvalidTypeExpressionError {
|
_ => Err(InvalidTypeExpressionError {
|
||||||
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::InvalidType(
|
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::InvalidType(
|
||||||
*self
|
*self
|
||||||
|
|
|
@ -1170,6 +1170,7 @@ pub(crate) enum KnownClass {
|
||||||
MethodType,
|
MethodType,
|
||||||
MethodWrapperType,
|
MethodWrapperType,
|
||||||
WrapperDescriptorType,
|
WrapperDescriptorType,
|
||||||
|
UnionType,
|
||||||
// Typeshed
|
// Typeshed
|
||||||
NoneType, // Part of `types` for Python >= 3.10
|
NoneType, // Part of `types` for Python >= 3.10
|
||||||
// Typing
|
// Typing
|
||||||
|
@ -1233,6 +1234,7 @@ impl<'db> KnownClass {
|
||||||
| Self::ParamSpecKwargs
|
| Self::ParamSpecKwargs
|
||||||
| Self::TypeVarTuple
|
| Self::TypeVarTuple
|
||||||
| Self::WrapperDescriptorType
|
| Self::WrapperDescriptorType
|
||||||
|
| Self::UnionType
|
||||||
| Self::MethodWrapperType => Truthiness::AlwaysTrue,
|
| Self::MethodWrapperType => Truthiness::AlwaysTrue,
|
||||||
|
|
||||||
Self::NoneType => Truthiness::AlwaysFalse,
|
Self::NoneType => Truthiness::AlwaysFalse,
|
||||||
|
@ -1305,6 +1307,7 @@ impl<'db> KnownClass {
|
||||||
Self::ModuleType => "ModuleType",
|
Self::ModuleType => "ModuleType",
|
||||||
Self::FunctionType => "FunctionType",
|
Self::FunctionType => "FunctionType",
|
||||||
Self::MethodType => "MethodType",
|
Self::MethodType => "MethodType",
|
||||||
|
Self::UnionType => "UnionType",
|
||||||
Self::MethodWrapperType => "MethodWrapperType",
|
Self::MethodWrapperType => "MethodWrapperType",
|
||||||
Self::WrapperDescriptorType => "WrapperDescriptorType",
|
Self::WrapperDescriptorType => "WrapperDescriptorType",
|
||||||
Self::NoneType => "NoneType",
|
Self::NoneType => "NoneType",
|
||||||
|
@ -1487,6 +1490,7 @@ impl<'db> KnownClass {
|
||||||
| Self::FunctionType
|
| Self::FunctionType
|
||||||
| Self::MethodType
|
| Self::MethodType
|
||||||
| Self::MethodWrapperType
|
| Self::MethodWrapperType
|
||||||
|
| Self::UnionType
|
||||||
| Self::WrapperDescriptorType => KnownModule::Types,
|
| Self::WrapperDescriptorType => KnownModule::Types,
|
||||||
Self::NoneType => KnownModule::Typeshed,
|
Self::NoneType => KnownModule::Typeshed,
|
||||||
Self::Any
|
Self::Any
|
||||||
|
@ -1539,6 +1543,7 @@ impl<'db> KnownClass {
|
||||||
| Self::VersionInfo
|
| Self::VersionInfo
|
||||||
| Self::EllipsisType
|
| Self::EllipsisType
|
||||||
| Self::TypeAliasType
|
| Self::TypeAliasType
|
||||||
|
| Self::UnionType
|
||||||
| Self::NotImplementedType => true,
|
| Self::NotImplementedType => true,
|
||||||
|
|
||||||
Self::Any
|
Self::Any
|
||||||
|
@ -1643,6 +1648,7 @@ impl<'db> KnownClass {
|
||||||
| Self::Sized
|
| Self::Sized
|
||||||
| Self::Enum
|
| Self::Enum
|
||||||
| Self::Super
|
| Self::Super
|
||||||
|
| Self::UnionType
|
||||||
| Self::NewType => false,
|
| Self::NewType => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1681,6 +1687,7 @@ impl<'db> KnownClass {
|
||||||
"ModuleType" => Self::ModuleType,
|
"ModuleType" => Self::ModuleType,
|
||||||
"FunctionType" => Self::FunctionType,
|
"FunctionType" => Self::FunctionType,
|
||||||
"MethodType" => Self::MethodType,
|
"MethodType" => Self::MethodType,
|
||||||
|
"UnionType" => Self::UnionType,
|
||||||
"MethodWrapperType" => Self::MethodWrapperType,
|
"MethodWrapperType" => Self::MethodWrapperType,
|
||||||
"WrapperDescriptorType" => Self::WrapperDescriptorType,
|
"WrapperDescriptorType" => Self::WrapperDescriptorType,
|
||||||
"NewType" => Self::NewType,
|
"NewType" => Self::NewType,
|
||||||
|
@ -1758,6 +1765,7 @@ impl<'db> KnownClass {
|
||||||
| Self::Enum
|
| Self::Enum
|
||||||
| Self::Super
|
| Self::Super
|
||||||
| Self::NotImplementedType
|
| Self::NotImplementedType
|
||||||
|
| Self::UnionType
|
||||||
| Self::WrapperDescriptorType => module == self.canonical_module(db),
|
| Self::WrapperDescriptorType => module == self.canonical_module(db),
|
||||||
Self::NoneType => matches!(module, KnownModule::Typeshed | KnownModule::Types),
|
Self::NoneType => matches!(module, KnownModule::Typeshed | KnownModule::Types),
|
||||||
Self::SpecialForm
|
Self::SpecialForm
|
||||||
|
@ -2259,6 +2267,7 @@ mod tests {
|
||||||
|
|
||||||
for class in KnownClass::iter() {
|
for class in KnownClass::iter() {
|
||||||
let version_added = match class {
|
let version_added = match class {
|
||||||
|
KnownClass::UnionType => PythonVersion::PY310,
|
||||||
KnownClass::BaseExceptionGroup => PythonVersion::PY311,
|
KnownClass::BaseExceptionGroup => PythonVersion::PY311,
|
||||||
KnownClass::GenericAlias => PythonVersion::PY39,
|
KnownClass::GenericAlias => PythonVersion::PY39,
|
||||||
_ => PythonVersion::PY37,
|
_ => PythonVersion::PY37,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue