Skip to content

Commit a3a4d20

Browse files
authored
bpo-44524: Fix cryptic TypeError message when trying to subclass special forms in typing (GH-27710)
This was a Python 3.9 regression.
1 parent 6fb62b4 commit a3a4d20

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

Lib/test/test_typing.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,22 @@ def __new__(cls, arg):
24242424
self.assertEqual(c.from_b, 'b')
24252425
self.assertEqual(c.from_c, 'c')
24262426

2427+
def test_subclass_special_form(self):
2428+
for obj in (
2429+
ClassVar[int],
2430+
Final[int],
2431+
Union[int, float],
2432+
Optional[int],
2433+
Literal[1, 2],
2434+
Concatenate[int, ParamSpec("P")],
2435+
TypeGuard[int],
2436+
):
2437+
with self.subTest(msg=obj):
2438+
with self.assertRaisesRegex(
2439+
TypeError, f'^{re.escape(f"Cannot subclass {obj!r}")}$'
2440+
):
2441+
class Foo(obj):
2442+
pass
24272443

24282444
class ClassVarTests(BaseTestCase):
24292445

Lib/typing.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,9 @@ def __reduce__(self):
10861086
return operator.getitem, (origin, args)
10871087

10881088
def __mro_entries__(self, bases):
1089+
if isinstance(self.__origin__, _SpecialForm):
1090+
raise TypeError(f"Cannot subclass {self!r}")
1091+
10891092
if self._name: # generic version of an ABC or built-in class
10901093
return super().__mro_entries__(bases)
10911094
if self.__origin__ is Generic:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Make exception message more useful when subclass from typing special form
2+
alias. Patch provided by Yurii Karabas.

0 commit comments

Comments
 (0)