Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Reject legacy TypeVars in PEP 695 class bases#25975

Merged
charliermarsh merged 2 commits into
mainfrom
charlie/pep695-legacy-base-typevar
Jun 14, 2026
Merged

[ty] Reject legacy TypeVars in PEP 695 class bases#25975
charliermarsh merged 2 commits into
mainfrom
charlie/pep695-legacy-base-typevar

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Jun 14, 2026

Copy link
Copy Markdown
Member

Summary

PEP 695 requires classes that use the new type parameter syntax not to introduce traditional type variables through their base classes. Prior to this change, we prioritized the PEP 695 generic context and silently discarded a legacy context inherited from another generic base:

from typing import TypeVar

K = TypeVar("K")

class Bad[V](dict[K, V]): ...

This reports invalid-generic-class when a PEP 695 class inherits a supported legacy generic context. A PEP 695 parameter with the same name continues to shadow the global TypeVar, and ordinary methods can still use the traditional implicit generic-function mechanism.

Generic base types are normalized before this validation runs, so for those cases, we just leave them as a TODO for now.

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

astral-sh-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

Typing conformance results improved 🎉

The percentage of diagnostics emitted that were expected errors increased from 94.36% to 94.36%. The percentage of expected errors that received a diagnostic increased from 88.82% to 88.91%. The number of fully passing files held steady at 93/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 953 954 +1 ⏫ (✅)
False Positives 57 57 +0
False Negatives 120 119 -1 ⏬ (✅)
Total Diagnostics 1058 1059 +1
Precision 94.36% 94.36% +0.01% ⏫ (✅)
Recall 88.82% 88.91% +0.09% ⏫ (✅)
Passing Files 93/134 93/134 +0

Test file breakdown

1 file altered
File True Positives False Positives False Negatives Status
generics_syntax_compatibility.py 1 (+1) ✅ 0 1 (-1) ✅ 📈 Improving
Total (all files) 954 (+1) ✅ 57 119 (-1) ✅ 93/134

True positives added (1)

1 diagnostic
Test case Diff

generics_syntax_compatibility.py:14

+error[invalid-generic-class] Legacy type variable `K` cannot be used in a PEP 695 class base

@astral-sh-bot

astral-sh-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Jun 14, 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)

Comment thread crates/ty_python_semantic/src/types/infer/builder/post_inference/static_class.rs Outdated
@charliermarsh charliermarsh enabled auto-merge (squash) June 14, 2026 22:56
@charliermarsh charliermarsh merged commit f432c0d into main Jun 14, 2026
58 checks passed
@charliermarsh charliermarsh deleted the charlie/pep695-legacy-base-typevar branch June 14, 2026 23:01
charliermarsh added a commit that referenced this pull request Jun 15, 2026
## Summary

A function with its own PEP 695 type parameter list cannot also
introduce a traditional `TypeVar` or `ParamSpec`. Prior to this change,
we discovered the legacy generic context while building the signature
but discarded it when merging with the PEP 695 context without reporting
an error:

```python
from typing import TypeVar

K = TypeVar("K")

def method[M](value: M, other: K) -> M | K:
    raise NotImplementedError
```

With #25975, we now pass the `generics_syntax_compatibility` test in the
conformance suite.
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