Skip to content

fix Feature: support @field.validator decorator for attrs #2013#2782

Open
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
asukaminato0721:2013
Open

fix Feature: support @field.validator decorator for attrs #2013#2782
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
asukaminato0721:2013

Conversation

@asukaminato0721
Copy link
Contributor

Summary

Fixes #2013

patched class-body name assignment handling so attrs/dataclass field specifiers are recognized before the annotated field type overwrites them.

Test Plan

update test

@meta-cla meta-cla bot added the cla signed label Mar 12, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@asukaminato0721 asukaminato0721 marked this pull request as ready for review March 12, 2026 08:26
Copilot AI review requested due to automatic review settings March 12, 2026 08:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Pyrefly’s class-body name-assignment inference so that attrs/dataclass field specifier assignments (e.g. attrs.field()) can be treated as runtime “field objects” inside the class body, enabling decorator surfaces like @x.validator / @a.default to resolve.

Changes:

  • Track the owning class for Binding::NameAssign via a new class_key field.
  • Adjust name-assignment inference in class-member contexts to treat dataclass/attrs field specifier assignments as Any (to avoid the annotation overwriting the field object type in the class body).
  • Update attrs tests to cover @x.validator resolution and refine the existing default-decorator test expectations.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
pyrefly/lib/test/attrs/fields.rs Updates attrs testcases to validate @field.validator / @field.default decorator attribute resolution behavior.
pyrefly/lib/binding/target.rs Populates NameAssign.class_key from the current class scope when binding class-body assignments.
pyrefly/lib/binding/binding.rs Adds class_key to the NameAssign binding payload.
pyrefly/lib/alt/solve.rs Uses class_key during NameAssign inference to detect field specifier assignments and model class-body reads as Any for decorator resolution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@github-actions
Copy link

Diff from mypy_primer, showing the effect of this PR on open source code:

core (https://github.com/home-assistant/core)
- ERROR homeassistant/helpers/entity_registry.py:220:6-20: Object of class `str` has no attribute `default` [missing-attribute]
- ERROR homeassistant/helpers/entity_registry.py:510:6-20: Object of class `str` has no attribute `default` [missing-attribute]

attrs (https://github.com/python-attrs/attrs)
- ERROR tests/test_next_gen.py:142:14-25: Object of class `list` has no attribute `validator` [missing-attribute]
- ERROR tests/test_next_gen.py:380:14-25: Object of class `int` has no attribute `validator` [missing-attribute]

@github-actions
Copy link

Primer Diff Classification

✅ 2 improvement(s) | 2 project(s) total | -4 errors

2 improvement(s) across core, attrs.

Project Verdict Changes Error Kinds Root Cause
core ✅ Improvement -2 missing-attribute name_assign_infer()
attrs ✅ Improvement -2 missing-attribute name_assign_infer()
Detailed analysis

✅ Improvement (2)

core (-2)

The removed errors were false positives. In attrs classes, assignments like a: dict = field() create field specifier objects at the class level, not instances of the annotated type. These field objects have decorator methods like .default and .validator that are commonly used in attrs patterns. Pyrefly was incorrectly treating a as having type dict instead of recognizing it as an attrs field specifier. The PR fixes this by detecting field specifier assignments in dataclass/attrs contexts and modeling them appropriately, removing the incorrect missing-attribute errors.
Attribution: The change to name_assign_infer() in pyrefly/lib/alt/solve.rs added logic to detect dataclass/attrs field specifier assignments within class bodies. When detected, it models the field as Any instead of the annotated type, allowing decorator attributes like .default and .validator to resolve correctly. The new is_dataclass_field_specifier_assignment() method specifically checks for this pattern.

attrs (-2)

These were false positive errors. The code y: list = attrs.field() creates an attrs field object (not a list), and attrs field objects have a .validator decorator method. Pyrefly was incorrectly using the type annotation (list) instead of recognizing the runtime type of the field specifier. The PR fixed this by detecting field specifiers in class bodies and modeling them correctly, allowing valid attrs patterns like @field.validator to type-check properly.
Attribution: The change to name_assign_infer() in pyrefly/lib/alt/solve.rs added logic to detect attrs/dataclass field specifiers and model them as Any type instead of the annotated type, allowing field decorator methods like .validator to resolve correctly.


Was this helpful? React with 👍 or 👎

Classification by primer-classifier (2 LLM)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: support @field.validator decorator for attrs

2 participants