コード例 #1
0
ファイル: typeanal.py プロジェクト: elarivie/mypy
 def visit_unbound_type(self, t: UnboundType) -> Type:
     if t.optional:
         t.optional = False
         # We don't need to worry about double-wrapping Optionals or
         # wrapping Anys: Union simplification will take care of that.
         return make_optional_type(self.visit_unbound_type(t))
     sym = self.lookup(t.name, t,
                       suppress_errors=self.third_pass)  # type: ignore
     if sym is not None:
         if sym.node is None:
             # UNBOUND_IMPORTED can happen if an unknown name was imported.
             if sym.kind != UNBOUND_IMPORTED:
                 self.fail(errorcode.INTERNAL_ERROR_NODE_IS_NONE(sym.kind),
                           t)
             return AnyType(TypeOfAny.special_form)
         fullname = sym.node.fullname()
         hook = self.plugin.get_type_analyze_hook(fullname)
         if hook:
             return hook(AnalyzeTypeContext(t, t, self))
         if (fullname in nongen_builtins and t.args and not sym.normalized
                 and not self.allow_unnormalized):
             self.fail(errorcode.NO_SUBSCRIPT_BUILTIN_ALIAS(fullname), t)
         if self.tvar_scope:
             tvar_def = self.tvar_scope.get_binding(sym)
         else:
             tvar_def = None
         if self.warn_bound_tvar and sym.kind == TVAR and tvar_def is not None:
             self.fail(
                 errorcode.
                 CANNOT_USE_BOUND_TYPE_VAR_TO_DEFINE_GENERIC_ALIAS(t.name),
                 t)
             return AnyType(TypeOfAny.from_error)
         elif sym.kind == TVAR and tvar_def is not None:
             if len(t.args) > 0:
                 self.fail(errorcode.TYPE_VAR_USED_WITH_ARG(t.name), t)
             return TypeVarType(tvar_def, t.line)
         elif fullname == 'builtins.None':
             return NoneTyp()
         elif fullname == 'typing.Any' or fullname == 'builtins.Any':
             return AnyType(TypeOfAny.explicit)
         elif fullname == 'typing.Tuple':
             if len(t.args) == 0 and not t.empty_tuple_index:
                 # Bare 'Tuple' is same as 'tuple'
                 if self.options.disallow_any_generics and not self.is_typeshed_stub:
                     self.fail(errorcode.BARE_GENERIC(), t)
                 typ = self.named_type('builtins.tuple',
                                       line=t.line,
                                       column=t.column)
                 typ.from_generic_builtin = True
                 return typ
             if len(t.args) == 2 and isinstance(t.args[1], EllipsisType):
                 # Tuple[T, ...] (uniform, variable-length tuple)
                 instance = self.named_type('builtins.tuple',
                                            [self.anal_type(t.args[0])])
                 instance.line = t.line
                 return instance
             return self.tuple_type(self.anal_array(t.args))
         elif fullname == 'typing.Union':
             items = self.anal_array(t.args)
             return UnionType.make_union(items)
         elif fullname == 'typing.Optional':
             if len(t.args) != 1:
                 self.fail(errorcode.OPTIONAL_MUST_HAVE_ONE_ARGUMENT(), t)
                 return AnyType(TypeOfAny.from_error)
             item = self.anal_type(t.args[0])
             return make_optional_type(item)
         elif fullname == 'typing.Callable':
             return self.analyze_callable_type(t)
         elif fullname == 'typing.Type':
             if len(t.args) == 0:
                 any_type = AnyType(TypeOfAny.from_omitted_generics,
                                    line=t.line,
                                    column=t.column)
                 return TypeType(any_type, line=t.line, column=t.column)
             if len(t.args) != 1:
                 self.fail(errorcode.TYPE_MUST_HAVE_EXACTLY_ONE_TYPE(), t)
             item = self.anal_type(t.args[0])
             return TypeType.make_normalized(item, line=t.line)
         elif fullname == 'typing.ClassVar':
             if self.nesting_level > 0:
                 self.fail(
                     errorcode.INVALID_TYPE_CLASSVAR_NESTED_INSIDE_TYPE(),
                     t)
             if len(t.args) == 0:
                 return AnyType(TypeOfAny.from_omitted_generics,
                                line=t.line,
                                column=t.column)
             if len(t.args) != 1:
                 self.fail(
                     errorcode.CLASS_VAR_MUST_HAVE_AT_MOST_ONE_TYPE_ARG(),
                     t)
                 return AnyType(TypeOfAny.from_error)
             item = self.anal_type(t.args[0])
             if isinstance(item, TypeVarType) or get_type_vars(item):
                 self.fail(errorcode.CLASSVAR_CANNOT_BE_GENERIC(), t)
                 return AnyType(TypeOfAny.from_error)
             return item
         elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'):
             return UninhabitedType(is_noreturn=True)
         elif sym.kind == TYPE_ALIAS:
             override = sym.type_override
             all_vars = sym.alias_tvars
             assert override is not None
             an_args = self.anal_array(t.args)
             if all_vars is not None:
                 exp_len = len(all_vars)
             else:
                 exp_len = 0
             act_len = len(an_args)
             if exp_len > 0 and act_len == 0:
                 # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
                 assert all_vars is not None
                 return set_any_tvars(override, all_vars, t.line, t.column)
             if exp_len == 0 and act_len == 0:
                 return override
             if act_len != exp_len:
                 self.fail(
                     errorcode.BAD_NUMBER_ARGUMENT_FOR_TYPEALIAS(
                         exp_len, act_len), t)
                 return set_any_tvars(override,
                                      all_vars or [],
                                      t.line,
                                      t.column,
                                      implicit=False)
             assert all_vars is not None
             return replace_alias_tvars(override, all_vars, an_args, t.line,
                                        t.column)
         elif not isinstance(sym.node, TypeInfo):
             name = sym.fullname
             if name is None:
                 name = sym.node.name()
             if isinstance(sym.node, Var) and isinstance(
                     sym.node.type, AnyType):
                 # Something with an Any type -- make it an alias for Any in a type
                 # context. This is slightly problematic as it allows using the type 'Any'
                 # as a base class -- however, this will fail soon at runtime so the problem
                 # is pretty minor.
                 return AnyType(TypeOfAny.from_unimported_type)
             # Allow unbound type variables when defining an alias
             if not (self.aliasing and sym.kind == TVAR and
                     (not self.tvar_scope
                      or self.tvar_scope.get_binding(sym) is None)):
                 if (not self.third_pass and not self.in_dynamic_func
                         and not (isinstance(sym.node, (FuncDef, Decorator))
                                  or isinstance(sym.node, Var)
                                  and sym.node.is_ready)
                         and not (sym.kind == TVAR and tvar_def is None)):
                     if t.args and not self.global_scope:
                         self.fail(
                             errorcode.UNSUPPORTED_FORWARD_REFERENCE(
                                 t.name), t)
                         return AnyType(TypeOfAny.from_error)
                     return ForwardRef(t)
                 self.fail(errorcode.INVALID_TYPE_X(name), t)
                 if self.third_pass and sym.kind == TVAR:
                     self.note_func(
                         errorcode.FORWARD_REERENCES_TO_TYPE_VAR_PROHIBITED(
                         ), t)
             return t
         info = sym.node  # type: TypeInfo
         if len(t.args) > 0 and info.fullname() == 'builtins.tuple':
             fallback = Instance(info, [AnyType(TypeOfAny.special_form)],
                                 t.line)
             return TupleType(self.anal_array(t.args), fallback, t.line)
         else:
             # Analyze arguments and construct Instance type. The
             # number of type arguments and their values are
             # checked only later, since we do not always know the
             # valid count at this point. Thus we may construct an
             # Instance with an invalid number of type arguments.
             instance = Instance(info, self.anal_array(t.args), t.line,
                                 t.column)
             instance.from_generic_builtin = sym.normalized
             tup = info.tuple_type
             if tup is not None:
                 # The class has a Tuple[...] base class so it will be
                 # represented as a tuple type.
                 if t.args:
                     self.fail(
                         errorcode.GENERIC_TUPLE_TYPES_NOT_SUPPORTED(), t)
                     return AnyType(TypeOfAny.from_error)
                 return tup.copy_modified(items=self.anal_array(tup.items),
                                          fallback=instance)
             td = info.typeddict_type
             if td is not None:
                 # The class has a TypedDict[...] base class so it will be
                 # represented as a typeddict type.
                 if t.args:
                     self.fail(
                         errorcode.GENERIC_TYPEDDICT_TYPES_NOT_SUPPORTED(),
                         t)
                     return AnyType(TypeOfAny.from_error)
                 # Create a named TypedDictType
                 return td.copy_modified(item_types=self.anal_array(
                     list(td.items.values())),
                                         fallback=instance)
             return instance
     else:
         if self.third_pass:
             self.fail(errorcode.INVALID_TYPE_X(t.name), t)
             return AnyType(TypeOfAny.from_error)
         return AnyType(TypeOfAny.special_form)
