Skip to content

Relax default overload subtyping checks #20720

@randolf-scholz

Description

@randolf-scholz

Currently, mypy ensures monotnonically increasing order when testing overloads against overloads:

mypy/mypy/subtypes.py

Lines 1003 to 1009 in 9f157d9

# Order matters: we need to make sure that the index of
# this item is at least the index of the previous one.
if subtype_match and previous_match_left_index <= left_index:
previous_match_left_index = left_index
found_match = True
matched_overloads.add(left_index)
break

However, I believe (1) this rule does more harm than good in many cases when it is correct, and (2) there are many cases where it is incorrect. Therefore, I propose to move this check behind a new strictness flag and disable it by default. Later, one can see if the check can be refined to deal with the cases listed below.

Rationale

In python/typing#2021 I showed that the current typing spec is too strict with respect to subtyping overloads.

When this check is incorrect

The check is incorrect when overloads are commutative, i.e. changing the overload order describes the same callable type. This is the case when:

  1. Argument signatures are mutually exclusive mypy-playground

  2. Argument types are mutually exclusive (e.g. via @disjoint_bases) mypy-playground

  3. Argument types overlap, but return types are identical. mypy-playground

When this check is technically correct, but hurts in practice

As @disjoint_bases is relatively new, many libraries likely do not use it. Moreover, Intersection types are still not supported. Thus, many classes that are compatible at runtime cannot be put under the umbrella of a shared Protocol because inadvertently they will use different overload order at one point or another.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions