I think generally any comprehension-like syntax is going to have too many shortcomings at runtime unless you can come up with a proper new syntax that is currently invalid and could be used within arbitrary subscript expressions, so that you can completely encapsulate the state the comprehension is trying to encode into a new object, rather than rely on the comprehension somehow magically returning an object that captures that state.
For backwards compatibility you could then manually construct that same object, just like you can with TypeAliasType
. It might even be more useful to first come up with a backwards compatible representation that doesn’t involve anything fancy like a comprehension and then think about if and how we could make this easier to use in the future with a proper syntax extension.
I feel similarly about TypedDict
literals, I think they could be a lot more powerful if they didn’t try to rely on current generics syntax in order to be backwards compatible but rather used completely new syntax. Ideally powerful enough to cover any corner-cases the class/functional syntax currently have, such as keys that aren’t valid identifier names, including good support for PEP-728. I would also try to design the syntax in such a way that adding support for different kinds of keys, e.g. int
or bytes
literals, would be possible in the future.
If you use completely new syntax it’s also easier to get away with allowing comprehension-like syntax within a typed dict literal, to support some of these use-cases, although I think it would be wiser to build something more generally useful and not limited to typed dict literals. Although to be fair, a lot of these use cases only make sense for structural types, so perhaps all we need is an equivalent syntax for Protocol
literals. There is however still the broader use-case of mapping variadic type parameters like TypeVarTuple
and ParamSpec
where a comprehension-like syntax extension could help with readability.