Skip to content

Commit

Permalink
Allow annotated assign with attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomas Novak authored and PCManticore committed Oct 9, 2019
1 parent d7db2c8 commit 276ada6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ Release Date: TBA
attributes, but rather virtual ones, thus an operation such as `getattr()`
does not make sense for them.

* Update attr brain to partly understand annotated attributes

Close #656


What's New in astroid 2.3.0?
============================
Expand Down
10 changes: 8 additions & 2 deletions astroid/brain/brain_attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,27 @@ def attr_attributes_transform(node):
node.locals["__attrs_attrs__"] = [astroid.Unknown(parent=node)]

for cdefbodynode in node.body:
if not isinstance(cdefbodynode, astroid.Assign):
if not isinstance(cdefbodynode, (astroid.Assign, astroid.AnnAssign)):
continue
if isinstance(cdefbodynode.value, astroid.Call):
if cdefbodynode.value.func.as_string() not in ATTRIB_NAMES:
continue
else:
continue
for target in cdefbodynode.targets:
targets = (
cdefbodynode.targets
if hasattr(cdefbodynode, "targets")
else [cdefbodynode.target]
)
for target in targets:

rhs_node = astroid.Unknown(
lineno=cdefbodynode.lineno,
col_offset=cdefbodynode.col_offset,
parent=cdefbodynode,
)
node.locals[target.name] = [rhs_node]
node.instance_attrs[target.name] = [rhs_node]


MANAGER.register_transform(
Expand Down
13 changes: 13 additions & 0 deletions astroid/tests/unittest_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,19 @@ class Foo:
"""
next(astroid.extract_node(code).infer())

@test_utils.require_version(minver="3.6")
def test_attrs_with_annotation(self):
code = """
import attr
@attr.s
class Foo:
bar: int = attr.ib(default=5)
Foo()
"""
should_be_unknown = next(astroid.extract_node(code).infer()).getattr("bar")[0]
self.assertIsInstance(should_be_unknown, astroid.Unknown)


class RandomSampleTest(unittest.TestCase):
def test_inferred_successfully(self):
Expand Down

0 comments on commit 276ada6

Please sign in to comment.