コード例 #2
0
 def visit_unbound_type(self, t: UnboundType) -> Type:
     if t.optional:
         t.optional = False
         # We don't need to worry about double-wrapping Optionals or
         # wrapping Anys: Union simplification will take care of that.
         return make_optional_type(self.visit_unbound_type(t))
     sym = self.lookup(t.name, t)
     if sym is not None:
         if sym.node is None:
             # UNBOUND_IMPORTED can happen if an unknown name was imported.
             if sym.kind != UNBOUND_IMPORTED:
                 self.fail(
                     'Internal error (node is None, kind={})'.format(
                         sym.kind), t)
             return AnyType()
         fullname = sym.node.fullname()
         hook = self.plugin.get_type_analyze_hook(fullname)
         if hook:
             return hook(AnalyzeTypeContext(t, t, self))
         if (fullname in nongen_builtins and t.args and not sym.normalized
                 and not self.allow_unnormalized):
             self.fail(no_subscript_builtin_alias(fullname), t)
         tvar_def = self.tvar_scope.get_binding(sym)
         if sym.kind == TVAR and tvar_def is not None:
             if len(t.args) > 0:
                 self.fail(
                     'Type variable "{}" used with arguments'.format(
                         t.name), t)
             return TypeVarType(tvar_def, t.line)
         elif fullname == 'builtins.None':
             return NoneTyp()
         elif fullname == 'typing.Any' or fullname == 'builtins.Any':
             return AnyType(explicit=True)
         elif fullname == 'typing.Tuple':
             if len(t.args) == 0 and not t.empty_tuple_index:
                 # Bare 'Tuple' is same as 'tuple'
                 if 'generics' in self.options.disallow_any and not self.is_typeshed_stub:
                     self.fail(messages.BARE_GENERIC, t)
                 typ = self.named_type('builtins.tuple',
                                       line=t.line,
                                       column=t.column)
                 typ.from_generic_builtin = True
                 return typ
             if len(t.args) == 2 and isinstance(t.args[1], EllipsisType):
                 # Tuple[T, ...] (uniform, variable-length tuple)
                 instance = self.named_type('builtins.tuple',
                                            [self.anal_type(t.args[0])])
                 instance.line = t.line
                 return instance
             return self.tuple_type(self.anal_array(t.args))
         elif fullname == 'typing.Union':
             items = self.anal_array(t.args)
             return UnionType.make_union(items)
         elif fullname == 'typing.Optional':
             if len(t.args) != 1:
                 self.fail(
                     'Optional[...] must have exactly one type argument', t)
                 return AnyType()
             item = self.anal_type(t.args[0])
             return make_optional_type(item)
         elif fullname == 'typing.Callable':
             return self.analyze_callable_type(t)
         elif fullname == 'typing.Type':
             if len(t.args) == 0:
                 any_type = AnyType(from_omitted_generics=True,
                                    line=t.line,
                                    column=t.column)
                 return TypeType(any_type, line=t.line, column=t.column)
             if len(t.args) != 1:
                 self.fail('Type[...] must have exactly one type argument',
                           t)
             item = self.anal_type(t.args[0])
             return TypeType.make_normalized(item, line=t.line)
         elif fullname == 'typing.ClassVar':
             if self.nesting_level > 0:
                 self.fail(
                     'Invalid type: ClassVar nested inside other type', t)
             if len(t.args) == 0:
                 return AnyType(line=t.line)
             if len(t.args) != 1:
                 self.fail(
                     'ClassVar[...] must have at most one type argument', t)
                 return AnyType()
             item = self.anal_type(t.args[0])
             if isinstance(item, TypeVarType) or get_type_vars(item):
                 self.fail('Invalid type: ClassVar cannot be generic', t)
                 return AnyType()
             return item
         elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'):
             return UninhabitedType(is_noreturn=True)
         elif sym.kind == TYPE_ALIAS:
             override = sym.type_override
             all_vars = sym.alias_tvars
             assert override is not None
             an_args = self.anal_array(t.args)
             if all_vars is not None:
                 exp_len = len(all_vars)
             else:
                 exp_len = 0
             act_len = len(an_args)
             if exp_len > 0 and act_len == 0:
                 # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
                 assert all_vars is not None
                 return set_any_tvars(override, all_vars, t.line, t.column)
             if exp_len == 0 and act_len == 0:
                 return override
             if act_len != exp_len:
                 self.fail(
                     'Bad number of arguments for type alias, expected: %s, given: %s'
                     % (exp_len, act_len), t)
                 return set_any_tvars(override,
                                      all_vars or [],
                                      t.line,
                                      t.column,
                                      implicit=False)
             assert all_vars is not None
             return replace_alias_tvars(override, all_vars, an_args, t.line,
                                        t.column)
         elif not isinstance(sym.node, TypeInfo):
             name = sym.fullname
             if name is None:
                 name = sym.node.name()
             if isinstance(sym.node, Var) and isinstance(
                     sym.node.type, AnyType):
                 # Something with an Any type -- make it an alias for Any in a type
                 # context. This is slightly problematic as it allows using the type 'Any'
                 # as a base class -- however, this will fail soon at runtime so the problem
                 # is pretty minor.
                 return AnyType(from_unimported_type=True)
             # Allow unbound type variables when defining an alias
             if not (self.aliasing and sym.kind == TVAR
                     and self.tvar_scope.get_binding(sym) is None):
                 self.fail('Invalid type "{}"'.format(name), t)
             return t
         info = sym.node  # type: TypeInfo
         if len(t.args) > 0 and info.fullname() == 'builtins.tuple':
             return TupleType(self.anal_array(t.args),
                              Instance(info, [AnyType()], t.line), t.line)
         else:
             # Analyze arguments and construct Instance type. The
             # number of type arguments and their values are
             # checked only later, since we do not always know the
             # valid count at this point. Thus we may construct an
             # Instance with an invalid number of type arguments.
             instance = Instance(info, self.anal_array(t.args), t.line,
                                 t.column)
             instance.from_generic_builtin = sym.normalized
             tup = info.tuple_type
             if tup is not None:
                 # The class has a Tuple[...] base class so it will be
                 # represented as a tuple type.
                 if t.args:
                     self.fail('Generic tuple types not supported', t)
                     return AnyType()
                 return tup.copy_modified(items=self.anal_array(tup.items),
                                          fallback=instance)
             td = info.typeddict_type
             if td is not None:
                 # The class has a TypedDict[...] base class so it will be
                 # represented as a typeddict type.
                 if t.args:
                     self.fail('Generic TypedDict types not supported', t)
                     return AnyType()
                 # Create a named TypedDictType
                 return td.copy_modified(item_types=self.anal_array(
                     list(td.items.values())),
                                         fallback=instance)
             return instance
     else:
         return AnyType()
