Skip to content

Incorrect join result in the presence of Any #11925

@hauntsaninja

Description

@hauntsaninja

Given test.py:

from unknown import X

class A: ...
class B(X, A): ...
class C(B): ...
class D(C): ...
class E(D): ...

reveal_type(E() if bool() else D())

Running mypy test.py --ignore-missing-imports gives test.py:10: note: Revealed type is "x.A"

Stepping through, things get unexpected starting here:

elif t.type.bases and is_subtype(t, s, ignore_type_params=True):

That is, mypy thinks D is a subtype of E!!! This seems obviously False; E is a subtype of D.

It turns out that due to the unknown type, TypeInfo(D).fallback_to_any is True, and so we throw our hands in the air and return True.

if left.type.fallback_to_any:

The following diff fixes this case, but needs to be investigated further:

diff --git a/mypy/join.py b/mypy/join.py
index d298b495f..392c79a07 100644
--- a/mypy/join.py
+++ b/mypy/join.py
@@ -72,7 +72,9 @@ class InstanceJoiner:
                 assert new_type is not None
                 args.append(new_type)
             result: ProperType = Instance(t.type, args)
-        elif t.type.bases and is_subtype(t, s, ignore_type_params=True):
+        elif t.type.bases and is_subtype(t, s, ignore_type_params=True) and not (
+            isinstance(t, Instance) and t.type.fallback_to_any
+        ):
             result = self.join_instances_via_supertype(t, s)
         else:
             # Now t is not a subtype of s, and t != s. Now s could be a subtype

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions