-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Open
Labels
bugmypy got something wrongmypy got something wrongtopic-pep-695Issues related to PEP 695 syntaxIssues related to PEP 695 syntaxtopic-self-typesTypes for selfTypes for selftopic-type-variables
Description
Using Self
with a dataclass
raises a type-var error even though Self
is an acceptable type.
Suspect it may be the same as #18812.
To Reproduce
from __future__ import annotations
from dataclasses import dataclass
from typing import Self
type HasParent[N] = N | Node[N | HasParent[N]]
class Node[P = None]:
def parent(self) -> P: ... # type: ignore
@dataclass
class C[P: Node | None = Node | None](Node[P]):
item: D[Self]
class D[P: HasParent[C] = C](Node[P]):
pass
Changing to Self
to the explicit class type (item: D[C]
) is accepted. Similarly using Self
in a regular class (e.g. below with __init__
) does not raise any errors.
class C[P: Node | None = Node | None](Node[P]):
def __init__(self, item: D[Self]):
self.item = item
Expected Behavior
No errors.
Actual Behavior
error: Type argument "C[P]" of "D" must be a subtype of "HasParent[C[Node[None] | None]]" [type-var]
error: Type argument "Self" of "D" must be a subtype of "HasParent[C[Node[None] | None]]" [type-var]
Environment
- Mypy version used: 1.15.0
- Python version used: 13.2
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrongtopic-pep-695Issues related to PEP 695 syntaxIssues related to PEP 695 syntaxtopic-self-typesTypes for selfTypes for selftopic-type-variables
Projects
Milestone
Relationships
Development
Select code repository
Activity
Jdwashin9 commentedon Apr 14, 2025
Hello! I am working on an Open Source project for the first time, but I have taken multiple academic classes in Python. Can I work on this issue?
sobolevn commentedon Apr 14, 2025
@Jdwashin9 sure, feel free :)
brianschubert commentedon Apr 18, 2025
I think this boils down to:
Whether this is correct depends on what the inferred variance of
P@C
is supposed to be. Currently, mypy infers it to be invariant, since it treatsSelf
likeC[P]
for the purposes of variance inference.I don't think (?) the typing spec comments on whether
Self
should contribute to the inferred variance of other type variables. But I think this behavior is at least defensible, since it guards against unsound modification ofitem
via a supertype reference that would otherwise be possible ifP@C
were covariant.If anything, I wonder if we should always warn about
Self
being used invariantly like this. E.g., the following code is unsound due toB
implicitly overriding a mutable attribute, but is accepted by mypy and pryight:sterliakov commentedon May 1, 2025
I'm big +1 on rejecting such
Self
usage in instance attributes right at the definition site.Self
is only well-defined in covariant positions, so any use in writeable attributes and parameters is immediately unsafe and confusing - it violates all the rules we know (like "upcasting to a supertype should never make an ill-typed program well-typed") and can hide a lot of soundness issues.However, it's too late to start doing that - we have final PEP 673, we have typing spec, and they both define
Self
usage in attribute position. I think it's a linter job - like ruff'sbanned-api
- to preventfrom typing import Self
once and forever in projects that want that.