Skip to content

Subsequent isinstance(cls, type) and issubclass(cls, upper_bound) erase TypeVar information #2689

@randolf-scholz

Description

@randolf-scholz

Describe the Bug

This example fails:

class Foo: ...

def initialize[F: Foo](cls: type[F]) -> F:
    assert isinstance(cls, type)
    assert issubclass(cls, Foo)

    try: 
        inst = cls()
    except:
        raise

    return inst  # ❌️ E: Returned type `Foo` is not assignable to declared return type `F`

but if we uncomment either assert clause it succeeds. The root cause seems to be that the subsequence asserts narrow the type in a way that forgets the type variable:

reveal_type(cls)  # type[F]
assert isinstance(cls, type)
reveal_type(cls)  # type
assert issubclass(cls, Foo)
reveal_type(cls)  # type[Foo]

My expectation would be that neither assert changes the type, because

  • type[F] & type should equal type[F] (n.b. type[F] & type[Any] would be another story...)
  • type[F] & type[Foo] should equal type[F], as every F is a Foo.

Python: 3.14

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN2UYANxiooAfSbEYAHXRyAxlFRw4dAGK5ciOoT1y5mGGE7oIDCGIgAvGAG11OzbgC6ACiVwdU%2B%2BpcBKOgBaAD4NRDk6KIFhUQkfDyg4QLoAYkZmXxdI6JU4GD5OOFY4BgwFGES4ABoM6X8cqMERMUlMqpT0n0a6PIL%2BCFUAV2wlPKra5wb0aJiW%2BPbPTrrfLWz5GeiGSlIdHtmS-gBeOk83admYfAriBgjN2abUQdkN2cEGIcoZw6j0wBlyQDwf3QAKI6ABKME%2B3xgmBWdAABs4EUU6OhcPw8hA2OhUNhYIxcHQjGNBHCPl8Zj5EeoESBqiAhhYkiRyIgQOkAKrM8ykOhgIboBQWXDoOAGLDGfm8GioBjidBDGjYApufA6VgMQKhOilSj3d5Qyn8mQgABySpV%2BrowHwAF9TXJ6SAyIIwFBSIQGLQoBR0gAFUhuj26jA4AinUWQNhfOUQUWEOTpADKMBgdAAFgwGMQvAB6POu4wewi8Nh5mDoPOYXAKOB5hRR7GxkVV6WUXpCZ7KfHpxvoaMt%2BMzXC3YdwRPoMgMDOioIiSjFUV0E6mgDMhAAjAAmR3oEB2hmoYUQETqaAwChoLB4IhkA9AA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions