Skip to content

[ty] Bind bare generic property receivers in protocol checks#26379

Draft
charliermarsh wants to merge 35 commits into
charlie/protocol-property-check-2from
charlie/protocol-property-generic-self
Draft

[ty] Bind bare generic property receivers in protocol checks#26379
charliermarsh wants to merge 35 commits into
charlie/protocol-property-check-2from
charlie/protocol-property-generic-self

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Jun 25, 2026

Copy link
Copy Markdown
Member

Summary

#25332 checks protocol property getter types covariantly, but it resolves a property accessor to its return type before binding an explicitly generic receiver. For a getter like as def value(self: T) -> T, the unresolved T can make an incompatible property appear to satisfy the protocol.

This binds a bare, unbounded accessor-local receiver type variable to the concrete implementing instance before comparing the getter result:

from typing import Protocol, TypeVar

T = TypeVar("T")

class HasValue(Protocol):
    @property
    def value(self: T) -> T: ...

class Good:
    @property
    def value(self) -> "Good":
        return self

class Bad:
    @property
    def value(self) -> int:
        return 1

good: HasValue = Good()
bad: HasValue = Bad()  # invalid

This is intentionally limited to a single non-overloaded getter whose receiver annotation is exactly one unbounded, unconstrained type variable bound by that accessor. Bounded or constrained type variables, nested receiver annotations such as Box[T], overloaded getters, generic setters, and protocol-to-protocol generic receiver relations remain unsupported and are rejected conservatively, so valid programs using those forms may still be rejected. Broader support should reuse a receiver-aware callable abstraction rather than adding a second generic solver inside protocol checking; the lazy receiver binding discussed in astral-sh/ty#1172 is the likely shared foundation.

@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label Jun 25, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Typing conformance results

The percentage of diagnostics emitted that were expected errors increased from 94.44% to 94.52%. The percentage of expected errors that received a diagnostic decreased from 90.21% to 90.03%. The number of fully passing files held steady at 95/134.

Summary

How are test cases classified?

Each test case represents one expected error annotation or a group of annotations sharing a tag. Counts are per test case, not per diagnostic — multiple diagnostics on the same line count as one. Required annotations (E) are true positives when ty flags the expected location and false negatives when it does not. Optional annotations (E?) are true positives when flagged but true negatives (not false negatives) when not. Tagged annotations (E[tag]) require ty to flag exactly one of the tagged lines; tagged multi-annotations (E[tag+]) allow any number up to the tag count. Flagging unexpected locations counts as a false positive.

Metric Old New Diff Outcome
True Positives 968 966 -2 ⏬ (❌)
False Positives 57 56 -1 ⏬ (✅)
False Negatives 105 107 +2 ⏫ (❌)
Total Diagnostics 1073 1070 -3
Precision 94.44% 94.52% +0.08% ⏫ (✅)
Recall 90.21% 90.03% -0.19% ⏬ (❌)
Passing Files 95/134 95/134 +0

Test file breakdown

1 file altered
File True Positives False Positives False Negatives Status
protocols_generic.py 7 (-2) ❌ 0 (-1) ✅ 2 (+2) ❌ 📉 Regressing
Total (all files) 966 (-2) ❌ 56 (-1) ✅ 107 (+2) ❌ 95/134

False positives removed (1)

1 diagnostic
Test case Diff

protocols_generic.py:144

-error[invalid-assignment] Object of type `ConcreteHasProperty1` is not assignable to `HasPropertyProto`

True positives removed (2)

2 diagnostics
Test case Diff

protocols_generic.py:145

-error[invalid-assignment] Object of type `ConcreteHasProperty2` is not assignable to `HasPropertyProto`

protocols_generic.py:147

-error[invalid-assignment] Object of type `ConcreteHasProperty4` is not assignable to `HasPropertyProto`

@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

@charliermarsh charliermarsh force-pushed the charlie/protocol-property-check-2 branch from 5c6e1ad to dde5560 Compare June 25, 2026 16:58
@charliermarsh charliermarsh reopened this Jun 25, 2026
@charliermarsh charliermarsh force-pushed the charlie/protocol-property-generic-self branch from 29fd2e9 to 5399dc5 Compare June 25, 2026 17:04
@codspeed-hq

codspeed-hq Bot commented Jun 25, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 18.18%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 2 regressed benchmarks
✅ 72 untouched benchmarks
⏩ 64 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation ty_micro[many_protocol_members_mismatch] 364.3 ms 801.5 ms -54.55%
WallTime colour_science 43.3 s 45.9 s -5.69%
Simulation DateType 258 ms 201.9 ms +27.78%

Tip

Investigate this regression with the CodSpeed MCP and your agent.


Comparing charlie/protocol-property-generic-self (5399dc5) with main (f82a36b)2

Open in CodSpeed

Footnotes

  1. 64 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on charlie/protocol-property-check-2 (8f86bcf) during the generation of this report, so main (f82a36b) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@charliermarsh charliermarsh force-pushed the charlie/protocol-property-check-2 branch 2 times, most recently from 385851c to 0e47141 Compare June 25, 2026 23:43
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.

2 participants