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
34 changes: 29 additions & 5 deletions crates/ty_ide/src/goto_type_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,10 +753,21 @@ mod tests {
"#,
);

// TODO: Goto type definition currently doesn't work for type var tuples
// because the inference doesn't support them yet.
// This snapshot should show a single target pointing to `T`
assert_snapshot!(test.goto_type_definition(), @"No type definitions found");
// TODO: Point to `Ts` once inference supports type-variable tuples here.
assert_snapshot!(test.goto_type_definition(), @"
info[goto-type definition]: Go to type definition
--> main.py:LL:31
|
LL | type Alias[*Ts = ()] = tuple[*Ts]
| ^^ Clicking here
|
info: Found 1 type definition
--> stdlib/ty_extensions.pyi:LL:1
|
LL | Todo: _SpecialForm
| ----
|
");
}

#[test]
Expand Down Expand Up @@ -1570,7 +1581,20 @@ mod tests {
"#,
);

assert_snapshot!(test.goto_type_definition(), @"No type definitions found");
assert_snapshot!(test.goto_type_definition(), @"
info[goto-type definition]: Go to type definition
--> main.py:LL:38
|
LL | type Alias3[*AB = ()] = tuple[tuple[*AB], tuple[*AB]]
| ^^ Clicking here
|
info: Found 1 type definition
--> stdlib/ty_extensions.pyi:LL:1
|
LL | Todo: _SpecialForm
| ----
|
");
}

#[test]
Expand Down
13 changes: 7 additions & 6 deletions crates/ty_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7052,17 +7052,18 @@ impl<'db> Type<'db> {
| DynamicType::AmbiguousOverload,
) => Type::SpecialForm(SpecialFormType::Unknown).definition(db),
Self::Divergent(_) => Type::SpecialForm(SpecialFormType::Divergent).definition(db),
Self::Dynamic(
DynamicType::Todo(_)
| DynamicType::TodoUnpack
| DynamicType::TodoStarredExpression
| DynamicType::TodoTypeVarTuple,
) => Type::SpecialForm(SpecialFormType::Todo).definition(db),
Self::AlwaysTruthy => Type::SpecialForm(SpecialFormType::AlwaysTruthy).definition(db),
Self::AlwaysFalsy => Type::SpecialForm(SpecialFormType::AlwaysFalsy).definition(db),

