Skip to content

Commit

Permalink
Merge pull request pylint-dev#2570 from pylint-dev/post-3.3.3
Browse files Browse the repository at this point in the history
Post 3.3.3
  • Loading branch information
jacobtylerwalls authored Sep 20, 2024
2 parents 5a93a9f + 11db16d commit 1368be1
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,4 @@ under this name, or we did not manage to find their commits in the history.
- correctmost <[email protected]>
- Oleh Prypin <[email protected]>
- Eric Vergnaud <[email protected]>
- Hashem Nasarat <[email protected]>
15 changes: 14 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Release date: TBA



What's New in astroid 3.3.3?
What's New in astroid 3.3.4?
============================
Release date: TBA

Expand All @@ -18,6 +18,19 @@ Release date: TBA
Closes pylint-dev/pylint#9811


What's New in astroid 3.3.3?
============================
Release date: 2024-09-20

* Fix inference regression with property setters.

Closes pylint-dev/pylint#9811

* Add annotation-only instance attributes to attrs classes to fix `no-member` false positives.

Closes #2514


What's New in astroid 3.3.2?
============================
Release date: 2024-08-11
Expand Down
14 changes: 10 additions & 4 deletions astroid/brain/brain_attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
"field",
)
)
NEW_ATTRS_NAMES = frozenset(
(
"attrs.define",
"attrs.mutable",
"attrs.frozen",
)
)
ATTRS_NAMES = frozenset(
(
"attr.s",
Expand All @@ -33,9 +40,7 @@
"attr.define",
"attr.mutable",
"attr.frozen",
"attrs.define",
"attrs.mutable",
"attrs.frozen",
*NEW_ATTRS_NAMES,
)
)

Expand Down Expand Up @@ -64,13 +69,14 @@ def attr_attributes_transform(node: ClassDef) -> None:
# Prevents https://github.com/pylint-dev/pylint/issues/1884
node.locals["__attrs_attrs__"] = [Unknown(parent=node)]

use_bare_annotations = is_decorated_with_attrs(node, NEW_ATTRS_NAMES)
for cdef_body_node in node.body:
if not isinstance(cdef_body_node, (Assign, AnnAssign)):
continue
if isinstance(cdef_body_node.value, Call):
if cdef_body_node.value.func.as_string() not in ATTRIB_NAMES:
continue
else:
elif not use_bare_annotations:
continue
targets = (
cdef_body_node.targets
Expand Down
4 changes: 4 additions & 0 deletions script/.contributors_aliases.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
"mails": ["[email protected]", "[email protected]"],
"name": "James Addison"
},
"[email protected]": {
"mails": ["[email protected]", "[email protected]"],
"name": "Hashem Nasarat"
},
"[email protected]": {
"mails": ["[email protected]"],
"name": "Adam Hendry"
Expand Down
30 changes: 29 additions & 1 deletion tests/brain/test_attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import unittest

import astroid
from astroid import nodes
from astroid import exceptions, nodes

try:
import attr # type: ignore[import] # pylint: disable=unused-import
Expand Down Expand Up @@ -201,3 +201,31 @@ class Foo:
"""
should_be_unknown = next(astroid.extract_node(code).infer()).getattr("bar")[0]
self.assertIsInstance(should_be_unknown, astroid.Unknown)

def test_attr_with_only_annotation_fails(self) -> None:
code = """
import attr
@attr.s
class Foo:
bar: int
Foo()
"""
with self.assertRaises(exceptions.AttributeInferenceError):
next(astroid.extract_node(code).infer()).getattr("bar")

def test_attrs_with_only_annotation_works(self) -> None:
code = """
import attrs
@attrs.define
class Foo:
bar: int
baz: str = "hello"
Foo(1)
"""
for attr_name in ("bar", "baz"):
should_be_unknown = next(astroid.extract_node(code).infer()).getattr(
attr_name
)[0]
self.assertIsInstance(should_be_unknown, astroid.Unknown)

0 comments on commit 1368be1

Please sign in to comment.