Skip to content

Literal tuples as iterator in a list/generator passed to tuple constructor show as not assignable to return type with fixed length #2994

@KeelanFh-QRoutes

Description

@KeelanFh-QRoutes

Describe the Bug

Pyrefly gives no errors for this:

def foo() -> tuple[tuple[int, ...], ...]:
    first = (1, 2, 3)
    second = (4, 5, 6)

    return tuple((*items,) for items in (first, second))

but this:

def foo() -> tuple[tuple[int, ...], tuple[int, ...]]:
    first = (1, 2, 3)
    second = (4, 5, 6)
    return tuple((*items,) for items in (first, second))

gives:

ERROR Returned type `tuple[tuple[Literal[1, 2, 3, 4, 5, 6], ...], ...]` is not assignable to declared return type `tuple[tuple[int, ...], tuple[int, ...]]` [bad-return]
 --> src\qroutes-files\foo.py:5:12
  |
1 | def foo() -> tuple[tuple[int, ...], tuple[int, ...]]:
  |              --------------------------------------- declared return type
2 |     first = (1, 2, 3)
3 |     second = (4, 5, 6)
4 |
5 |     return tuple((*items,) for items in (first, second))
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
 INFO 1 error

gives an error, even though the return value will always have length 2.

Similarly, for this case:

def bar(lines: tuple[str, ...]) -> tuple[tuple[str, ...], tuple[str, ...]]:
    first, second = lines[0], lines[1]

    return tuple(("baz", *items) for items in (first, second))

pyrefly gives

ERROR Returned type `tuple[tuple[Literal['baz'], *tuple[str, ...]], ...]` is not assignable to declared return type `tuple[tuple[str, ...], tuple[str, ...]]` [bad-return]
  --> src\qroutes-files\foo.py:11:12
   |
 8 | def bar(lines: tuple[str, ...]) -> tuple[tuple[str, ...], tuple[str, ...]]:
   |                                    --------------------------------------- declared return type
 9 |     first, second = lines[0], lines[1]
10 |
11 |     return tuple(("baz", *items) for items in (first, second))
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
 INFO 1 error

even though again the length of the tuple guarantees the return value will always have length 2.

This means your only option is to relax the type annotation to remove the pyrefly error, even though the stricter annotation was valid.

Sandbox Link

No response

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions