Skip to content

__class__ seen as type[Self] vs runtime #10685

@Enegg

Description

@Enegg

Describe the bug
__class__ within a method's body resolves to the concrete class that method has been created in, and doesn't consider subclasses.
Pyright seems to incorrectly treat that identifier as type[Self], while it really should be type[<class name>] (and thus not assignable to type[Self]). I think the following bug(s) stem from this.

Prior to Pyright 1.1.401, the code in #10451 rightly reported an error at this return statement:

return __class__()  # Type "Self@Foo" is not assignable to return type "Self@Foo"

In >=1.1.401, this diagnostic went away, likely due to the fix for the linked issue.

Code or Screenshots
Prior to the fix:

from typing import Self, reveal_type

class Foo:
    def func(self) -> Self:
        reveal_type(__class__)  # type[Self@Foo]
        reveal_type(__class__())  # Self@Foo
        _: Self = __class__()  # ok
        return __class__()  # Type "Self@Foo" is not assignable to return type "Self@Foo"

After the fix:

class Foo:
    def func(self) -> Self:
        reveal_type(__class__)  # type[Self@Foo]; should probably be "type[Foo]"
        reveal_type(__class__())  # Self@Foo; should probably be "Foo"
        _: Self = __class__()  # ok; should be an error
        return __class__()  # ok; should be an error
class Bar(Foo): ...
bar = Bar()
reveal_type(bar.func())  # pylance: Type of "bar.func()" is "Bar"; runtime: Runtime type is 'Foo'

VS Code extension or command-line
Pylance; the (somewhat correct) error message is present in 2025.5.100.
In 2025.5.101, it went away.

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions