Skip to content

Commit 5dfcdb0

Browse files
committed
Narrowing for comparisons against x.__class__
1 parent 21d6773 commit 5dfcdb0

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎mypy/checker.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6734,6 +6734,8 @@ def narrow_type_by_identity_equality(
67346734
and len(type_expr.args) == 1
67356735
):
67366736
expr_in_type_expr = type_expr.args[0]
6737+
elif isinstance(type_expr, MemberExpr) and type_expr.name == "__class__":
6738+
expr_in_type_expr = type_expr.expr
67376739
else:
67386740
continue
67396741
for j in expr_indices:

‎test-data/unit/check-narrowing.test‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3076,3 +3076,31 @@ if type(x) is not C:
30763076
reveal_type(x) # N: Revealed type is "__main__.D"
30773077
else:
30783078
reveal_type(x) # N: Revealed type is "__main__.C"
3079+
3080+
[case testDunderClassNarrowing]
3081+
# flags: --warn-unreachable
3082+
from typing import Any
3083+
3084+
def foo(y: object):
3085+
if y.__class__ == int:
3086+
reveal_type(y) # N: Revealed type is "builtins.int"
3087+
else:
3088+
reveal_type(y) # N: Revealed type is "builtins.object"
3089+
3090+
if y.__class__ is int:
3091+
reveal_type(y) # N: Revealed type is "builtins.int"
3092+
else:
3093+
reveal_type(y) # N: Revealed type is "builtins.object"
3094+
3095+
3096+
def bar(y: Any):
3097+
if y.__class__ == int:
3098+
reveal_type(y) # N: Revealed type is "Any"
3099+
else:
3100+
reveal_type(y) # N: Revealed type is "Any"
3101+
3102+
if y.__class__ is int:
3103+
reveal_type(y) # N: Revealed type is "builtins.int"
3104+
else:
3105+
reveal_type(y) # N: Revealed type is "Any"
3106+
[builtins fixtures/dict-full.pyi]

‎test-data/unit/fixtures/dict-full.pyi‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ KT = TypeVar('KT')
1313
VT = TypeVar('VT')
1414

1515
class object:
16+
__class__: object
1617
def __init__(self) -> None: pass
1718
def __init_subclass__(cls) -> None: pass
1819
def __eq__(self, other: object) -> bool: pass
@@ -75,8 +76,7 @@ class float: pass
7576
class complex: pass
7677
class bool(int): pass
7778

78-
class ellipsis:
79-
__class__: object
79+
class ellipsis: pass
8080
def isinstance(x: object, t: Union[type, Tuple[type, ...]]) -> bool: pass
8181
class BaseException: pass
8282

0 commit comments

Comments
 (0)