コード例 #3
0
ファイル: typeanal.py プロジェクト: troyboy1102/Python
 def visit_unbound_type_nonoptional(self, t: UnboundType) -> Type:
     sym = self.lookup(t.name, t, suppress_errors=self.third_pass)
     if '.' in t.name:
         # Handle indirect references to imported names.
         #
         # TODO: Do this for module-local references as well and remove ImportedName
         #    type check below.
         sym = self.api.dereference_module_cross_ref(sym)
     if sym is not None:
         if isinstance(sym.node, ImportedName):
             # Forward reference to an imported name that hasn't been processed yet.
             # To maintain backward compatibility, these get translated to Any.
             #
             # TODO: Remove this special case.
             return AnyType(TypeOfAny.implementation_artifact)
         if sym.fullname in type_aliases:
             # Resolve forward reference to type alias like 'typing.List'.
             # TODO: Unify how type aliases are handled; currently we resolve them in two
             #     places (the other is in the semantic analyzer pass 2).
             resolved = type_aliases[sym.fullname]
             new = self.api.lookup_qualified(resolved, t)
             if new:
                 sym = new.copy()
                 sym.normalized = True
         if sym.node is None:
             # UNBOUND_IMPORTED can happen if an unknown name was imported.
             if sym.kind != UNBOUND_IMPORTED:
                 self.fail(
                     'Internal error (node is None, kind={})'.format(
                         sym.kind), t)
             return AnyType(TypeOfAny.special_form)
         fullname = sym.node.fullname()
         hook = self.plugin.get_type_analyze_hook(fullname)
         if hook:
             return hook(AnalyzeTypeContext(t, t, self))
         if (fullname in nongen_builtins and t.args and not sym.normalized
                 and not self.allow_unnormalized):
             self.fail(no_subscript_builtin_alias(fullname), t)
         if self.tvar_scope:
             tvar_def = self.tvar_scope.get_binding(sym)
         else:
             tvar_def = None
         if self.warn_bound_tvar and sym.kind == TVAR and tvar_def is not None:
             self.fail(
                 'Can\'t use bound type variable "{}"'
                 ' to define generic alias'.format(t.name), t)
             return AnyType(TypeOfAny.from_error)
         elif sym.kind == TVAR and tvar_def is not None:
             if len(t.args) > 0:
                 self.fail(
                     'Type variable "{}" used with arguments'.format(
                         t.name), t)
             return TypeVarType(tvar_def, t.line)
         elif fullname == 'builtins.None':
             return NoneTyp()
         elif fullname == 'typing.Any' or fullname == 'builtins.Any':
             return AnyType(TypeOfAny.explicit)
         elif fullname == 'typing.Tuple':
             if len(t.args) == 0 and not t.empty_tuple_index:
                 # Bare 'Tuple' is same as 'tuple'
                 if self.options.disallow_any_generics and not self.is_typeshed_stub:
                     self.fail(messages.BARE_GENERIC, t)
                 typ = self.named_type('builtins.tuple',
                                       line=t.line,
                                       column=t.column)
                 typ.from_generic_builtin = True
                 return typ
             if len(t.args) == 2 and isinstance(t.args[1], EllipsisType):
                 # Tuple[T, ...] (uniform, variable-length tuple)
                 instance = self.named_type('builtins.tuple',
                                            [self.anal_type(t.args[0])])
                 instance.line = t.line
                 return instance
             return self.tuple_type(self.anal_array(t.args))
         elif fullname == 'typing.Union':
             items = self.anal_array(t.args)
             return UnionType.make_union(items)
         elif fullname == 'typing.Optional':
             if len(t.args) != 1:
                 self.fail(
                     'Optional[...] must have exactly one type argument', t)
                 return AnyType(TypeOfAny.from_error)
             item = self.anal_type(t.args[0])
             return make_optional_type(item)
         elif fullname == 'typing.Callable':
             return self.analyze_callable_type(t)
         elif fullname == 'typing.Type':
             if len(t.args) == 0:
                 any_type = AnyType(TypeOfAny.from_omitted_generics,
                                    line=t.line,
                                    column=t.column)
                 return TypeType(any_type, line=t.line, column=t.column)
             if len(t.args) != 1:
                 self.fail('Type[...] must have exactly one type argument',
                           t)
             item = self.anal_type(t.args[0])
             return TypeType.make_normalized(item, line=t.line)
         elif fullname == 'typing.ClassVar':
             if self.nesting_level > 0:
                 self.fail(
                     'Invalid type: ClassVar nested inside other type', t)
             if len(t.args) == 0:
                 return AnyType(TypeOfAny.from_omitted_generics,
                                line=t.line,
                                column=t.column)
             if len(t.args) != 1:
                 self.fail(
                     'ClassVar[...] must have at most one type argument', t)
                 return AnyType(TypeOfAny.from_error)
             item = self.anal_type(t.args[0])
             if isinstance(item, TypeVarType) or get_type_vars(item):
                 self.fail('Invalid type: ClassVar cannot be generic', t)
                 return AnyType(TypeOfAny.from_error)
             return item
         elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'):
             return UninhabitedType(is_noreturn=True)
         elif sym.kind == TYPE_ALIAS:
             if sym.alias_name is not None:
                 self.aliases_used.add(sym.alias_name)
             override = sym.type_override
             all_vars = sym.alias_tvars
             assert override is not None
             an_args = self.anal_array(t.args)
             if all_vars is not None:
                 exp_len = len(all_vars)
             else:
                 exp_len = 0
             act_len = len(an_args)
             if exp_len > 0 and act_len == 0:
                 # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
                 assert all_vars is not None
                 return set_any_tvars(override, all_vars, t.line, t.column)
             if exp_len == 0 and act_len == 0:
                 return override
             if act_len != exp_len:
                 self.fail(
                     'Bad number of arguments for type alias, expected: %s, given: %s'
                     % (exp_len, act_len), t)
                 return set_any_tvars(override,
                                      all_vars or [],
                                      t.line,
                                      t.column,
                                      implicit=False)
             assert all_vars is not None
             return replace_alias_tvars(override, all_vars, an_args, t.line,
                                        t.column)
         elif not isinstance(sym.node, TypeInfo):
             name = sym.fullname
             if name is None:
                 name = sym.node.name()
             if isinstance(sym.node, Var) and isinstance(
                     sym.node.type, AnyType):
                 # Something with an Any type -- make it an alias for Any in a type
                 # context. This is slightly problematic as it allows using the type 'Any'
                 # as a base class -- however, this will fail soon at runtime so the problem
                 # is pretty minor.
                 return AnyType(
                     TypeOfAny.from_unimported_type,
                     missing_import_name=sym.node.type.missing_import_name)
             # Allow unbound type variables when defining an alias
             if not (self.aliasing and sym.kind == TVAR and
                     (not self.tvar_scope
                      or self.tvar_scope.get_binding(sym) is None)):
                 if (not self.third_pass and not self.in_dynamic_func
                         and not (isinstance(sym.node, (FuncDef, Decorator))
                                  or isinstance(sym.node, Var)
                                  and sym.node.is_ready)
                         and not (sym.kind == TVAR and tvar_def is None)):
                     if t.args and not self.global_scope:
                         self.fail(
                             'Unsupported forward reference to "{}"'.format(
                                 t.name), t)
                         return AnyType(TypeOfAny.from_error)
                     return ForwardRef(t)
                 self.fail('Invalid type "{}"'.format(name), t)
                 if self.third_pass and sym.kind == TVAR:
                     self.note_func(
                         "Forward references to type variables are prohibited",
                         t)
             return t
         info = sym.node  # type: TypeInfo
         if sym.is_aliasing:
             if sym.alias_name is not None:
                 self.aliases_used.add(sym.alias_name)
         if len(t.args) > 0 and info.fullname() == 'builtins.tuple':
             fallback = Instance(info, [AnyType(TypeOfAny.special_form)],
                                 t.line)
             return TupleType(self.anal_array(t.args), fallback, t.line)
         else:
             # Analyze arguments and construct Instance type. The
             # number of type arguments and their values are
             # checked only later, since we do not always know the
             # valid count at this point. Thus we may construct an
             # Instance with an invalid number of type arguments.
             instance = Instance(info, self.anal_array(t.args), t.line,
                                 t.column)
             instance.from_generic_builtin = sym.normalized
             tup = info.tuple_type
             if tup is not None:
                 # The class has a Tuple[...] base class so it will be
                 # represented as a tuple type.
                 if t.args:
                     self.fail('Generic tuple types not supported', t)
                     return AnyType(TypeOfAny.from_error)
                 return tup.copy_modified(items=self.anal_array(tup.items),
                                          fallback=instance)
             td = info.typeddict_type
             if td is not None:
                 # The class has a TypedDict[...] base class so it will be
                 # represented as a typeddict type.
                 if t.args:
                     self.fail('Generic TypedDict types not supported', t)
                     return AnyType(TypeOfAny.from_error)
                 # Create a named TypedDictType
                 return td.copy_modified(item_types=self.anal_array(
                     list(td.items.values())),
                                         fallback=instance)
             return instance
     else:
         if self.third_pass:
             self.fail('Invalid type "{}"'.format(t.name), t)
             return AnyType(TypeOfAny.from_error)
         return AnyType(TypeOfAny.special_form)
コード例 #4
0
 def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) -> Type:
     sym = self.lookup_qualified(t.name, t)
     if sym is not None:
         node = sym.node
         if isinstance(node, PlaceholderNode):
             if node.becomes_typeinfo:
                 # Reference to placeholder type.
                 if self.api.final_iteration:
                     self.cannot_resolve_type(t)
                     return AnyType(TypeOfAny.from_error)
                 elif self.allow_placeholder:
                     self.api.defer()
                 else:
                     self.api.record_incomplete_ref()
                 return PlaceholderType(node.fullname(), self.anal_array(t.args), t.line)
             else:
                 if self.api.final_iteration:
                     self.cannot_resolve_type(t)
                     return AnyType(TypeOfAny.from_error)
                 else:
                     # Reference to an unknown placeholder node.
                     self.api.record_incomplete_ref()
                     return AnyType(TypeOfAny.special_form)
         if node is None:
             self.fail('Internal error (node is None, kind={})'.format(sym.kind), t)
             return AnyType(TypeOfAny.special_form)
         fullname = node.fullname()
         hook = self.plugin.get_type_analyze_hook(fullname)
         if hook is not None:
             return hook(AnalyzeTypeContext(t, t, self))
         if (fullname in nongen_builtins
                 and t.args and
                 not self.allow_unnormalized):
             self.fail(no_subscript_builtin_alias(fullname,
                                                  propose_alt=not self.defining_alias), t)
         tvar_def = self.tvar_scope.get_binding(sym)
         if isinstance(sym.node, TypeVarExpr) and tvar_def is not None and self.defining_alias:
             self.fail('Can\'t use bound type variable "{}"'
                       ' to define generic alias'.format(t.name), t)
             return AnyType(TypeOfAny.from_error)
         if isinstance(sym.node, TypeVarExpr) and tvar_def is not None:
             if len(t.args) > 0:
                 self.fail('Type variable "{}" used with arguments'.format(t.name), t)
             return TypeVarType(tvar_def, t.line)
         special = self.try_analyze_special_unbound_type(t, fullname)
         if special is not None:
             return special
         if isinstance(node, TypeAlias):
             self.aliases_used.add(fullname)
             all_vars = node.alias_tvars
             target = node.target
             an_args = self.anal_array(t.args)
             res = expand_type_alias(target, all_vars, an_args, self.fail, node.no_args, t)
             # The only case where expand_type_alias() can return an incorrect instance is
             # when it is top-level instance, so no need to recurse.
             if (isinstance(res, Instance) and len(res.args) != len(res.type.type_vars) and
                     not self.defining_alias):
                 fix_instance(res, self.fail)
             return res
         elif isinstance(node, TypeInfo):
             return self.analyze_type_with_type_info(node, t.args, t)
         else:
             return self.analyze_unbound_type_without_type_info(t, sym, defining_literal)
     else:  # sym is None
         return AnyType(TypeOfAny.special_form)
