Exemple #1
0
 def visit_callable_type(self, t: CallableType) -> ProperType:
     if isinstance(self.s, CallableType) and is_similar_callables(
             t, self.s):
         if is_equivalent(t, self.s):
             return combine_similar_callables(t, self.s)
         result = meet_similar_callables(t, self.s)
         # We set the from_type_type flag to suppress error when a collection of
         # concrete class objects gets inferred as their common abstract superclass.
         if not (
             (t.is_type_obj() and t.type_object().is_abstract) or
             (self.s.is_type_obj() and self.s.type_object().is_abstract)):
             result.from_type_type = True
         if isinstance(get_proper_type(result.ret_type), UninhabitedType):
             # Return a plain None or <uninhabited> instead of a weird function.
             return self.default(self.s)
         return result
     elif isinstance(self.s,
                     TypeType) and t.is_type_obj() and not t.is_generic():
         # In this case we are able to potentially produce a better meet.
         res = meet_types(self.s.item, t.ret_type)
         if not isinstance(res, (NoneType, UninhabitedType)):
             return TypeType.make_normalized(res)
         return self.default(self.s)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return self.default(self.s)
Exemple #2
0
 def visit_callable_type(self, t: CallableType) -> Type:
     if isinstance(self.s, CallableType) and is_similar_callables(t, self.s):
         if is_equivalent(t, self.s):
             return combine_similar_callables(t, self.s)
         result = meet_similar_callables(t, self.s)
         if isinstance(result.ret_type, UninhabitedType):
             # Return a plain None or <uninhabited> instead of a weird function.
             return self.default(self.s)
         return result
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return self.default(self.s)
Exemple #3
0
 def visit_callable_type(self, t: CallableType) -> Type:
     if isinstance(self.s, CallableType) and is_similar_callables(t, self.s):
         if is_equivalent(t, self.s):
             return combine_similar_callables(t, self.s)
         result = meet_similar_callables(t, self.s)
         if isinstance(result.ret_type, UninhabitedType):
             # Return a plain None or <uninhabited> instead of a weird function.
             return self.default(self.s)
         return result
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return self.default(self.s)
Exemple #4
0
 def visit_instance(self, t: Instance) -> ProperType:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 # N.B: We use zip instead of indexing because the lengths might have
                 # mismatches during daemon reprocessing.
                 for ta, sia in zip(t.args, si.args):
                     args.append(self.meet(ta, sia))
                 return Instance(t.type, args)
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, FunctionLike) and self.s.is_type_obj(
     ) and t.type.is_metaclass():
         if is_subtype(self.s.fallback, t):
             return self.s
         return self.default(self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TypedDictType):
         return meet_types(t, self.s)
     return self.default(self.s)
Exemple #5
0
 def visit_instance(self, t: Instance) -> ProperType:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 for i in range(len(t.args)):
                     args.append(self.meet(t.args[i], si.args[i]))
                 return Instance(t.type, args)
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneType()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, FunctionLike) and self.s.is_type_obj(
     ) and t.type.is_metaclass():
         if is_subtype(self.s.fallback, t):
             return self.s
         return self.default(self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TypedDictType):
         return meet_types(t, self.s)
     return self.default(self.s)
Exemple #6
0
 def visit_overloaded(self, t: Overloaded) -> ProperType:
     # TODO: Implement a better algorithm that covers at least the same cases
     # as TypeJoinVisitor.visit_overloaded().
     s = self.s
     if isinstance(s, FunctionLike):
         if s.items() == t.items():
             return Overloaded(t.items())
         elif is_subtype(s, t):
             return s
         elif is_subtype(t, s):
             return t
         else:
             return meet_types(t.fallback, s.fallback)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return meet_types(t.fallback, s)
Exemple #7
0
 def visit_overloaded(self, t: Overloaded) -> Type:
     # TODO: Implement a better algorithm that covers at least the same cases
     # as TypeJoinVisitor.visit_overloaded().
     s = self.s
     if isinstance(s, FunctionLike):
         if s.items() == t.items():
             return Overloaded(t.items())
         elif is_subtype(s, t):
             return s
         elif is_subtype(t, s):
             return t
         else:
             return meet_types(t.fallback, s.fallback)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return meet_types(t.fallback, s)
Exemple #8
0
 def visit_callable_type(self, t: CallableType) -> Type:
     if isinstance(self.s, CallableType) and is_similar_callables(t, self.s):
         if is_equivalent(t, self.s):
             return combine_similar_callables(t, self.s)
         result = meet_similar_callables(t, self.s)
         if isinstance(result.ret_type, UninhabitedType):
             # Return a plain None or <uninhabited> instead of a weird function.
             return self.default(self.s)
         return result
     elif isinstance(self.s, TypeType) and t.is_type_obj() and not t.is_generic():
         # In this case we are able to potentially produce a better meet.
         res = meet_types(self.s.item, t.ret_type)
         if not isinstance(res, (NoneType, UninhabitedType)):
             return TypeType.make_normalized(res)
         return self.default(self.s)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return self.default(self.s)
Exemple #9
0
 def visit_callable_type(self, t: CallableType) -> Type:
     if isinstance(self.s, CallableType) and is_similar_callables(t, self.s):
         if is_equivalent(t, self.s):
             return combine_similar_callables(t, self.s)
         result = meet_similar_callables(t, self.s)
         if isinstance(result.ret_type, UninhabitedType):
             # Return a plain None or <uninhabited> instead of a weird function.
             return self.default(self.s)
         return result
     elif isinstance(self.s, TypeType) and t.is_type_obj() and not t.is_generic():
         # In this case we are able to potentially produce a better meet.
         res = meet_types(self.s.item, t.ret_type)
         if not isinstance(res, (NoneType, UninhabitedType)):
             return TypeType.make_normalized(res)
         return self.default(self.s)
     elif isinstance(self.s, Instance) and self.s.type.is_protocol:
         call = unpack_callback_protocol(self.s)
         if call:
             return meet_types(t, call)
     return self.default(self.s)
Exemple #10
0
 def visit_instance(self, t: Instance) -> Type:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 for i in range(len(t.args)):
                     args.append(self.meet(t.args[i], si.args[i]))
                 return Instance(t.type, args)
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if state.strict_optional:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     return self.default(self.s)
Exemple #11
0
 def visit_instance(self, t: Instance) -> Type:
     if isinstance(self.s, Instance):
         si = self.s
         if t.type == si.type:
             if is_subtype(t, self.s) or is_subtype(self.s, t):
                 # Combine type arguments. We could have used join below
                 # equivalently.
                 args = []  # type: List[Type]
                 for i in range(len(t.args)):
                     args.append(self.meet(t.args[i], si.args[i]))
                 return Instance(t.type, args)
             else:
                 if experiments.STRICT_OPTIONAL:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
         else:
             if is_subtype(t, self.s):
                 return t
             elif is_subtype(self.s, t):
                 # See also above comment.
                 return self.s
             else:
                 if experiments.STRICT_OPTIONAL:
                     return UninhabitedType()
                 else:
                     return NoneTyp()
     elif isinstance(self.s, FunctionLike) and t.type.is_protocol:
         call = unpack_callback_protocol(t)
         if call:
             return meet_types(call, self.s)
     elif isinstance(self.s, TypeType):
         return meet_types(t, self.s)
     elif isinstance(self.s, TupleType):
         return meet_types(t, self.s)
     elif isinstance(self.s, LiteralType):
         return meet_types(t, self.s)
     return self.default(self.s)