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
22 changes: 2 additions & 20 deletions crates/ty_ide/src/goto_type_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,26 +308,8 @@ mod tests {
"#,
);

assert_snapshot!(test.goto_type_definition(), @r#"
info[goto-type-definition]: Type definition
--> main.py:4:1
|
2 | from typing_extensions import TypeAliasType
3 |
4 | Alias = TypeAliasType("Alias", tuple[int, int])
| ^^^^^
5 |
6 | Alias
|
info: Source
--> main.py:6:1
|
4 | Alias = TypeAliasType("Alias", tuple[int, int])
5 |
6 | Alias
| ^^^^^
|
"#);
// TODO: This should jump to the definition of `Alias` above.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create an issue for this. It's otherwise hard to remember

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it will be hard to remember, because I have to fix it in order to fix the cases in astral-sh/ty#256 related to TypeAliasType. So in that sense we already have an issue that ensures we won't forget it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(And I plan to do this PR next.)

assert_snapshot!(test.goto_type_definition(), @"No type definitions found");
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Legacy typevar creation diagnostics

The full tests for these features are in `generics/legacy/variables.md`.

<!-- snapshot-diagnostics -->

## Must have a name

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar()
```

## Name can't be given more than once

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", name="T")
```

## Must be directly assigned to a variable

> A `TypeVar()` expression must always directly be assigned to a variable (it should not be used as
> part of a larger expression).

```py
from typing import TypeVar

T = TypeVar("T")
# error: [invalid-legacy-type-variable]
U: TypeVar = TypeVar("U")

# error: [invalid-legacy-type-variable]
tuple_with_typevar = ("foo", TypeVar("W"))
```

## `TypeVar` parameter must match variable name

> The argument to `TypeVar()` must be a string equal to the variable name to which it is assigned.

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("Q")
```

## No variadic arguments

```py
from typing import TypeVar

types = (int, str)

# error: [invalid-legacy-type-variable]
T = TypeVar("T", *types)

# error: [invalid-legacy-type-variable]
S = TypeVar("S", **{"bound": int})
```

## Cannot have only one constraint

> `TypeVar` supports constraining parametric types to a fixed set of possible types...There should
> be at least two constraints, if any; specifying a single constraint is disallowed.

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", int)
```

## Cannot have both bound and constraint

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", int, str, bound=bytes)
```

## Cannot be both covariant and contravariant

> To facilitate the declaration of container types where covariant or contravariant type checking is
> acceptable, type variables accept keyword arguments `covariant=True` or `contravariant=True`. At
> most one of these may be passed.

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", covariant=True, contravariant=True)
```

## Boolean parameters must be unambiguous

```py
from typing_extensions import TypeVar

def cond() -> bool:
return True

# error: [invalid-legacy-type-variable]
T = TypeVar("T", covariant=cond())

# error: [invalid-legacy-type-variable]
U = TypeVar("U", contravariant=cond())

# error: [invalid-legacy-type-variable]
V = TypeVar("V", infer_variance=cond())
```

## Invalid keyword arguments

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", invalid_keyword=True)
```

## Invalid feature for this Python version

```toml
[environment]
python-version = "3.10"
```

```py
from typing import TypeVar

# error: [invalid-legacy-type-variable]
T = TypeVar("T", default=int)
```
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ reveal_type(generic_context(ExplicitInheritedGenericPartiallySpecializedExtraTyp
The type parameter can be specified explicitly:

```py
from typing import Generic, Literal, TypeVar
from typing_extensions import Generic, Literal, TypeVar

T = TypeVar("T")

Expand Down Expand Up @@ -195,7 +195,7 @@ reveal_type(WithDefault[str]()) # revealed: WithDefault[str, int]
We can infer the type parameter from a type context:

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand Down Expand Up @@ -240,7 +240,7 @@ consistent with each other.
### `__new__` only

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -257,7 +257,7 @@ wrong_innards: C[int] = C("five")
### `__init__` only

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -273,7 +273,7 @@ wrong_innards: C[int] = C("five")
### Identical `__new__` and `__init__` signatures

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -292,7 +292,7 @@ wrong_innards: C[int] = C("five")
### Compatible `__new__` and `__init__` signatures

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand Down Expand Up @@ -325,7 +325,7 @@ If either method comes from a generic base class, we don't currently use its inf
to specialize the class.

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand All @@ -344,7 +344,7 @@ reveal_type(D(1)) # revealed: D[int]
### Generic class inherits `__init__` from generic base class

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand All @@ -364,7 +364,7 @@ reveal_type(D(1, "str")) # revealed: D[int, str]
This is a specific example of the above, since it was reported specifically by a user.

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand All @@ -382,7 +382,7 @@ for `tuple`, so we use a different mechanism to make sure it has the right inher
context. But from the user's point of view, this is another example of the above.)

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand All @@ -403,7 +403,7 @@ python-version = "3.11"
```

```py
from typing import TypeVar, Sequence, Never
from typing_extensions import TypeVar, Sequence, Never

T = TypeVar("T")

Expand All @@ -421,7 +421,7 @@ def func8(t1: tuple[complex, list[int]], t2: tuple[int, *tuple[str, ...]], t3: t
### `__init__` is itself generic

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

S = TypeVar("S")
T = TypeVar("T")
Expand All @@ -440,7 +440,7 @@ wrong_innards: C[int] = C("five", 1)
### Some `__init__` overloads only apply to certain specializations

```py
from typing import overload, Generic, TypeVar
from typing_extensions import overload, Generic, TypeVar

T = TypeVar("T")

Expand Down Expand Up @@ -480,7 +480,7 @@ C[None](12)

```py
from dataclasses import dataclass
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -494,7 +494,7 @@ reveal_type(A(x=1)) # revealed: A[int]
### Class typevar has another typevar as a default

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U", default=T)
Expand All @@ -515,7 +515,7 @@ When a generic subclass fills its superclass's type parameter with one of its ow
propagate through:

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand Down Expand Up @@ -549,7 +549,7 @@ scope for the method.

```py
from ty_extensions import generic_context
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")
U = TypeVar("U")
Expand Down Expand Up @@ -581,7 +581,7 @@ In a specialized generic alias, the specialization is applied to the attributes
class.

```py
from typing import Generic, TypeVar, Protocol
from typing_extensions import Generic, TypeVar, Protocol

T = TypeVar("T")
U = TypeVar("U")
Expand Down Expand Up @@ -639,7 +639,7 @@ reveal_type(d.method3().x) # revealed: int
When a method is overloaded, the specialization is applied to all overloads.

```py
from typing import overload, Generic, TypeVar
from typing_extensions import overload, Generic, TypeVar

S = TypeVar("S")

Expand Down Expand Up @@ -667,7 +667,7 @@ A class can use itself as the type parameter of one of its superclasses. (This i
Here, `Sub` is not a generic class, since it fills its superclass's type parameter (with itself).

```pyi
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -682,7 +682,7 @@ reveal_type(Sub) # revealed: <class 'Sub'>
A similar case can work in a non-stub file, if forward references are stringified:

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -697,7 +697,7 @@ reveal_type(Sub) # revealed: <class 'Sub'>
In a non-stub file, without stringified forward references, this raises a `NameError`:

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -710,7 +710,7 @@ class Sub(Base[Sub]): ...
### Cyclic inheritance as a generic parameter

```pyi
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand All @@ -722,7 +722,7 @@ class Derived(list[Derived[T]], Generic[T]): ...
Inheritance that would result in a cyclic MRO is detected as an error.

```py
from typing import Generic, TypeVar
from typing_extensions import Generic, TypeVar

T = TypeVar("T")

Expand Down
Loading
Loading