Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpret type annotations as type[Any] annotations #16366

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a430c12
Interpret `type` annotations as `type[Any]` annotations.
tyralla Oct 29, 2023
56fb2bd
Replace `type` with `type[object]` in Mypy's code.
tyralla Nov 13, 2023
fe0cd0a
Find other places where `analyze_annotation` should eventually be set…
tyralla Nov 15, 2023
28ee26b
* Rename `analyze_annotation` to `builtin_type_is_type_type` and mak…
tyralla Nov 21, 2023
84d06cb
Merge branch 'master' into fix/narrow_type_vs_Type
tyralla Nov 21, 2023
dcf1f95
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 21, 2023
b1bb26c
small fixes
tyralla Nov 21, 2023
339f0b9
Merge branch 'fix/narrow_type_vs_Type' of https://github.com/tyralla/…
tyralla Nov 21, 2023
80a8c67
minor fixes after review
tyralla Nov 21, 2023
ab7322c
Add type[ignore] to tuple.pyi to satisfy testDisallowAnyExplicitGener…
tyralla Nov 21, 2023
aa0cd97
Add error codes to the type: ignores in tuple.pyi (and tuple.pyi) to …
tyralla Nov 21, 2023
dcd12ba
Consider TypeType as hashable if (if no metaclass sets __hash__ to None)
tyralla Nov 24, 2023
e25f8e8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 24, 2023
ed0f652
Look for __hash__ instead of checking the name of the potential Hashable
tyralla Nov 24, 2023
a46e5d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 24, 2023
721465a
Merge branch 'master' into fix/narrow_type_vs_Type
tyralla Nov 26, 2023
7d1d3f2
Add another `TypeVar`-related test to `testBuiltinTypeType`.
tyralla Nov 26, 2023
7107fb8
Add more test cases to `testBuiltinTypeType`.
tyralla Nov 27, 2023
3858928
Check more thoroughly if the `Protocol` is `Hashable`-like.
tyralla Nov 27, 2023
a09c6e2
Check more thoroughly if the signatures agree.
tyralla Nov 27, 2023
1a2202f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 27, 2023
4330ea0
remove unused local symtab variable
tyralla Dec 11, 2023
d6e4338
Merge remote-tracking branch 'upstream/master' into fix/narrow_type_v…
hauntsaninja Nov 3, 2024
c7dbe6a
fix merge
hauntsaninja Nov 3, 2024
5a3e028
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 3, 2024
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
2 changes: 1 addition & 1 deletion mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def __init__(
self.type_ignores: dict[int, list[str]] = {}

# Cache of visit_X methods keyed by type of visited object
self.visitor_cache: dict[type, Callable[[AST | None], Any]] = {}
self.visitor_cache: dict[type[object], Callable[[AST | None], Any]] = {}

def note(self, msg: str, line: int, column: int) -> None:
self.errors.report(line, column, msg, severity="note", code=codes.SYNTAX)
Expand Down
2 changes: 1 addition & 1 deletion mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2068,7 +2068,7 @@ def report_protocol_problems(
# note: method, attr
MAX_ITEMS = 2 # Maximum number of conflicts, missing members, and overloads shown
# List of special situations where we don't want to report additional problems
exclusions: dict[type, list[str]] = {
exclusions: dict[type[object], list[str]] = {
TypedDictType: ["typing.Mapping"],
TupleType: ["typing.Iterable", "typing.Sequence"],
}
Expand Down
8 changes: 7 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3384,7 +3384,9 @@ def process_type_annotation(self, s: AssignmentStmt) -> None:
if s.type:
lvalue = s.lvalues[-1]
allow_tuple_literal = isinstance(lvalue, TupleExpr)
analyzed = self.anal_type(s.type, allow_tuple_literal=allow_tuple_literal)
analyzed = self.anal_type(
s.type, allow_tuple_literal=allow_tuple_literal, analyze_annotation=True
)
# Don't store not ready types (including placeholders).
if analyzed is None or has_placeholder(analyzed):
self.defer(s)
Expand Down Expand Up @@ -6602,6 +6604,7 @@ def type_analyzer(
report_invalid_types: bool = True,
prohibit_self_type: str | None = None,
allow_type_any: bool = False,
analyze_annotation: bool = False,
) -> TypeAnalyser:
if tvar_scope is None:
tvar_scope = self.tvar_scope
Expand All @@ -6620,6 +6623,7 @@ def type_analyzer(
allow_unpack=allow_unpack,
prohibit_self_type=prohibit_self_type,
allow_type_any=allow_type_any,
analyze_annotation=analyze_annotation,
)
tpan.in_dynamic_func = bool(self.function_stack and self.function_stack[-1].is_dynamic())
tpan.global_scope = not self.type and not self.function_stack
Expand All @@ -6644,6 +6648,7 @@ def anal_type(
report_invalid_types: bool = True,
prohibit_self_type: str | None = None,
allow_type_any: bool = False,
analyze_annotation: bool = False,
third_pass: bool = False,
) -> Type | None:
"""Semantically analyze a type.
Expand Down Expand Up @@ -6682,6 +6687,7 @@ def anal_type(
report_invalid_types=report_invalid_types,
prohibit_self_type=prohibit_self_type,
allow_type_any=allow_type_any,
analyze_annotation=analyze_annotation,
)
tag = self.track_incomplete_refs()
typ = typ.accept(a)
Expand Down
2 changes: 1 addition & 1 deletion mypy/stubgenc.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ def get_base_types(self, obj: type) -> list[str]:
# remove the class itself
all_bases = all_bases[1:]
# Remove base classes of other bases as redundant.
bases: list[type] = []
bases: list[type[object]] = []
for base in all_bases:
if not any(issubclass(b, base) for b in bases):
bases.append(base)
Expand Down
6 changes: 5 additions & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ def __init__(
prohibit_self_type: str | None = None,
allowed_alias_tvars: list[TypeVarLikeType] | None = None,
allow_type_any: bool = False,
analyze_annotation: bool = False,
) -> None:
self.api = api
self.fail_func = api.fail
Expand Down Expand Up @@ -246,6 +247,7 @@ def __init__(
self.allow_type_any = allow_type_any
self.allow_type_var_tuple = False
self.allow_unpack = allow_unpack
self.analyze_annotation = analyze_annotation

def lookup_qualified(
self, name: str, ctx: Context, suppress_errors: bool = False
Expand Down Expand Up @@ -588,7 +590,9 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ
and (self.always_allow_new_syntax or self.options.python_version >= (3, 9))
):
if len(t.args) == 0:
if fullname == "typing.Type":
if fullname == "typing.Type" or (
self.analyze_annotation and (fullname == "builtins.type")
):
any_type = self.get_omitted_any(t)
return TypeType(any_type, line=t.line, column=t.column)
else:
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-generic-alias.test
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ reveal_type(t6) # N: Revealed type is "Tuple[builtins.int, builtins.str]"
reveal_type(t7) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
reveal_type(t8) # N: Revealed type is "builtins.dict[Any, Any]"
reveal_type(t9) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]"
reveal_type(t10) # N: Revealed type is "builtins.type"
reveal_type(t10) # N: Revealed type is "Type[Any]"
reveal_type(t11) # N: Revealed type is "Type[builtins.int]"
[builtins fixtures/dict.pyi]

Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-lowercase.test
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ x = 3 # E: Incompatible types in assignment (expression has type "int", variabl

[case testTypeLowercaseSettingOff]
# flags: --python-version 3.9 --no-force-uppercase-builtins
x: type[type]
x: type[type] # E: Type[...] can't contain another Type[...]
y: int

y = x # E: Incompatible types in assignment (expression has type "type[type]", variable has type "int")
y = x # E: Incompatible types in assignment (expression has type "type[Any]", variable has type "int")
33 changes: 32 additions & 1 deletion test-data/unit/check-narrowing.test
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,37 @@ else:
reveal_type(y["model"]) # N: Revealed type is "Union[TypedDict('__main__.Model1', {'key': Literal['A']}), TypedDict('__main__.Model2', {'key': Literal['B']})]"
[builtins fixtures/primitives.pyi]

[case testNarrowingTypingTypeTypeAndBuiltinTypeTypeExplicitAny]
# flags: --python-version 3.9 --warn-unreachable --disallow-any-generics

from typing import Any, Type

t1: Type[Any]
t2: type[Any]

class C: ...

if isinstance(t1, C):
reveal_type(t1) # E: Statement is unreachable
if isinstance(t2, C):
reveal_type(t2) # E: Statement is unreachable
[builtins fixtures/isinstance.pyi]

[case testNarrowingTypingTypeTypeAndBuiltinTypeTypeImplicitAny]
# flags: --python-version 3.9 --warn-unreachable --disallow-any-generics

from typing import Type

t1: Type # E: Missing type parameters for generic type "Type"
t2: type # E: Missing type parameters for generic type "type"
class C: ...

if isinstance(t1, C):
reveal_type(t1) # E: Statement is unreachable
if isinstance(t2, C):
reveal_type(t2) # E: Statement is unreachable
[builtins fixtures/isinstance.pyi]

[case testNarrowingExprPropagation]
from typing import Union
from typing_extensions import Literal
Expand Down Expand Up @@ -1330,7 +1361,7 @@ else:

raw: tuple[type, ...]
if isinstance(some, raw):
reveal_type(some) # N: Revealed type is "Union[builtins.int, __main__.Base]"
reveal_type(some) # N: Revealed type is "Any"
else:
reveal_type(some) # N: Revealed type is "Union[builtins.int, __main__.Base]"
[builtins fixtures/dict.pyi]
Expand Down