Skip to content

Commit dae4fa7

Browse files
ambvsigmavirus24
authored andcommitted
Enable support for PEP 526 annotated assignments (#84)
Without this change, code with annotated assignments is crashing pyflakes with an attribute error (`object has no attribute 'ANNASSIGN'`). Test plan: new tests introduced conforming to behavior described in the PEP.
1 parent 34a0696 commit dae4fa7

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

pyflakes/checker.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,3 +1335,21 @@ def EXCEPTHANDLER(self, node):
13351335
del self.scope[node.name]
13361336
except KeyError:
13371337
pass
1338+
1339+
def ANNASSIGN(self, node):
1340+
"""
1341+
Annotated assignments don't have annotations evaluated on function
1342+
scope, hence the custom implementation.
1343+
1344+
See: PEP 526.
1345+
"""
1346+
if node.value:
1347+
# Only bind the *targets* if the assignment has a value.
1348+
# Otherwise it's not really ast.Store and shouldn't silence
1349+
# UndefinedLocal warnings.
1350+
self.handleNode(node.target, node)
1351+
if not isinstance(self.scope, FunctionScope):
1352+
self.handleNode(node.annotation, node)
1353+
if node.value:
1354+
# If the assignment has value, handle the *value* now.
1355+
self.handleNode(node.value, node)

pyflakes/test/test_other.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,3 +1808,64 @@ def test_formatstring(self):
18081808
mom = 'mom'
18091809
f'{hi} {mom}'
18101810
''')
1811+
1812+
@skipIf(version_info < (3, 6), 'new in Python 3.6')
1813+
def test_variable_annotations(self):
1814+
self.flakes('''
1815+
name: str
1816+
age: int
1817+
''')
1818+
self.flakes('''
1819+
name: str = 'Bob'
1820+
age: int = 18
1821+
''')
1822+
self.flakes('''
1823+
class C:
1824+
name: str
1825+
age: int
1826+
''')
1827+
self.flakes('''
1828+
class C:
1829+
name: str = 'Bob'
1830+
age: int = 18
1831+
''')
1832+
self.flakes('''
1833+
def f():
1834+
name: str
1835+
age: int
1836+
''')
1837+
self.flakes('''
1838+
def f():
1839+
name: str = 'Bob'
1840+
age: int = 18
1841+
foo: not_a_real_type = None
1842+
''', m.UnusedVariable, m.UnusedVariable, m.UnusedVariable)
1843+
self.flakes('''
1844+
def f():
1845+
name: str
1846+
print(name)
1847+
''', m.UndefinedName)
1848+
self.flakes('''
1849+
foo: not_a_real_type
1850+
''', m.UndefinedName)
1851+
self.flakes('''
1852+
foo: not_a_real_type = None
1853+
''', m.UndefinedName)
1854+
self.flakes('''
1855+
class C:
1856+
foo: not_a_real_type
1857+
''', m.UndefinedName)
1858+
self.flakes('''
1859+
class C:
1860+
foo: not_a_real_type = None
1861+
''', m.UndefinedName)
1862+
self.flakes('''
1863+
def f():
1864+
class C:
1865+
foo: not_a_real_type
1866+
''', m.UndefinedName)
1867+
self.flakes('''
1868+
def f():
1869+
class C:
1870+
foo: not_a_real_type = None
1871+
''', m.UndefinedName)

0 commit comments

Comments
 (0)