diff options
author | Anthony Sottile <asottile@umich.edu> | 2019-01-04 13:58:26 -0800 |
---|---|---|
committer | Ian Stapleton Cordasco <graffatcolmingov@gmail.com> | 2019-01-05 14:43:35 -0600 |
commit | f1444872d7e4abfe1359778bca56ad3fd59a6f9b (patch) | |
tree | 85d1ff1ba3ecb2098d5044ad2b0516ae270925f1 | |
parent | ac0aeba0eddb0b8e2285f5ac568e4621426b3aa7 (diff) | |
download | pyflakes-f1444872d7e4abfe1359778bca56ad3fd59a6f9b.tar.gz |
Move type annotations tests to their own class
-rw-r--r-- | pyflakes/test/test_other.py | 253 | ||||
-rw-r--r-- | pyflakes/test/test_type_annotations.py | 273 |
2 files changed, 273 insertions, 253 deletions
diff --git a/pyflakes/test/test_other.py b/pyflakes/test/test_other.py index f75b3d9..1b10e02 100644 --- a/pyflakes/test/test_other.py +++ b/pyflakes/test/test_other.py @@ -291,35 +291,6 @@ class Test(TestCase): pass """) - def test_typingOverload(self): - """Allow intentional redefinitions via @typing.overload""" - self.flakes(""" - import typing - from typing import overload - - @overload - def f(s): # type: (None) -> None - pass - - @overload - def f(s): # type: (int) -> int - pass - - def f(s): - return s - - @typing.overload - def g(s): # type: (None) -> None - pass - - @typing.overload - def g(s): # type: (int) -> int - pass - - def g(s): - return s - """) - def test_unaryPlus(self): """Don't die on unary +.""" self.flakes('+1') @@ -1915,230 +1886,6 @@ class TestAsyncStatements(TestCase): f'{hi} {mom}' ''') - @skipIf(version_info < (3, 6), 'new in Python 3.6') - def test_variable_annotations(self): - self.flakes(''' - name: str - age: int - ''') - self.flakes(''' - name: str = 'Bob' - age: int = 18 - ''') - self.flakes(''' - class C: - name: str - age: int - ''') - self.flakes(''' - class C: - name: str = 'Bob' - age: int = 18 - ''') - self.flakes(''' - def f(): - name: str - age: int - ''') - self.flakes(''' - def f(): - name: str = 'Bob' - age: int = 18 - foo: not_a_real_type = None - ''', m.UnusedVariable, m.UnusedVariable, m.UnusedVariable, m.UndefinedName) - self.flakes(''' - def f(): - name: str - print(name) - ''', m.UndefinedName) - self.flakes(''' - from typing import Any - def f(): - a: Any - ''') - self.flakes(''' - foo: not_a_real_type - ''', m.UndefinedName) - self.flakes(''' - foo: not_a_real_type = None - ''', m.UndefinedName) - self.flakes(''' - class C: - foo: not_a_real_type - ''', m.UndefinedName) - self.flakes(''' - class C: - foo: not_a_real_type = None - ''', m.UndefinedName) - self.flakes(''' - def f(): - class C: - foo: not_a_real_type - ''', m.UndefinedName) - self.flakes(''' - def f(): - class C: - foo: not_a_real_type = None - ''', m.UndefinedName) - self.flakes(''' - from foo import Bar - bar: Bar - ''') - self.flakes(''' - from foo import Bar - bar: 'Bar' - ''') - self.flakes(''' - import foo - bar: foo.Bar - ''') - self.flakes(''' - import foo - bar: 'foo.Bar' - ''') - self.flakes(''' - from foo import Bar - def f(bar: Bar): pass - ''') - self.flakes(''' - from foo import Bar - def f(bar: 'Bar'): pass - ''') - self.flakes(''' - from foo import Bar - def f(bar) -> Bar: return bar - ''') - self.flakes(''' - from foo import Bar - def f(bar) -> 'Bar': return bar - ''') - self.flakes(''' - bar: 'Bar' - ''', m.UndefinedName) - self.flakes(''' - bar: 'foo.Bar' - ''', m.UndefinedName) - self.flakes(''' - from foo import Bar - bar: str - ''', m.UnusedImport) - self.flakes(''' - from foo import Bar - def f(bar: str): pass - ''', m.UnusedImport) - self.flakes(''' - def f(a: A) -> A: pass - class A: pass - ''', m.UndefinedName, m.UndefinedName) - self.flakes(''' - def f(a: 'A') -> 'A': return a - class A: pass - ''') - self.flakes(''' - a: A - class A: pass - ''', m.UndefinedName) - self.flakes(''' - a: 'A' - class A: pass - ''') - self.flakes(''' - a: 'A B' - ''', m.ForwardAnnotationSyntaxError) - self.flakes(''' - a: 'A; B' - ''', m.ForwardAnnotationSyntaxError) - self.flakes(''' - a: '1 + 2' - ''') - self.flakes(''' - a: 'a: "A"' - ''', m.ForwardAnnotationSyntaxError) - - @skipIf(version_info < (3, 7), 'new in Python 3.7') - def test_postponed_annotations(self): - self.flakes(''' - from __future__ import annotations - def f(a: A) -> A: pass - class A: - b: B - class B: pass - ''') - - self.flakes(''' - from __future__ import annotations - def f(a: A) -> A: pass - class A: - b: Undefined - class B: pass - ''', m.UndefinedName) - - def test_typeCommentsMarkImportsAsUsed(self): - self.flakes(""" - from mod import A, B, C, D, E, F, G - - - def f( - a, # type: A - ): - # type: (...) -> B - for b in a: # type: C - with b as c: # type: D - d = c.x # type: E - return d - - - def g(x): # type: (F) -> G - return x.y - """) - - def test_typeCommentsFullSignature(self): - self.flakes(""" - from mod import A, B, C, D - def f(a, b): - # type: (A, B[C]) -> D - return a + b - """) - - def test_typeCommentsAdditionalComemnt(self): - self.flakes(""" - from mod import F - - x = 1 # type: F # noqa - """) - - def test_typeCommentsNoWhitespaceAnnotation(self): - self.flakes(""" - from mod import F - - x = 1 #type:F - """) - - def test_typeCommentsInvalidDoesNotMarkAsUsed(self): - self.flakes(""" - from mod import F - - # type: F - """, m.UnusedImport) - - def test_typeCommentsSyntaxError(self): - self.flakes(""" - def f(x): # type: (F[) -> None - pass - """, m.CommentAnnotationSyntaxError) - - def test_typeCommentsAssignedToPreviousNode(self): - # This test demonstrates an issue in the implementation which - # associates the type comment with a node above it, however the type - # comment isn't valid according to mypy. If an improved approach - # which can detect these "invalid" type comments is implemented, this - # test should be removed / improved to assert that new check. - self.flakes(""" - from mod import F - x = 1 - # type: F - """) - def test_raise_notimplemented(self): self.flakes(''' raise NotImplementedError("This is fine") diff --git a/pyflakes/test/test_type_annotations.py b/pyflakes/test/test_type_annotations.py new file mode 100644 index 0000000..e828412 --- /dev/null +++ b/pyflakes/test/test_type_annotations.py @@ -0,0 +1,273 @@ +""" +Tests for behaviour related to type annotations. +""" + +from sys import version_info + +from pyflakes import messages as m +from pyflakes.test.harness import TestCase, skipIf + + +class TestTypeAnnotations(TestCase): + + def test_typingOverload(self): + """Allow intentional redefinitions via @typing.overload""" + self.flakes(""" + import typing + from typing import overload + + @overload + def f(s): # type: (None) -> None + pass + + @overload + def f(s): # type: (int) -> int + pass + + def f(s): + return s + + @typing.overload + def g(s): # type: (None) -> None + pass + + @typing.overload + def g(s): # type: (int) -> int + pass + + def g(s): + return s + """) + + @skipIf(version_info < (3, 6), 'new in Python 3.6') + def test_variable_annotations(self): + self.flakes(''' + name: str + age: int + ''') + self.flakes(''' + name: str = 'Bob' + age: int = 18 + ''') + self.flakes(''' + class C: + name: str + age: int + ''') + self.flakes(''' + class C: + name: str = 'Bob' + age: int = 18 + ''') + self.flakes(''' + def f(): + name: str + age: int + ''') + self.flakes(''' + def f(): + name: str = 'Bob' + age: int = 18 + foo: not_a_real_type = None + ''', m.UnusedVariable, m.UnusedVariable, m.UnusedVariable, m.UndefinedName) + self.flakes(''' + def f(): + name: str + print(name) + ''', m.UndefinedName) + self.flakes(''' + from typing import Any + def f(): + a: Any + ''') + self.flakes(''' + foo: not_a_real_type + ''', m.UndefinedName) + self.flakes(''' + foo: not_a_real_type = None + ''', m.UndefinedName) + self.flakes(''' + class C: + foo: not_a_real_type + ''', m.UndefinedName) + self.flakes(''' + class C: + foo: not_a_real_type = None + ''', m.UndefinedName) + self.flakes(''' + def f(): + class C: + foo: not_a_real_type + ''', m.UndefinedName) + self.flakes(''' + def f(): + class C: + foo: not_a_real_type = None + ''', m.UndefinedName) + self.flakes(''' + from foo import Bar + bar: Bar + ''') + self.flakes(''' + from foo import Bar + bar: 'Bar' + ''') + self.flakes(''' + import foo + bar: foo.Bar + ''') + self.flakes(''' + import foo + bar: 'foo.Bar' + ''') + self.flakes(''' + from foo import Bar + def f(bar: Bar): pass + ''') + self.flakes(''' + from foo import Bar + def f(bar: 'Bar'): pass + ''') + self.flakes(''' + from foo import Bar + def f(bar) -> Bar: return bar + ''') + self.flakes(''' + from foo import Bar + def f(bar) -> 'Bar': return bar + ''') + self.flakes(''' + bar: 'Bar' + ''', m.UndefinedName) + self.flakes(''' + bar: 'foo.Bar' + ''', m.UndefinedName) + self.flakes(''' + from foo import Bar + bar: str + ''', m.UnusedImport) + self.flakes(''' + from foo import Bar + def f(bar: str): pass + ''', m.UnusedImport) + self.flakes(''' + def f(a: A) -> A: pass + class A: pass + ''', m.UndefinedName, m.UndefinedName) + self.flakes(''' + def f(a: 'A') -> 'A': return a + class A: pass + ''') + self.flakes(''' + a: A + class A: pass + ''', m.UndefinedName) + self.flakes(''' + a: 'A' + class A: pass + ''') + self.flakes(''' + a: 'A B' + ''', m.ForwardAnnotationSyntaxError) + self.flakes(''' + a: 'A; B' + ''', m.ForwardAnnotationSyntaxError) + self.flakes(''' + a: '1 + 2' + ''') + self.flakes(''' + a: 'a: "A"' + ''', m.ForwardAnnotationSyntaxError) + + @skipIf(version_info < (3, 7), 'new in Python 3.7') + def test_postponed_annotations(self): + self.flakes(''' + from __future__ import annotations + def f(a: A) -> A: pass + class A: + b: B + class B: pass + ''') + + self.flakes(''' + from __future__ import annotations + def f(a: A) -> A: pass + class A: + b: Undefined + class B: pass + ''', m.UndefinedName) + + def test_typeCommentsMarkImportsAsUsed(self): + self.flakes(""" + from mod import A, B, C, D, E, F, G + + + def f( + a, # type: A + ): + # type: (...) -> B + for b in a: # type: C + with b as c: # type: D + d = c.x # type: E + return d + + + def g(x): # type: (F) -> G + return x.y + """) + + def test_typeCommentsFullSignature(self): + self.flakes(""" + from mod import A, B, C, D + def f(a, b): + # type: (A, B[C]) -> D + return a + b + """) + + def test_typeCommentsFullSignatureWithDocstring(self): + self.flakes(''' + from mod import A, B, C, D + def f(a, b): + # type: (A, B[C]) -> D + """do the thing!""" + return a + b + ''') + + def test_typeCommentsAdditionalComemnt(self): + self.flakes(""" + from mod import F + + x = 1 # type: F # noqa + """) + + def test_typeCommentsNoWhitespaceAnnotation(self): + self.flakes(""" + from mod import F + + x = 1 #type:F + """) + + def test_typeCommentsInvalidDoesNotMarkAsUsed(self): + self.flakes(""" + from mod import F + + # type: F + """, m.UnusedImport) + + def test_typeCommentsSyntaxError(self): + self.flakes(""" + def f(x): # type: (F[) -> None + pass + """, m.CommentAnnotationSyntaxError) + + def test_typeCommentsAssignedToPreviousNode(self): + # This test demonstrates an issue in the implementation which + # associates the type comment with a node above it, however the type + # comment isn't valid according to mypy. If an improved approach + # which can detect these "invalid" type comments is implemented, this + # test should be removed / improved to assert that new check. + self.flakes(""" + from mod import F + x = 1 + # type: F + """) |