ty icon indicating copy to clipboard operation
ty copied to clipboard

Conversion of abc.Collection[str] to set() becomes set[Unknown] instead of set[str]

Open sinon opened this issue 1 week ago • 2 comments

Summary

Couldn't find an issue that quite matched (maybe this https://github.com/astral-sh/ty/issues/1473 if so please close this and I will link my suppression comment to reference it instead)

Problem: Conversion of abc.Collection[str] to set() loses type see following code for example

from collections.abc import Collection
from typing import reveal_type


async def some_fn(
    collect_str: Collection[str] | None = None,
) -> None:
    if collect_str is not None:
        reveal_type(collect_str) # Collection[str]
        set_of_collection = set(collect_str)
        reveal_type(set_of_collection)  # set[Unknown]

https://play.ty.dev/08c04eb9-d638-4062-a327-3a75648adcf4

Pyrefly and Pyright both resolves as set[str]

Version

ty 0.0.3 (fadfe0966 2025-12-17)

sinon avatar Dec 18 '25 10:12 sinon

Thank you for reporting this.

I minified this further to:

from collections.abc import Collection
from typing import reveal_type

def _(collect_str: Collection[str]):
    reveal_type(set(collect_str))  # set[Unknown]

Since the set constructor is generic (def __init__(self, iterable: Iterable[_T], /) -> None: ...), I think this is just an instance of #1714.

sharkdp avatar Dec 18 '25 12:12 sharkdp

Since the set constructor is generic (def __init__(self, iterable: Iterable[_T], /) -> None: ...), I think this is just an instance of #1714.

but our existing generics solver should be able to already handle cases where classes explicitly inherit from generic protocols. It's only cases where types are implicit subtypes of generic protocols where there are still TODOs. And Collection explicitly inherits from Iterable. So I think there may be something else going on here.

AlexWaygood avatar Dec 18 '25 12:12 AlexWaygood