Skip to content

Commit c00494a

Browse files
committed
no non default value after default value
Also draft for others
1 parent 507088c commit c00494a

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/test_typing_extensions.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7318,6 +7318,65 @@ def test_type_params_possibilities(self):
73187318
with self.assertRaisesRegex(TypeError, "type_params must be a tuple"):
73197319
TypeAliasType("InvalidTypeParams", List[T], type_params=[T])
73207320

7321+
# Regression test assure compatibility with typing.TypeVar
7322+
typing_T = typing.TypeVar('T')
7323+
with self.subTest(type_params="typing.TypeVar"):
7324+
TypeAliasType("TypingTypeParams", List[typing_T], type_params=(typing_T,))
7325+
7326+
# Test default order
7327+
T_default = TypeVar('T_default', default=int)
7328+
Ts = TypeVarTuple('Ts')
7329+
Ts_default = TypeVarTuple('Ts_default', default=Unpack[Tuple[str, int]])
7330+
P = ParamSpec('P')
7331+
P_default = ParamSpec('P_default', default=[str, int])
7332+
P_default2 = ParamSpec('P_default2', default=...)
7333+
7334+
ok_cases = [
7335+
(T, T_default),
7336+
(T, Ts_default),
7337+
(T, T_default, Ts_default),
7338+
(T, P, Ts),
7339+
(T, P, Ts_default),
7340+
(T, P_default),
7341+
(T, P_default, T_default),
7342+
(T, P_default, Ts_default),
7343+
(T, Ts_default, P_default),
7344+
(T, P_default, P_default2),
7345+
]
7346+
invalid_cases = [
7347+
(T_default, T),
7348+
(Ts_default, T),
7349+
7350+
# TypeVar after TypeVarTuple
7351+
# "TypeVars with defaults cannot immediately follow TypeVarTuples"
7352+
# (T, Ts, T_default),
7353+
# (T, Ts_default, T_default),
7354+
7355+
# Two TypeVarTuples in a row, should the reverse be also invalid?
7356+
(T, Ts_default, Ts),
7357+
7358+
(P_default, T),
7359+
(P_default, Ts),
7360+
7361+
# Double defintion
7362+
# (T, T)
7363+
# (Ts, *Ts)
7364+
# (P, **P)
7365+
7366+
# Potentially add invalid inputs, e.g. literals or classes
7367+
# depends on upstream
7368+
# (1,)
7369+
# (str,)
7370+
]
7371+
7372+
for case in ok_cases:
7373+
with self.subTest(type_params=case):
7374+
TypeAliasType("OkCase", List[T], type_params=case)
7375+
for case in invalid_cases:
7376+
with self.subTest(type_params=case):
7377+
with self.assertRaises(TypeError):
7378+
TypeAliasType("InvalidCase", List[T], type_params=case)
7379+
73217380
class DocTests(BaseTestCase):
73227381
def test_annotation(self):
73237382

src/typing_extensions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,8 +3536,15 @@ def __init__(self, name: str, value, *, type_params=()):
35363536
self.__value__ = value
35373537
self.__type_params__ = type_params
35383538

3539+
default_value_encountered = False
35393540
parameters = []
35403541
for type_param in type_params:
3542+
has_default = getattr(type_param, '__default__', NoDefault) is not NoDefault
3543+
if default_value_encountered and not has_default:
3544+
raise TypeError(f'Type parameter {type_param!r} without a default'
3545+
' follows type parameter with a default')
3546+
if has_default:
3547+
default_value_encountered = True
35413548
if isinstance(type_param, TypeVarTuple):
35423549
parameters.extend(type_param)
35433550
else:

0 commit comments

Comments
 (0)