diff --git a/mypy/binder.py b/mypy/binder.py index d3482d1dad4f..228cc3f8bd7b 100644 --- a/mypy/binder.py +++ b/mypy/binder.py @@ -11,7 +11,6 @@ from mypy.nodes import Expression, IndexExpr, MemberExpr, NameExpr, RefExpr, TypeInfo, Var from mypy.options import Options from mypy.subtypes import is_same_type, is_subtype -from mypy.typeops import make_simplified_union from mypy.types import ( AnyType, Instance, @@ -277,7 +276,7 @@ def update_from_options(self, frames: list[Frame]) -> bool: # interfere with our (hacky) TypeGuard support. type = possible_types[0] else: - type = make_simplified_union(possible_types) + type = UnionType.make_union(possible_types) # Legacy guard for corner case when the original type is TypeVarType. if isinstance(declaration_type, TypeVarType) and not is_subtype( type, declaration_type diff --git a/mypy/checker.py b/mypy/checker.py index 2d82d74cc197..f98e6c26336e 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -161,7 +161,6 @@ function_type, is_literal_type_like, is_singleton_type, - make_simplified_union, true_only, try_expanding_sum_type_to_union, try_getting_int_literals_from_type, @@ -750,9 +749,6 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: defn.is_explicit_override and not found_method_base_classes and found_method_base_classes is not None - # If the class has Any fallback, we can't be certain that a method - # is really missing - it might come from unfollowed import. - and not defn.info.fallback_to_any ): self.msg.no_overridable_method(defn.name, defn) self.check_explicit_override_decorator(defn, found_method_base_classes, defn.impl) @@ -789,7 +785,7 @@ def extract_callable_type(self, inner_type: Type | None, ctx: Context) -> Callab if isinstance(inner_call, FunctionLike): outer_type = inner_call elif isinstance(inner_type, UnionType): - union_type = make_simplified_union(inner_type.items) + union_type = UnionType.make_union(inner_type.items) if isinstance(union_type, UnionType): items = [] for item in union_type.items: @@ -1024,7 +1020,7 @@ def get_generator_yield_type(self, return_type: Type, is_coroutine: bool) -> Typ if isinstance(return_type, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=return_type) elif isinstance(return_type, UnionType): - return make_simplified_union( + return UnionType.make_union( [self.get_generator_yield_type(item, is_coroutine) for item in return_type.items] ) elif not self.is_generator_return_type( @@ -1058,7 +1054,7 @@ def get_generator_receive_type(self, return_type: Type, is_coroutine: bool) -> T if isinstance(return_type, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=return_type) elif isinstance(return_type, UnionType): - return make_simplified_union( + return UnionType.make_union( [self.get_generator_receive_type(item, is_coroutine) for item in return_type.items] ) elif not self.is_generator_return_type( @@ -1101,7 +1097,7 @@ def get_generator_return_type(self, return_type: Type, is_coroutine: bool) -> Ty if isinstance(return_type, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=return_type) elif isinstance(return_type, UnionType): - return make_simplified_union( + return UnionType.make_union( [self.get_generator_return_type(item, is_coroutine) for item in return_type.items] ) elif not self.is_generator_return_type(return_type, is_coroutine): @@ -2332,7 +2328,7 @@ def get_op_other_domain(self, tp: FunctionLike) -> Type | None: raw_items = [self.get_op_other_domain(it) for it in tp.items] items = [it for it in raw_items if it] if items: - return make_simplified_union(items) + return UnionType.make_union(items) return None else: assert False, "Need to check all FunctionLike subtypes here" @@ -3184,7 +3180,7 @@ def check_assignment( if not self.current_node_deferred: # Partial type can't be final, so strip any literal values. rvalue_type = remove_instance_last_known_values(rvalue_type) - inferred_type = make_simplified_union([rvalue_type, NoneType()]) + inferred_type = UnionType.make_union([rvalue_type, NoneType()]) self.set_inferred_type(var, lvalue, inferred_type) else: var.type = None @@ -4000,7 +3996,7 @@ def check_multi_assignment_from_union( # We can access _type_maps directly since temporary type maps are # only created within expressions. t.append(self._type_maps[0].pop(lv, AnyType(TypeOfAny.special_form))) - union_types = tuple(make_simplified_union(col) for col in transposed) + union_types = tuple(UnionType.make_union(col) for col in transposed) for expr, items in assignments.items(): # Bind a union of types collected in 'assignments' to every expression. if isinstance(expr, StarExpr): @@ -4015,9 +4011,7 @@ def check_multi_assignment_from_union( types, declared_types = zip(*clean_items) self.binder.assign_type( - expr, - make_simplified_union(list(types)), - make_simplified_union(list(declared_types)), + expr, UnionType.make_union(list(types)), UnionType.make_union(list(declared_types)) ) for union, lv in zip(union_types, self.flatten_lvalues(lvalues)): # Properly store the inferred types. @@ -4510,7 +4504,7 @@ def check_simple_assignment( # at module level or class bodies can't be widened in functions, or # in another module. if not self.refers_to_different_scope(lvalue): - lvalue_type = make_simplified_union([inferred.type, new_inferred]) + lvalue_type = UnionType.make_union([inferred.type, new_inferred]) if not is_same_type(lvalue_type, inferred.type) and not isinstance( inferred.type, PartialType ): @@ -5064,7 +5058,7 @@ def check_except_handler_test(self, n: Expression, is_star: bool) -> Type: else: new_all_types.append(typ) return self.wrap_exception_group(new_all_types) - return make_simplified_union(all_types) + return UnionType.make_union(all_types) def default_exception_type(self, is_star: bool) -> Type: """Exception type to return in case of a previous type error.""" @@ -5075,7 +5069,7 @@ def default_exception_type(self, is_star: bool) -> Type: def wrap_exception_group(self, types: Sequence[Type]) -> Type: """Transform except* variable type into an appropriate exception group.""" - arg = make_simplified_union(types) + arg = UnionType.make_union(types) if is_subtype(arg, self.named_type("builtins.Exception")): base = "builtins.ExceptionGroup" else: @@ -5288,15 +5282,12 @@ def visit_decorator_inner( # For overloaded functions/properties we already checked override for overload as a whole. if allow_empty or skip_first_item: return - if e.func.info and not e.is_overload: + if e.func.info and not e.func.is_dynamic() and not e.is_overload: found_method_base_classes = self.check_method_override(e) if ( e.func.is_explicit_override and not found_method_base_classes and found_method_base_classes is not None - # If the class has Any fallback, we can't be certain that a method - # is really missing - it might come from unfollowed import. - and not e.func.info.fallback_to_any ): self.msg.no_overridable_method(e.func.name, e.func) self.check_explicit_override_decorator(e.func, found_method_base_classes) @@ -6569,7 +6560,7 @@ def replay_lookup(new_parent_type: ProperType) -> Type | None: member_types = [new_parent_type.items[key] for key in str_literals] except KeyError: return None - return make_simplified_union(member_types) + return UnionType.make_union(member_types) else: int_literals = try_getting_int_literals_from_type(index_type) @@ -6583,7 +6574,7 @@ def replay_lookup(new_parent_type: ProperType) -> Type | None: member_types = [new_parent_type.items[key] for key in int_literals] except IndexError: return None - return make_simplified_union(member_types) + return UnionType.make_union(member_types) else: return output @@ -6623,7 +6614,7 @@ def replay_lookup(new_parent_type: ProperType) -> Type | None: return output expr = parent_expr - expr_type = output[parent_expr] = make_simplified_union(new_parent_types) + expr_type = output[parent_expr] = UnionType.make_union(new_parent_types) def refine_identity_comparison_expression( self, @@ -6975,11 +6966,11 @@ def narrow_with_len(self, typ: Type, op: str, size: int) -> tuple[Type | None, T yes_types += other_types no_types += other_types if yes_types: - yes_type = make_simplified_union(yes_types) + yes_type = UnionType.make_union(yes_types) else: yes_type = None if no_types: - no_type = make_simplified_union(no_types) + no_type = UnionType.make_union(no_types) else: no_type = None return yes_type, no_type @@ -7653,7 +7644,7 @@ def conditional_types_with_intersection( for types, reason in errors: self.msg.impossible_intersection(types, reason, ctx) return UninhabitedType(), expr_type - new_yes_type = make_simplified_union(out) + new_yes_type = UnionType.make_union(out) return new_yes_type, expr_type def is_writable_attribute(self, node: Node) -> bool: @@ -7777,7 +7768,7 @@ def add_any_attribute_to_type(self, typ: Type, name: str) -> Type: ) if isinstance(typ, UnionType): with_attr, without_attr = self.partition_union_by_attr(typ, name) - return make_simplified_union( + return UnionType.make_union( with_attr + [self.add_any_attribute_to_type(typ, name) for typ in without_attr] ) return orig_typ @@ -7800,7 +7791,7 @@ def hasattr_type_maps( if isinstance(source_type, UnionType): _, without_attr = self.partition_union_by_attr(source_type, name) yes_map = {expr: self.add_any_attribute_to_type(source_type, name)} - return yes_map, {expr: make_simplified_union(without_attr)} + return yes_map, {expr: UnionType.make_union(without_attr)} type_with_attr = self.add_any_attribute_to_type(source_type, name) if type_with_attr != source_type: @@ -7945,7 +7936,7 @@ def conditional_types( enum_name = target.fallback.type.fullname current_type = try_expanding_sum_type_to_union(current_type, enum_name) proposed_items = [type_range.item for type_range in proposed_type_ranges] - proposed_type = make_simplified_union(proposed_items) + proposed_type = UnionType.make_union(proposed_items) if isinstance(proposed_type, AnyType): # We don't really know much about the proposed type, so we shouldn't # attempt to narrow anything. Instead, we broaden the expr to Any to @@ -8084,7 +8075,7 @@ def builtin_item_type(tp: Type) -> Type | None: else: normalized_items.append(it) if all(not isinstance(it, AnyType) for it in get_proper_types(normalized_items)): - return make_simplified_union(normalized_items) # this type is not externally visible + return UnionType.make_union(normalized_items) # this type is not externally visible elif isinstance(tp, TypedDictType): # TypedDict always has non-optional string keys. Find the key type from the Mapping # base class. @@ -8147,7 +8138,7 @@ def or_conditional_maps(m1: TypeMap, m2: TypeMap, coalesce_any: bool = False) -> if coalesce_any and isinstance(get_proper_type(m1[n1]), AnyType): result[n1] = m1[n1] else: - result[n1] = make_simplified_union([m1[n1], m2[n2]]) + result[n1] = UnionType.make_union([m1[n1], m2[n2]]) return result diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index ba2d38b6f528..7a9a384c6121 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -631,7 +631,7 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) -> self.check_str_format_call(e) ret_type = get_proper_type(ret_type) if isinstance(ret_type, UnionType): - ret_type = make_simplified_union(ret_type.items) + ret_type = UnionType.make_union(ret_type.items) if isinstance(ret_type, UninhabitedType) and not ret_type.ambiguous: self.chk.binder.unreachable() # Warn on calls to functions that always return None. The check @@ -1529,7 +1529,7 @@ def check_union_call_expr(self, e: CallExpr, object_type: UnionType, member: str res.append( self.check_call_expr_with_callee_type(narrowed, e, callable_name, item_object_type) ) - return make_simplified_union(res) + return UnionType.make_union(res) def check_call( self, @@ -3205,12 +3205,12 @@ def combine_function_signatures(self, types: list[ProperType]) -> AnyType | Call union_type_guard = None union_type_is = None else: - union_type_guard = make_simplified_union(new_type_guards) if new_type_guards else None + union_type_guard = UnionType.make_union(new_type_guards) if new_type_guards else None union_type_is = ( - make_simplified_union(new_type_narrowers) if new_type_narrowers else None + UnionType.make_union(new_type_narrowers) if new_type_narrowers else None ) - union_return = make_simplified_union(new_returns) + union_return = UnionType.make_union(new_returns) if too_complex: any = AnyType(TypeOfAny.special_form) @@ -3227,7 +3227,7 @@ def combine_function_signatures(self, types: list[ProperType]) -> AnyType | Call final_args = [] for args_list in new_args: - new_type = make_simplified_union(args_list) + new_type = UnionType.make_union(args_list) final_args.append(new_type) return callables[0].copy_modified( @@ -3334,7 +3334,7 @@ def check_union_call( for subtype in callee.relevant_items() ] - return (make_simplified_union([res[0] for res in results]), callee) + return (UnionType.make_union([res[0] for res in results]), callee) def visit_member_expr(self, e: MemberExpr, is_lvalue: bool = False) -> Type: """Visit member expression (of form e.id).""" @@ -3927,7 +3927,7 @@ def check_union_method_call_by_name( ) res.append(item) meth_res.append(meth_item) - return make_simplified_union(res), make_simplified_union(meth_res) + return UnionType.make_union(res), UnionType.make_union(meth_res) def check_method_call( self, @@ -4096,7 +4096,7 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None: results = [] for name, method, obj, arg in variants: with self.msg.filter_errors(save_filtered_errors=True) as local_errors: - result = self.check_method_call(name, obj, method, [arg], [ARG_POS], context) + result = self.check_method_call(op_name, obj, method, [arg], [ARG_POS], context) if local_errors.has_new_errors(): errors.append(local_errors.filtered_errors()) results.append(result) @@ -4194,8 +4194,8 @@ def check_op( all_inferred.append(inferred) if not local_errors.has_new_errors(): - results_final = make_simplified_union(all_results) - inferred_final = make_simplified_union(all_inferred) + results_final = UnionType.make_union(all_results) + inferred_final = UnionType.make_union(all_inferred) return results_final, inferred_final # Step 2: If that fails, we try again but also destructure the right argument. @@ -4253,7 +4253,7 @@ def check_op( # See the comment in 'check_overload_call' for more details on why # we call 'combine_function_signature' instead of just unioning the inferred # callable types. - results_final = make_simplified_union(all_results) + results_final = UnionType.make_union(all_results) inferred_final = self.combine_function_signatures(get_proper_types(all_inferred)) return results_final, inferred_final else: @@ -4338,7 +4338,7 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type: # The left operand is always the result return left_type else: - return make_simplified_union([restricted_left_type, right_type]) + return UnionType.make_union([restricted_left_type, right_type]) def check_list_multiply(self, e: OpExpr) -> Type: """Type check an expression of form '[...] * e'. @@ -4451,7 +4451,7 @@ def visit_index_with_type( min_len = self.min_tuple_length(left_type) self.chk.note(f"Variadic tuple can have length {min_len}", e) return AnyType(TypeOfAny.from_error) - return make_simplified_union(out) + return UnionType.make_union(out) else: return self.nonliteral_tuple_index_helper(left_type, index) elif isinstance(left_type, TypedDictType): @@ -4567,7 +4567,7 @@ def visit_tuple_slice_helper(self, left_type: TupleType, slic: SliceExpr) -> Typ self.chk.fail(message_registry.AMBIGUOUS_SLICE_OF_VARIADIC_TUPLE, slic) return AnyType(TypeOfAny.from_error) items.append(item) - return make_simplified_union(items) + return UnionType.make_union(items) def try_getting_int_literals(self, index: Expression) -> list[int] | None: """If the given expression or type corresponds to an int literal @@ -4632,7 +4632,7 @@ def union_tuple_fallback_item(self, left_type: TupleType) -> Type: raise NotImplementedError else: items.append(item) - return make_simplified_union(items) + return UnionType.make_union(items) def visit_typeddict_index_expr( self, td_type: TypedDictType, index: Expression, setitem: bool = False @@ -4669,7 +4669,7 @@ def visit_typeddict_index_expr( return AnyType(TypeOfAny.from_error), set() else: value_types.append(value_type) - return make_simplified_union(value_types), set(key_names) + return UnionType.make_union(value_types), set(key_names) def visit_enum_index_expr( self, enum_type: TypeInfo, index: Expression, context: Context @@ -5899,7 +5899,7 @@ def visit_conditional_expr(self, e: ConditionalExpr, allow_none_return: bool = F if is_literal_type_like(full_context_else_type) and not is_literal_type_like(else_type): else_type = full_context_else_type - res: Type = make_simplified_union([if_type, else_type]) + res: Type = UnionType.make_union([if_type, else_type]) if has_uninhabited_component(res) and not isinstance( get_proper_type(self.type_context[-1]), UnionType ): @@ -6297,13 +6297,7 @@ def narrow_type_from_binder( known_type, restriction, prohibit_none_typevar_overlap=True ): return None - narrowed = narrow_declared_type(known_type, restriction) - if isinstance(get_proper_type(narrowed), UninhabitedType): - # If we hit this case, it means that we can't reliably mark the code as - # unreachable, but the resulting type can't be expressed in type system. - # Falling back to restriction is more intuitive in most cases. - return restriction - return narrowed + return narrow_declared_type(known_type, restriction) return known_type def has_abstract_type_part(self, caller_type: ProperType, callee_type: ProperType) -> bool: diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 1a76372d4731..16995e73e3cc 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -45,7 +45,6 @@ function_type, get_all_type_vars, get_type_vars, - make_simplified_union, supported_self_type, tuple_fallback, type_object_type, @@ -258,7 +257,7 @@ def _analyze_member_access( elif isinstance(typ, TypeVarLikeType): if isinstance(typ, TypeVarType) and typ.values: return _analyze_member_access( - name, make_simplified_union(typ.values), mx, override_info + name, UnionType.make_union(typ.values), mx, override_info ) return _analyze_member_access(name, typ.upper_bound, mx, override_info) elif isinstance(typ, DeletedType): @@ -486,7 +485,7 @@ def analyze_union_member_access(name: str, typ: UnionType, mx: MemberContext) -> # Self types should be bound to every individual item of a union. item_mx = mx.copy_modified(self_type=subtype) results.append(_analyze_member_access(name, subtype, item_mx)) - return make_simplified_union(results) + return UnionType.make_union(results) def analyze_none_member_access(name: str, typ: NoneType, mx: MemberContext) -> Type: @@ -668,7 +667,7 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type: if isinstance(descriptor_type, UnionType): # Map the access over union types - return make_simplified_union( + return UnionType.make_union( [analyze_descriptor_access(typ, mx) for typ in descriptor_type.items] ) elif not isinstance(descriptor_type, Instance): diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 4cf7c1ca7862..12f1f50f964f 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -29,12 +29,7 @@ ) from mypy.plugin import Plugin from mypy.subtypes import is_subtype -from mypy.typeops import ( - coerce_to_literal, - make_simplified_union, - try_getting_str_literals_from_type, - tuple_fallback, -) +from mypy.typeops import coerce_to_literal, try_getting_str_literals_from_type, tuple_fallback from mypy.types import ( AnyType, Instance, @@ -196,7 +191,7 @@ def visit_or_pattern(self, o: OrPattern) -> PatternType: captures[capture_list[0][0]] = typ - union_type = make_simplified_union(types) + union_type = UnionType.make_union(types) return PatternType(union_type, current_type, captures) def visit_value_pattern(self, o: ValuePattern) -> PatternType: @@ -359,7 +354,7 @@ def get_sequence_type(self, t: Type, context: Context) -> Type | None: items = [self.get_sequence_type(item, context) for item in t.items] not_none_items = [item for item in items if item is not None] if not_none_items: - return make_simplified_union(not_none_items) + return UnionType.make_union(not_none_items) else: return None @@ -409,13 +404,13 @@ def contract_starred_pattern_types( new_middle.append(unpacked.args[0]) else: new_middle.append(m) - return list(prefix) + [make_simplified_union(new_middle)] + list(suffix) + return list(prefix) + [UnionType.make_union(new_middle)] + list(suffix) else: if star_pos is None: return types new_types = types[:star_pos] star_length = len(types) - num_patterns - new_types.append(make_simplified_union(types[star_pos : star_pos + star_length])) + new_types.append(UnionType.make_union(types[star_pos : star_pos + star_length])) new_types += types[star_pos + star_length :] return new_types @@ -764,7 +759,7 @@ def construct_sequence_child(self, outer_type: Type, inner_type: Type) -> Type: for item in proper_type.items if self.can_match_sequence(get_proper_type(item)) ] - return make_simplified_union(types) + return UnionType.make_union(types) sequence = self.chk.named_generic_type("typing.Sequence", [inner_type]) if is_subtype(outer_type, self.chk.named_type("typing.Sequence")): if isinstance(proper_type, TupleType): diff --git a/mypy/erasetype.py b/mypy/erasetype.py index 6c47670d6687..f2528229a7ce 100644 --- a/mypy/erasetype.py +++ b/mypy/erasetype.py @@ -129,9 +129,8 @@ def visit_literal_type(self, t: LiteralType) -> ProperType: def visit_union_type(self, t: UnionType) -> ProperType: erased_items = [erase_type(item) for item in t.items] - from mypy.typeops import make_simplified_union - return make_simplified_union(erased_items) + return UnionType.make_union(erased_items) def visit_type_type(self, t: TypeType) -> ProperType: return TypeType.make_normalized(t.item.accept(self), line=t.line) @@ -269,9 +268,8 @@ def visit_union_type(self, t: UnionType) -> Type: if len(types) == 1: merged.append(item) else: - from mypy.typeops import make_simplified_union - merged.append(make_simplified_union(types)) + merged.append(UnionType.make_union(types)) del instances_by_name[item.type.fullname] else: merged.append(orig_item) diff --git a/mypy/meet.py b/mypy/meet.py index add0785f5e71..2d2f150f0f0b 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -15,7 +15,7 @@ is_same_type, is_subtype, ) -from mypy.typeops import is_recursive_pair, make_simplified_union, tuple_fallback +from mypy.typeops import is_recursive_pair, tuple_fallback from mypy.types import ( MYPYC_NATIVE_INT_NAMES, TUPLE_LIKE_INSTANCE_NAMES, @@ -127,7 +127,7 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type: if declared == narrowed: return original_declared if isinstance(declared, UnionType): - return make_simplified_union( + return UnionType.make_union( [ narrow_declared_type(x, narrowed) for x in declared.relevant_items() @@ -146,7 +146,7 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type: # Quick check before reaching `is_overlapping_types`. If it's enum/literal overlap, # avoid full expansion and make it faster. assert isinstance(narrowed, UnionType) - return make_simplified_union( + return UnionType.make_union( [narrow_declared_type(declared, x) for x in narrowed.relevant_items()] ) elif not is_overlapping_types(declared, narrowed, prohibit_none_typevar_overlap=True): @@ -155,7 +155,7 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type: else: return NoneType() elif isinstance(narrowed, UnionType): - return make_simplified_union( + return UnionType.make_union( [narrow_declared_type(declared, x) for x in narrowed.relevant_items()] ) elif isinstance(narrowed, AnyType): @@ -745,7 +745,7 @@ def visit_union_type(self, t: UnionType) -> ProperType: meets.append(meet_types(x, y)) else: meets = [meet_types(x, self.s) for x in t.items] - return make_simplified_union(meets) + return UnionType.make_union(meets) def visit_none_type(self, t: NoneType) -> ProperType: if state.strict_optional: diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index b7b3821576ea..f106dd7395ba 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -56,12 +56,7 @@ ) from mypy.server.trigger import make_wildcard_trigger from mypy.state import state -from mypy.typeops import ( - get_type_vars, - make_simplified_union, - map_type_from_supertype, - type_object_type, -) +from mypy.typeops import get_type_vars, map_type_from_supertype, type_object_type from mypy.types import ( AnyType, CallableType, @@ -782,7 +777,7 @@ def _parse_converter( types.append(item.arg_types[0]) # Make a union of all the valid types. if types: - converter_info.init_type = make_simplified_union(types) + converter_info.init_type = UnionType.make_union(types) if is_attr_converters_optional and converter_info.init_type: # If the converter was attr.converter.optional(type) then add None to diff --git a/mypy/plugins/ctypes.py b/mypy/plugins/ctypes.py index b6dbec13ce90..98b63998ab17 100644 --- a/mypy/plugins/ctypes.py +++ b/mypy/plugins/ctypes.py @@ -8,7 +8,6 @@ from mypy.maptype import map_instance_to_supertype from mypy.messages import format_type from mypy.subtypes import is_subtype -from mypy.typeops import make_simplified_union from mypy.types import ( AnyType, CallableType, @@ -72,7 +71,7 @@ def _autoconvertible_to_cdata(tp: Type, api: mypy.plugin.CheckerPluginInterface) allowed_types.append(api.named_generic_type("builtins.int", [])) allowed_types.append(NoneType()) - return make_simplified_union(allowed_types) + return UnionType.make_union(allowed_types) def _autounboxed_cdata(tp: Type) -> ProperType: @@ -85,7 +84,7 @@ def _autounboxed_cdata(tp: Type) -> ProperType: tp = get_proper_type(tp) if isinstance(tp, UnionType): - return make_simplified_union([_autounboxed_cdata(t) for t in tp.items]) + return UnionType.make_union([_autounboxed_cdata(t) for t in tp.items]) elif isinstance(tp, Instance): for base in tp.type.bases: if base.type.fullname == "_ctypes._SimpleCData": @@ -218,7 +217,7 @@ def array_value_callback(ctx: mypy.plugin.AttributeContext) -> Type: ), ctx.context, ) - return make_simplified_union(types) + return UnionType.make_union(types) return ctx.default_attr_type @@ -241,5 +240,5 @@ def array_raw_callback(ctx: mypy.plugin.AttributeContext) -> Type: ' with element type "c_char", not {}'.format(format_type(et, ctx.api.options)), ctx.context, ) - return make_simplified_union(types) + return UnionType.make_union(types) return ctx.default_attr_type diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index 81d2f19dc17b..070c56a29e8c 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -17,7 +17,7 @@ ) from mypy.plugins.common import try_getting_str_literals from mypy.subtypes import is_subtype -from mypy.typeops import is_literal_type_like, make_simplified_union +from mypy.typeops import is_literal_type_like from mypy.types import ( TPDICT_FB_NAMES, AnyType, @@ -222,7 +222,7 @@ def typed_dict_get_signature_callback(ctx: MethodSigContext) -> CallableType: tv = signature.variables[0] assert isinstance(tv, TypeVarType) return signature.copy_modified( - arg_types=[signature.arg_types[0], make_simplified_union([value_type, tv])], + arg_types=[signature.arg_types[0], UnionType.make_union([value_type, tv])], ret_type=ret_type, ) return signature @@ -263,7 +263,7 @@ def typed_dict_get_callback(ctx: MethodContext) -> Type: if len(ctx.arg_types) == 1: output_types.append(NoneType()) - return make_simplified_union(output_types) + return UnionType.make_union(output_types) return ctx.default_return_type @@ -292,7 +292,7 @@ def typed_dict_pop_signature_callback(ctx: MethodSigContext) -> CallableType: # variable that accepts everything. tv = signature.variables[0] assert isinstance(tv, TypeVarType) - typ = make_simplified_union([value_type, tv]) + typ = UnionType.make_union([value_type, tv]) return signature.copy_modified(arg_types=[str_type, typ], ret_type=typ) return signature.copy_modified(arg_types=[str_type, signature.arg_types[1]]) @@ -327,9 +327,9 @@ def typed_dict_pop_callback(ctx: MethodContext) -> Type: return AnyType(TypeOfAny.from_error) if len(ctx.args[1]) == 0: - return make_simplified_union(value_types) + return UnionType.make_union(value_types) elif len(ctx.arg_types) == 2 and len(ctx.arg_types[1]) == 1 and len(ctx.args[1]) == 1: - return make_simplified_union([*value_types, ctx.arg_types[1][0]]) + return UnionType.make_union([*value_types, ctx.arg_types[1][0]]) return ctx.default_return_type @@ -401,7 +401,7 @@ def typed_dict_setdefault_callback(ctx: MethodContext) -> Type: value_types.append(value_type) - return make_simplified_union(value_types) + return UnionType.make_union(value_types) return ctx.default_return_type @@ -479,7 +479,7 @@ def typed_dict_update_signature_callback(ctx: MethodSigContext) -> CallableType: item = item.copy_modified(item_names=list(td.items)) items.append(item) if items: - arg_type = make_simplified_union(items) + arg_type = UnionType.make_union(items) return signature.copy_modified(arg_types=[arg_type]) return signature diff --git a/mypy/plugins/enums.py b/mypy/plugins/enums.py index 8b7c5df6f51f..1a65614c0f3a 100644 --- a/mypy/plugins/enums.py +++ b/mypy/plugins/enums.py @@ -20,13 +20,14 @@ from mypy.nodes import TypeInfo from mypy.semanal_enum import ENUM_BASES from mypy.subtypes import is_equivalent -from mypy.typeops import fixup_partial_type, make_simplified_union +from mypy.typeops import fixup_partial_type from mypy.types import ( CallableType, Instance, LiteralType, ProperType, Type, + UnionType, get_proper_type, is_named_instance, ) @@ -235,7 +236,7 @@ class SomeEnum: for proper_type in proper_types ) if all_equivalent_types: - return make_simplified_union(cast(Sequence[Type], proper_types)) + return UnionType.make_union(cast(Sequence[Type], proper_types)) return ctx.default_attr_type assert isinstance(ctx.type, Instance) diff --git a/mypy/semanal_shared.py b/mypy/semanal_shared.py index bdd01ef6a6f3..63479e311338 100644 --- a/mypy/semanal_shared.py +++ b/mypy/semanal_shared.py @@ -28,7 +28,6 @@ from mypy.plugin import SemanticAnalyzerPluginInterface from mypy.tvar_scope import TypeVarLikeScope from mypy.type_visitor import ANY_STRATEGY, BoolTypeQuery -from mypy.typeops import make_simplified_union from mypy.types import ( TPDICT_FB_NAMES, AnyType, @@ -45,6 +44,7 @@ TypeVarId, TypeVarLikeType, TypeVarTupleType, + UnionType, UnpackType, get_proper_type, ) @@ -305,7 +305,7 @@ def calculate_tuple_fallback(typ: TupleType) -> None: raise NotImplementedError else: items.append(item) - fallback.args = (make_simplified_union(items),) + fallback.args = (UnionType.make_union(items),) class _NamedTypeCallback(Protocol): diff --git a/mypy/suggestions.py b/mypy/suggestions.py index f27ad7cdb637..55c92eb75f7a 100644 --- a/mypy/suggestions.py +++ b/mypy/suggestions.py @@ -60,7 +60,7 @@ from mypy.server.update import FineGrainedBuildManager from mypy.state import state from mypy.traverser import TraverserVisitor -from mypy.typeops import bind_self, make_simplified_union +from mypy.typeops import bind_self from mypy.types import ( AnyType, CallableType, @@ -924,7 +924,7 @@ def generate_type_combinations(types: list[Type]) -> list[Type]: and unioning the types. We try both. """ joined_type = join_type_list(types) - union_type = make_simplified_union(types) + union_type = UnionType.make_union(types) if joined_type == union_type: return [joined_type] else: @@ -1018,7 +1018,7 @@ def refine_union(t: UnionType, s: ProperType) -> Type: # Turn strict optional on when simplifying the union since we # don't want to drop Nones. with state.strict_optional_set(True): - return make_simplified_union(new_items) + return UnionType.make_union(new_items) def refine_callable(t: CallableType, s: CallableType) -> CallableType: diff --git a/mypy/typeops.py b/mypy/typeops.py index bcf946900563..ebfca1297bdf 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -846,14 +846,14 @@ def erase_def_to_union_or_bound(tdef: TypeVarLikeType) -> Type: if isinstance(tdef, ParamSpecType): return AnyType(TypeOfAny.from_error) if isinstance(tdef, TypeVarType) and tdef.values: - return make_simplified_union(tdef.values) + return UnionType.make_union(tdef.values) else: return tdef.upper_bound def erase_to_union_or_bound(typ: TypeVarType) -> ProperType: if typ.values: - return make_simplified_union(typ.values) + return UnionType.make_union(typ.values) else: return get_proper_type(typ.upper_bound)