Skip to content

unsoundness with Self parameter type #21421

Closed as duplicate
Closed as duplicate

Description

@sanderr

Bug Report

When Self is used as a method parameter type (e.g. other: Self), mypy allows constructing unsound inheritance structures where it accepts a non-self value at runtime.

Concretely, consider a parent class which defines a method with a Self parameter, and a child class which overrides that method. The child class would also define the parameter type as Self, which would allow it to treat the object as an instance of itself. But the child can be assigned to a variable of the parent type, in which case a method call on the (static) parent variable with (dynamic) child value, mypy will accept values of the parent type for the method call.

An example based on the unsoundness proof from JelleZijlstra/unsoundness. Note how reveal_type shows that the inferred static type is str, while the runtime type is int.

from typing import Self, reveal_type


class A:
    def hello(self: Self, other: Self) -> str:
        return f"Hello {other!r}!"


class B(A):
    def __init__(self) -> None:
        self.x: str = "Hello B"

    def hello(self: Self, other: Self) -> str:
        return other.x


class C(A):
    def __init__(self, x: int) -> None:
        self.x: int = x


def func(x: int) -> str:
    b: A = B()
    return b.hello(C(x))


reveal_type(func(42))

This snippet is also available on https://mypy-play.net/?mypy=latest&python=3.13&gist=5c095b6462c3015f76b0cacad3efe47a.

Expected Behavior

I'm honestly not sure what the expected behavior should be. pyright rejects the method override. I think that's a sensible approach, but I can not judge what other consequences it might have.

I'm not 100% certain this is a mypy bug. I don't exclude the possibility that this is an issue with the typing spec, rather than with mypy specifically. But based on the fact that pyright does reject this, I'm assuming that labeling it as a bug is appropriate.

Actual Behavior

# from running mypy on the snippet
main.py:27: note: Revealed type is "str"
# from running the snippet
Runtime type is 'int'

Your Environment

  • Mypy version used: 1.20.2
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.13.11

Activity

  1. sanderr commented on May 7, 2026

    @sanderr
    Author

    Thanks. I had searched for duplicates, but there were so many search results for applicable keywords that I didn't manage to find a match.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions