mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-07 21:25:08 +00:00
[ruff
] Allow more field
calls from attrs
(RUF009
) (#19021)
Summary -- Closes #19014 by identifying more `field` functions from `attrs`. We already detected these when imported from `attrs` but not the `attr` module from the same package. These functions are identical to the `attrs` versions: ```pycon >>> import attrs, attr >>> attrs.field is attr.field True >>> attrs.Factory is attr.Factory True >>> ``` Test Plan -- Regression tests based on the issue
This commit is contained in:
parent
710c60f713
commit
b00f68a23c
3 changed files with 31 additions and 3 deletions
|
@ -125,3 +125,20 @@ class J:
|
|||
class K:
|
||||
f: F = F()
|
||||
g: G = G()
|
||||
|
||||
|
||||
# Regression test for https://github.com/astral-sh/ruff/issues/19014
|
||||
# These are all valid field calls and should not cause diagnostics.
|
||||
@attr.define
|
||||
class TestAttrField:
|
||||
attr_field_factory: list[int] = attr.field(factory=list)
|
||||
attr_field_default: list[int] = attr.field(default=attr.Factory(list))
|
||||
attr_factory: list[int] = attr.Factory(list)
|
||||
attr_ib: list[int] = attr.ib(factory=list)
|
||||
attr_attr: list[int] = attr.attr(factory=list)
|
||||
attr_attrib: list[int] = attr.attrib(factory=list)
|
||||
|
||||
|
||||
@attr.attributes
|
||||
class TestAttrAttributes:
|
||||
x: list[int] = list() # RUF009
|
||||
|
|
|
@ -25,14 +25,16 @@ fn is_stdlib_dataclass_field(func: &Expr, semantic: &SemanticModel) -> bool {
|
|||
.is_some_and(|qualified_name| matches!(qualified_name.segments(), ["dataclasses", "field"]))
|
||||
}
|
||||
|
||||
/// Returns `true` if the given [`Expr`] is a call to `attr.ib()` or `attrs.field()`.
|
||||
/// Returns `true` if the given [`Expr`] is a call to an `attrs` field function.
|
||||
fn is_attrs_field(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
semantic
|
||||
.resolve_qualified_name(func)
|
||||
.is_some_and(|qualified_name| {
|
||||
matches!(
|
||||
qualified_name.segments(),
|
||||
["attrs", "field" | "Factory"] | ["attr", "ib"]
|
||||
["attrs", "field" | "Factory"]
|
||||
// See https://github.com/python-attrs/attrs/blob/main/src/attr/__init__.py#L33
|
||||
| ["attr", "ib" | "attr" | "attrib" | "field" | "Factory"]
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -120,7 +122,8 @@ pub(super) fn dataclass_kind<'a>(
|
|||
|
||||
match qualified_name.segments() {
|
||||
["attrs" | "attr", func @ ("define" | "frozen" | "mutable")]
|
||||
| ["attr", func @ ("s" | "attrs")] => {
|
||||
// See https://github.com/python-attrs/attrs/blob/main/src/attr/__init__.py#L32
|
||||
| ["attr", func @ ("s" | "attributes" | "attrs")] => {
|
||||
// `.define`, `.frozen` and `.mutable` all default `auto_attribs` to `None`,
|
||||
// whereas `@attr.s` implicitly sets `auto_attribs=False`.
|
||||
// https://www.attrs.org/en/stable/api.html#attrs.define
|
||||
|
|
|
@ -98,3 +98,11 @@ RUF009_attrs.py:127:12: RUF009 Do not perform function call `G` in dataclass def
|
|||
127 | g: G = G()
|
||||
| ^^^ RUF009
|
||||
|
|
||||
|
||||
RUF009_attrs.py:144:20: RUF009 Do not perform function call `list` in dataclass defaults
|
||||
|
|
||||
142 | @attr.attributes
|
||||
143 | class TestAttrAttributes:
|
||||
144 | x: list[int] = list() # RUF009
|
||||
| ^^^^^^ RUF009
|
||||
|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue