Skip to content

[ty] Fix instance-attribute lookup in methods of protocol classes#24213

Merged
AlexWaygood merged 1 commit intomainfrom
alex/proto-instance-fix
Mar 26, 2026
Merged

[ty] Fix instance-attribute lookup in methods of protocol classes#24213
AlexWaygood merged 1 commit intomainfrom
alex/proto-instance-fix

Conversation

@AlexWaygood
Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood commented Mar 26, 2026

Summary

Our existing @Todo type for the meta-type of protocols was being applied too broadly. The intent was only ever to use a @Todo type for type[P] when a user had actually written such an annotation in an annotation expression. This PR makes the situations where we infer this @Todo type much narrower, reflecting the original intent and allowing us to fix a bunch of TODOs in our test suite.

Test Plan

mdtests updated

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Mar 26, 2026
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 26, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 86.59%. The percentage of expected errors that received a diagnostic held steady at 80.96%. The number of fully passing files held steady at 68/132.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 26, 2026

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 26, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
unused-type-ignore-comment 0 16 0
invalid-argument-type 8 1 6
unresolved-attribute 3 0 1
invalid-return-type 3 0 0
no-matching-overload 2 0 0
not-subscriptable 1 0 0
possibly-missing-attribute 1 0 0
Total 18 17 7
Raw diff (42 changes)
altair (https://github.com/vega/altair)
+ altair/datasets/_reader.py:339:16 error[unresolved-attribute] Object of type `IntoLazyFrameT@Reader` has no attribute `lazy`
+ altair/datasets/_readimpl.py:227:20 warning[possibly-missing-attribute] Attribute `lazy` may be missing on object of type `IntoDataFrameT@into_scan`
+ altair/vegalite/v6/api.py:937:26 error[invalid-argument-type] Argument is incorrect: Expected `<TypedDict with items '__extra_items__', 'empty', 'param', 'test', 'value'> | Iterable[tuple[str, object]]`, found `dict[str, Any]`

koda-validate (https://github.com/keithasaurus/koda-validate)
- koda_validate/set.py:72:34 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `Invalid`, found `Unknown | Valid[_ItemT@SetValidator] | Invalid`
+ koda_validate/set.py:72:34 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `Invalid`, found `Unknown | _ItemT@SetValidator | Valid[_ItemT@SetValidator] | Invalid`
- koda_validate/set.py:74:32 error[invalid-argument-type] Argument to bound method `add` is incorrect: Expected `_ItemT@SetValidator`, found `Unknown | Valid[_ItemT@SetValidator] | Invalid`
+ koda_validate/set.py:74:32 error[invalid-argument-type] Argument to bound method `add` is incorrect: Expected `_ItemT@SetValidator`, found `Unknown | _ItemT@SetValidator | Valid[_ItemT@SetValidator] | Invalid`
- koda_validate/set.py:128:34 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `Invalid`, found `Unknown | Valid[_ItemT@SetValidator] | Invalid`
+ koda_validate/set.py:128:34 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `Invalid`, found `Unknown | _ItemT@SetValidator | Valid[_ItemT@SetValidator] | Invalid`
- koda_validate/set.py:130:32 error[invalid-argument-type] Argument to bound method `add` is incorrect: Expected `_ItemT@SetValidator`, found `Unknown | Valid[_ItemT@SetValidator] | Invalid`
+ koda_validate/set.py:130:32 error[invalid-argument-type] Argument to bound method `add` is incorrect: Expected `_ItemT@SetValidator`, found `Unknown | _ItemT@SetValidator | Valid[_ItemT@SetValidator] | Invalid`

schemathesis (https://github.com/schemathesis/schemathesis)
+ src/schemathesis/schemas.py:682:43 error[unresolved-attribute] Object of type `P@APIOperation` has no attribute `media_type`

static-frame (https://github.com/static-frame/static-frame)
+ static_frame/core/store_sqlite.py:83:34 error[invalid-argument-type] Argument to function `register_adapter` is incorrect: Expected `type[SupportsInt | str | Buffer | SupportsIndex | SupportsTrunc]`, found `<class 'signedinteger[_64Bit]'>`
+ static_frame/core/store_sqlite.py:84:34 error[invalid-argument-type] Argument to function `register_adapter` is incorrect: Expected `type[SupportsInt | str | Buffer | SupportsIndex | SupportsTrunc]`, found `<class 'signedinteger[_32Bit]'>`
+ static_frame/core/store_sqlite.py:85:34 error[invalid-argument-type] Argument to function `register_adapter` is incorrect: Expected `type[SupportsInt | str | Buffer | SupportsIndex | SupportsTrunc]`, found `<class 'signedinteger[_16Bit]'>`

sympy (https://github.com/sympy/sympy)
+ sympy/polys/rootconditions.py:98:20 error[invalid-return-type] Return type does not match returned value: expected `list[Er@_dup_routh_hurwitz_fraction_free]`, found `list[RingElement]`
+ sympy/polys/rootconditions.py:297:18 error[invalid-argument-type] Argument to bound method `is_zero` is incorrect: Expected `Er@_dup_schur_conditions`, found `RingElement`
+ sympy/polys/rootconditions.py:297:38 error[invalid-argument-type] Argument to function `dup_eval` is incorrect: Expected `Domain[RingElement]`, found `Domain[Er@_dup_schur_conditions]`
+ sympy/polys/rootconditions.py:298:16 error[invalid-return-type] Return type does not match returned value: expected `list[Er@_dup_schur_conditions]`, found `list[RingElement]`
- sympy/polys/compatibility.py:850:77 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/domains/domain.py:1202:22 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/domains/domain.py:1206:22 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/domains/domain.py:1210:23 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/domains/domain.py:1214:23 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ sympy/polys/domains/domain.py:1222:20 error[invalid-return-type] Return type does not match returned value: expected `Er@Domain`, found `RingElement`
+ sympy/polys/euclidtools.py:368:30 error[invalid-argument-type] Argument to function `dup_mul_ground` is incorrect: Expected `Domain[RingElement]`, found `Domain[Er@dup_inner_subresultants]`
+ sympy/polys/euclidtools.py:396:18 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `Er@dup_inner_subresultants`, found `RingElement`
- sympy/polys/euclidtools.py:386:36 error[invalid-argument-type] Argument to function `dup_exquo_ground` is incorrect: Expected `Domain[@Todo | RingElement]`, found `Domain[Er@dup_inner_subresultants]`
+ sympy/polys/euclidtools.py:386:36 error[invalid-argument-type] Argument to function `dup_exquo_ground` is incorrect: Expected `Domain[RingElement]`, found `Domain[Er@dup_inner_subresultants]`
- sympy/polys/euclidtools.py:392:33 error[invalid-argument-type] Argument to bound method `quo` is incorrect: Expected `Er@dup_inner_subresultants`, found `@Todo | RingElement`
+ sympy/polys/euclidtools.py:392:33 error[invalid-argument-type] Argument to bound method `quo` is incorrect: Expected `Er@dup_inner_subresultants`, found `RingElement`
+ sympy/polys/fields.py:663:17 error[unresolved-attribute] Attribute `ring` is not defined on `Er@FracElement` in union `Unknown | PolyElement[Er@FracElement] | Er@FracElement`
- sympy/polys/polyclasses.py:2351:26 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/polyclasses.py:2378:25 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/polyclasses.py:2385:28 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/polyclasses.py:2386:28 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ sympy/polys/polyclasses.py:2146:16 error[no-matching-overload] No overload of function `divmod` matches arguments
+ sympy/polys/polyclasses.py:2167:16 error[no-matching-overload] No overload of function `divmod` matches arguments
- sympy/polys/puiseux.py:809:28 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/puiseux.py:832:41 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:1670:36 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:1672:37 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:1677:80 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:3062:38 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:3064:37 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- sympy/polys/rings.py:1340:46 error[unresolved-attribute] Attribute `itermonoms` is not defined on `int` in union `PolyElement[Er@PolyElement] | Er@PolyElement | int`
+ sympy/polys/rings.py:1340:46 error[unresolved-attribute] Attribute `itermonoms` is not defined on `Er@PolyElement`, `int` in union `PolyElement[Er@PolyElement] | Er@PolyElement | int`
+ sympy/polys/rings.py:1345:46 error[not-subscriptable] Cannot subscript object of type `Er@PolyElement` with no `__getitem__` method

werkzeug (https://github.com/pallets/werkzeug)
- src/werkzeug/middleware/lint.py:153:14 error[invalid-argument-type] Argument to bound method `__next__` is incorrect: Expected `Self@__next__`, found `Iterator[bytes]`

Full report with detailed diff (timing results)

@AlexWaygood
Copy link
Copy Markdown
Member Author

There's some weirdness in that ecosystem report but I think it's mostly other pre-existing issues rather than anything in this PR.

@AlexWaygood AlexWaygood marked this pull request as ready for review March 26, 2026 19:03
@charliermarsh
Copy link
Copy Markdown
Member

I came to the same conclusion in my own analysis on that other PR -- that this was mostly surfacing existing false positives via better inference.

@AlexWaygood AlexWaygood merged commit 229e49f into main Mar 26, 2026
49 checks passed
@AlexWaygood AlexWaygood deleted the alex/proto-instance-fix branch March 26, 2026 22:32
carljm added a commit that referenced this pull request Mar 31, 2026
* main: (40 commits)
  [ty] resolve union-likes in emitting union attribute errors (#24263)
  [ty] Improve support for `Callable` type context (#23888)
  [ty] Propagate type context through `await` expressions (#24256)
  [`pyflakes`] Flag annotated variable redeclarations as `F811` in preview mode (#24244)
  [ty] Preserve `Divergent` when materializing recursive aliases (#24245)
  Fix W391 fixes for consecutive empty notebook cells (#24236)
  [flake8-bugbear] Clarify RUF071 fix safety for non-path string comparisons (#24149)
  [ty] Ban type qualifiers in PEP-695 type aliases (#24242)
  [ty] Include keyword-prefixed symbols in completions for attributes (#24232)
  [ty] Add tests for TypedDict method overloads on unions (#24230)
  [ty] report unused bindings as unnecessary hint diagnostics (#23305)
  Remove unused `non_root` variable (#24238)
  Extend F507 to flag %-format strings with zero placeholders (#24215)
  [`flake8-simplify`] Suppress `SIM105` for `except*` before Python 3.12 (#23869)
  Ignore pre-initialization references in SIM113 (#24235)
  Parenthesize expression in RUF050 fix (#24234)
  Publish playgrounds using the `release-playground` environment (#24223)
  [ty] Fix instance-attribute lookup in methods of protocol classes (#24213)
  [ty] Used shared expression cache during generic call inference (#24219)
  [ty] make `Type::BoundMethod` include instances of same-named methods bound to a subclass (#24039)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants