Repository: python/mypy

Issue:
Incorrect join result in the presence of Any
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:
https://github.com/python/mypy/blob/1beed9af48bed07033490f8cf2d4e08229450c5f/mypy/join.py#L75

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. 
https://github.com/python/mypy/blob/1beed9af48bed07033490f8cf2d4e08229450c5f/mypy/subtypes.py#L243

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
```


Discussion:
Hey there , I am new to open source  I just have done some good first issue but I would love to work on this issue but if you allow me , and can you guide me in this??

Resolving patch:
diff --git a/mypy/join.py b/mypy/join.py
--- a/mypy/join.py
+++ b/mypy/join.py
@@ -9,6 +9,7 @@
 from mypy.nodes import CONTRAVARIANT, COVARIANT, INVARIANT
 from mypy.state import state
 from mypy.subtypes import (
+    SubtypeContext,
     find_member,
     is_equivalent,
     is_proper_subtype,
@@ -101,7 +102,9 @@ def join_instances(self, t: Instance, s: Instance) -> ProperType:
                 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_proper_subtype(
+            t, s, subtype_context=SubtypeContext(ignore_type_params=True)
+        ):
             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
diff --git a/mypy/subtypes.py b/mypy/subtypes.py
--- a/mypy/subtypes.py
+++ b/mypy/subtypes.py
@@ -103,11 +103,7 @@ def check_context(self, proper_subtype: bool) -> None:
         # Historically proper and non-proper subtypes were defined using different helpers
         # and different visitors. Check if flag values are such that we definitely support.
         if proper_subtype:
-            assert (
-                not self.ignore_type_params
-                and not self.ignore_pos_arg_names
-                and not self.ignore_declared_variance
-            )
+            assert not self.ignore_pos_arg_names and not self.ignore_declared_variance
         else:
             assert not self.erase_instances and not self.keep_erased_types
 


Test patch:
diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test
--- a/test-data/unit/check-inference.test
+++ b/test-data/unit/check-inference.test
@@ -3382,3 +3382,15 @@ class A:
 T = TypeVar("T")
 def type_or_callable(value: T, tp: Union[Type[T], Callable[[int], T]]) -> T: ...
 reveal_type(type_or_callable(A("test"), A))  # N: Revealed type is "__main__.A"
+
+[case testJoinWithAnyFallback]
+from unknown import X  # type: ignore[import]
+
+class A: ...
+class B(X, A): ...
+class C(B): ...
+class D(C): ...
+class E(D): ...
+
+reveal_type([E(), D()])  # N: Revealed type is "builtins.list[__main__.D]"
+reveal_type([D(), E()])  # N: Revealed type is "builtins.list[__main__.D]"