Skip to content

Commit d5b168e

Browse files
committed
TypeStrVisitor: show narrowed upper bound
1 parent cc3714b commit d5b168e

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

mypy/checker.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6864,7 +6864,10 @@ def conditional_types(
68646864
]
68656865
)
68666866
if isinstance(current_type, TypeVarType):
6867-
proposed_type = current_type.copy_modified(upper_bound=proposed_type)
6867+
assert not current_type.values # constrained TypeVars should not reach here
6868+
proposed_type = current_type.copy_modified(
6869+
values=[], upper_bound=proposed_type, narrowed=True
6870+
)
68686871
remaining_type = restrict_subtype_away(current_type, proposed_precise_type)
68696872
return proposed_type, remaining_type
68706873
else:

mypy/types.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ def has_default(self) -> bool:
576576
class TypeVarType(TypeVarLikeType):
577577
"""Type that refers to a type variable."""
578578

579-
__slots__ = ("values", "variance")
579+
__slots__ = ("values", "variance", "narrowed")
580580

581581
values: list[Type] # Value restriction, empty list if no restriction
582582
variance: int
@@ -592,11 +592,14 @@ def __init__(
592592
variance: int = INVARIANT,
593593
line: int = -1,
594594
column: int = -1,
595+
*,
596+
narrowed: bool = False,
595597
) -> None:
596598
super().__init__(name, fullname, id, upper_bound, default, line, column)
597599
assert values is not None, "No restrictions must be represented by empty list"
598600
self.values = values
599601
self.variance = variance
602+
self.narrowed = narrowed
600603

601604
def copy_modified(
602605
self,
@@ -607,6 +610,7 @@ def copy_modified(
607610
id: Bogus[TypeVarId | int] = _dummy,
608611
line: int = _dummy_int,
609612
column: int = _dummy_int,
613+
narrowed: Bogus[bool] = _dummy,
610614
**kwargs: Any,
611615
) -> TypeVarType:
612616
return TypeVarType(
@@ -619,6 +623,7 @@ def copy_modified(
619623
variance=self.variance,
620624
line=self.line if line == _dummy_int else line,
621625
column=self.column if column == _dummy_int else column,
626+
narrowed=self.narrowed if narrowed is _dummy else narrowed,
622627
)
623628

624629
def accept(self, visitor: TypeVisitor[T]) -> T:
@@ -3047,7 +3052,7 @@ def visit_type_var(self, t: TypeVarType) -> str:
30473052
else:
30483053
# Named type variable type.
30493054
s = f"{t.name}`{t.id}"
3050-
if self.id_mapper and t.upper_bound:
3055+
if (self.id_mapper or t.narrowed) and t.upper_bound:
30513056
s += f"(upper_bound={t.upper_bound.accept(self)})"
30523057
return s
30533058

test-data/unit/check-isinstance.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1829,7 +1829,7 @@ T = TypeVar('T', bound=A)
18291829

18301830
def f(x: T) -> None:
18311831
if isinstance(x, B):
1832-
reveal_type(x) # N: Revealed type is "T`-1"
1832+
reveal_type(x) # N: Revealed type is "T`-1(upper_bound=__main__.B)"
18331833
x1: T = x
18341834
a: A = x
18351835
b: B = x

0 commit comments

Comments
 (0)