2025, Nov 27 17:00

PyCharm bug: typing.Self on generic classmethods in Python 3.13 shows a false-positive warning

Learn why PyCharm flags typing.Self on generic classmethods in Python 3.13, how to suppress the false-positive warning, and verify with mypy or Pyright.

Working with typing.Self in Python 3.13 should be straightforward: a classmethod returning Self on a generic base is expected to resolve to the concrete subclass when called through that subclass. Yet PyCharm can raise a confusing warning in this setup, suggesting a mismatch between the declared return type and the actual type. Let’s unpack what happens and how to deal with it pragmatically.

Reproducible example

The scenario: a generic base class with a classmethod returning Self, and a subclass that fixes the generic parameter. Calling the classmethod on the subclass triggers a warning in PyCharm.

from typing import Self

class Root[T]:
    @classmethod
    def build(cls) -> Self:
        return cls()

class Leaf(Root[int]):
    pass

def make_leaf() -> Leaf:
    return Leaf.build()  # Warning in PyCharm: "Expected type 'Leaf', got 'Root[int]' instead"

What’s actually going on

The code is correct. The classmethod build returns Self, so invoking it on the subclass should yield an instance typed as that subclass. The warning arises from PyCharm’s type checker, not from an issue in the code or the typing model.

There’s nothing wrong with your code. This is a bug in PyCharm.

The issue is tracked here: youtrack.jetbrains.com/issue/PY-75679/typing.Self-is-broken-for-Generic-base-classes. According to the shared observations, mypy does not exhibit the error, and it was also noted that PyCharm’s type-checker is not really up-to-spec. If you want an extra sanity check, you can validate with mypy and Pyright; both provide online sandboxes at mypy-play.net and pyright-play.net.

Practical fix

Since the warning is a false positive, the pragmatic way forward is to suppress it locally and move on. Two common, unobtrusive options are to add an inline directive that other tools will either accept or ignore harmlessly.

from typing import Self

class Root[T]:
    @classmethod
    def build(cls) -> Self:
        return cls()

class Leaf(Root[int]):
    pass

def make_leaf() -> Leaf:
    return Leaf.build()  # type: ignore

Alternatively, the same line can be silenced with # noqa. It was also pointed out that # noinspection PyTypeChecker is a PyCharm-specific directive; some prefer to avoid it unless a directive is needed that PyCharm will follow while other type checkers ignore.

Why this matters

False positives from static analysis cost time and erode trust in the tools. Knowing that this particular warning is a known issue helps you keep momentum without second-guessing sound typing patterns. When in doubt, cross-check with multiple type checkers; here, mypy does not report a problem, and Pyright can be used as a second opinion.

Takeaways

If you see PyCharm claim that a classmethod returning Self on a subclass of a generic returns the base generic instead of the subclass, treat it as a PyCharm bug (see the linked tracker). Keep the implementation as is, suppress the warning with # type: ignore or # noqa, and, if you want further assurance, validate the same snippet with mypy or Pyright using their online sandboxes. That way you preserve correct typing while keeping your editor noiseless.