コード例 #5
0
    def visit_unbound_type_nonoptional(self, t: UnboundType) -> Type:
        sym = self.lookup(t.name, t, suppress_errors=self.third_pass)
        if '.' in t.name:
            # Handle indirect references to imported names.
            #
            # TODO: Do this for module-local references as well and remove ImportedName
            #    type check below.
            sym = self.api.dereference_module_cross_ref(sym)
        if sym is not None:
            if isinstance(sym.node, ImportedName):
                # Forward reference to an imported name that hasn't been processed yet.
                # To maintain backward compatibility, these get translated to Any.
                #
                # TODO: Remove this special case.
                return AnyType(TypeOfAny.implementation_artifact)
            if sym.node is None:
                # UNBOUND_IMPORTED can happen if an unknown name was imported.
                if sym.kind != UNBOUND_IMPORTED:
                    self.fail(
                        'Internal error (node is None, kind={})'.format(
                            sym.kind), t)
                return AnyType(TypeOfAny.special_form)
            fullname = sym.node.fullname()
            hook = self.plugin.get_type_analyze_hook(fullname)
            if hook:
                return hook(AnalyzeTypeContext(t, t, self))
            if (fullname in nongen_builtins and t.args
                    and not self.allow_unnormalized):
                self.fail(
                    no_subscript_builtin_alias(
                        fullname, propose_alt=not self.defining_alias), t)
            if self.tvar_scope:
                tvar_def = self.tvar_scope.get_binding(sym)
            else:
                tvar_def = None
            if sym.kind == TVAR and tvar_def is not None and self.defining_alias:
                self.fail(
                    'Can\'t use bound type variable "{}"'
                    ' to define generic alias'.format(t.name), t)
                return AnyType(TypeOfAny.from_error)
            elif sym.kind == TVAR and tvar_def is not None:
                if len(t.args) > 0:
                    self.fail(
                        'Type variable "{}" used with arguments'.format(
                            t.name), t)
                return TypeVarType(tvar_def, t.line)
            elif fullname == 'builtins.None':
                return NoneTyp()
            elif fullname == 'typing.Any' or fullname == 'builtins.Any':
                return AnyType(TypeOfAny.explicit)
            elif fullname in ('typing.Final', 'typing_extensions.Final'):
                self.fail(
                    "Final can be only used as an outermost qualifier"
                    " in a variable annotation", t)
                return AnyType(TypeOfAny.from_error)
            elif fullname == 'typing.Tuple':
                if len(t.args) == 0 and not t.empty_tuple_index:
                    # Bare 'Tuple' is same as 'tuple'
                    if self.options.disallow_any_generics and not self.is_typeshed_stub:
                        self.fail(messages.BARE_GENERIC, t)
                    return self.named_type('builtins.tuple',
                                           line=t.line,
                                           column=t.column)
                if len(t.args) == 2 and isinstance(t.args[1], EllipsisType):
                    # Tuple[T, ...] (uniform, variable-length tuple)
                    instance = self.named_type('builtins.tuple',
                                               [self.anal_type(t.args[0])])
                    instance.line = t.line
                    return instance
                return self.tuple_type(self.anal_array(t.args))
            elif fullname == 'typing.Union':
                items = self.anal_array(t.args)
                return UnionType.make_union(items)
            elif fullname == 'typing.Optional':
                if len(t.args) != 1:
                    self.fail(
                        'Optional[...] must have exactly one type argument', t)
                    return AnyType(TypeOfAny.from_error)
                item = self.anal_type(t.args[0])
                return make_optional_type(item)
            elif fullname == 'typing.Callable':
                return self.analyze_callable_type(t)
            elif fullname == 'typing.Type':
                if len(t.args) == 0:
                    any_type = AnyType(TypeOfAny.from_omitted_generics,
                                       line=t.line,
                                       column=t.column)
                    return TypeType(any_type, line=t.line, column=t.column)
                if len(t.args) != 1:
                    self.fail('Type[...] must have exactly one type argument',
                              t)
                item = self.anal_type(t.args[0])
                return TypeType.make_normalized(item, line=t.line)
            elif fullname == 'typing.ClassVar':
                if self.nesting_level > 0:
                    self.fail(
                        'Invalid type: ClassVar nested inside other type', t)
                if len(t.args) == 0:
                    return AnyType(TypeOfAny.from_omitted_generics,
                                   line=t.line,
                                   column=t.column)
                if len(t.args) != 1:
                    self.fail(
                        'ClassVar[...] must have at most one type argument', t)
                    return AnyType(TypeOfAny.from_error)
                item = self.anal_type(t.args[0])
                if isinstance(item, TypeVarType) or get_type_vars(item):
                    self.fail('Invalid type: ClassVar cannot be generic', t)
                    return AnyType(TypeOfAny.from_error)
                return item
            elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'):
                return UninhabitedType(is_noreturn=True)
            elif isinstance(sym.node, TypeAlias):
                self.aliases_used.add(sym.node.fullname())
                all_vars = sym.node.alias_tvars
                target = sym.node.target
                an_args = self.anal_array(t.args)
                return expand_type_alias(target, all_vars, an_args, self.fail,
                                         sym.node.no_args, t)
            elif not isinstance(sym.node, TypeInfo):
                # Something unusual. We try our best to find out what it is.
                name = sym.fullname
                if name is None:
                    name = sym.node.name()
                # Option 1:
                # Something with an Any type -- make it an alias for Any in a type
                # context. This is slightly problematic as it allows using the type 'Any'
                # as a base class -- however, this will fail soon at runtime so the problem
                # is pretty minor.
                if isinstance(sym.node, Var) and isinstance(
                        sym.node.type, AnyType):
                    return AnyType(
                        TypeOfAny.from_unimported_type,
                        missing_import_name=sym.node.type.missing_import_name)
                # Option 2:
                # Unbound type variable. Currently these may be still valid,
                # for example when defining a generic type alias.
                unbound_tvar = ((sym.kind == TVAR) and
                                (not self.tvar_scope
                                 or self.tvar_scope.get_binding(sym) is None))
                if self.allow_unbound_tvars and unbound_tvar and not self.third_pass:
                    return t
                # Option 3:
                # If it is not something clearly bad (like a known function, variable,
                # type variable, or module), and it is still not too late, we try deferring
                # this type using a forward reference wrapper. It will be revisited in
                # the third pass.
                allow_forward_ref = not (
                    self.third_pass or isinstance(sym.node,
                                                  (FuncDef, Decorator))
                    or isinstance(sym.node, Var) and sym.node.is_ready
                    or sym.kind in (MODULE_REF, TVAR))
                if allow_forward_ref:
                    # We currently can't support subscripted forward refs in functions;
                    # see https://github.com/python/mypy/pull/3952#discussion_r139950690
                    # for discussion.
                    if t.args and not self.global_scope:
                        if not self.in_dynamic_func:
                            self.fail(
                                'Unsupported forward reference to "{}"'.format(
                                    t.name), t)
                        return AnyType(TypeOfAny.from_error)
                    return ForwardRef(t)
                # None of the above options worked, we give up.
                self.fail('Invalid type "{}"'.format(name), t)
                if self.third_pass and sym.kind == TVAR:
                    self.note_func(
                        "Forward references to type variables are prohibited",
                        t)
                    return AnyType(TypeOfAny.from_error)
                # TODO: Would it be better to always return Any instead of UnboundType
                # in case of an error? On one hand, UnboundType has a name so error messages
                # are more detailed, on the other hand, some of them may be bogus.
                return t
            info = sym.node  # type: TypeInfo
            if len(t.args) > 0 and info.fullname() == 'builtins.tuple':
                fallback = Instance(info, [AnyType(TypeOfAny.special_form)],
                                    t.line)
                return TupleType(self.anal_array(t.args), fallback, t.line)
            else:
                # Analyze arguments and construct Instance type. The
                # number of type arguments and their values are
                # checked only later, since we do not always know the
                # valid count at this point. Thus we may construct an
                # Instance with an invalid number of type arguments.
                instance = Instance(info, self.anal_array(t.args), t.line,
                                    t.column)
                if not t.args and self.options.disallow_any_generics and not self.defining_alias:
                    # We report/patch invalid built-in instances already during second pass.
                    # This is done to avoid storing additional state on instances.
                    # All other (including user defined) generics will be patched/reported
                    # in the third pass.
                    if not self.is_typeshed_stub and info.fullname(
                    ) in nongen_builtins:
                        alternative = nongen_builtins[info.fullname()]
                        self.fail(
                            messages.IMPLICIT_GENERIC_ANY_BUILTIN.format(
                                alternative), t)
                        any_type = AnyType(TypeOfAny.from_error, line=t.line)
                    else:
                        any_type = AnyType(TypeOfAny.from_omitted_generics,
                                           line=t.line)
                    instance.args = [any_type] * len(info.type_vars)

                tup = info.tuple_type
                if tup is not None:
                    # The class has a Tuple[...] base class so it will be
                    # represented as a tuple type.
                    if t.args:
                        self.fail('Generic tuple types not supported', t)
                        return AnyType(TypeOfAny.from_error)
                    return tup.copy_modified(items=self.anal_array(tup.items),
                                             fallback=instance)
                td = info.typeddict_type
                if td is not None:
                    # The class has a TypedDict[...] base class so it will be
                    # represented as a typeddict type.
                    if t.args:
                        self.fail('Generic TypedDict types not supported', t)
                        return AnyType(TypeOfAny.from_error)
                    # Create a named TypedDictType
                    return td.copy_modified(item_types=self.anal_array(
                        list(td.items.values())),
                                            fallback=instance)
                return instance
        else:
            if self.third_pass:
                self.fail('Invalid type "{}"'.format(t.name), t)
                return AnyType(TypeOfAny.from_error)
            return AnyType(TypeOfAny.special_form)