Latest Results
[ty] Preserve inference when filtering constructor overloads (#27254)
## Summary
Fixes astral-sh/ty#4106.
A concrete call to an overloaded generic constructor should select the
first matching overload, unless there is real ambiguity due to gradual
arguments. In main, the following instead incorrectly resolves to
`Unknown`:
```python
class MixedSelf[T]:
@overload
def __new__(cls, value: list[T]) -> Self: ...
@overload
def __new__(cls, value: T) -> T: ...
reveal_type(MixedSelf([1])) # should be MixedSelf[int], but is Unknown in main
```
During step 5 of overload evaluation, the `cls` argument is
`type[MixedSelf[T]]`, while the first matching overload has already
specialized its receiver to `type[MixedSelf[int]]`. The previous step 5
check accidentally treated `T` as fixed instead of inferable, so it
could not recognize that `type[MixedSelf[T]]` is assignable to
`type[MixedSelf[int]]`. This caused step 5 to wrongly consider the
overloads gradually ambiguous and infer `Unknown`. In this PR, we pass
the current overload's inferable type variables into the assignability
check to fix this.
The receiver must still participate in overload filtering (Codex's first
fix attempt here was to simply exclude it, which is wrong): it can be
the only gradual argument. For example:
```python
class Foo[T]:
@overload
def __new__(cls: type[Foo[int]]) -> int: ...
@overload
def __new__(cls: type[Foo[str]]) -> str: ...
reveal_type(Foo[int]()) # int
reveal_type(Foo[str]()) # str
reveal_type(Foo[Any]()) # Unknown: genuinely ambiguous
```
## Test plan
- Cover the original overlapping `Self`/`T` constructor regression and a
non-instance-return variant.
- Cover concrete receiver-specific overload selection for `Foo[int]()`
and `Foo[str]()`.
- Cover `Foo[Any]()` as a genuine ambiguity when the synthetic receiver
is the only gradual argument.
###
All ecosystem changes are improvements. Bokeh is the only
suspicious-looking case, but this is just exposing an existing
unsupported metaclass-provides-property-descriptors thing that Bokeh
does, so these errors are expected. [`pydocstyle`] Skip section detection inside RST directive bodies (`D214`, `D405`, `D413`) (#23635)
## Summary
Fixes #23562.
Content inside reStructuredText directives (e.g., `.. code-block::
yaml`) was incorrectly identified as docstring section headers. For
example, `references:` inside a code-block would trigger D405
(capitalization), D214 (over-indentation), and D413 (missing blank
line).
The root cause is that the section parser in `from_docstring`
(`docstrings/sections.rs`) iterates docstring lines and calls
`is_docstring_section` with no awareness of RST directive blocks. The
word `references` matches `SectionKind::References`, the suffix `:`
passes the section name check, and the preceding blank line (required by
RST after the directive declaration) satisfies the end-of-paragraph
heuristic.
There is already existing RST awareness in
`blanks_and_section_underline` (the `is_sphinx` check at lines 1593 and
1691), but that serves a different purpose — it preserves blank lines
when a *real* section header like `Example:` has a `.. code-block::`
directive as its body content. This fix is complementary: it prevents
content *inside* a directive body from being misidentified as section
headers in the first place.
This adds RST directive body tracking to `from_docstring`. When a line
starting with `.. ` is detected (an RST directive), all subsequent lines
indented deeper than the directive are skipped from section detection.
Real sections after directives continue to be detected correctly.
## Test Plan
Added `sphinx_directive.py` test fixture with cases for:
- Module-level docstring with `.. code-block:: yaml` containing
`references:` (the exact case from #23562)
- Function-level docstring with directive followed by real sections
(`Returns:`)
- Single-colon directive variant (`.. code-block: yaml`)
- Nested directives (`.. note::` containing `.. code-block::`)
- Real section (`Notes:`) following a directive — verifies sections
after directives are still detected
Registered test cases for `D214`, `D405`, and `D413` against the new
fixture. All 72 pydocstyle tests pass:
```
cargo test -p ruff_linter -- "pydocstyle::tests::rules"
test result: ok. 72 passed; 0 failed; 0 ignored
```
Also manually verified the original reproduction case no longer triggers
D405/D214/D413 false positives.
---------
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com> Latest Branches
0%
WhiteFox0-0:fix/pth-autofix -18%
charlie/callable-protocol-receiver-overloads -5%
charlie/fix-is-dataclass-narrowing © 2026 CodSpeed Technology