Repository: python/mypy

Issue:
"Need type annotation for '<variable>'" in Python < 3.6
mypy is complaining about missing variable type annotations even if the Python version is explicitly set.

This is the code I have:
```
i_am_a_set = set()
```
I then run mypy with the command:
```
mypy --python-version 3.5 test.py
```
This results in an error message saying `error: Need type annotation for 'i_am_a_set'`. However, since variable annotations were introduced in Python 3.6, this is clearly a nonsense error for Python 3.5.

Also please note that if I change the code to `i_am_a_set: Set[int] = set()`, and run mypy again with `--python-version 3.5`, I get: `error: Variable annotation syntax is only supported in Python 3.6 and greater`. So mypy knows that this annotation is invalid in Python 3.5, but still requests it.

I used the latest release version of mypy (0.700).


Discussion:
OK, I've just realized that I could have written:
```
i_am_a_set = set()  # type: Set[int]
```

Closing...
I guess mypy could be more explicit and say something like "Need type comment for 'foo'" if we are targeting a pre-3.6 Python.
taking a look at this
Also, I got an error message like saying:
```
error: "Counter" is not subscriptable, use "typing.Counter" instead
```
, while `typing.Counter`, again, was introduced in 3.6.1.

@DavidNemeskey That seems like a separate issue (though related).
@christinepinho Are you working on this ?
@mandarvaze I’m not right now. Got pulled off onto other projects. It’s all yours if you want to tackle it!

Resolving patch:
diff --git a/mypy/messages.py b/mypy/messages.py
--- a/mypy/messages.py
+++ b/mypy/messages.py
@@ -1087,6 +1087,7 @@ def unimported_type_becomes_any(self, prefix: str, typ: Type, ctx: Context) -> N
     def need_annotation_for_var(self, node: SymbolNode, context: Context,
                                 python_version: Optional[Tuple[int, int]] = None) -> None:
         hint = ''
+        has_variable_annotations = not python_version or python_version >= (3, 6)
         # Only gives hint if it's a variable declaration and the partial type is a builtin type
         if (python_version and isinstance(node, Var) and isinstance(node.type, PartialType) and
                 node.type.type and node.type.type.fullname() in reverse_builtin_aliases):
@@ -1095,11 +1096,17 @@ def need_annotation_for_var(self, node: SymbolNode, context: Context,
             type_dec = '<type>'
             if alias == 'Dict':
                 type_dec = '{}, {}'.format(type_dec, type_dec)
-            if python_version < (3, 6):
-                hint = ' (hint: "{} = ...  # type: {}[{}]")'.format(node.name(), alias, type_dec)
-            else:
+            if has_variable_annotations:
                 hint = ' (hint: "{}: {}[{}] = ...")'.format(node.name(), alias, type_dec)
-        self.fail("Need type annotation for '{}'{}".format(unmangle(node.name()), hint), context)
+            else:
+                hint = ' (hint: "{} = ...  # type: {}[{}]")'.format(node.name(), alias, type_dec)
+
+        if has_variable_annotations:
+            needed = 'annotation'
+        else:
+            needed = 'comment'
+
+        self.fail("Need type {} for '{}'{}".format(needed, unmangle(node.name()), hint), context)
 
     def explicit_any(self, ctx: Context) -> None:
         self.fail('Explicit "Any" is not allowed', ctx)


Test patch:
diff --git a/test-data/unit/check-python2.test b/test-data/unit/check-python2.test
--- a/test-data/unit/check-python2.test
+++ b/test-data/unit/check-python2.test
@@ -366,5 +366,5 @@ b = none.__bool__() # E: "None" has no attribute "__bool__"
 
 [case testDictWithoutTypeCommentInPython2]
 # flags: --py2
-d = dict() # E: Need type annotation for 'd' (hint: "d = ...  \# type: Dict[<type>, <type>]")
+d = dict() # E: Need type comment for 'd' (hint: "d = ...  \# type: Dict[<type>, <type>]")
 [builtins_py2 fixtures/floatdict_python2.pyi]