|
7 | 7 | import weakref |
8 | 8 | from test.support import check_syntax_error, run_code, run_no_yield_async_fn |
9 | 9 |
|
10 | | -from typing import Generic, NoDefault, Sequence, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, get_args |
| 10 | +from typing import (Callable, Generic, NoDefault, Sequence, TypeAliasType, |
| 11 | + TypeVar, TypeVarTuple, ParamSpec, get_args) |
11 | 12 |
|
12 | 13 |
|
13 | 14 | class TypeParamsInvalidTest(unittest.TestCase): |
@@ -1418,6 +1419,111 @@ def test_symtable_key_regression_name(self): |
1418 | 1419 | self.assertEqual(ns["X1"].__type_params__[0].__default__, "A") |
1419 | 1420 | self.assertEqual(ns["X2"].__type_params__[0].__default__, "B") |
1420 | 1421 |
|
| 1422 | + def test_default_refers_to_earlier_type_param(self): |
| 1423 | + class A[T1, T2=T1]: ... |
| 1424 | + |
| 1425 | + self.assertEqual(A[int].__args__, (int, int)) |
| 1426 | + self.assertEqual(A[int, str].__args__, (int, str)) |
| 1427 | + |
| 1428 | + def test_default_refers_to_earlier_type_param_chain(self): |
| 1429 | + class A[T1, T2=T1, T3=T2]: ... |
| 1430 | + |
| 1431 | + self.assertEqual(A[int].__args__, (int, int, int)) |
| 1432 | + self.assertEqual(A[int, str].__args__, (int, str, str)) |
| 1433 | + self.assertEqual(A[int, str, bool].__args__, (int, str, bool)) |
| 1434 | + |
| 1435 | + def test_default_refers_to_earlier_type_param_nested(self): |
| 1436 | + class A[T1, T2=list[T1]]: ... |
| 1437 | + |
| 1438 | + self.assertEqual(A[int].__args__, (int, list[int])) |
| 1439 | + |
| 1440 | + class B[T1, T2, T3=dict[T1, T2]]: ... |
| 1441 | + |
| 1442 | + self.assertEqual(B[int, str].__args__, (int, str, dict[int, str])) |
| 1443 | + |
| 1444 | + class C[T1, T2, T3=T1 | T2]: ... |
| 1445 | + |
| 1446 | + self.assertEqual(C[int, str].__args__, (int, str, int | str)) |
| 1447 | + |
| 1448 | + class D[T1, T2=Callable[[T1], T1]]: ... |
| 1449 | + |
| 1450 | + self.assertEqual(D[int].__args__, (int, Callable[[int], int])) |
| 1451 | + |
| 1452 | + def test_default_refers_to_earlier_type_param_typevartuple(self): |
| 1453 | + class A[T1, *Ts=*tuple[T1, ...]]: ... |
| 1454 | + |
| 1455 | + self.assertEqual(A[int].__args__, (int, *tuple[int, ...])) |
| 1456 | + |
| 1457 | + class B[T1, T2, *Ts=*tuple[T1, T2]]: ... |
| 1458 | + |
| 1459 | + self.assertEqual(B[int, str].__args__, (int, str, int, str)) |
| 1460 | + |
| 1461 | + def test_default_refers_to_earlier_type_param_paramspec(self): |
| 1462 | + class A[T1, **P=[T1, int]]: ... |
| 1463 | + |
| 1464 | + self.assertEqual(A[str].__args__, (str, (str, int))) |
| 1465 | + |
| 1466 | + class B[**P, T=int]: ... |
| 1467 | + |
| 1468 | + self.assertEqual(B[[int, str]].__args__, ((int, str), int)) |
| 1469 | + |
| 1470 | + def test_default_refers_to_earlier_type_param_in_base_class(self): |
| 1471 | + # gh-140596: omitting a type parameter with a default when |
| 1472 | + # subclassing used to leave the default unsubstituted, which made |
| 1473 | + # the type parameter it refers to leak into the subclass. |
| 1474 | + class Bar[T, S=T]: ... |
| 1475 | + class Baz[U](Bar[U]): ... |
| 1476 | + |
| 1477 | + U, = Baz.__type_params__ |
| 1478 | + self.assertEqual(Baz.__orig_bases__[0].__args__, (U, U)) |
| 1479 | + self.assertEqual(Baz.__parameters__, (U,)) |
| 1480 | + self.assertEqual(Baz[int].__args__, (int,)) |
| 1481 | + |
| 1482 | + def test_default_refers_to_type_param_from_enclosing_scope(self): |
| 1483 | + # A default that refers to a type variable which is not a type |
| 1484 | + # parameter of the class itself is left untouched. |
| 1485 | + T = TypeVar('T') |
| 1486 | + S = TypeVar('S', default=T) |
| 1487 | + class A(Generic[S]): ... |
| 1488 | + |
| 1489 | + self.assertEqual(A[()].__args__, (T,)) |
| 1490 | + |
| 1491 | + def test_default_refers_to_type_param_supplied_by_the_user(self): |
| 1492 | + T = TypeVar('T') |
| 1493 | + class A[T1, T2=T1]: ... |
| 1494 | + |
| 1495 | + self.assertEqual(A[T].__args__, (T, T)) |
| 1496 | + |
| 1497 | + def test_default_refers_to_itself(self): |
| 1498 | + class A[T1=T1]: ... |
| 1499 | + |
| 1500 | + with self.assertRaisesRegex( |
| 1501 | + TypeError, |
| 1502 | + r"The default of type parameter T1 refers to type parameter T1, " |
| 1503 | + r"which is not declared before it", |
| 1504 | + ): |
| 1505 | + A[()] |
| 1506 | + |
| 1507 | + def test_default_refers_to_later_type_param(self): |
| 1508 | + class A[T1=T2, T2=int]: ... |
| 1509 | + |
| 1510 | + with self.assertRaisesRegex( |
| 1511 | + TypeError, |
| 1512 | + r"The default of type parameter T1 refers to type parameter T2, " |
| 1513 | + r"which is not declared before it", |
| 1514 | + ): |
| 1515 | + A[()] |
| 1516 | + |
| 1517 | + def test_defaults_refer_to_each_other(self): |
| 1518 | + class A[T1=T2, T2=T1]: ... |
| 1519 | + |
| 1520 | + with self.assertRaisesRegex( |
| 1521 | + TypeError, |
| 1522 | + r"The default of type parameter T1 refers to type parameter T2, " |
| 1523 | + r"which is not declared before it", |
| 1524 | + ): |
| 1525 | + A[()] |
| 1526 | + |
1421 | 1527 |
|
1422 | 1528 | class TestEvaluateFunctions(unittest.TestCase): |
1423 | 1529 | def test_general(self): |
|
0 commit comments