From a67630f907c356f3db17934af8e73b7885b64638 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 11 Jul 2025 14:20:16 +0100 Subject: [PATCH] [ty] Filter out private type aliases from stub files when offering autocomplete suggestions (#19282) --- crates/ty_ide/src/completion.rs | 7 ++++++- crates/ty_python_semantic/src/types.rs | 12 +++++++++++- crates/ty_python_semantic/src/types/class_base.rs | 6 +++++- crates/ty_python_semantic/src/types/ide_support.rs | 4 +++- crates/ty_python_semantic/src/types/infer.rs | 12 ++++++++++-- crates/ty_python_semantic/src/types/type_ordering.rs | 3 +++ 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/crates/ty_ide/src/completion.rs b/crates/ty_ide/src/completion.rs index f689a04533..312a715d8f 100644 --- a/crates/ty_ide/src/completion.rs +++ b/crates/ty_ide/src/completion.rs @@ -536,6 +536,9 @@ _private_type_var_tuple = TypeVarTuple("_private_type_var_tuple") public_explicit_type_alias: TypeAlias = Literal[1] _private_explicit_type_alias: TypeAlias = Literal[1] +public_implicit_union_alias = int | str +_private_implicit_union_alias = int | str + class PublicProtocol(Protocol): def method(self) -> None: ... @@ -557,7 +560,9 @@ class _PrivateProtocol(Protocol): test.assert_completions_include("public_type_var_tuple"); test.assert_completions_do_not_include("_private_type_var_tuple"); test.assert_completions_include("public_explicit_type_alias"); - test.assert_completions_include("_private_explicit_type_alias"); + test.assert_completions_do_not_include("_private_explicit_type_alias"); + test.assert_completions_include("public_implicit_union_alias"); + test.assert_completions_do_not_include("_private_implicit_union_alias"); test.assert_completions_include("PublicProtocol"); test.assert_completions_do_not_include("_PrivateProtocol"); } diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index ed37dcc0c6..3463ee933e 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -4995,7 +4995,7 @@ impl<'db> Type<'db> { TypeVarKind::Legacy, ))) } - SpecialFormType::TypeAlias => Ok(todo_type!("Support for `typing.TypeAlias`")), + SpecialFormType::TypeAlias => Ok(Type::Dynamic(DynamicType::TodoTypeAlias)), SpecialFormType::TypedDict => Ok(todo_type!("Support for `typing.TypedDict`")), SpecialFormType::Literal @@ -5880,6 +5880,9 @@ pub enum DynamicType { /// A special Todo-variant for PEP-695 `ParamSpec` types. A temporary variant to detect and special- /// case the handling of these types in `Callable` annotations. TodoPEP695ParamSpec, + /// A special Todo-variant for type aliases declared using `typing.TypeAlias`. + /// A temporary variant to detect and special-case the handling of these aliases in autocomplete suggestions. + TodoTypeAlias, } impl DynamicType { @@ -5904,6 +5907,13 @@ impl std::fmt::Display for DynamicType { f.write_str("@Todo") } } + DynamicType::TodoTypeAlias => { + if cfg!(debug_assertions) { + f.write_str("@Todo(Support for `typing.TypeAlias`)") + } else { + f.write_str("@Todo") + } + } } } } diff --git a/crates/ty_python_semantic/src/types/class_base.rs b/crates/ty_python_semantic/src/types/class_base.rs index ce5686e9c1..c4b3d1f2a6 100644 --- a/crates/ty_python_semantic/src/types/class_base.rs +++ b/crates/ty_python_semantic/src/types/class_base.rs @@ -48,7 +48,11 @@ impl<'db> ClassBase<'db> { ClassBase::Class(class) => class.name(db), ClassBase::Dynamic(DynamicType::Any) => "Any", ClassBase::Dynamic(DynamicType::Unknown) => "Unknown", - ClassBase::Dynamic(DynamicType::Todo(_) | DynamicType::TodoPEP695ParamSpec) => "@Todo", + ClassBase::Dynamic( + DynamicType::Todo(_) + | DynamicType::TodoPEP695ParamSpec + | DynamicType::TodoTypeAlias, + ) => "@Todo", ClassBase::Protocol => "Protocol", ClassBase::Generic => "Generic", } diff --git a/crates/ty_python_semantic/src/types/ide_support.rs b/crates/ty_python_semantic/src/types/ide_support.rs index 3df5a4bb91..baf8b35625 100644 --- a/crates/ty_python_semantic/src/types/ide_support.rs +++ b/crates/ty_python_semantic/src/types/ide_support.rs @@ -9,7 +9,7 @@ use crate::semantic_index::{ }; use crate::types::call::CallArguments; use crate::types::signatures::Signature; -use crate::types::{ClassBase, ClassLiteral, KnownClass, KnownInstanceType, Type}; +use crate::types::{ClassBase, ClassLiteral, DynamicType, KnownClass, KnownInstanceType, Type}; use crate::{Db, HasType, NameKind, SemanticModel}; use ruff_db::files::File; use ruff_python_ast as ast; @@ -181,6 +181,7 @@ impl<'db> AllMembers<'db> { KnownClass::TypeVar | KnownClass::TypeVarTuple | KnownClass::ParamSpec + | KnownClass::UnionType ) ) => { @@ -190,6 +191,7 @@ impl<'db> AllMembers<'db> { Type::KnownInstance( KnownInstanceType::TypeVar(_) | KnownInstanceType::TypeAliasType(_), ) => continue, + Type::Dynamic(DynamicType::TodoTypeAlias) => continue, _ => {} } } diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index fff33b7826..e49c294285 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -6390,13 +6390,21 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { (unknown @ Type::Dynamic(DynamicType::Unknown), _, _) | (_, unknown @ Type::Dynamic(DynamicType::Unknown), _) => Some(unknown), ( - todo @ Type::Dynamic(DynamicType::Todo(_) | DynamicType::TodoPEP695ParamSpec), + todo @ Type::Dynamic( + DynamicType::Todo(_) + | DynamicType::TodoPEP695ParamSpec + | DynamicType::TodoTypeAlias, + ), _, _, ) | ( _, - todo @ Type::Dynamic(DynamicType::Todo(_) | DynamicType::TodoPEP695ParamSpec), + todo @ Type::Dynamic( + DynamicType::Todo(_) + | DynamicType::TodoPEP695ParamSpec + | DynamicType::TodoTypeAlias, + ), _, ) => Some(todo), (Type::Never, _, _) | (_, Type::Never, _) => Some(Type::Never), diff --git a/crates/ty_python_semantic/src/types/type_ordering.rs b/crates/ty_python_semantic/src/types/type_ordering.rs index d4b1a5bcf4..5393fd8933 100644 --- a/crates/ty_python_semantic/src/types/type_ordering.rs +++ b/crates/ty_python_semantic/src/types/type_ordering.rs @@ -250,6 +250,9 @@ fn dynamic_elements_ordering(left: DynamicType, right: DynamicType) -> Ordering (DynamicType::TodoPEP695ParamSpec, _) => Ordering::Less, (_, DynamicType::TodoPEP695ParamSpec) => Ordering::Greater, + + (DynamicType::TodoTypeAlias, _) => Ordering::Less, + (_, DynamicType::TodoTypeAlias) => Ordering::Greater, } }