PEP 841 proposes adding new display syntax for frozenset and frozenlist:
f{1, 2, 3}for afrozensetf{"a": 1}for afrozendict
It also proposes comprehension syntax for both of these immutable collections, supporting both synchronous and asynchronous iterables:
f{item for item in items}/f{item async for item in ait}f{k: v for item in items}/f{k: v async for item in ait}
If PEP 841 were to be accepted, there would be a pretty striking asymmetry in comprehension syntax for Python’s primitive container types:
dict: {k: v for k, v in items}
frozendict: f{k, v for k, v in items}
set: {item for item in items}
frozenset: f{item for item in items}
list: [item for item in items]
tuple: No such construct exists .
tuple(item for item in items) and tuple([item for item in items]) are the best alternatives. The generator expression-based approach to constructing a tuple has the benefit that, for large lazy iterators, a separate list does not need to be materialized. However, this approach fails when the iterable is an async iterable:
tuple(item async for item in ait) # Does not work, because tuple() does not accept AsyncGenerator
The original rationale for the exclusion of tuple comprehensions appears to be due to its immutability (reference). Serhiy Storchaka explicitly cites the same reasoning as the reason why frozenset comprehensions were excluded as well. If PEP 841 were to be accepted, this rationale would no longer hold, as frozenset comprehensions would be introduced to Python.
For these reasons, I think that the idea of tuple comprehensions deserves to be revisited specifically in relation to PEP 841. Besides the motivation for asynchronous iterables listed above, PEP 841 lists one of the motivations for the PEP is to “increase the use of immutable containers in CPython”, and a first-class representation of tuple comprehensions would help further that motivation.
In terms of syntax, the obvious representation is currently used by generator expressions, so I would propose the following:
(item for item in items,)
The trailing comma presents no backwards compatibility concerns, as this is not valid syntax in any Python version, and it mirrors the use of a trailing comma to distinguish a parenthesized expression ("foo") from a singleton tuple ("foo",).
An alternative is perhaps f[item for item in items], treating tuple as the frozen counterpart to list, but this notation may be confusing since tuples are normally denoted using parentheses, not brackets.