// These types have no definition
Self::Dynamic(
DynamicType::Todo(_)
| DynamicType::TodoUnpack
| DynamicType::TodoStarredExpression
| DynamicType::TodoTypeVarTuple
| DynamicType::InvalidConcatenateUnknown
| DynamicType::UnspecializedTypeVar,
DynamicType::InvalidConcatenateUnknown | DynamicType::UnspecializedTypeVar,
)
| Self::Callable(_)
| Self::TypeIs(_)
Expand Down
1 change: 1 addition & 0 deletions crates/ty_python_semantic/src/types/class_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ impl<'db> ClassBase<'db> {
| SpecialFormType::CallableTypeOf
| SpecialFormType::RegularCallableTypeOf
| SpecialFormType::Divergent
| SpecialFormType::Todo
| SpecialFormType::AlwaysTruthy
| SpecialFormType::AlwaysFalsy
| SpecialFormType::TypeForm => None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2460,6 +2460,7 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
| SpecialFormType::TypedDict
| SpecialFormType::Unknown
| SpecialFormType::Divergent
| SpecialFormType::Todo
| SpecialFormType::Any
| SpecialFormType::NamedTuple => {
if !self.in_string_annotation() {
Expand Down
13 changes: 12 additions & 1 deletion crates/ty_python_semantic/src/types/special_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum SpecialFormType {
Unknown,
/// The symbol `ty_extensions.Divergent`
Divergent,
/// The symbol `ty_extensions.Todo`
Todo,
/// The symbol `ty_extensions.AlwaysTruthy`
AlwaysTruthy,
/// The symbol `ty_extensions.AlwaysFalsy`
Expand Down Expand Up @@ -162,6 +164,7 @@ impl SpecialFormType {
| Self::RegularCallableTypeOf
| Self::Unknown
| Self::Divergent
| Self::Todo
| Self::AlwaysTruthy
| Self::AlwaysFalsy => KnownClass::SpecialForm,

Expand Down Expand Up @@ -276,6 +279,7 @@ impl SpecialFormType {
Never,
Unknown,
Divergent,
Todo,
AlwaysTruthy,
AlwaysFalsy,
Not,
Expand Down Expand Up @@ -344,6 +348,7 @@ impl SpecialFormType {
SpecialFormType::Union => Self::Union,
SpecialFormType::Unknown => Self::Unknown,
SpecialFormType::Divergent => Self::Divergent,
SpecialFormType::Todo => Self::Todo,
SpecialFormType::Generic => Self::Generic,
SpecialFormType::NamedTuple => Self::NamedTuple,
SpecialFormType::Any => Self::Any,
Expand Down Expand Up @@ -403,6 +408,7 @@ impl SpecialFormType {
SpecialFormTypeBuilder::Union => Self::Union,
SpecialFormTypeBuilder::Unknown => Self::Unknown,
SpecialFormTypeBuilder::Divergent => Self::Divergent,
SpecialFormTypeBuilder::Todo => Self::Todo,
SpecialFormTypeBuilder::Generic => Self::Generic,
SpecialFormTypeBuilder::NamedTuple => Self::NamedTuple,
SpecialFormTypeBuilder::Any => Self::Any,
Expand Down Expand Up @@ -478,6 +484,7 @@ impl SpecialFormType {

Self::Unknown
| Self::Divergent
| Self::Todo
| Self::AlwaysTruthy
| Self::AlwaysFalsy
| Self::Not
Expand Down Expand Up @@ -542,6 +549,7 @@ impl SpecialFormType {
| Self::Never
| Self::Unknown
| Self::Divergent
| Self::Todo
| Self::AlwaysTruthy
| Self::AlwaysFalsy
| Self::Not
Expand Down Expand Up @@ -603,6 +611,7 @@ impl SpecialFormType {
| Self::Union
| Self::Unknown
| Self::Divergent
| Self::Todo
| Self::TypeOf
| Self::Any // can be used in `issubclass()` but not `isinstance()`.
| Self::Unpack => false,
Expand Down Expand Up @@ -644,6 +653,7 @@ impl SpecialFormType {
SpecialFormType::LegacyStdlibAlias(LegacyStdlibAlias::OrderedDict) => "OrderedDict",
SpecialFormType::Unknown => "Unknown",
SpecialFormType::Divergent => "Divergent",
SpecialFormType::Todo => "Todo",
SpecialFormType::AlwaysTruthy => "AlwaysTruthy",
SpecialFormType::AlwaysFalsy => "AlwaysFalsy",
SpecialFormType::Not => "Not",
Expand Down Expand Up @@ -694,6 +704,7 @@ impl SpecialFormType {

SpecialFormType::Unknown
| SpecialFormType::Divergent
| SpecialFormType::Todo
| SpecialFormType::AlwaysTruthy
| SpecialFormType::AlwaysFalsy
| SpecialFormType::Not
Expand Down Expand Up @@ -739,7 +750,7 @@ impl SpecialFormType {
Self::LiteralString => Ok(Type::literal_string()),
Self::Any => Ok(Type::any()),
Self::Unknown => Ok(Type::unknown()),
Self::Divergent => Err(InvalidTypeExpression::InvalidType(
Self::Divergent | Self::Todo => Err(InvalidTypeExpression::InvalidType(
Type::SpecialForm(self),
scope_id,
)),
Expand Down
13 changes: 13 additions & 0 deletions crates/ty_vendored/ty_extensions/ty_extensions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ fallback after certain type errors. This contrasts with `Any`, which represents
annotated dynamic type. Like `Any`, however, it is a dynamic type, so ty allows any operation on it.
"""

Todo: _SpecialForm
"""
`@Todo` is a dynamic type inferred due to a known missing feature or incomplete implementation in
ty.

Like `Any` and `Unknown`, `@Todo` is a dynamic type, so ty allows any operation on it. Unlike `Any`,
it is not explicitly provided in an annotation; unlike `Unknown`, it specifically indicates a
limitation in ty.

It is an internal type used by ty and cannot be used in annotations. These types should disappear
as ty implements the missing functionality.
"""

Divergent: _SpecialForm
"""
`Divergent` is a dynamic type inferred due to type-level recursion that does not converge.
Expand Down
Loading