When working with function return annotations, I encountered a situation where (str, str) was used instead of Tuple[str, str]. This syntax is valid Python for creating a tuple of types, but it’s not recognized by typing.get_origin in the same way as Tuple[str, str] or tuple[str, str].
As someone who’s has not been intimately familiar with python’s typing development I would be keen to learn any background/ if this is intentional. If not I’d be happy to look into what changes would be required for a PR.
I’m also keen to validate my understanding for correctness with this community, as I currently see it this change would have:
Benefits
Alignment in validity between type annotation declarations and typing utils
Better support for static type checking tools (my use case)
More intuitive behavior for users
Drawbacks
Backward compatibility concerns
Crossing the boundary between typing declarations and standard declarations
Tuple expressions are not currently allowed in type expressions. For details, refer to the Python typing spec. Refer to this section for details.
In addition to the drawbacks you’ve already listed, I’ll add:
3. Backward compatibility with static type checkers, language servers, linters, etc. that honor the current static type spec. (I’m assuming here that your “backward compatibility” point is referring to runtime concerns.)
4. Exposes a second, redundant way to “spell” a tuple type in a type expression. Adding redundant ways to do something can lead to confusion, so it should be done cautiously.
5. Eliminates tuple expressions for future use in static typing for other purposes.
Perhaps most importantly:
6. Introduces an ambiguity in PEP 695 generics syntax between a type parameter with an upper bound versus a type parameter with value constraints. For details, refer to this section and this section of PEP 695.
What you’re suggesting has a lot of downsides, and I don’t think it solves any real problem. If you want to spell a tuple type in a type expression, you can already do so today using the expression tuple[str, str].
I think there was also another longer discussion, but I couldn’t find it. Generally this is a bad idea because subscript syntax contains implicit parentheses for brevity, so T[A, B] is equivalent to T[(A, B)][1].
Technically parantheses aren’t a required part of any tuple, they’re only there to resolves ambiguities, what makes a tuple a tuple is , the only exception to that rule is the empty tuple syntax sugar ()↩︎