Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple-like Sequence #8441

Open
llchan opened this issue Feb 25, 2020 · 4 comments
Open

Tuple-like Sequence #8441

llchan opened this issue Feb 25, 2020 · 4 comments

Comments

@llchan
Copy link
Contributor

llchan commented Feb 25, 2020

There are situations where a variable can be either a list or a tuple (or more generally, a sequence), but it is used/unpacked in a tuple-like way. That is, the length is fixed and types are possibly heterogeneous. A practical example of this is mpi4py's buffer specifications.

I don't believe it's possible to express a fixed-length heterogeneous sequence without using Tuple and forcing a specific type/inheritance. It'd be useful to have an abstract type that expresses tuple semantics without the inheritance bounds. So the analogy is roughly: List is to Sequence as Tuple is to FixedSequence (or whatever name we choose).

def foo(x: FixedSequence[int, str]) -> int:
    return x[0]

foo((0, ''))
foo([0, ''])

Currently I think it's necessary to do Sequence[Union[int, str]] and this loses both the fixed length and the ordering of the elements in the sequence.

@JukkaL
Copy link
Collaborator

JukkaL commented Feb 28, 2020

I've encountered cases where something like this would have been useful.

A possible implementation would generalize the internal TupleType type to support other tuple-like types, with different fallback types. List expression type inference should also be modified to look for these new types in the type context.

The priority seems pretty low right now, however. If somebody writes a PEP draft about this feature and it gains some interest from the community, we'd likely increase the priority.

@jamesbraza
Copy link
Contributor

Python 3.9's Annotated gets us closer to the fixed-length part. Something like:

from collections.abc import Sequence
from typing import Annotated, TypeAlias

TTwoItem: TypeAlias = Annotated[Sequence[int], 2]

some_list: TTwoItem = [1, 2]
some_tuple: TTwoItem = (1, 2)
some_incorrect_tuple: TTwoItem = (1, 2, 3)  # A possible future mypy would error here

Note this would not accommodate the type heterogeneity aspect of this request.

@kwikwag
Copy link

kwikwag commented Dec 27, 2022

TTwoItem: TypeAlias = Annotated[Sequence[int], 2]

Could also be used to specify a range of valid lengths, e.g.

TTwoOrThreeInts: TypeAlias = Annotated[Sequence[int], range(2, 4)]

would specify a sequence with either 2 or 3 items.

@dimaqq
Copy link

dimaqq commented Mar 1, 2024

Just chiming in that I'd love to be able to have code like this pass type checks, and I think this request would be perfect for my case:

dict([[1,2]))

dict(["aa", "gg", "tt", "cc"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants