Skip to content

Commit fde3a0c

Browse files
dmoissetJukkaL
authored andcommitted
Handle member access on Type[Any], fix #3098 (#3246)
* Handle member access on Type[Any], fix #3098 * Add test on member assignment * Fallback to builtin.type attributes if possible when accessing members of Type[Any] * Add type.pyi fixture to make test pass
1 parent 84ebd45 commit fde3a0c

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

mypy/checkmember.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ def analyze_member_access(name: str,
176176
item = None
177177
if isinstance(typ.item, Instance):
178178
item = typ.item
179+
elif isinstance(typ.item, AnyType):
180+
fallback = builtin_type('builtins.type')
181+
ignore_messages = msg.copy()
182+
ignore_messages.disable_errors()
183+
return analyze_member_access(name, fallback, node, is_lvalue, is_super,
184+
is_operator, builtin_type, not_ready_callback,
185+
ignore_messages, original_type=original_type, chk=chk)
179186
elif isinstance(typ.item, TypeVarType):
180187
if isinstance(typ.item.upper_bound, Instance):
181188
item = typ.item.upper_bound

test-data/unit/check-classes.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,25 @@ class X: pass
20512051
foo(X)
20522052
[out]
20532053

2054+
[case testTypeUsingTypeCTypeAnyMember]
2055+
from typing import Type, Any
2056+
def foo(arg: Type[Any]):
2057+
x = arg.member_name
2058+
arg.new_member_name = 42
2059+
# Member access is ok and types as Any
2060+
reveal_type(x) # E: Revealed type is 'Any'
2061+
# But Type[Any] is distinct from Any
2062+
y: int = arg # E: Incompatible types in assignment (expression has type Type[Any], variable has type "int")
2063+
[out]
2064+
2065+
[case testTypeUsingTypeCTypeAnyMemberFallback]
2066+
from typing import Type, Any
2067+
def foo(arg: Type[Any]):
2068+
reveal_type(arg.__str__) # E: Revealed type is 'def () -> builtins.str'
2069+
reveal_type(arg.mro()) # E: Revealed type is 'builtins.list[builtins.type]'
2070+
[builtins fixtures/type.pyi]
2071+
[out]
2072+
20542073
[case testTypeUsingTypeCTypeNoArg]
20552074
from typing import Type
20562075
def foo(arg: Type):

test-data/unit/fixtures/type.pyi

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# builtins stub used in type-related test cases.
2+
3+
from typing import builtinclass, Generic, TypeVar, List
4+
5+
T = TypeVar('T')
6+
7+
@builtinclass
8+
class object:
9+
def __init__(self) -> None: pass
10+
def __str__(self) -> 'str': pass
11+
12+
class list(Generic[T]): pass
13+
14+
class type:
15+
def mro(self) -> List['type']: pass
16+
17+
class tuple: pass
18+
class function: pass
19+
class bool: pass
20+
class int: pass
21+
class str: pass
22+
class unicode: pass

typeshed

Submodule typeshed updated 133 files

0 commit comments

Comments
 (0)