diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 45109b8b14dfc..702c6cb4f58d3 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1775,9 +1775,14 @@ def overload_arg_similarity(actual: Type, formal: Type) -> int: (isinstance(actual, Instance) and actual.type.fallback_to_any)): # These could match anything at runtime. return 2 - if not experiments.STRICT_OPTIONAL and isinstance(actual, NoneTyp): - # NoneTyp matches anything if we're not doing strict Optional checking - return 2 + if isinstance(actual, NoneTyp): + if not experiments.STRICT_OPTIONAL: + # NoneTyp matches anything if we're not doing strict Optional checking + return 2 + else: + # NoneType is a subtype of object + if isinstance(formal, Instance) and formal.type.fullname() == "builtins.object": + return 2 if isinstance(actual, UnionType): return max(overload_arg_similarity(item, formal) for item in actual.items) diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 22c3e6ef894b9..8a606384c932d 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -245,3 +245,14 @@ def f(b: T) -> T: a = None b = "foo" reveal_type(a and b) # E: Revealed type is 'builtins.None' + +[case testNoneMatchesObjectInOverload] +import a +a.f(None) + +[file a.pyi] +from typing import overload +@overload +def f() -> None: ... +@overload +def f(o: object) -> None: ...