From aef413079f47486521ee5f9ab26549d09b9992fc Mon Sep 17 00:00:00 2001 From: Jacob Bogdanov Date: Wed, 5 Jan 2022 08:33:00 -0500 Subject: [PATCH 1/9] Add support for attrs v21.3.0+ Since version [21.3.0](https://github.com/python-attrs/attrs/releases/tag/21.3.0) you can now `import attrs` instead of just `import attr`. This patch adds support so that astroid doesn't barf on classes created using `@attrs.define`. --- astroid/brain/brain_attrs.py | 8 ++++- tests/unittest_brain.py | 62 ++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index 65e897ca1..c1f0798ce 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -10,16 +10,22 @@ from astroid.nodes.node_classes import AnnAssign, Assign, AssignName, Call, Unknown from astroid.nodes.scoped_nodes import ClassDef -ATTRIB_NAMES = frozenset(("attr.ib", "attrib", "attr.attrib", "attr.field", "field")) +ATTRIB_NAMES = frozenset( + ("attr.ib", "attrib", "attr.attrib", "attr.field", "attrs.field", "field") +) ATTRS_NAMES = frozenset( ( "attr.s", "attrs", + "define", "attr.attrs", "attr.attributes", "attr.define", "attr.mutable", "attr.frozen", + "attrs.define", + "attrs.mutable", + "attrs.frozen", ) ) diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 71cee383d..37134e9db 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -2211,6 +2211,68 @@ class Eggs: should_be_unknown = next(module.getattr(name)[0].infer()).getattr("d")[0] self.assertIsInstance(should_be_unknown, astroid.Unknown) + def test_attrs_transform(self) -> None: + module = astroid.parse( + """ + import attrs + from attrs import define, field, mutable, frozen + + @attrs.define + class Foo: + + d = attrs.field(attrs.Factory(dict)) + + f = Foo() + f.d['answer'] = 42 + + @define(slots=True) + class Bar: + d = field(attrs.Factory(dict)) + + g = Bar() + g.d['answer'] = 42 + + @attrs.mutable + class Bah: + d = field(attrs.Factory(dict)) + + h = Bah() + h.d['answer'] = 42 + + @attrs.frozen + class Bai: + d = attrs.field(attrs.Factory(dict)) + + i = Bai() + i.d['answer'] = 42 + + @attrs.define + class Spam: + d = field(default=attrs.Factory(dict)) + + j = Spam(d=1) + j.d['answer'] = 42 + + @attrs.mutable + class Eggs: + d = attrs.field(default=attrs.Factory(dict)) + + k = Eggs(d=1) + k.d['answer'] = 42 + + @attrs.frozen + class Eggs: + d = attrs.field(default=attrs.Factory(dict)) + + l = Eggs(d=1) + l.d['answer'] = 42 + """ + ) + + for name in ("f", "g", "h", "i", "j", "k", "l"): + should_be_unknown = next(module.getattr(name)[0].infer()).getattr("d")[0] + self.assertIsInstance(should_be_unknown, astroid.Unknown) + def test_special_attributes(self) -> None: """Make sure special attrs attributes exist""" From d4a7bd823ccc7a90cd4918754b17ee6dcbfbe35a Mon Sep 17 00:00:00 2001 From: Jacob Bogdanov Date: Thu, 13 Jan 2022 10:56:02 -0500 Subject: [PATCH 2/9] Remove @define from support for attrs --- astroid/brain/brain_attrs.py | 1 - tests/unittest_brain.py | 16 ++++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index c1f0798ce..6d664ade8 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -17,7 +17,6 @@ ( "attr.s", "attrs", - "define", "attr.attrs", "attr.attributes", "attr.define", diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 37134e9db..791e99066 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -1346,11 +1346,7 @@ def test_collections_object_not_subscriptable(self) -> None: inferred = next(right_node.infer()) check_metaclass_is_abc(inferred) assertEqualMro( - inferred, - [ - "_collections_abc.Hashable", - "builtins.object", - ], + inferred, ["_collections_abc.Hashable", "builtins.object",], ) with self.assertRaises(AttributeInferenceError): inferred.getattr("__class_getitem__") @@ -1882,11 +1878,7 @@ def test_typing_object_not_subscriptable(self): inferred = next(right_node.infer()) assertEqualMro( inferred, - [ - "typing.Hashable", - "_collections_abc.Hashable", - "builtins.object", - ], + ["typing.Hashable", "_collections_abc.Hashable", "builtins.object",], ) with self.assertRaises(AttributeInferenceError): inferred.getattr("__class_getitem__") @@ -2215,7 +2207,7 @@ def test_attrs_transform(self) -> None: module = astroid.parse( """ import attrs - from attrs import define, field, mutable, frozen + from attrs import field, mutable, frozen @attrs.define class Foo: @@ -2225,7 +2217,7 @@ class Foo: f = Foo() f.d['answer'] = 42 - @define(slots=True) + @attrs.define(slots=True) class Bar: d = field(attrs.Factory(dict)) From 2e164f32daa75bc0255cffb724c64ec4308fef0b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Jan 2022 15:57:15 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/unittest_brain.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 791e99066..4f6735852 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -1346,7 +1346,11 @@ def test_collections_object_not_subscriptable(self) -> None: inferred = next(right_node.infer()) check_metaclass_is_abc(inferred) assertEqualMro( - inferred, ["_collections_abc.Hashable", "builtins.object",], + inferred, + [ + "_collections_abc.Hashable", + "builtins.object", + ], ) with self.assertRaises(AttributeInferenceError): inferred.getattr("__class_getitem__") @@ -1878,7 +1882,11 @@ def test_typing_object_not_subscriptable(self): inferred = next(right_node.infer()) assertEqualMro( inferred, - ["typing.Hashable", "_collections_abc.Hashable", "builtins.object",], + [ + "typing.Hashable", + "_collections_abc.Hashable", + "builtins.object", + ], ) with self.assertRaises(AttributeInferenceError): inferred.getattr("__class_getitem__") From 31199971e906b2094048f632158bf65211fa6364 Mon Sep 17 00:00:00 2001 From: Jacob Bogdanov Date: Tue, 18 Jan 2022 17:28:23 -0500 Subject: [PATCH 4/9] Update tests/unittest_brain.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> --- tests/unittest_brain.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 4f6735852..702f1cc5d 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -2212,6 +2212,11 @@ class Eggs: self.assertIsInstance(should_be_unknown, astroid.Unknown) def test_attrs_transform(self) -> None: + """Test brain for decorators of the 'attrs' package. + + Package added support for 'attrs' a long side 'attr' in v21.3.0. + See: https://github.com/python-attrs/attrs/releases/tag/21.3.0 + """ module = astroid.parse( """ import attrs From 2e7cefecbfb20fc77c16591bb3b26c7eb248204b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Jan 2022 22:29:03 +0000 Subject: [PATCH 5/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/unittest_brain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 702f1cc5d..7dfbdff23 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -2213,7 +2213,7 @@ class Eggs: def test_attrs_transform(self) -> None: """Test brain for decorators of the 'attrs' package. - + Package added support for 'attrs' a long side 'attr' in v21.3.0. See: https://github.com/python-attrs/attrs/releases/tag/21.3.0 """ From b2b038b93ac25b3bfa89f800247883e7e5069cad Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Wed, 19 Jan 2022 09:54:48 +0100 Subject: [PATCH 6/9] Update astroid/brain/brain_attrs.py --- astroid/brain/brain_attrs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index 6d664ade8..ffc3053fc 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -11,7 +11,7 @@ from astroid.nodes.scoped_nodes import ClassDef ATTRIB_NAMES = frozenset( - ("attr.ib", "attrib", "attr.attrib", "attr.field", "attrs.field", "field") + ("attr.ib", "attr.attrib", "attr.field", "attrs.field") ) ATTRS_NAMES = frozenset( ( From f95d7ea9efcdf22212cb761df6365ad9530b05d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Jan 2022 08:55:35 +0000 Subject: [PATCH 7/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- astroid/brain/brain_attrs.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index ffc3053fc..8962fd529 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -10,9 +10,7 @@ from astroid.nodes.node_classes import AnnAssign, Assign, AssignName, Call, Unknown from astroid.nodes.scoped_nodes import ClassDef -ATTRIB_NAMES = frozenset( - ("attr.ib", "attr.attrib", "attr.field", "attrs.field") -) +ATTRIB_NAMES = frozenset(("attr.ib", "attr.attrib", "attr.field", "attrs.field")) ATTRS_NAMES = frozenset( ( "attr.s", From 1564691d26b62a56f30ac7b324d90bc587c7d4c2 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 20 Jan 2022 17:18:35 +0100 Subject: [PATCH 8/9] Update astroid/brain/brain_attrs.py --- astroid/brain/brain_attrs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index 8962fd529..92bd93a65 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -10,7 +10,7 @@ from astroid.nodes.node_classes import AnnAssign, Assign, AssignName, Call, Unknown from astroid.nodes.scoped_nodes import ClassDef -ATTRIB_NAMES = frozenset(("attr.ib", "attr.attrib", "attr.field", "attrs.field")) +ATTRIB_NAMES = frozenset( ("attr.ib", "attrib", "attr.attrib", "attr.field", "attrs.field", "field")) ATTRS_NAMES = frozenset( ( "attr.s", From e1d02eb8f71e45446073cb89920080e2046c0587 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 20 Jan 2022 16:19:13 +0000 Subject: [PATCH 9/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- astroid/brain/brain_attrs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/astroid/brain/brain_attrs.py b/astroid/brain/brain_attrs.py index 92bd93a65..6d664ade8 100644 --- a/astroid/brain/brain_attrs.py +++ b/astroid/brain/brain_attrs.py @@ -10,7 +10,9 @@ from astroid.nodes.node_classes import AnnAssign, Assign, AssignName, Call, Unknown from astroid.nodes.scoped_nodes import ClassDef -ATTRIB_NAMES = frozenset( ("attr.ib", "attrib", "attr.attrib", "attr.field", "attrs.field", "field")) +ATTRIB_NAMES = frozenset( + ("attr.ib", "attrib", "attr.attrib", "attr.field", "attrs.field", "field") +) ATTRS_NAMES = frozenset( ( "attr.s",