Skip to content

Commit

Permalink
Changed tuple expression inference behavior to not preserve literal e…
Browse files Browse the repository at this point in the history
…ntry types if the tuple expression is embedded within another tuple, set, list, or dictionary expression. This addresses #7159.
  • Loading branch information
erictraut committed May 21, 2024
1 parent 4a8b2db commit 4ab8a98
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 37 deletions.
11 changes: 9 additions & 2 deletions docs/type-inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,11 @@ var1 = [4]
When inferring the type of a tuple expression (in the absence of bidirectional inference hints), Pyright assumes that the tuple has a fixed length, and each tuple element is typed as specifically as possible.

```python
# The inferred type is tuple[Literal[1], Literal["a"], Literal[True]]
# The inferred type is tuple[Literal[1], Literal["a"], Literal[True]].
var1 = (1, "a", True)

def func1(a: int):
# The inferred type is tuple[int, int]
# The inferred type is tuple[int, int].
var2 = (a, a)

# If you want the type to be tuple[int, ...]
Expand All @@ -274,6 +274,13 @@ def func1(a: int):
var3: tuple[int, ...] = (a, a)
```

Because tuples are typed as specifically as possible, literal types are normally retained. However, as an exception to this inference rule, if the tuple expression is nested within another tuple, set, list or dictionary expression, literal types are not retained. This is done to avoid the inference of complex types (e.g. unions with many subtypes) when evaluating tuple statements with many entries.

```python
# The inferred type is list[tuple[int, str, bool]].
var4 = [(1, "a", True), (2, "b", False), (3, "c", False)]
```

#### List Expressions

When inferring the type of a list expression (in the absence of bidirectional inference hints), Pyright uses the following heuristics:
Expand Down
Loading

0 comments on commit 4ab8a98

Please sign in to comment.