Repository: python/mypy

Issue:
Use fully qualified name for class with confusing name such as "Any"
The following example generates a confusing error message, since it's unclear which `Any` type it is referring to:

```py
class Any: pass

x = Any()
x = 1  # Incompatible types in assignment 
       # (expression has type "int", variable has type "Any")
```

(It would be more confusing if the `Any` type is inferred from the return type of a function.)

It would be better to always use a fully qualified name for a class named `Any` in error messages (similarly also for `None`, `Union`, etc.). 

This can also happen with classes that have names resembling built-in types:

```py
class float: pass

x = float()
x = 0  # Incompatible types in assignment 
       # (expression has type "int", variable has type "float")
```

The relevant code seems to be in `mypy.messages.format_type`.


Discussion:
This has been bothering me from time to time. I'd be happy to give this a shot. Do you have any thoughts on what classes this should apply to? I don't immediately see a nice way to find a good criteria to separate here.
Maybe everything in `typing` and `builtins`, or everything that appears more than once somewhere in the whole program.
I like the first one. Thanks!
Since it's been a while, I hope it's okay if I work on this?

Resolving patch:
diff --git a/mypy/messages.py b/mypy/messages.py
--- a/mypy/messages.py
+++ b/mypy/messages.py
@@ -42,6 +42,21 @@
 from mypy.errorcodes import ErrorCode
 from mypy import message_registry, errorcodes as codes
 
+TYPES_FOR_UNIMPORTED_HINTS = {
+    'typing.Any',
+    'typing.Callable',
+    'typing.Dict',
+    'typing.Iterable',
+    'typing.Iterator',
+    'typing.List',
+    'typing.Optional',
+    'typing.Set',
+    'typing.Tuple',
+    'typing.TypeVar',
+    'typing.Union',
+    'typing.cast',
+}  # type: Final
+
 
 ARG_CONSTRUCTOR_NAMES = {
     ARG_POS: "Arg",
@@ -1720,6 +1735,9 @@ def find_type_overlaps(*types: Type) -> Set[str]:
     for type in types:
         for inst in collect_all_instances(type):
             d.setdefault(inst.type.name, set()).add(inst.type.fullname)
+    for shortname in d.keys():
+        if 'typing.{}'.format(shortname) in TYPES_FOR_UNIMPORTED_HINTS:
+            d[shortname].add('typing.{}'.format(shortname))
 
     overlaps = set()  # type: Set[str]
     for fullnames in d.values():
diff --git a/mypy/semanal.py b/mypy/semanal.py
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -81,7 +81,9 @@
 from mypy.typevars import fill_typevars
 from mypy.visitor import NodeVisitor
 from mypy.errors import Errors, report_internal_error
-from mypy.messages import best_matches, MessageBuilder, pretty_seq, SUGGESTED_TEST_FIXTURES
+from mypy.messages import (
+    best_matches, MessageBuilder, pretty_seq, SUGGESTED_TEST_FIXTURES, TYPES_FOR_UNIMPORTED_HINTS
+)
 from mypy.errorcodes import ErrorCode
 from mypy import message_registry, errorcodes as codes
 from mypy.types import (
@@ -120,21 +122,6 @@
 
 T = TypeVar('T')
 
-TYPES_FOR_UNIMPORTED_HINTS = {
-    'typing.Any',
-    'typing.Callable',
-    'typing.Dict',
-    'typing.Iterable',
-    'typing.Iterator',
-    'typing.List',
-    'typing.Optional',
-    'typing.Set',
-    'typing.Tuple',
-    'typing.TypeVar',
-    'typing.Union',
-    'typing.cast',
-}  # type: Final
-
 
 # Special cased built-in classes that are needed for basic functionality and need to be
 # available very early on.


Test patch:
diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test
--- a/test-data/unit/check-basic.test
+++ b/test-data/unit/check-basic.test
@@ -75,6 +75,26 @@ if int():
     x = 1
 
 
+[case testIncompatibleAssignmentAmbiguousShortnames]
+
+class Any: pass
+class List: pass
+class Dict: pass
+class Iterator: pass
+
+x = Any()
+x = 1  # E: Incompatible types in assignment (expression has type "int", variable has type "__main__.Any")
+
+y = List()
+y = 1  # E: Incompatible types in assignment (expression has type "int", variable has type "__main__.List")
+
+z = Dict()
+z = 1  # E: Incompatible types in assignment (expression has type "int", variable has type "__main__.Dict")
+
+w = Iterator()
+w = 1  # E: Incompatible types in assignment (expression has type "int", variable has type "__main__.Iterator")
+
+
 -- Simple functions and calling
 -- ----------------------------