39
39
from mypy import messages
40
40
from mypy .subtypes import (
41
41
is_subtype , is_equivalent , is_proper_subtype , is_more_precise ,
42
- restrict_subtype_away , is_subtype_ignoring_tvars , is_callable_subtype ,
42
+ restrict_subtype_away , is_subtype_ignoring_tvars , is_callable_compatible ,
43
43
unify_generic_callable , find_member
44
44
)
45
45
from mypy .maptype import map_instance_to_supertype
@@ -407,22 +407,32 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
407
407
if defn .info :
408
408
self .check_method_override (defn )
409
409
self .check_inplace_operator_method (defn )
410
- self .check_overlapping_overloads (defn )
410
+ if not defn .is_property :
411
+ self .check_overlapping_overloads (defn )
411
412
return None
412
413
413
414
def check_overlapping_overloads (self , defn : OverloadedFuncDef ) -> None :
414
415
# At this point we should have set the impl already, and all remaining
415
416
# items are decorators
416
417
for i , item in enumerate (defn .items ):
418
+ # TODO overloads involving decorators
417
419
assert isinstance (item , Decorator )
418
420
sig1 = self .function_type (item .func )
421
+
419
422
for j , item2 in enumerate (defn .items [i + 1 :]):
420
- # TODO overloads involving decorators
421
423
assert isinstance (item2 , Decorator )
422
424
sig2 = self .function_type (item2 .func )
423
- if is_unsafe_overlapping_signatures (sig1 , sig2 ):
424
- self .msg .overloaded_signatures_overlap (i + 1 , i + j + 2 ,
425
- item .func )
425
+
426
+ assert isinstance (sig1 , CallableType )
427
+ assert isinstance (sig2 , CallableType )
428
+
429
+ if not are_argument_counts_overlapping (sig1 , sig2 ):
430
+ continue
431
+
432
+ if if_overload_can_never_match (sig1 , sig2 ):
433
+ self .msg .overloaded_signature_will_never_match (i + 1 , i + j + 2 , item2 .func )
434
+ elif is_unsafe_overlapping_overload_signatures (sig1 , sig2 ):
435
+ self .msg .overloaded_signatures_overlap (i + 1 , i + j + 2 , item .func )
426
436
if defn .impl :
427
437
if isinstance (defn .impl , FuncDef ):
428
438
impl_type = defn .impl .type
@@ -437,7 +447,8 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None:
437
447
438
448
assert isinstance (impl_type , CallableType )
439
449
assert isinstance (sig1 , CallableType )
440
- if not is_callable_subtype (impl_type , sig1 , ignore_return = True ):
450
+ if not is_callable_compatible (impl_type , sig1 ,
451
+ is_compat = is_subtype , ignore_return = True ):
441
452
self .msg .overloaded_signatures_arg_specific (i + 1 , defn .impl )
442
453
impl_type_subst = impl_type
443
454
if impl_type .variables :
@@ -1038,8 +1049,8 @@ def check_overlapping_op_methods(self,
1038
1049
fallback = self .named_type ('builtins.function' ),
1039
1050
name = reverse_type .name )
1040
1051
1041
- if is_unsafe_overlapping_signatures ( forward_tweaked ,
1042
- reverse_tweaked ):
1052
+ if is_unsafe_overlapping_operator_signatures (
1053
+ forward_tweaked , reverse_tweaked ):
1043
1054
self .msg .operator_method_signatures_overlap (
1044
1055
reverse_class , reverse_name ,
1045
1056
forward_base , forward_name , context )
@@ -1812,10 +1823,18 @@ def check_multi_assignment_from_union(self, lvalues: List[Expression], rvalue: E
1812
1823
# Bind a union of types collected in 'assignments' to every expression.
1813
1824
if isinstance (expr , StarExpr ):
1814
1825
expr = expr .expr
1815
- types , declared_types = zip (* items )
1826
+
1827
+ # TODO: See todo in binder.py, ConditionalTypeBinder.assign_type
1828
+ # It's unclear why the 'declared_type' param is sometimes 'None'
1829
+ clean_items = [] # type: List[Tuple[Type, Type]]
1830
+ for type , declared_type in items :
1831
+ assert declared_type is not None
1832
+ clean_items .append ((type , declared_type ))
1833
+
1834
+ types , declared_types = zip (* clean_items )
1816
1835
self .binder .assign_type (expr ,
1817
- UnionType .make_simplified_union (types ),
1818
- UnionType .make_simplified_union (declared_types ),
1836
+ UnionType .make_simplified_union (list ( types ) ),
1837
+ UnionType .make_simplified_union (list ( declared_types ) ),
1819
1838
False )
1820
1839
for union , lv in zip (union_types , self .flatten_lvalues (lvalues )):
1821
1840
# Properly store the inferred types.
@@ -3527,18 +3546,96 @@ def type(self, type: Type) -> Type:
3527
3546
return expand_type (type , self .map )
3528
3547
3529
3548
3530
- def is_unsafe_overlapping_signatures (signature : Type , other : Type ) -> bool :
3531
- """Check if two signatures may be unsafely overlapping.
3549
+ def are_argument_counts_overlapping (t : CallableType , s : CallableType ) -> bool :
3550
+ """Can a single call match both t and s, based just on positional argument counts?
3551
+ """
3552
+ min_args = max (t .min_args , s .min_args )
3553
+ max_args = min (t .max_possible_positional_args (), s .max_possible_positional_args ())
3554
+ return min_args <= max_args
3532
3555
3533
- Two signatures s and t are overlapping if both can be valid for the same
3556
+
3557
+ def is_unsafe_overlapping_overload_signatures (signature : CallableType ,
3558
+ other : CallableType ) -> bool :
3559
+ """Check if two overloaded function signatures may be unsafely overlapping.
3560
+
3561
+ We consider two functions 's' and 't' to be unsafely overlapping both
3562
+ of the following are true:
3563
+
3564
+ 1. s's parameters are all more precise or partially overlapping with t's
3565
+ 1. s's return type is NOT a subtype of t's.
3566
+
3567
+ both can be valid for the same
3534
3568
statically typed values and the return types are incompatible.
3535
3569
3570
+ Assumes that 'signature' appears earlier in the list of overload
3571
+ alternatives then 'other' and that their argument counts are overlapping.
3572
+ """
3573
+ # TODO: Handle partially overlapping parameter types and argument counts
3574
+ #
3575
+ # For example, the signatures "f(x: Union[A, B]) -> int" and "f(x: Union[B, C]) -> str"
3576
+ # is unsafe: the parameter types are partially overlapping.
3577
+ #
3578
+ # To fix this, we need to either modify meet.is_overlapping_types or add a new
3579
+ # function and use "is_more_precise(...) or is_partially_overlapping(...)" for the is_compat
3580
+ # checks.
3581
+ #
3582
+ # Similarly, the signatures "f(x: A, y: A) -> str" and "f(*x: A) -> int" are also unsafe:
3583
+ # the parameter *counts* or arity are partially overlapping.
3584
+ #
3585
+ # To fix this, we need to modify is_callable_compatible so it can optionally detect
3586
+ # functions that are *potentially* compatible rather then *definitely* compatible.
3587
+
3588
+ # The reason we repeat this check twice is so we can do a slightly better job of
3589
+ # checking for potentially overlapping param counts. Both calls will actually check
3590
+ # the param and return types in the same "direction" -- the only thing that differs
3591
+ # is how is_callable_compatible checks non-positional arguments.
3592
+ return (is_callable_compatible (signature , other ,
3593
+ is_compat = is_more_precise ,
3594
+ is_compat_return = lambda l , r : not is_subtype (l , r ),
3595
+ check_args_covariantly = True ) or
3596
+ is_callable_compatible (other , signature ,
3597
+ is_compat = is_more_precise ,
3598
+ is_compat_return = lambda l , r : not is_subtype (r , l )))
3599
+
3600
+
3601
+ def if_overload_can_never_match (signature : CallableType , other : CallableType ) -> bool :
3602
+ """Check if the 'other' method can never be matched due to 'signature'.
3603
+
3604
+ This can happen if signature's parameters are all strictly broader then
3605
+ other's parameters.
3606
+
3607
+ Assumes that both signatures have overlapping argument counts.
3608
+ """
3609
+ return is_callable_compatible (signature , other ,
3610
+ is_compat = is_more_precise ,
3611
+ ignore_return = True )
3612
+
3613
+
3614
+ def is_unsafe_overlapping_operator_signatures (signature : Type , other : Type ) -> bool :
3615
+ """Check if two operator method signatures may be unsafely overlapping.
3616
+
3617
+ Two signatures s and t are overlapping if both can be valid for the same
3618
+ statically typed values and the return types are incompatible.
3619
+
3536
3620
Assume calls are first checked against 'signature', then against 'other'.
3537
3621
Thus if 'signature' is more general than 'other', there is no unsafe
3538
3622
overlapping.
3539
3623
3540
- TODO If argument types vary covariantly, the return type may vary
3541
- covariantly as well.
3624
+ TODO: Clean up this function and make it not perform type erasure.
3625
+
3626
+ Context: This function was previously used to make sure both overloaded
3627
+ functions and operator methods were not unsafely overlapping.
3628
+
3629
+ We changed the semantics for we should handle overloaded definitions,
3630
+ but not operator functions. (We can't reuse the same semantics for both:
3631
+ the overload semantics are too restrictive here).
3632
+
3633
+ We should rewrite this method so that:
3634
+
3635
+ 1. It uses many of the improvements made to overloads: in particular,
3636
+ eliminating type erasure.
3637
+
3638
+ 2. It contains just the logic necessary for operator methods.
3542
3639
"""
3543
3640
if isinstance (signature , CallableType ):
3544
3641
if isinstance (other , CallableType ):
@@ -3581,12 +3678,11 @@ def is_more_general_arg_prefix(t: FunctionLike, s: FunctionLike) -> bool:
3581
3678
"""Does t have wider arguments than s?"""
3582
3679
# TODO should an overload with additional items be allowed to be more
3583
3680
# general than one with fewer items (or just one item)?
3584
- # TODO check argument kinds and otherwise make more general
3585
3681
if isinstance (t , CallableType ):
3586
3682
if isinstance (s , CallableType ):
3587
- t , s = unify_generic_callables (t , s )
3588
- return all ( is_proper_subtype ( args , argt )
3589
- for argt , args in zip ( t . arg_types , s . arg_types ) )
3683
+ return is_callable_compatible (t , s ,
3684
+ is_compat = is_proper_subtype ,
3685
+ ignore_return = True )
3590
3686
elif isinstance (t , FunctionLike ):
3591
3687
if isinstance (s , FunctionLike ):
3592
3688
if len (t .items ()) == len (s .items ()):
@@ -3595,29 +3691,6 @@ def is_more_general_arg_prefix(t: FunctionLike, s: FunctionLike) -> bool:
3595
3691
return False
3596
3692
3597
3693
3598
- def unify_generic_callables (t : CallableType ,
3599
- s : CallableType ) -> Tuple [CallableType ,
3600
- CallableType ]:
3601
- """Make type variables in generic callables the same if possible.
3602
-
3603
- Return updated callables. If we can't unify the type variables,
3604
- return the unmodified arguments.
3605
- """
3606
- # TODO: Use this elsewhere when comparing generic callables.
3607
- if t .is_generic () and s .is_generic ():
3608
- t_substitutions = {}
3609
- s_substitutions = {}
3610
- for tv1 , tv2 in zip (t .variables , s .variables ):
3611
- # Are these something we can unify?
3612
- if tv1 .id != tv2 .id and is_equivalent_type_var_def (tv1 , tv2 ):
3613
- newdef = TypeVarDef .new_unification_variable (tv2 )
3614
- t_substitutions [tv1 .id ] = TypeVarType (newdef )
3615
- s_substitutions [tv2 .id ] = TypeVarType (newdef )
3616
- return (cast (CallableType , expand_type (t , t_substitutions )),
3617
- cast (CallableType , expand_type (s , s_substitutions )))
3618
- return t , s
3619
-
3620
-
3621
3694
def is_equivalent_type_var_def (tv1 : TypeVarDef , tv2 : TypeVarDef ) -> bool :
3622
3695
"""Are type variable definitions equivalent?
3623
3696
@@ -3633,17 +3706,17 @@ def is_equivalent_type_var_def(tv1: TypeVarDef, tv2: TypeVarDef) -> bool:
3633
3706
3634
3707
3635
3708
def is_same_arg_prefix (t : CallableType , s : CallableType ) -> bool :
3636
- # TODO check argument kinds
3637
- return all (is_same_type (argt , args )
3638
- for argt , args in zip (t .arg_types , s .arg_types ))
3709
+ return is_callable_compatible (t , s ,
3710
+ is_compat = is_same_type ,
3711
+ ignore_return = True ,
3712
+ check_args_covariantly = True ,
3713
+ ignore_pos_arg_names = True )
3639
3714
3640
3715
3641
3716
def is_more_precise_signature (t : CallableType , s : CallableType ) -> bool :
3642
3717
"""Is t more precise than s?
3643
-
3644
3718
A signature t is more precise than s if all argument types and the return
3645
3719
type of t are more precise than the corresponding types in s.
3646
-
3647
3720
Assume that the argument kinds and names are compatible, and that the
3648
3721
argument counts are overlapping.
3649
3722
"""
0 commit comments