1"""Semantic analysis of types""" 2 3import itertools 4from itertools import chain 5from contextlib import contextmanager 6from mypy.ordered_dict import OrderedDict 7 8from typing import Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable, Sequence 9from typing_extensions import Final 10from mypy_extensions import DefaultNamedArg 11 12from mypy.messages import MessageBuilder, quote_type_string, format_type_bare 13from mypy.options import Options 14from mypy.types import ( 15 Type, UnboundType, TypeVarType, TupleType, TypedDictType, UnionType, Instance, AnyType, 16 CallableType, NoneType, ErasedType, DeletedType, TypeList, TypeVarDef, SyntheticTypeVisitor, 17 StarType, PartialType, EllipsisType, UninhabitedType, TypeType, TypeGuardType, 18 CallableArgument, TypeQuery, union_items, TypeOfAny, LiteralType, RawExpressionType, 19 PlaceholderType, Overloaded, get_proper_type, TypeAliasType, TypeVarLikeDef, ParamSpecDef 20) 21 22from mypy.nodes import ( 23 TypeInfo, Context, SymbolTableNode, Var, Expression, 24 get_nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED, 25 ARG_OPT, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, TypeVarExpr, TypeVarLikeExpr, ParamSpecExpr, 26 TypeAlias, PlaceholderNode, SYMBOL_FUNCBASE_TYPES, Decorator, MypyFile 27) 28from mypy.typetraverser import TypeTraverserVisitor 29from mypy.tvar_scope import TypeVarLikeScope 30from mypy.exprtotype import expr_to_unanalyzed_type, TypeTranslationError 31from mypy.plugin import Plugin, TypeAnalyzerPluginInterface, AnalyzeTypeContext 32from mypy.semanal_shared import SemanticAnalyzerCoreInterface 33from mypy.errorcodes import ErrorCode 34from mypy import nodes, message_registry, errorcodes as codes 35 36T = TypeVar('T') 37 38type_constructors = { 39 'typing.Callable', 40 'typing.Optional', 41 'typing.Tuple', 42 'typing.Type', 43 'typing.Union', 44 'typing.Literal', 45 'typing_extensions.Literal', 46 'typing.Annotated', 47 'typing_extensions.Annotated', 48} # type: Final 49 50ARG_KINDS_BY_CONSTRUCTOR = { 51 'mypy_extensions.Arg': ARG_POS, 52 'mypy_extensions.DefaultArg': ARG_OPT, 53 'mypy_extensions.NamedArg': ARG_NAMED, 54 'mypy_extensions.DefaultNamedArg': ARG_NAMED_OPT, 55 'mypy_extensions.VarArg': ARG_STAR, 56 'mypy_extensions.KwArg': ARG_STAR2, 57} # type: Final 58 59GENERIC_STUB_NOT_AT_RUNTIME_TYPES = { 60 'queue.Queue', 61 'builtins._PathLike', 62 'asyncio.futures.Future', 63} # type: Final 64 65 66def analyze_type_alias(node: Expression, 67 api: SemanticAnalyzerCoreInterface, 68 tvar_scope: TypeVarLikeScope, 69 plugin: Plugin, 70 options: Options, 71 is_typeshed_stub: bool, 72 allow_unnormalized: bool = False, 73 allow_placeholder: bool = False, 74 in_dynamic_func: bool = False, 75 global_scope: bool = True) -> Optional[Tuple[Type, Set[str]]]: 76 """Analyze r.h.s. of a (potential) type alias definition. 77 78 If `node` is valid as a type alias rvalue, return the resulting type and a set of 79 full names of type aliases it depends on (directly or indirectly). 80 Return None otherwise. 'node' must have been semantically analyzed. 81 """ 82 try: 83 type = expr_to_unanalyzed_type(node) 84 except TypeTranslationError: 85 api.fail('Invalid type alias: expression is not a valid type', node) 86 return None 87 analyzer = TypeAnalyser(api, tvar_scope, plugin, options, is_typeshed_stub, 88 allow_unnormalized=allow_unnormalized, defining_alias=True, 89 allow_placeholder=allow_placeholder) 90 analyzer.in_dynamic_func = in_dynamic_func 91 analyzer.global_scope = global_scope 92 res = type.accept(analyzer) 93 return res, analyzer.aliases_used 94 95 96def no_subscript_builtin_alias(name: str, propose_alt: bool = True) -> str: 97 msg = '"{}" is not subscriptable'.format(name.split('.')[-1]) 98 # This should never be called if the python_version is 3.9 or newer 99 nongen_builtins = get_nongen_builtins((3, 8)) 100 replacement = nongen_builtins[name] 101 if replacement and propose_alt: 102 msg += ', use "{}" instead'.format(replacement) 103 return msg 104 105 106class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface): 107 """Semantic analyzer for types. 108 109 Converts unbound types into bound types. This is a no-op for already 110 bound types. 111 112 If an incomplete reference is encountered, this does a defer. The 113 caller never needs to defer. 114 """ 115 116 # Is this called from an untyped function definition? 117 in_dynamic_func = False # type: bool 118 # Is this called from global scope? 119 global_scope = True # type: bool 120 121 def __init__(self, 122 api: SemanticAnalyzerCoreInterface, 123 tvar_scope: TypeVarLikeScope, 124 plugin: Plugin, 125 options: Options, 126 is_typeshed_stub: bool, *, 127 defining_alias: bool = False, 128 allow_tuple_literal: bool = False, 129 allow_unnormalized: bool = False, 130 allow_unbound_tvars: bool = False, 131 allow_placeholder: bool = False, 132 report_invalid_types: bool = True) -> None: 133 self.api = api 134 self.lookup_qualified = api.lookup_qualified 135 self.lookup_fqn_func = api.lookup_fully_qualified 136 self.fail_func = api.fail 137 self.note_func = api.note 138 self.tvar_scope = tvar_scope 139 # Are we analysing a type alias definition rvalue? 140 self.defining_alias = defining_alias 141 self.allow_tuple_literal = allow_tuple_literal 142 # Positive if we are analyzing arguments of another (outer) type 143 self.nesting_level = 0 144 # Should we allow unnormalized types like `list[int]` 145 # (currently allowed in stubs)? 146 self.allow_unnormalized = allow_unnormalized 147 # Should we accept unbound type variables (always OK in aliases)? 148 self.allow_unbound_tvars = allow_unbound_tvars or defining_alias 149 # If false, record incomplete ref if we generate PlaceholderType. 150 self.allow_placeholder = allow_placeholder 151 # Should we report an error whenever we encounter a RawExpressionType outside 152 # of a Literal context: e.g. whenever we encounter an invalid type? Normally, 153 # we want to report an error, but the caller may want to do more specialized 154 # error handling. 155 self.report_invalid_types = report_invalid_types 156 self.plugin = plugin 157 self.options = options 158 self.is_typeshed_stub = is_typeshed_stub 159 # Names of type aliases encountered while analysing a type will be collected here. 160 self.aliases_used = set() # type: Set[str] 161 162 def visit_unbound_type(self, t: UnboundType, defining_literal: bool = False) -> Type: 163 typ = self.visit_unbound_type_nonoptional(t, defining_literal) 164 if t.optional: 165 # We don't need to worry about double-wrapping Optionals or 166 # wrapping Anys: Union simplification will take care of that. 167 return make_optional_type(typ) 168 return typ 169 170 def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) -> Type: 171 sym = self.lookup_qualified(t.name, t) 172 if sym is not None: 173 node = sym.node 174 if isinstance(node, PlaceholderNode): 175 if node.becomes_typeinfo: 176 # Reference to placeholder type. 177 if self.api.final_iteration: 178 self.cannot_resolve_type(t) 179 return AnyType(TypeOfAny.from_error) 180 elif self.allow_placeholder: 181 self.api.defer() 182 else: 183 self.api.record_incomplete_ref() 184 return PlaceholderType(node.fullname, self.anal_array(t.args), t.line) 185 else: 186 if self.api.final_iteration: 187 self.cannot_resolve_type(t) 188 return AnyType(TypeOfAny.from_error) 189 else: 190 # Reference to an unknown placeholder node. 191 self.api.record_incomplete_ref() 192 return AnyType(TypeOfAny.special_form) 193 if node is None: 194 self.fail('Internal error (node is None, kind={})'.format(sym.kind), t) 195 return AnyType(TypeOfAny.special_form) 196 fullname = node.fullname 197 hook = self.plugin.get_type_analyze_hook(fullname) 198 if hook is not None: 199 return hook(AnalyzeTypeContext(t, t, self)) 200 if (fullname in get_nongen_builtins(self.options.python_version) 201 and t.args and 202 not self.allow_unnormalized and 203 not self.api.is_future_flag_set("annotations")): 204 self.fail(no_subscript_builtin_alias(fullname, 205 propose_alt=not self.defining_alias), t) 206 tvar_def = self.tvar_scope.get_binding(sym) 207 if isinstance(sym.node, ParamSpecExpr): 208 if tvar_def is None: 209 self.fail('ParamSpec "{}" is unbound'.format(t.name), t) 210 return AnyType(TypeOfAny.from_error) 211 self.fail('Invalid location for ParamSpec "{}"'.format(t.name), t) 212 self.note( 213 'You can use ParamSpec as the first argument to Callable, e.g., ' 214 "'Callable[{}, int]'".format(t.name), 215 t 216 ) 217 return AnyType(TypeOfAny.from_error) 218 if isinstance(sym.node, TypeVarExpr) and tvar_def is not None and self.defining_alias: 219 self.fail('Can\'t use bound type variable "{}"' 220 ' to define generic alias'.format(t.name), t) 221 return AnyType(TypeOfAny.from_error) 222 if isinstance(sym.node, TypeVarExpr) and tvar_def is not None: 223 assert isinstance(tvar_def, TypeVarDef) 224 if len(t.args) > 0: 225 self.fail('Type variable "{}" used with arguments'.format(t.name), t) 226 return TypeVarType(tvar_def, t.line) 227 special = self.try_analyze_special_unbound_type(t, fullname) 228 if special is not None: 229 return special 230 if isinstance(node, TypeAlias): 231 self.aliases_used.add(fullname) 232 an_args = self.anal_array(t.args) 233 disallow_any = self.options.disallow_any_generics and not self.is_typeshed_stub 234 res = expand_type_alias(node, an_args, self.fail, node.no_args, t, 235 unexpanded_type=t, 236 disallow_any=disallow_any) 237 # The only case where expand_type_alias() can return an incorrect instance is 238 # when it is top-level instance, so no need to recurse. 239 if (isinstance(res, Instance) and # type: ignore[misc] 240 len(res.args) != len(res.type.type_vars) and 241 not self.defining_alias): 242 fix_instance( 243 res, 244 self.fail, 245 self.note, 246 disallow_any=disallow_any, 247 python_version=self.options.python_version, 248 use_generic_error=True, 249 unexpanded_type=t) 250 if node.eager: 251 # TODO: Generate error if recursive (once we have recursive types) 252 res = get_proper_type(res) 253 return res 254 elif isinstance(node, TypeInfo): 255 return self.analyze_type_with_type_info(node, t.args, t) 256 else: 257 return self.analyze_unbound_type_without_type_info(t, sym, defining_literal) 258 else: # sym is None 259 return AnyType(TypeOfAny.special_form) 260 261 def cannot_resolve_type(self, t: UnboundType) -> None: 262 # TODO: Move error message generation to messages.py. We'd first 263 # need access to MessageBuilder here. Also move the similar 264 # message generation logic in semanal.py. 265 self.api.fail( 266 'Cannot resolve name "{}" (possible cyclic definition)'.format(t.name), 267 t) 268 269 def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Optional[Type]: 270 """Bind special type that is recognized through magic name such as 'typing.Any'. 271 272 Return the bound type if successful, and return None if the type is a normal type. 273 """ 274 if fullname == 'builtins.None': 275 return NoneType() 276 elif fullname == 'typing.Any' or fullname == 'builtins.Any': 277 return AnyType(TypeOfAny.explicit) 278 elif fullname in ('typing.Final', 'typing_extensions.Final'): 279 self.fail("Final can be only used as an outermost qualifier" 280 " in a variable annotation", t) 281 return AnyType(TypeOfAny.from_error) 282 elif (fullname == 'typing.Tuple' or 283 (fullname == 'builtins.tuple' and (self.options.python_version >= (3, 9) or 284 self.api.is_future_flag_set('annotations')))): 285 # Tuple is special because it is involved in builtin import cycle 286 # and may be not ready when used. 287 sym = self.api.lookup_fully_qualified_or_none('builtins.tuple') 288 if not sym or isinstance(sym.node, PlaceholderNode): 289 if self.api.is_incomplete_namespace('builtins'): 290 self.api.record_incomplete_ref() 291 else: 292 self.fail('Name "tuple" is not defined', t) 293 return AnyType(TypeOfAny.special_form) 294 if len(t.args) == 0 and not t.empty_tuple_index: 295 # Bare 'Tuple' is same as 'tuple' 296 any_type = self.get_omitted_any(t) 297 return self.named_type('builtins.tuple', [any_type], 298 line=t.line, column=t.column) 299 if len(t.args) == 2 and isinstance(t.args[1], EllipsisType): 300 # Tuple[T, ...] (uniform, variable-length tuple) 301 instance = self.named_type('builtins.tuple', [self.anal_type(t.args[0])]) 302 instance.line = t.line 303 return instance 304 return self.tuple_type(self.anal_array(t.args)) 305 elif fullname == 'typing.Union': 306 items = self.anal_array(t.args) 307 return UnionType.make_union(items) 308 elif fullname == 'typing.Optional': 309 if len(t.args) != 1: 310 self.fail('Optional[...] must have exactly one type argument', t) 311 return AnyType(TypeOfAny.from_error) 312 item = self.anal_type(t.args[0]) 313 return make_optional_type(item) 314 elif fullname == 'typing.Callable': 315 return self.analyze_callable_type(t) 316 elif (fullname == 'typing.Type' or 317 (fullname == 'builtins.type' and (self.options.python_version >= (3, 9) or 318 self.api.is_future_flag_set('annotations')))): 319 if len(t.args) == 0: 320 if fullname == 'typing.Type': 321 any_type = self.get_omitted_any(t) 322 return TypeType(any_type, line=t.line, column=t.column) 323 else: 324 # To prevent assignment of 'builtins.type' inferred as 'builtins.object' 325 # See https://github.com/python/mypy/issues/9476 for more information 326 return None 327 type_str = 'Type[...]' if fullname == 'typing.Type' else 'type[...]' 328 if len(t.args) != 1: 329 self.fail(type_str + ' must have exactly one type argument', t) 330 item = self.anal_type(t.args[0]) 331 return TypeType.make_normalized(item, line=t.line) 332 elif fullname == 'typing.ClassVar': 333 if self.nesting_level > 0: 334 self.fail('Invalid type: ClassVar nested inside other type', t) 335 if len(t.args) == 0: 336 return AnyType(TypeOfAny.from_omitted_generics, line=t.line, column=t.column) 337 if len(t.args) != 1: 338 self.fail('ClassVar[...] must have at most one type argument', t) 339 return AnyType(TypeOfAny.from_error) 340 return self.anal_type(t.args[0]) 341 elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'): 342 return UninhabitedType(is_noreturn=True) 343 elif fullname in ('typing_extensions.Literal', 'typing.Literal'): 344 return self.analyze_literal_type(t) 345 elif fullname in ('typing_extensions.Annotated', 'typing.Annotated'): 346 if len(t.args) < 2: 347 self.fail("Annotated[...] must have exactly one type argument" 348 " and at least one annotation", t) 349 return AnyType(TypeOfAny.from_error) 350 return self.anal_type(t.args[0]) 351 elif self.anal_type_guard_arg(t, fullname) is not None: 352 # In most contexts, TypeGuard[...] acts as an alias for bool (ignoring its args) 353 return self.named_type('builtins.bool') 354 return None 355 356 def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType: 357 disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics 358 return get_omitted_any(disallow_any, self.fail, self.note, typ, 359 self.options.python_version, fullname) 360 361 def analyze_type_with_type_info( 362 self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type: 363 """Bind unbound type when were able to find target TypeInfo. 364 365 This handles simple cases like 'int', 'modname.UserClass[str]', etc. 366 """ 367 368 if len(args) > 0 and info.fullname == 'builtins.tuple': 369 fallback = Instance(info, [AnyType(TypeOfAny.special_form)], ctx.line) 370 return TupleType(self.anal_array(args), fallback, ctx.line) 371 # Analyze arguments and (usually) construct Instance type. The 372 # number of type arguments and their values are 373 # checked only later, since we do not always know the 374 # valid count at this point. Thus we may construct an 375 # Instance with an invalid number of type arguments. 376 instance = Instance(info, self.anal_array(args), ctx.line, ctx.column) 377 # Check type argument count. 378 if len(instance.args) != len(info.type_vars) and not self.defining_alias: 379 fix_instance(instance, self.fail, self.note, 380 disallow_any=self.options.disallow_any_generics and 381 not self.is_typeshed_stub, 382 python_version=self.options.python_version) 383 384 tup = info.tuple_type 385 if tup is not None: 386 # The class has a Tuple[...] base class so it will be 387 # represented as a tuple type. 388 if args: 389 self.fail('Generic tuple types not supported', ctx) 390 return AnyType(TypeOfAny.from_error) 391 return tup.copy_modified(items=self.anal_array(tup.items), 392 fallback=instance) 393 td = info.typeddict_type 394 if td is not None: 395 # The class has a TypedDict[...] base class so it will be 396 # represented as a typeddict type. 397 if args: 398 self.fail('Generic TypedDict types not supported', ctx) 399 return AnyType(TypeOfAny.from_error) 400 # Create a named TypedDictType 401 return td.copy_modified(item_types=self.anal_array(list(td.items.values())), 402 fallback=instance) 403 return instance 404 405 def analyze_unbound_type_without_type_info(self, t: UnboundType, sym: SymbolTableNode, 406 defining_literal: bool) -> Type: 407 """Figure out what an unbound type that doesn't refer to a TypeInfo node means. 408 409 This is something unusual. We try our best to find out what it is. 410 """ 411 name = sym.fullname 412 if name is None: 413 assert sym.node is not None 414 name = sym.node.name 415 # Option 1: 416 # Something with an Any type -- make it an alias for Any in a type 417 # context. This is slightly problematic as it allows using the type 'Any' 418 # as a base class -- however, this will fail soon at runtime so the problem 419 # is pretty minor. 420 if isinstance(sym.node, Var): 421 typ = get_proper_type(sym.node.type) 422 if isinstance(typ, AnyType): 423 return AnyType(TypeOfAny.from_unimported_type, 424 missing_import_name=typ.missing_import_name) 425 # Option 2: 426 # Unbound type variable. Currently these may be still valid, 427 # for example when defining a generic type alias. 428 unbound_tvar = (isinstance(sym.node, TypeVarExpr) and 429 self.tvar_scope.get_binding(sym) is None) 430 if self.allow_unbound_tvars and unbound_tvar: 431 return t 432 433 # Option 3: 434 # Enum value. Note: we only want to return a LiteralType when 435 # we're using this enum value specifically within context of 436 # a "Literal[...]" type. So, if `defining_literal` is not set, 437 # we bail out early with an error. 438 # 439 # If, in the distant future, we decide to permit things like 440 # `def foo(x: Color.RED) -> None: ...`, we can remove that 441 # check entirely. 442 if isinstance(sym.node, Var) and sym.node.info and sym.node.info.is_enum: 443 value = sym.node.name 444 base_enum_short_name = sym.node.info.name 445 if not defining_literal: 446 msg = message_registry.INVALID_TYPE_RAW_ENUM_VALUE.format( 447 base_enum_short_name, value) 448 self.fail(msg, t) 449 return AnyType(TypeOfAny.from_error) 450 return LiteralType( 451 value=value, 452 fallback=Instance(sym.node.info, [], line=t.line, column=t.column), 453 line=t.line, 454 column=t.column, 455 ) 456 457 # None of the above options worked. We parse the args (if there are any) 458 # to make sure there are no remaining semanal-only types, then give up. 459 t = t.copy_modified(args=self.anal_array(t.args)) 460 # TODO: Move this message building logic to messages.py. 461 notes = [] # type: List[str] 462 if isinstance(sym.node, Var): 463 notes.append('See https://mypy.readthedocs.io/en/' 464 'stable/common_issues.html#variables-vs-type-aliases') 465 message = 'Variable "{}" is not valid as a type' 466 elif isinstance(sym.node, (SYMBOL_FUNCBASE_TYPES, Decorator)): 467 message = 'Function "{}" is not valid as a type' 468 notes.append('Perhaps you need "Callable[...]" or a callback protocol?') 469 elif isinstance(sym.node, MypyFile): 470 # TODO: suggest a protocol when supported. 471 message = 'Module "{}" is not valid as a type' 472 elif unbound_tvar: 473 message = 'Type variable "{}" is unbound' 474 short = name.split('.')[-1] 475 notes.append(('(Hint: Use "Generic[{}]" or "Protocol[{}]" base class' 476 ' to bind "{}" inside a class)').format(short, short, short)) 477 notes.append('(Hint: Use "{}" in function signature to bind "{}"' 478 ' inside a function)'.format(short, short)) 479 else: 480 message = 'Cannot interpret reference "{}" as a type' 481 self.fail(message.format(name), t, code=codes.VALID_TYPE) 482 for note in notes: 483 self.note(note, t, code=codes.VALID_TYPE) 484 485 # TODO: Would it be better to always return Any instead of UnboundType 486 # in case of an error? On one hand, UnboundType has a name so error messages 487 # are more detailed, on the other hand, some of them may be bogus, 488 # see https://github.com/python/mypy/issues/4987. 489 return t 490 491 def visit_any(self, t: AnyType) -> Type: 492 return t 493 494 def visit_none_type(self, t: NoneType) -> Type: 495 return t 496 497 def visit_uninhabited_type(self, t: UninhabitedType) -> Type: 498 return t 499 500 def visit_erased_type(self, t: ErasedType) -> Type: 501 # This type should exist only temporarily during type inference 502 assert False, "Internal error: Unexpected erased type" 503 504 def visit_deleted_type(self, t: DeletedType) -> Type: 505 return t 506 507 def visit_type_list(self, t: TypeList) -> Type: 508 self.fail('Bracketed expression "[...]" is not valid as a type', t) 509 self.note('Did you mean "List[...]"?', t) 510 return AnyType(TypeOfAny.from_error) 511 512 def visit_callable_argument(self, t: CallableArgument) -> Type: 513 self.fail('Invalid type', t) 514 return AnyType(TypeOfAny.from_error) 515 516 def visit_instance(self, t: Instance) -> Type: 517 return t 518 519 def visit_type_alias_type(self, t: TypeAliasType) -> Type: 520 # TODO: should we do something here? 521 return t 522 523 def visit_type_var(self, t: TypeVarType) -> Type: 524 return t 525 526 def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type: 527 # Every Callable can bind its own type variables, if they're not in the outer scope 528 with self.tvar_scope_frame(): 529 if self.defining_alias: 530 variables = t.variables 531 else: 532 variables = self.bind_function_type_variables(t, t) 533 special = self.anal_type_guard(t.ret_type) 534 ret = t.copy_modified(arg_types=self.anal_array(t.arg_types, nested=nested), 535 ret_type=self.anal_type(t.ret_type, nested=nested), 536 # If the fallback isn't filled in yet, 537 # its type will be the falsey FakeInfo 538 fallback=(t.fallback if t.fallback.type 539 else self.named_type('builtins.function')), 540 variables=self.anal_var_defs(variables), 541 type_guard=special, 542 ) 543 return ret 544 545 def visit_type_guard_type(self, t: TypeGuardType) -> Type: 546 return t 547 548 def anal_type_guard(self, t: Type) -> Optional[Type]: 549 if isinstance(t, UnboundType): 550 sym = self.lookup_qualified(t.name, t) 551 if sym is not None and sym.node is not None: 552 return self.anal_type_guard_arg(t, sym.node.fullname) 553 # TODO: What if it's an Instance? Then use t.type.fullname? 554 return None 555 556 def anal_type_guard_arg(self, t: UnboundType, fullname: str) -> Optional[Type]: 557 if fullname in ('typing_extensions.TypeGuard', 'typing.TypeGuard'): 558 if len(t.args) != 1: 559 self.fail("TypeGuard must have exactly one type argument", t) 560 return AnyType(TypeOfAny.from_error) 561 return self.anal_type(t.args[0]) 562 return None 563 564 def visit_overloaded(self, t: Overloaded) -> Type: 565 # Overloaded types are manually constructed in semanal.py by analyzing the 566 # AST and combining together the Callable types this visitor converts. 567 # 568 # So if we're ever asked to reanalyze an Overloaded type, we know it's 569 # fine to just return it as-is. 570 return t 571 572 def visit_tuple_type(self, t: TupleType) -> Type: 573 # Types such as (t1, t2, ...) only allowed in assignment statements. They'll 574 # generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead. 575 if t.implicit and not self.allow_tuple_literal: 576 self.fail('Syntax error in type annotation', t, code=codes.SYNTAX) 577 if len(t.items) == 0: 578 self.note('Suggestion: Use Tuple[()] instead of () for an empty tuple, or ' 579 'None for a function without a return value', t, code=codes.SYNTAX) 580 elif len(t.items) == 1: 581 self.note('Suggestion: Is there a spurious trailing comma?', t, code=codes.SYNTAX) 582 else: 583 self.note('Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)', t, 584 code=codes.SYNTAX) 585 return AnyType(TypeOfAny.from_error) 586 star_count = sum(1 for item in t.items if isinstance(item, StarType)) 587 if star_count > 1: 588 self.fail('At most one star type allowed in a tuple', t) 589 if t.implicit: 590 return TupleType([AnyType(TypeOfAny.from_error) for _ in t.items], 591 self.named_type('builtins.tuple'), 592 t.line) 593 else: 594 return AnyType(TypeOfAny.from_error) 595 any_type = AnyType(TypeOfAny.special_form) 596 # If the fallback isn't filled in yet, its type will be the falsey FakeInfo 597 fallback = (t.partial_fallback if t.partial_fallback.type 598 else self.named_type('builtins.tuple', [any_type])) 599 return TupleType(self.anal_array(t.items), fallback, t.line) 600 601 def visit_typeddict_type(self, t: TypedDictType) -> Type: 602 items = OrderedDict([ 603 (item_name, self.anal_type(item_type)) 604 for (item_name, item_type) in t.items.items() 605 ]) 606 return TypedDictType(items, set(t.required_keys), t.fallback) 607 608 def visit_raw_expression_type(self, t: RawExpressionType) -> Type: 609 # We should never see a bare Literal. We synthesize these raw literals 610 # in the earlier stages of semantic analysis, but those 611 # "fake literals" should always be wrapped in an UnboundType 612 # corresponding to 'Literal'. 613 # 614 # Note: if at some point in the distant future, we decide to 615 # make signatures like "foo(x: 20) -> None" legal, we can change 616 # this method so it generates and returns an actual LiteralType 617 # instead. 618 619 if self.report_invalid_types: 620 if t.base_type_name in ('builtins.int', 'builtins.bool'): 621 # The only time it makes sense to use an int or bool is inside of 622 # a literal type. 623 msg = "Invalid type: try using Literal[{}] instead?".format(repr(t.literal_value)) 624 elif t.base_type_name in ('builtins.float', 'builtins.complex'): 625 # We special-case warnings for floats and complex numbers. 626 msg = "Invalid type: {} literals cannot be used as a type".format(t.simple_name()) 627 else: 628 # And in all other cases, we default to a generic error message. 629 # Note: the reason why we use a generic error message for strings 630 # but not ints or bools is because whenever we see an out-of-place 631 # string, it's unclear if the user meant to construct a literal type 632 # or just misspelled a regular type. So we avoid guessing. 633 msg = 'Invalid type comment or annotation' 634 635 self.fail(msg, t, code=codes.VALID_TYPE) 636 if t.note is not None: 637 self.note(t.note, t, code=codes.VALID_TYPE) 638 639 return AnyType(TypeOfAny.from_error, line=t.line, column=t.column) 640 641 def visit_literal_type(self, t: LiteralType) -> Type: 642 return t 643 644 def visit_star_type(self, t: StarType) -> Type: 645 return StarType(self.anal_type(t.type), t.line) 646 647 def visit_union_type(self, t: UnionType) -> Type: 648 if (t.uses_pep604_syntax is True 649 and t.is_evaluated is True 650 and self.api.is_stub_file is False 651 and self.options.python_version < (3, 10) 652 and self.api.is_future_flag_set('annotations') is False): 653 self.fail("X | Y syntax for unions requires Python 3.10", t) 654 return UnionType(self.anal_array(t.items), t.line) 655 656 def visit_partial_type(self, t: PartialType) -> Type: 657 assert False, "Internal error: Unexpected partial type" 658 659 def visit_ellipsis_type(self, t: EllipsisType) -> Type: 660 self.fail('Unexpected "..."', t) 661 return AnyType(TypeOfAny.from_error) 662 663 def visit_type_type(self, t: TypeType) -> Type: 664 return TypeType.make_normalized(self.anal_type(t.item), line=t.line) 665 666 def visit_placeholder_type(self, t: PlaceholderType) -> Type: 667 n = None if t.fullname is None else self.api.lookup_fully_qualified(t.fullname) 668 if not n or isinstance(n.node, PlaceholderNode): 669 self.api.defer() # Still incomplete 670 return t 671 else: 672 # TODO: Handle non-TypeInfo 673 assert isinstance(n.node, TypeInfo) 674 return self.analyze_type_with_type_info(n.node, t.args, t) 675 676 def analyze_callable_args_for_paramspec( 677 self, 678 callable_args: Type, 679 ret_type: Type, 680 fallback: Instance, 681 ) -> Optional[CallableType]: 682 """Construct a 'Callable[P, RET]', where P is ParamSpec, return None if we cannot.""" 683 if not isinstance(callable_args, UnboundType): 684 return None 685 sym = self.lookup_qualified(callable_args.name, callable_args) 686 if sym is None: 687 return None 688 tvar_def = self.tvar_scope.get_binding(sym) 689 if not isinstance(tvar_def, ParamSpecDef): 690 return None 691 692 # TODO(shantanu): construct correct type for paramspec 693 return CallableType( 694 [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)], 695 [nodes.ARG_STAR, nodes.ARG_STAR2], 696 [None, None], 697 ret_type=ret_type, 698 fallback=fallback, 699 is_ellipsis_args=True 700 ) 701 702 def analyze_callable_type(self, t: UnboundType) -> Type: 703 fallback = self.named_type('builtins.function') 704 if len(t.args) == 0: 705 # Callable (bare). Treat as Callable[..., Any]. 706 any_type = self.get_omitted_any(t) 707 ret = CallableType([any_type, any_type], 708 [nodes.ARG_STAR, nodes.ARG_STAR2], 709 [None, None], 710 ret_type=any_type, 711 fallback=fallback, 712 is_ellipsis_args=True) 713 elif len(t.args) == 2: 714 callable_args = t.args[0] 715 ret_type = t.args[1] 716 if isinstance(callable_args, TypeList): 717 # Callable[[ARG, ...], RET] (ordinary callable type) 718 analyzed_args = self.analyze_callable_args(callable_args) 719 if analyzed_args is None: 720 return AnyType(TypeOfAny.from_error) 721 args, kinds, names = analyzed_args 722 ret = CallableType(args, 723 kinds, 724 names, 725 ret_type=ret_type, 726 fallback=fallback) 727 elif isinstance(callable_args, EllipsisType): 728 # Callable[..., RET] (with literal ellipsis; accept arbitrary arguments) 729 ret = CallableType([AnyType(TypeOfAny.explicit), 730 AnyType(TypeOfAny.explicit)], 731 [nodes.ARG_STAR, nodes.ARG_STAR2], 732 [None, None], 733 ret_type=ret_type, 734 fallback=fallback, 735 is_ellipsis_args=True) 736 else: 737 # Callable[P, RET] (where P is ParamSpec) 738 maybe_ret = self.analyze_callable_args_for_paramspec( 739 callable_args, 740 ret_type, 741 fallback 742 ) 743 if maybe_ret is None: 744 # Callable[?, RET] (where ? is something invalid) 745 # TODO(shantanu): change error to mention paramspec, once we actually have some 746 # support for it 747 self.fail('The first argument to Callable must be a list of types or "..."', t) 748 return AnyType(TypeOfAny.from_error) 749 ret = maybe_ret 750 else: 751 self.fail('Please use "Callable[[<parameters>], <return type>]" or "Callable"', t) 752 return AnyType(TypeOfAny.from_error) 753 assert isinstance(ret, CallableType) 754 return ret.accept(self) 755 756 def analyze_callable_args(self, arglist: TypeList) -> Optional[Tuple[List[Type], 757 List[int], 758 List[Optional[str]]]]: 759 args = [] # type: List[Type] 760 kinds = [] # type: List[int] 761 names = [] # type: List[Optional[str]] 762 for arg in arglist.items: 763 if isinstance(arg, CallableArgument): 764 args.append(arg.typ) 765 names.append(arg.name) 766 if arg.constructor is None: 767 return None 768 found = self.lookup_qualified(arg.constructor, arg) 769 if found is None: 770 # Looking it up already put an error message in 771 return None 772 elif found.fullname not in ARG_KINDS_BY_CONSTRUCTOR: 773 self.fail('Invalid argument constructor "{}"'.format( 774 found.fullname), arg) 775 return None 776 else: 777 assert found.fullname is not None 778 kind = ARG_KINDS_BY_CONSTRUCTOR[found.fullname] 779 kinds.append(kind) 780 if arg.name is not None and kind in {ARG_STAR, ARG_STAR2}: 781 self.fail("{} arguments should not have names".format( 782 arg.constructor), arg) 783 return None 784 else: 785 args.append(arg) 786 kinds.append(ARG_POS) 787 names.append(None) 788 # Note that arglist below is only used for error context. 789 check_arg_names(names, [arglist] * len(args), self.fail, "Callable") 790 check_arg_kinds(kinds, [arglist] * len(args), self.fail) 791 return args, kinds, names 792 793 def analyze_literal_type(self, t: UnboundType) -> Type: 794 if len(t.args) == 0: 795 self.fail('Literal[...] must have at least one parameter', t) 796 return AnyType(TypeOfAny.from_error) 797 798 output = [] # type: List[Type] 799 for i, arg in enumerate(t.args): 800 analyzed_types = self.analyze_literal_param(i + 1, arg, t) 801 if analyzed_types is None: 802 return AnyType(TypeOfAny.from_error) 803 else: 804 output.extend(analyzed_types) 805 return UnionType.make_union(output, line=t.line) 806 807 def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> Optional[List[Type]]: 808 # This UnboundType was originally defined as a string. 809 if isinstance(arg, UnboundType) and arg.original_str_expr is not None: 810 assert arg.original_str_fallback is not None 811 return [LiteralType( 812 value=arg.original_str_expr, 813 fallback=self.named_type_with_normalized_str(arg.original_str_fallback), 814 line=arg.line, 815 column=arg.column, 816 )] 817 818 # If arg is an UnboundType that was *not* originally defined as 819 # a string, try expanding it in case it's a type alias or something. 820 if isinstance(arg, UnboundType): 821 self.nesting_level += 1 822 try: 823 arg = self.visit_unbound_type(arg, defining_literal=True) 824 finally: 825 self.nesting_level -= 1 826 827 # Literal[...] cannot contain Any. Give up and add an error message 828 # (if we haven't already). 829 arg = get_proper_type(arg) 830 if isinstance(arg, AnyType): 831 # Note: We can encounter Literals containing 'Any' under three circumstances: 832 # 833 # 1. If the user attempts use an explicit Any as a parameter 834 # 2. If the user is trying to use an enum value imported from a module with 835 # no type hints, giving it an an implicit type of 'Any' 836 # 3. If there's some other underlying problem with the parameter. 837 # 838 # We report an error in only the first two cases. In the third case, we assume 839 # some other region of the code has already reported a more relevant error. 840 # 841 # TODO: Once we start adding support for enums, make sure we report a custom 842 # error for case 2 as well. 843 if arg.type_of_any not in (TypeOfAny.from_error, TypeOfAny.special_form): 844 self.fail('Parameter {} of Literal[...] cannot be of type "Any"'.format(idx), ctx) 845 return None 846 elif isinstance(arg, RawExpressionType): 847 # A raw literal. Convert it directly into a literal if we can. 848 if arg.literal_value is None: 849 name = arg.simple_name() 850 if name in ('float', 'complex'): 851 msg = 'Parameter {} of Literal[...] cannot be of type "{}"'.format(idx, name) 852 else: 853 msg = 'Invalid type: Literal[...] cannot contain arbitrary expressions' 854 self.fail(msg, ctx) 855 # Note: we deliberately ignore arg.note here: the extra info might normally be 856 # helpful, but it generally won't make sense in the context of a Literal[...]. 857 return None 858 859 # Remap bytes and unicode into the appropriate type for the correct Python version 860 fallback = self.named_type_with_normalized_str(arg.base_type_name) 861 assert isinstance(fallback, Instance) 862 return [LiteralType(arg.literal_value, fallback, line=arg.line, column=arg.column)] 863 elif isinstance(arg, (NoneType, LiteralType)): 864 # Types that we can just add directly to the literal/potential union of literals. 865 return [arg] 866 elif isinstance(arg, Instance) and arg.last_known_value is not None: 867 # Types generated from declarations like "var: Final = 4". 868 return [arg.last_known_value] 869 elif isinstance(arg, UnionType): 870 out = [] 871 for union_arg in arg.items: 872 union_result = self.analyze_literal_param(idx, union_arg, ctx) 873 if union_result is None: 874 return None 875 out.extend(union_result) 876 return out 877 else: 878 self.fail('Parameter {} of Literal[...] is invalid'.format(idx), ctx) 879 return None 880 881 def analyze_type(self, t: Type) -> Type: 882 return t.accept(self) 883 884 def fail(self, msg: str, ctx: Context, *, code: Optional[ErrorCode] = None) -> None: 885 self.fail_func(msg, ctx, code=code) 886 887 def note(self, msg: str, ctx: Context, *, code: Optional[ErrorCode] = None) -> None: 888 self.note_func(msg, ctx, code=code) 889 890 @contextmanager 891 def tvar_scope_frame(self) -> Iterator[None]: 892 old_scope = self.tvar_scope 893 self.tvar_scope = self.tvar_scope.method_frame() 894 yield 895 self.tvar_scope = old_scope 896 897 def infer_type_variables(self, 898 type: CallableType) -> List[Tuple[str, TypeVarLikeExpr]]: 899 """Return list of unique type variables referred to in a callable.""" 900 names = [] # type: List[str] 901 tvars = [] # type: List[TypeVarLikeExpr] 902 for arg in type.arg_types: 903 for name, tvar_expr in arg.accept( 904 TypeVarLikeQuery(self.lookup_qualified, self.tvar_scope) 905 ): 906 if name not in names: 907 names.append(name) 908 tvars.append(tvar_expr) 909 # When finding type variables in the return type of a function, don't 910 # look inside Callable types. Type variables only appearing in 911 # functions in the return type belong to those functions, not the 912 # function we're currently analyzing. 913 for name, tvar_expr in type.ret_type.accept( 914 TypeVarLikeQuery(self.lookup_qualified, self.tvar_scope, include_callables=False) 915 ): 916 if name not in names: 917 names.append(name) 918 tvars.append(tvar_expr) 919 return list(zip(names, tvars)) 920 921 def bind_function_type_variables( 922 self, fun_type: CallableType, defn: Context 923 ) -> Sequence[TypeVarLikeDef]: 924 """Find the type variables of the function type and bind them in our tvar_scope""" 925 if fun_type.variables: 926 for var in fun_type.variables: 927 var_node = self.lookup_qualified(var.name, defn) 928 assert var_node, "Binding for function type variable not found within function" 929 var_expr = var_node.node 930 assert isinstance(var_expr, TypeVarLikeExpr) 931 self.tvar_scope.bind_new(var.name, var_expr) 932 return fun_type.variables 933 typevars = self.infer_type_variables(fun_type) 934 # Do not define a new type variable if already defined in scope. 935 typevars = [(name, tvar) for name, tvar in typevars 936 if not self.is_defined_type_var(name, defn)] 937 defs = [] # type: List[TypeVarLikeDef] 938 for name, tvar in typevars: 939 if not self.tvar_scope.allow_binding(tvar.fullname): 940 self.fail('Type variable "{}" is bound by an outer class'.format(name), defn) 941 self.tvar_scope.bind_new(name, tvar) 942 binding = self.tvar_scope.get_binding(tvar.fullname) 943 assert binding is not None 944 defs.append(binding) 945 946 return defs 947 948 def is_defined_type_var(self, tvar: str, context: Context) -> bool: 949 tvar_node = self.lookup_qualified(tvar, context) 950 if not tvar_node: 951 return False 952 return self.tvar_scope.get_binding(tvar_node) is not None 953 954 def anal_array(self, a: Iterable[Type], nested: bool = True) -> List[Type]: 955 res = [] # type: List[Type] 956 for t in a: 957 res.append(self.anal_type(t, nested)) 958 return res 959 960 def anal_type(self, t: Type, nested: bool = True) -> Type: 961 if nested: 962 self.nesting_level += 1 963 try: 964 return t.accept(self) 965 finally: 966 if nested: 967 self.nesting_level -= 1 968 969 def anal_var_def(self, var_def: TypeVarLikeDef) -> TypeVarLikeDef: 970 if isinstance(var_def, TypeVarDef): 971 return TypeVarDef( 972 var_def.name, 973 var_def.fullname, 974 var_def.id.raw_id, 975 self.anal_array(var_def.values), 976 var_def.upper_bound.accept(self), 977 var_def.variance, 978 var_def.line 979 ) 980 else: 981 return var_def 982 983 def anal_var_defs(self, var_defs: Sequence[TypeVarLikeDef]) -> List[TypeVarLikeDef]: 984 return [self.anal_var_def(vd) for vd in var_defs] 985 986 def named_type_with_normalized_str(self, fully_qualified_name: str) -> Instance: 987 """Does almost the same thing as `named_type`, except that we immediately 988 unalias `builtins.bytes` and `builtins.unicode` to `builtins.str` as appropriate. 989 """ 990 python_version = self.options.python_version 991 if python_version[0] == 2 and fully_qualified_name == 'builtins.bytes': 992 fully_qualified_name = 'builtins.str' 993 if python_version[0] >= 3 and fully_qualified_name == 'builtins.unicode': 994 fully_qualified_name = 'builtins.str' 995 return self.named_type(fully_qualified_name) 996 997 def named_type(self, fully_qualified_name: str, 998 args: Optional[List[Type]] = None, 999 line: int = -1, 1000 column: int = -1) -> Instance: 1001 node = self.lookup_fqn_func(fully_qualified_name) 1002 assert isinstance(node.node, TypeInfo) 1003 any_type = AnyType(TypeOfAny.special_form) 1004 return Instance(node.node, args or [any_type] * len(node.node.defn.type_vars), 1005 line=line, column=column) 1006 1007 def tuple_type(self, items: List[Type]) -> TupleType: 1008 any_type = AnyType(TypeOfAny.special_form) 1009 return TupleType(items, fallback=self.named_type('builtins.tuple', [any_type])) 1010 1011 1012TypeVarLikeList = List[Tuple[str, TypeVarLikeExpr]] 1013 1014# Mypyc doesn't support callback protocols yet. 1015MsgCallback = Callable[[str, Context, DefaultNamedArg(Optional[ErrorCode], 'code')], None] 1016 1017 1018def get_omitted_any(disallow_any: bool, fail: MsgCallback, note: MsgCallback, 1019 orig_type: Type, python_version: Tuple[int, int], 1020 fullname: Optional[str] = None, 1021 unexpanded_type: Optional[Type] = None) -> AnyType: 1022 if disallow_any: 1023 nongen_builtins = get_nongen_builtins(python_version) 1024 if fullname in nongen_builtins: 1025 typ = orig_type 1026 # We use a dedicated error message for builtin generics (as the most common case). 1027 alternative = nongen_builtins[fullname] 1028 fail(message_registry.IMPLICIT_GENERIC_ANY_BUILTIN.format(alternative), typ, 1029 code=codes.TYPE_ARG) 1030 else: 1031 typ = unexpanded_type or orig_type 1032 type_str = typ.name if isinstance(typ, UnboundType) else format_type_bare(typ) 1033 1034 fail( 1035 message_registry.BARE_GENERIC.format(quote_type_string(type_str)), 1036 typ, 1037 code=codes.TYPE_ARG) 1038 base_type = get_proper_type(orig_type) 1039 base_fullname = ( 1040 base_type.type.fullname if isinstance(base_type, Instance) else fullname 1041 ) 1042 # Ideally, we'd check whether the type is quoted or `from __future__ annotations` 1043 # is set before issuing this note 1044 if python_version < (3, 9) and base_fullname in GENERIC_STUB_NOT_AT_RUNTIME_TYPES: 1045 # Recommend `from __future__ import annotations` or to put type in quotes 1046 # (string literal escaping) for classes not generic at runtime 1047 note( 1048 "Subscripting classes that are not generic at runtime may require " 1049 "escaping, see https://mypy.readthedocs.io/en/stable/runtime_troubles.html" 1050 "#not-generic-runtime", 1051 typ, 1052 code=codes.TYPE_ARG) 1053 1054 any_type = AnyType(TypeOfAny.from_error, line=typ.line, column=typ.column) 1055 else: 1056 any_type = AnyType( 1057 TypeOfAny.from_omitted_generics, line=orig_type.line, column=orig_type.column 1058 ) 1059 return any_type 1060 1061 1062def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, 1063 disallow_any: bool, python_version: Tuple[int, int], 1064 use_generic_error: bool = False, 1065 unexpanded_type: Optional[Type] = None,) -> None: 1066 """Fix a malformed instance by replacing all type arguments with Any. 1067 1068 Also emit a suitable error if this is not due to implicit Any's. 1069 """ 1070 if len(t.args) == 0: 1071 if use_generic_error: 1072 fullname = None # type: Optional[str] 1073 else: 1074 fullname = t.type.fullname 1075 any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, 1076 unexpanded_type) 1077 t.args = (any_type,) * len(t.type.type_vars) 1078 return 1079 # Invalid number of type parameters. 1080 n = len(t.type.type_vars) 1081 s = '{} type arguments'.format(n) 1082 if n == 0: 1083 s = 'no type arguments' 1084 elif n == 1: 1085 s = '1 type argument' 1086 act = str(len(t.args)) 1087 if act == '0': 1088 act = 'none' 1089 fail('"{}" expects {}, but {} given'.format( 1090 t.type.name, s, act), t, code=codes.TYPE_ARG) 1091 # Construct the correct number of type arguments, as 1092 # otherwise the type checker may crash as it expects 1093 # things to be right. 1094 t.args = tuple(AnyType(TypeOfAny.from_error) for _ in t.type.type_vars) 1095 t.invalid = True 1096 1097 1098def expand_type_alias(node: TypeAlias, args: List[Type], 1099 fail: MsgCallback, no_args: bool, ctx: Context, *, 1100 unexpanded_type: Optional[Type] = None, 1101 disallow_any: bool = False) -> Type: 1102 """Expand a (generic) type alias target following the rules outlined in TypeAlias docstring. 1103 1104 Here: 1105 target: original target type (contains unbound type variables) 1106 alias_tvars: type variable names 1107 args: types to be substituted in place of type variables 1108 fail: error reporter callback 1109 no_args: whether original definition used a bare generic `A = List` 1110 ctx: context where expansion happens 1111 """ 1112 exp_len = len(node.alias_tvars) 1113 act_len = len(args) 1114 if exp_len > 0 and act_len == 0: 1115 # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...] 1116 return set_any_tvars(node, ctx.line, ctx.column, 1117 disallow_any=disallow_any, fail=fail, 1118 unexpanded_type=unexpanded_type) 1119 if exp_len == 0 and act_len == 0: 1120 if no_args: 1121 assert isinstance(node.target, Instance) # type: ignore[misc] 1122 # Note: this is the only case where we use an eager expansion. See more info about 1123 # no_args aliases like L = List in the docstring for TypeAlias class. 1124 return Instance(node.target.type, [], line=ctx.line, column=ctx.column) 1125 return TypeAliasType(node, [], line=ctx.line, column=ctx.column) 1126 if (exp_len == 0 and act_len > 0 1127 and isinstance(node.target, Instance) # type: ignore[misc] 1128 and no_args): 1129 tp = Instance(node.target.type, args) 1130 tp.line = ctx.line 1131 tp.column = ctx.column 1132 return tp 1133 if act_len != exp_len: 1134 fail('Bad number of arguments for type alias, expected: %s, given: %s' 1135 % (exp_len, act_len), ctx) 1136 return set_any_tvars(node, ctx.line, ctx.column, from_error=True) 1137 typ = TypeAliasType(node, args, ctx.line, ctx.column) 1138 assert typ.alias is not None 1139 # HACK: Implement FlexibleAlias[T, typ] by expanding it to typ here. 1140 if (isinstance(typ.alias.target, Instance) # type: ignore 1141 and typ.alias.target.type.fullname == 'mypy_extensions.FlexibleAlias'): 1142 exp = get_proper_type(typ) 1143 assert isinstance(exp, Instance) 1144 return exp.args[-1] 1145 return typ 1146 1147 1148def set_any_tvars(node: TypeAlias, 1149 newline: int, newcolumn: int, *, 1150 from_error: bool = False, 1151 disallow_any: bool = False, 1152 fail: Optional[MsgCallback] = None, 1153 unexpanded_type: Optional[Type] = None) -> Type: 1154 if from_error or disallow_any: 1155 type_of_any = TypeOfAny.from_error 1156 else: 1157 type_of_any = TypeOfAny.from_omitted_generics 1158 if disallow_any: 1159 assert fail is not None 1160 otype = unexpanded_type or node.target 1161 type_str = otype.name if isinstance(otype, UnboundType) else format_type_bare(otype) 1162 1163 fail(message_registry.BARE_GENERIC.format(quote_type_string(type_str)), 1164 Context(newline, newcolumn), code=codes.TYPE_ARG) 1165 any_type = AnyType(type_of_any, line=newline, column=newcolumn) 1166 return TypeAliasType(node, [any_type] * len(node.alias_tvars), newline, newcolumn) 1167 1168 1169def remove_dups(tvars: Iterable[T]) -> List[T]: 1170 # Get unique elements in order of appearance 1171 all_tvars = set() # type: Set[T] 1172 new_tvars = [] # type: List[T] 1173 for t in tvars: 1174 if t not in all_tvars: 1175 new_tvars.append(t) 1176 all_tvars.add(t) 1177 return new_tvars 1178 1179 1180def flatten_tvars(ll: Iterable[List[T]]) -> List[T]: 1181 return remove_dups(chain.from_iterable(ll)) 1182 1183 1184class TypeVarLikeQuery(TypeQuery[TypeVarLikeList]): 1185 1186 def __init__(self, 1187 lookup: Callable[[str, Context], Optional[SymbolTableNode]], 1188 scope: 'TypeVarLikeScope', 1189 *, 1190 include_callables: bool = True, 1191 include_bound_tvars: bool = False) -> None: 1192 self.include_callables = include_callables 1193 self.lookup = lookup 1194 self.scope = scope 1195 self.include_bound_tvars = include_bound_tvars 1196 super().__init__(flatten_tvars) 1197 1198 def _seems_like_callable(self, type: UnboundType) -> bool: 1199 if not type.args: 1200 return False 1201 if isinstance(type.args[0], (EllipsisType, TypeList)): 1202 return True 1203 return False 1204 1205 def visit_unbound_type(self, t: UnboundType) -> TypeVarLikeList: 1206 name = t.name 1207 node = self.lookup(name, t) 1208 if node and isinstance(node.node, TypeVarLikeExpr) and ( 1209 self.include_bound_tvars or self.scope.get_binding(node) is None): 1210 assert isinstance(node.node, TypeVarLikeExpr) 1211 return [(name, node.node)] 1212 elif not self.include_callables and self._seems_like_callable(t): 1213 return [] 1214 elif node and node.fullname in ('typing_extensions.Literal', 'typing.Literal'): 1215 return [] 1216 else: 1217 return super().visit_unbound_type(t) 1218 1219 def visit_callable_type(self, t: CallableType) -> TypeVarLikeList: 1220 if self.include_callables: 1221 return super().visit_callable_type(t) 1222 else: 1223 return [] 1224 1225 1226def check_for_explicit_any(typ: Optional[Type], 1227 options: Options, 1228 is_typeshed_stub: bool, 1229 msg: MessageBuilder, 1230 context: Context) -> None: 1231 if (options.disallow_any_explicit and 1232 not is_typeshed_stub and 1233 typ and 1234 has_explicit_any(typ)): 1235 msg.explicit_any(context) 1236 1237 1238def has_explicit_any(t: Type) -> bool: 1239 """ 1240 Whether this type is or type it contains is an Any coming from explicit type annotation 1241 """ 1242 return t.accept(HasExplicitAny()) 1243 1244 1245class HasExplicitAny(TypeQuery[bool]): 1246 def __init__(self) -> None: 1247 super().__init__(any) 1248 1249 def visit_any(self, t: AnyType) -> bool: 1250 return t.type_of_any == TypeOfAny.explicit 1251 1252 def visit_typeddict_type(self, t: TypedDictType) -> bool: 1253 # typeddict is checked during TypedDict declaration, so don't typecheck it here. 1254 return False 1255 1256 1257def has_any_from_unimported_type(t: Type) -> bool: 1258 """Return true if this type is Any because an import was not followed. 1259 1260 If type t is such Any type or has type arguments that contain such Any type 1261 this function will return true. 1262 """ 1263 return t.accept(HasAnyFromUnimportedType()) 1264 1265 1266class HasAnyFromUnimportedType(TypeQuery[bool]): 1267 def __init__(self) -> None: 1268 super().__init__(any) 1269 1270 def visit_any(self, t: AnyType) -> bool: 1271 return t.type_of_any == TypeOfAny.from_unimported_type 1272 1273 def visit_typeddict_type(self, t: TypedDictType) -> bool: 1274 # typeddict is checked during TypedDict declaration, so don't typecheck it here 1275 return False 1276 1277 1278def collect_any_types(t: Type) -> List[AnyType]: 1279 """Return all inner `AnyType`s of type t""" 1280 return t.accept(CollectAnyTypesQuery()) 1281 1282 1283class CollectAnyTypesQuery(TypeQuery[List[AnyType]]): 1284 def __init__(self) -> None: 1285 super().__init__(self.combine_lists_strategy) 1286 1287 def visit_any(self, t: AnyType) -> List[AnyType]: 1288 return [t] 1289 1290 @classmethod 1291 def combine_lists_strategy(cls, it: Iterable[List[AnyType]]) -> List[AnyType]: 1292 result = [] # type: List[AnyType] 1293 for l in it: 1294 result.extend(l) 1295 return result 1296 1297 1298def collect_all_inner_types(t: Type) -> List[Type]: 1299 """ 1300 Return all types that `t` contains 1301 """ 1302 return t.accept(CollectAllInnerTypesQuery()) 1303 1304 1305class CollectAllInnerTypesQuery(TypeQuery[List[Type]]): 1306 def __init__(self) -> None: 1307 super().__init__(self.combine_lists_strategy) 1308 1309 def query_types(self, types: Iterable[Type]) -> List[Type]: 1310 return self.strategy([t.accept(self) for t in types]) + list(types) 1311 1312 @classmethod 1313 def combine_lists_strategy(cls, it: Iterable[List[Type]]) -> List[Type]: 1314 return list(itertools.chain.from_iterable(it)) 1315 1316 1317def make_optional_type(t: Type) -> Type: 1318 """Return the type corresponding to Optional[t]. 1319 1320 Note that we can't use normal union simplification, since this function 1321 is called during semantic analysis and simplification only works during 1322 type checking. 1323 """ 1324 t = get_proper_type(t) 1325 if isinstance(t, NoneType): 1326 return t 1327 elif isinstance(t, UnionType): 1328 items = [item for item in union_items(t) 1329 if not isinstance(item, NoneType)] 1330 return UnionType(items + [NoneType()], t.line, t.column) 1331 else: 1332 return UnionType([t, NoneType()], t.line, t.column) 1333 1334 1335def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, 1336 python_version: Tuple[int, int]) -> None: 1337 """Recursively fix all instance types (type argument count) in a given type. 1338 1339 For example 'Union[Dict, List[str, int]]' will be transformed into 1340 'Union[Dict[Any, Any], List[Any]]' in place. 1341 """ 1342 t.accept(InstanceFixer(fail, note, python_version)) 1343 1344 1345class InstanceFixer(TypeTraverserVisitor): 1346 def __init__( 1347 self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int] 1348 ) -> None: 1349 self.fail = fail 1350 self.note = note 1351 self.python_version = python_version 1352 1353 def visit_instance(self, typ: Instance) -> None: 1354 super().visit_instance(typ) 1355 if len(typ.args) != len(typ.type.type_vars): 1356 fix_instance(typ, self.fail, self.note, disallow_any=False, 1357 python_version=self.python_version, use_generic_error=True) 1358