mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 05:20:49 -05:00
## Summary Fixes some TODOs introduced in #22672 around cases like the following: ```python from collections import namedtuple from dataclasses import dataclass NT = namedtuple("NT", "x y") # error: [invalid-dataclass] "Cannot use `dataclass()` on a `NamedTuple` class" dataclass(NT) ``` On main, `dataclass(NT)` emits `# error: [no-matching-overload]` instead, which is wrong -- the overload does match! On main, the logic proceeds as follows: 1. `dataclass` has two overloads: - `dataclass(cls: type[_T], ...) -> type[_T]` - `dataclass(cls: None = None, ...) -> Callable[[type[_T]], type[_T]]` 2. When `dataclass(NT)` is called: - Arity check: Both overloads accept one positional argument, so both pass. - Type checking on first overload: `NT` matches `type[_T]`... but then `invalid_dataclass_target()` runs and adds `InvalidDataclassApplication` error - Type checking on second overload: `NT` doesn't match `None`, so we have a type error. 3. After type checking, both overloads have errors. 4. `matching_overload_index()` filters by `overload.as_result().is_ok()`, which checks if `errors.is_empty()`. Since both overloads have errors, neither matches... 5. We emit the "No overload matches arguments" error. Instead, we now differentiate between non-matching errors, and errors that occur when we _do_ match, but the call has some other semantic failure.